Add unit test and documentation for module API

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
This commit is contained in:
Chris Adams 2011-05-06 13:18:19 +10:00
parent e50b7c9299
commit 24bb6f90f8
5 changed files with 119 additions and 2 deletions

View 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 *))
{

View 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();
}
}

View 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();

View 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();

View 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);