From: Chris Adams Date: Wed, 3 Aug 2011 01:04:01 +0000 (+1000) Subject: Implement script module api property get and set X-Git-Url: http://git.silmor.de/gitweb/?a=commitdiff_plain;h=be244df6cdce029eeb04d3e919ccf5c4983bd3e4;p=konrad%2Fqtdeclarative.git Implement script module api property get and set This commit adds code for property get and set for script module APIs, and also splits up the module API unit tests into QObject and Script (QJSValue) parts. Related to commit: 3ee8a19f5b7142b96e2df649ea0dac444b5622a2 Task-number: QMLNG-33 Task-number: QTBUG-17318 Change-Id: I4aaf5d1cc1d4774dd0f0999f0985439e4d76f0ca Reviewed-on: http://codereview.qt.nokia.com/1472 Reviewed-by: Qt Sanity Bot Reviewed-by: Aaron Kennedy --- diff --git a/src/declarative/qml/qdeclarative.h b/src/declarative/qml/qdeclarative.h index 311ecd3..a0eb98d 100644 --- a/src/declarative/qml/qdeclarative.h +++ b/src/declarative/qml/qdeclarative.h @@ -420,33 +420,35 @@ Q_DECLARATIVE_EXPORT void qmlRegisterBaseTypes(const char *uri, int versionMajor Installing a module API into a uri allows developers to provide arbitrary functionality (methods and properties) in a namespace that doesn't necessarily contain elements. - A module API may be either a QObject or a QScriptValue. Only one module API provider + A module API may be either a QObject or a QJSValue. Only one module API provider may be registered into any given namespace (combination of \a uri, \a majorVersion and \a minorVersion). - This function should be used to register a module API provider function which returns a QScriptValue as a module API. + This function should be used to register a module API provider function which returns a QJSValue as a module API. + + \e NOTE: QJSValue module API properties will \e not trigger binding re-evaluation if changed. Usage: \code // first, define the module API provider function (callback). - static QScriptValue *example_qscriptvalue_module_api_provider(QDeclarativeEngine *engine, QScriptEngine *scriptEngine) + static QJSValue *example_qjsvalue_module_api_provider(QDeclarativeEngine *engine, QJSEngine *scriptEngine) { Q_UNUSED(engine) static int seedValue = 5; - QScriptValue example = scriptEngine->newObject(); + QJSValue example = scriptEngine->newObject(); example.setProperty("someProperty", seedValue++); return example; } // second, register the module API provider with QML by calling this function in an initialization function. ... - qmlRegisterModuleApi("Qt.example.qscriptvalueApi", 1, 0, example_qscriptvalue_module_api_provider); + qmlRegisterModuleApi("Qt.example.qjsvalueApi", 1, 0, example_qjsvalue_module_api_provider); ... \endcode In order to use the registered module API in QML, you must import the module API. \qml import QtQuick 2.0 - import Qt.example.qscriptvalueApi 1.0 as ExampleApi + import Qt.example.qjsvalueApi 1.0 as ExampleApi Item { id: root property int someValue: ExampleApi.someProperty @@ -474,7 +476,7 @@ inline int qmlRegisterModuleApi(const char *uri, int versionMajor, int versionMi Installing a module API into a uri allows developers to provide arbitrary functionality (methods and properties) in a namespace that doesn't necessarily contain elements. - A module API may be either a QObject or a QScriptValue. Only one module API provider + A module API may be either a QObject or a QJSValue. Only one module API provider may be registered into any given namespace (combination of \a uri, \a majorVersion and \a minorVersion). This function should be used to register a module API provider function which returns a QObject as a module API. @@ -507,7 +509,7 @@ inline int qmlRegisterModuleApi(const char *uri, int versionMajor, int versionMi }; // second, define the module API provider function (callback). - static QObject *example_qobject_module_api_provider(QDeclarativeEngine *engine, QScriptEngine *scriptEngine) + static QObject *example_qobject_module_api_provider(QDeclarativeEngine *engine, QJSEngine *scriptEngine) { Q_UNUSED(engine) Q_UNUSED(scriptEngine) diff --git a/src/declarative/qml/v8/qv8typewrapper.cpp b/src/declarative/qml/v8/qv8typewrapper.cpp index c51a2ee..98ed1d5 100644 --- a/src/declarative/qml/v8/qv8typewrapper.cpp +++ b/src/declarative/qml/v8/qv8typewrapper.cpp @@ -45,6 +45,9 @@ #include #include +#include +#include + QT_BEGIN_NAMESPACE class QV8TypeResource : public QV8ObjectResource @@ -186,6 +189,11 @@ v8::Handle QV8TypeWrapper::Getter(v8::Local property, if (moduleApi->qobjectApi) { v8::Handle rv = v8engine->qobjectWrapper()->getProperty(moduleApi->qobjectApi, propertystring, QV8QObjectWrapper::IgnoreRevision); return rv; + } else if (moduleApi->scriptApi.isValid()) { + // NOTE: if used in a binding, changes will not trigger re-evaluation since non-NOTIFYable. + QJSValuePrivate *apiprivate = QJSValuePrivate::get(moduleApi->scriptApi); + QScopedPointer propertyValue(apiprivate->property(property).give()); + return propertyValue->asV8Value(v8engine); } else { return v8::Handle(); } @@ -212,8 +220,6 @@ v8::Handle QV8TypeWrapper::Setter(v8::Local property, QV8Engine *v8engine = resource->engine; - // XXX TODO: Implement writes to module API objects - QHashedV8String propertystring(property); if (resource->type && resource->object) { @@ -235,9 +241,20 @@ v8::Handle QV8TypeWrapper::Setter(v8::Local property, moduleApi->qobjectCallback = 0; } - if (moduleApi->qobjectApi) + if (moduleApi->qobjectApi) { v8engine->qobjectWrapper()->setProperty(moduleApi->qobjectApi, propertystring, value, QV8QObjectWrapper::IgnoreRevision); + } else if (moduleApi->scriptApi.isValid()) { + QScopedPointer setvalp(new QJSValuePrivate(v8engine, value)); + QJSValuePrivate *apiprivate = QJSValuePrivate::get(moduleApi->scriptApi); + if (apiprivate->propertyFlags(property) & QJSValue::ReadOnly) { + QString error = QLatin1String("Cannot assign to read-only property \"") + + v8engine->toString(property) + QLatin1Char('\"'); + v8::ThrowException(v8::Exception::Error(v8engine->toString(error))); + } else { + apiprivate->setProperty(property, setvalp.data()); + } + } } } diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/moduleApiMajorVersionFail.qml b/tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/moduleApiMajorVersionFail.qml similarity index 100% rename from tests/auto/declarative/qdeclarativeecmascript/data/moduleApiMajorVersionFail.qml rename to tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/moduleApiMajorVersionFail.qml diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/moduleApiMinorVersionFail.qml b/tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/moduleApiMinorVersionFail.qml similarity index 100% rename from tests/auto/declarative/qdeclarativeecmascript/data/moduleApiMinorVersionFail.qml rename to tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/moduleApiMinorVersionFail.qml diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/moduleApi.qml b/tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/qobjectModuleApi.qml similarity index 87% rename from tests/auto/declarative/qdeclarativeecmascript/data/moduleApi.qml rename to tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/qobjectModuleApi.qml index 67e8c1b..718a646 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/data/moduleApi.qml +++ b/tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/qobjectModuleApi.qml @@ -1,7 +1,6 @@ import QtQuick 2.0 import Qt.test 1.0 as QtTest // module API installed into existing uri -import Qt.test.scriptApi 1.0 as QtTestScriptApi // script module API installed into new uri import Qt.test.qobjectApi 1.0 as QtTestQObjectApi // qobject module API installed into new uri import Qt.test.qobjectApi 1.3 as QtTestMinorVersionQObjectApi // qobject module API installed into existing uri with new minor version import Qt.test.qobjectApi 2.0 as QtTestMajorVersionQObjectApi // qobject module API installed into existing uri with new major version @@ -9,7 +8,6 @@ import Qt.test.qobjectApiParented 1.0 as QtTestParentedQObjectApi // qobject (wi QtObject { property int existingUriTest: QtTest.qobjectTestProperty - property int scriptTest: QtTestScriptApi.scriptTestProperty property int qobjectTest: QtTestQObjectApi.qobjectTestProperty property int qobjectMethodTest: 2 property int qobjectMinorVersionTest: QtTestMinorVersionQObjectApi.qobjectTestProperty diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/moduleApiCaching.qml b/tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/qobjectModuleApiCaching.qml similarity index 70% rename from tests/auto/declarative/qdeclarativeecmascript/data/moduleApiCaching.qml rename to tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/qobjectModuleApiCaching.qml index f6ce205..56a55e4 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/data/moduleApiCaching.qml +++ b/tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/qobjectModuleApiCaching.qml @@ -1,12 +1,10 @@ import QtQuick 2.0 import Qt.test 1.0 as QtTest // module API installed into existing uri -import Qt.test.scriptApi 1.0 as QtTestScriptApi // script module API installed into new uri import Qt.test.qobjectApiParented 1.0 as QtTestParentedQObjectApi // qobject (with parent) module API installed into a new uri QtObject { property int existingUriTest: QtTest.qobjectTestProperty - property int scriptTest: QtTestScriptApi.scriptTestProperty property int qobjectParentedTest: QtTestParentedQObjectApi.qobjectTestProperty } diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/moduleApiWriting.qml b/tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/qobjectModuleApiWriting.qml similarity index 91% rename from tests/auto/declarative/qdeclarativeecmascript/data/moduleApiWriting.qml rename to tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/qobjectModuleApiWriting.qml index 500c35e..be647ca 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/data/moduleApiWriting.qml +++ b/tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/qobjectModuleApiWriting.qml @@ -1,6 +1,5 @@ import QtQuick 2.0 - -import Qt.test 1.0 as QtTest // module API installed into existing uri +import Qt.test 1.0 as QtTest // qobject module API installed into existing uri QtObject { property int firstProperty: 1 diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/scriptModuleApi.qml b/tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/scriptModuleApi.qml new file mode 100644 index 0000000..7c4e204 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/scriptModuleApi.qml @@ -0,0 +1,6 @@ +import QtQuick 2.0 +import Qt.test.scriptApi 1.0 as QtTestScriptApi // script module API installed into new uri + +QtObject { + property int scriptTest: QtTestScriptApi.scriptTestProperty // script module api's only provide properties. +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/scriptModuleApiCaching.qml b/tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/scriptModuleApiCaching.qml new file mode 100644 index 0000000..90974b5 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/scriptModuleApiCaching.qml @@ -0,0 +1,6 @@ +import QtQuick 2.0 +import Qt.test.scriptApi 1.0 as QtTestScriptApi // script module API installed into new uri + +QtObject { + property int scriptTest: QtTestScriptApi.scriptTestProperty +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/scriptModuleApiWriting.qml b/tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/scriptModuleApiWriting.qml new file mode 100644 index 0000000..02461d5 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/moduleapi/scriptModuleApiWriting.qml @@ -0,0 +1,32 @@ +import QtQuick 2.0 +import Qt.test.scriptApi 1.0 as QtTestScriptApi +import Qt.test.scriptApi 2.0 as QtTestScriptApi2 + +QtObject { + property int firstProperty + property int readBack + + property int secondProperty + property int unchanged + + onFirstPropertyChanged: { + if (QtTestScriptApi.scriptTestProperty != firstProperty) { + QtTestScriptApi.scriptTestProperty = firstProperty; + readBack = QtTestScriptApi.scriptTestProperty; + } + } + + onSecondPropertyChanged: { + if (QtTestScriptApi2.scriptTestProperty != secondProperty) { + QtTestScriptApi2.scriptTestProperty = secondProperty; + unchanged = QtTestScriptApi2.scriptTestProperty; + } + } + + Component.onCompleted: { + firstProperty = QtTestScriptApi.scriptTestProperty; + readBack = QtTestScriptApi.scriptTestProperty; + secondProperty = QtTestScriptApi2.scriptTestProperty; + unchanged = QtTestScriptApi2.scriptTestProperty; + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/testtypes.cpp b/tests/auto/declarative/qdeclarativeecmascript/testtypes.cpp index 160a572..05d5510 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/testtypes.cpp +++ b/tests/auto/declarative/qdeclarativeecmascript/testtypes.cpp @@ -111,6 +111,21 @@ static QJSValue script_api(QDeclarativeEngine *engine, QJSEngine *scriptEngine) return v; } +static QJSValue readonly_script_api(QDeclarativeEngine *engine, QJSEngine *scriptEngine) +{ + Q_UNUSED(engine) + + static int testProperty = 42; + QJSValue v = scriptEngine->newObject(); + v.setProperty("scriptTestProperty", testProperty++); + + // now freeze it so that it's read-only + QJSValue freezeFunction = scriptEngine->evaluate("(function(obj) { return Object.freeze(obj); })"); + v = freezeFunction.call(QJSValue(), (QJSValueList() << v)); + + return v; +} + static QObject *qobject_api(QDeclarativeEngine *engine, QJSEngine *scriptEngine) { Q_UNUSED(engine) @@ -166,6 +181,7 @@ void registerTypes() qmlRegisterModuleApi("Qt.test",1,0,script_api); // register (script) module API for an existing uri which contains elements qmlRegisterModuleApi("Qt.test",1,0,qobject_api); // register (qobject) for an existing uri for which another module API was previously regd. Should replace! qmlRegisterModuleApi("Qt.test.scriptApi",1,0,script_api); // register (script) module API for a uri which doesn't contain elements + qmlRegisterModuleApi("Qt.test.scriptApi",2,0,readonly_script_api); // register (script) module API for a uri which doesn't contain elements - will be made read-only qmlRegisterModuleApi("Qt.test.qobjectApi",1,0,qobject_api); // register (qobject) module API for a uri which doesn't contain elements qmlRegisterModuleApi("Qt.test.qobjectApi",1,3,qobject_api); // register (qobject) module API for a uri which doesn't contain elements, minor version set qmlRegisterModuleApi("Qt.test.qobjectApi",2,0,qobject_api); // register (qobject) module API for a uri which doesn't contain elements, major version set diff --git a/tests/auto/declarative/qdeclarativeecmascript/testtypes.h b/tests/auto/declarative/qdeclarativeecmascript/testtypes.h index afb361e..d88fcd0 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/testtypes.h +++ b/tests/auto/declarative/qdeclarativeecmascript/testtypes.h @@ -945,7 +945,7 @@ public: ~testQObjectApi() {} - Q_INVOKABLE int qobjectTestMethod() { m_methodCallCount += 1; return m_methodCallCount; } + Q_INVOKABLE int qobjectTestMethod(int increment = 1) { m_methodCallCount += increment; return m_methodCallCount; } int qobjectTestProperty() const { return m_testProperty; } void setQObjectTestProperty(int tp) { m_testProperty = tp; emit qobjectTestPropertyChanged(tp); } diff --git a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp index 3efe189..111c04d 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp +++ b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp @@ -145,6 +145,7 @@ private slots: void numberAssignment(); void propertySplicing(); void signalWithUnknownTypes(); + void moduleApi_data(); void moduleApi(); void importScripts(); void scarceResources(); @@ -2735,55 +2736,142 @@ void tst_qdeclarativeecmascript::signalWithUnknownTypes() delete object; } +void tst_qdeclarativeecmascript::moduleApi_data() +{ + QTest::addColumn("testfile"); + QTest::addColumn("errorMessage"); + QTest::addColumn("warningMessages"); + QTest::addColumn("readProperties"); + QTest::addColumn("readExpectedValues"); + QTest::addColumn("writeProperties"); + QTest::addColumn("writeValues"); + QTest::addColumn("readBackProperties"); + QTest::addColumn("readBackExpectedValues"); + + QTest::newRow("qobject, register + read + method") + << TEST_FILE("moduleapi/qobjectModuleApi.qml") + << QString() + << QStringList() + << (QStringList() << "existingUriTest" << "qobjectTest" << "qobjectMethodTest" + << "qobjectMinorVersionTest" << "qobjectMajorVersionTest" << "qobjectParentedTest") + << (QVariantList() << 20 << 20 << 1 << 20 << 20 << 26) + << QStringList() + << QVariantList() + << QStringList() + << QVariantList(); + + QTest::newRow("script, register + read") + << TEST_FILE("moduleapi/scriptModuleApi.qml") + << QString() + << QStringList() + << (QStringList() << "scriptTest") + << (QVariantList() << 13) + << QStringList() + << QVariantList() + << QStringList() + << QVariantList(); + + QTest::newRow("qobject, caching + read") + << TEST_FILE("moduleapi/qobjectModuleApiCaching.qml") + << QString() + << QStringList() + << (QStringList() << "existingUriTest" << "qobjectParentedTest") + << (QVariantList() << 20 << 26) // 26, shouldn't have incremented to 27. + << QStringList() + << QVariantList() + << QStringList() + << QVariantList(); + + QTest::newRow("script, caching + read") + << TEST_FILE("moduleapi/scriptModuleApiCaching.qml") + << QString() + << QStringList() + << (QStringList() << "scriptTest") + << (QVariantList() << 13) // 13, shouldn't have incremented to 14. + << QStringList() + << QVariantList() + << QStringList() + << QVariantList(); + + QTest::newRow("qobject, writing + readonly constraints") + << TEST_FILE("moduleapi/qobjectModuleApiWriting.qml") + << QString() + << (QStringList() << QString(QLatin1String("file://") + TEST_FILE("moduleapi/qobjectModuleApiWriting.qml").toLocalFile() + QLatin1String(":14: Error: Cannot assign to read-only property \"qobjectTestProperty\""))) + << (QStringList() << "readOnlyProperty" << "writableProperty") + << (QVariantList() << 20 << 50) + << (QStringList() << "firstProperty" << "writableProperty") + << (QVariantList() << 30 << 30) + << (QStringList() << "readOnlyProperty" << "writableProperty") + << (QVariantList() << 20 << 30); + + QTest::newRow("script, writing + readonly constraints") + << TEST_FILE("moduleapi/scriptModuleApiWriting.qml") + << QString() + << (QStringList() << QString(QLatin1String("file://") + TEST_FILE("moduleapi/scriptModuleApiWriting.qml").toLocalFile() + QLatin1String(":21: Error: Cannot assign to read-only property \"scriptTestProperty\""))) + << (QStringList() << "readBack" << "unchanged") + << (QVariantList() << 13 << 42) + << (QStringList() << "firstProperty" << "secondProperty") + << (QVariantList() << 30 << 30) + << (QStringList() << "readBack" << "unchanged") + << (QVariantList() << 30 << 42); + + QTest::newRow("qobject, invalid major version fail") + << TEST_FILE("moduleapi/moduleApiMajorVersionFail.qml") + << QString("QDeclarativeComponent: Component is not ready") + << QStringList() + << QStringList() + << QVariantList() + << QStringList() + << QVariantList() + << QStringList() + << QVariantList(); + + QTest::newRow("qobject, invalid minor version fail") + << TEST_FILE("moduleapi/moduleApiMinorVersionFail.qml") + << QString("QDeclarativeComponent: Component is not ready") + << QStringList() + << QStringList() + << QVariantList() + << QStringList() + << QVariantList() + << QStringList() + << QVariantList(); +} + void tst_qdeclarativeecmascript::moduleApi() { - QDeclarativeComponent component(&engine, TEST_FILE("moduleApi.qml")); - QObject *object = component.create(); - QVERIFY(object != 0); - QCOMPARE(object->property("existingUriTest").toInt(), 20); + QFETCH(QUrl, testfile); + QFETCH(QString, errorMessage); + QFETCH(QStringList, warningMessages); + QFETCH(QStringList, readProperties); + QFETCH(QVariantList, readExpectedValues); + QFETCH(QStringList, writeProperties); + QFETCH(QVariantList, writeValues); + QFETCH(QStringList, readBackProperties); + QFETCH(QVariantList, readBackExpectedValues); - QEXPECT_FAIL("", "QTBUG-17318", Continue); - QCOMPARE(object->property("scriptTest").toInt(), 13); - QCOMPARE(object->property("qobjectTest").toInt(), 20); - QCOMPARE(object->property("qobjectMethodTest").toInt(), 1); // first call of method, so count = 1. - QCOMPARE(object->property("qobjectMinorVersionTest").toInt(), 20); - QCOMPARE(object->property("qobjectMajorVersionTest").toInt(), 20); - QCOMPARE(object->property("qobjectParentedTest").toInt(), 26); - delete object; + QDeclarativeComponent component(&engine, testfile); - // test that caching of module apis works correctly. - QDeclarativeComponent componentTwo(&engine, TEST_FILE("moduleApiCaching.qml")); - object = componentTwo.create(); - QVERIFY(object != 0); - QCOMPARE(object->property("existingUriTest").toInt(), 20); - QEXPECT_FAIL("", "QTBUG-17318", Continue); - QCOMPARE(object->property("scriptTest").toInt(), 13); // shouldn't have incremented. - QCOMPARE(object->property("qobjectParentedTest").toInt(), 26); // shouldn't have incremented. - delete object; + if (!errorMessage.isEmpty()) + QTest::ignoreMessage(QtWarningMsg, errorMessage.toAscii().constData()); - // test that writing to a property of module apis works correctly. - QDeclarativeComponent componentThree(&engine, TEST_FILE("moduleApiWriting.qml")); - QString expectedWarning = QLatin1String("file://") + TEST_FILE("moduleApiWriting.qml").toLocalFile() + QLatin1String(":15: Error: Cannot assign to read-only property \"qobjectTestProperty\""); - QTest::ignoreMessage(QtWarningMsg, expectedWarning.toAscii().constData()); - object = componentThree.create(); - QVERIFY(object != 0); - QCOMPARE(object->property("readOnlyProperty").toInt(), 20); - QCOMPARE(object->property("writableProperty").toInt(), 50); - QVERIFY(object->setProperty("firstProperty", QVariant(30))); // shouldn't affect value of readOnlyProperty - QVERIFY(object->setProperty("writableProperty", QVariant(30))); // SHOULD affect value of writableProperty - QCOMPARE(object->property("readOnlyProperty").toInt(), 20); - QCOMPARE(object->property("writableProperty").toInt(), 30); - delete object; + if (warningMessages.size()) + foreach (const QString &warning, warningMessages) + QTest::ignoreMessage(QtWarningMsg, warning.toAscii().constData()); - QDeclarativeComponent failOne(&engine, TEST_FILE("moduleApiMajorVersionFail.qml")); - QTest::ignoreMessage(QtWarningMsg, "QDeclarativeComponent: Component is not ready"); - object = failOne.create(); - QVERIFY(object == 0); // should have failed: invalid major version - - QDeclarativeComponent failTwo(&engine, TEST_FILE("moduleApiMinorVersionFail.qml")); - QTest::ignoreMessage(QtWarningMsg, "QDeclarativeComponent: Component is not ready"); - object = failTwo.create(); - QVERIFY(object == 0); // should have failed: invalid minor version + QObject *object = component.create(); + if (!errorMessage.isEmpty()) { + QVERIFY(object == 0); + } else { + QVERIFY(object != 0); + for (int i = 0; i < readProperties.size(); ++i) + QCOMPARE(object->property(readProperties.at(i).toAscii().constData()), readExpectedValues.at(i)); + for (int i = 0; i < writeProperties.size(); ++i) + QVERIFY(object->setProperty(writeProperties.at(i).toAscii().constData(), writeValues.at(i))); + for (int i = 0; i < readBackProperties.size(); ++i) + QCOMPARE(object->property(readBackProperties.at(i).toAscii().constData()), readBackExpectedValues.at(i)); + delete object; + } } void tst_qdeclarativeecmascript::importScripts()