Add unit test and documentation for module API
authorChris Adams <christopher.adams@nokia.com>
Fri, 6 May 2011 03:18:19 +0000 (13:18 +1000)
committerChris Adams <christopher.adams@nokia.com>
Fri, 6 May 2011 03:56:10 +0000 (13:56 +1000)
Related to commit ae6c7a44394d4a5f943f1fc92f4de015ec7bcc96.
Previously, only property access on module API was tested.
This commit adds a test which calls a method on a module API.
It also adds documentation for the qmlRegisterModuleApi functions.

Task-number: QMLNG-33
Reviewed-by: Martin Jones
src/declarative/qml/qdeclarative.h
tests/auto/declarative/qdeclarativeecmascript/data/moduleApi.qml
tests/auto/declarative/qdeclarativeecmascript/testtypes.cpp
tests/auto/declarative/qdeclarativeecmascript/testtypes.h
tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp

index 9227260..f3d91e8 100644 (file)
@@ -410,6 +410,46 @@ QObject *qmlAttachedPropertiesObject(const QObject *obj, bool create = true)
     return qmlAttachedPropertiesObject(&idx, obj, &T::staticMetaObject, create);
 }
 
+/*!
+   This function may be used to register a module API provider \a callback in a particular \a uri
+   with a version specified in \a versionMajor and \a versionMinor.
+
+   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
+   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.
+
+   Usage:
+   \code
+   // first, define the module API provider function (callback).
+   static QScriptValue *example_qscriptvalue_module_api_provider(QDeclarativeEngine *engine, QScriptEngine *scriptEngine)
+   {
+       Q_UNUSED(engine)
+
+       static int seedValue = 5;
+       QScriptValue 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);
+   ...
+   \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
+   Item {
+       id: root
+       property int someValue: ExampleApi.someProperty
+   }
+   \endqml
+  */
 inline int qmlRegisterModuleApi(const char *uri, int versionMajor, int versionMinor,
                                 QScriptValue (*callback)(QDeclarativeEngine *, QScriptEngine *))
 {
@@ -424,6 +464,75 @@ inline int qmlRegisterModuleApi(const char *uri, int versionMajor, int versionMi
     return QDeclarativePrivate::qmlregister(QDeclarativePrivate::ModuleApiRegistration, &api);
 }
 
+/*!
+   This function may be used to register a module API provider \a callback in a particular \a uri
+   with a version specified in \a versionMajor and \a versionMinor.
+
+   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
+   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.
+
+   Usage:
+   \code
+   // first, define your QObject which provides the functionality.
+   class ModuleApiExample : public QObject
+   {
+       Q_OBJECT
+       Q_PROPERTY (int someProperty READ someProperty WRITE setSomeProperty NOTIFY somePropertyChanged)
+
+   public:
+       ModuleApiExample(QObject* parent = 0)
+           : QObject(parent), m_someProperty(0)
+       {
+       }
+
+       ~ModuleApiExample() {}
+
+       Q_INVOKABLE int doSomething() { setSomeProperty(5); return m_someProperty; }
+
+       int someProperty() const { return m_someProperty; }
+       void setSomeProperty(int val) { m_someProperty = val; emit somePropertyChanged(val); }
+
+   signals:
+       void somePropertyChanged(int newValue);
+
+   private:
+       int m_someProperty;
+   };
+
+   // second, define the module API provider function (callback).
+   static QObject *example_qobject_module_api_provider(QDeclarativeEngine *engine, QScriptEngine *scriptEngine)
+   {
+       Q_UNUSED(engine)
+       Q_UNUSED(scriptEngine)
+
+       ModuleApiExample *example = new ModuleApiExample();
+       return example;
+   }
+
+   // third, register the module API provider with QML by calling this function in an initialization function.
+   ...
+   qmlRegisterModuleApi("Qt.example.qobjectApi", 1, 0, example_qobject_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.qobjectApi 1.0 as ExampleApi
+   Item {
+       id: root
+       property int someValue: ExampleApi.someProperty
+
+       Component.onCompleted: {
+           someValue = ExampleApi.doSomething()
+       }
+   }
+   \endqml
+  */
 inline int qmlRegisterModuleApi(const char *uri, int versionMajor, int versionMinor,
                                 QObject *(*callback)(QDeclarativeEngine *, QScriptEngine *))
 {
index 62abcb7..23c1eb0 100644 (file)
@@ -11,8 +11,13 @@ 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
     property int qobjectMajorVersionTest: QtTestMajorVersionQObjectApi.qobjectTestProperty
     property int qobjectParentedTest: QtTestParentedQObjectApi.qobjectTestProperty
+
+    Component.onCompleted: {
+        qobjectMethodTest = QtTestQObjectApi.qobjectTestMethod();
+    }
 }
 
index 7256d44..44d0046 100644 (file)
@@ -104,7 +104,6 @@ public:
 static QScriptValue script_api(QDeclarativeEngine *engine, QScriptEngine *scriptEngine)
 {
     Q_UNUSED(engine)
-    Q_UNUSED(scriptEngine)
 
     static int testProperty = 13;
     QScriptValue v = scriptEngine->newObject();
index 320e60c..8c7b838 100644 (file)
@@ -939,12 +939,14 @@ class testQObjectApi : public QObject
 
 public:
     testQObjectApi(QObject* parent = 0)
-        : QObject(parent), m_testProperty(0)
+        : QObject(parent), m_testProperty(0), m_testWritableProperty(0), m_methodCallCount(0)
     {
     }
 
     ~testQObjectApi() {}
 
+    Q_INVOKABLE int qobjectTestMethod() { m_methodCallCount += 1; return m_methodCallCount; }
+
     int qobjectTestProperty() const { return m_testProperty; }
     void setQObjectTestProperty(int tp) { m_testProperty = tp; emit qobjectTestPropertyChanged(tp); }
 
@@ -958,6 +960,7 @@ signals:
 private:
     int m_testProperty;
     int m_testWritableProperty;
+    int m_methodCallCount;
 };
 
 void registerTypes();
index efa95d3..d9cd825 100644 (file)
@@ -2509,6 +2509,7 @@ void tst_qdeclarativeecmascript::moduleApi()
     QCOMPARE(object->property("existingUriTest").toInt(), 20);
     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);