summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWarwick Allison <warwick.allison@nokia.com>2009-09-10 00:20:35 (GMT)
committerWarwick Allison <warwick.allison@nokia.com>2009-09-10 00:20:35 (GMT)
commit487c18cebc3fac5db3506bc8c64417feeb85c6b9 (patch)
treef6f47673e25d07c06570719c5e82290ec563cb71
parenta250db23c96fc1ec47ea4d19d62a19cad7c50b46 (diff)
parent8fdbb7474d41a8b2e0581c06a7f075549ef29336 (diff)
downloadQt-487c18cebc3fac5db3506bc8c64417feeb85c6b9.zip
Qt-487c18cebc3fac5db3506bc8c64417feeb85c6b9.tar.gz
Qt-487c18cebc3fac5db3506bc8c64417feeb85c6b9.tar.bz2
Merge branch 'kinetic-declarativeui' of git@scm.dev.nokia.troll.no:qt/kinetic into kinetic-declarativeui
-rw-r--r--doc/src/declarative/qmlformat.qdoc6
-rw-r--r--tests/auto/declarative/qfxtextinput/data/navigation.qml4
-rw-r--r--tests/auto/declarative/qfxtextinput/tst_qfxtextinput.cpp291
-rw-r--r--tests/auto/declarative/qmlparser/Alias.qml8
-rw-r--r--tests/auto/declarative/qmlparser/alias.1.qml8
-rw-r--r--tests/auto/declarative/qmlparser/alias.2.qml8
-rw-r--r--tests/auto/declarative/qmlparser/alias.3.qml10
-rw-r--r--tests/auto/declarative/qmlparser/testtypes.h8
-rw-r--r--tests/auto/declarative/qmlparser/tst_qmlparser.cpp71
9 files changed, 406 insertions, 8 deletions
diff --git a/doc/src/declarative/qmlformat.qdoc b/doc/src/declarative/qmlformat.qdoc
index 5013ee7..f16adca 100644
--- a/doc/src/declarative/qmlformat.qdoc
+++ b/doc/src/declarative/qmlformat.qdoc
@@ -91,8 +91,8 @@ The blue rectangle in the diagram represents a property binding. Associated wit
binding is the QML context to which it belongs, the object property to which it is bound and a
\e {scope object}. The scope object is usually, but not always, the object to which the bound
property belongs. The context properties, context default objects and the scope object are all
-involved when resolving a variable name in a binding. The following psuedo code describes the
-alogithm used:
+involved when resolving a variable name in a binding. The following pseudo code describes the
+algorithm used:
\table
\row
@@ -139,7 +139,7 @@ To the QML engine, a composite type is just another QML document. When a compos
used the engine instantiates it just as it would any other document - by creating a new implicit
QML context and the object tree described by the document. The diagram below shows the
\c SquareImage composite type used from within another QML document. When instantiated, the
-\c SquareImage object is created in its own QML context. Any property bindings sepecified in the
+\c SquareImage object is created in its own QML context. Any property bindings specified in the
\c SquareImage composite type document are associated with this context. Property bindings created
in the outer document, however, are associated with its context, even those that are applied to the
created \c SquareImage object. That is, the \c size, \c source, \c width and \c height property
diff --git a/tests/auto/declarative/qfxtextinput/data/navigation.qml b/tests/auto/declarative/qfxtextinput/data/navigation.qml
index c1a6162..282c52c 100644
--- a/tests/auto/declarative/qfxtextinput/data/navigation.qml
+++ b/tests/auto/declarative/qfxtextinput/data/navigation.qml
@@ -6,11 +6,11 @@ Rectangle {
width: 800; height: 600; color: "blue"
Item {
- id: FirstItem
+ id: FirstItem;
KeyNavigation.right: Input
}
- TextInput { id: Input; focus: true;
+ TextInput { id: Input; focus: true
KeyNavigation.left: FirstItem
KeyNavigation.right: LastItem
KeyNavigation.up: FirstItem
diff --git a/tests/auto/declarative/qfxtextinput/tst_qfxtextinput.cpp b/tests/auto/declarative/qfxtextinput/tst_qfxtextinput.cpp
index 852a868..c883aa3 100644
--- a/tests/auto/declarative/qfxtextinput/tst_qfxtextinput.cpp
+++ b/tests/auto/declarative/qfxtextinput/tst_qfxtextinput.cpp
@@ -1,8 +1,9 @@
#include <qtest.h>
+#include "../../../shared/util.h"
#include <QtDeclarative/qmlengine.h>
#include <QFile>
#include <QtDeclarative/qfxview.h>
-#include <qfxtextinput.h>
+#include <QFxTextInput>
#include <QDebug>
class tst_qfxtextinput : public QObject
@@ -13,6 +14,17 @@ public:
tst_qfxtextinput();
private slots:
+ void text();
+ void width();
+ void font();
+ void color();
+ void selection();
+
+ void maxLength();
+ void masks();
+ void validators();
+
+ void cursorDelegate();
void navigation();
private:
@@ -20,10 +32,280 @@ private:
QFxView *createView(const QString &filename);
QmlEngine engine;
+ QStringList standard;
+ QStringList colorStrings;
};
tst_qfxtextinput::tst_qfxtextinput()
{
+ standard << "the quick brown fox jumped over the lazy dog"
+ << "It's supercalifragisiticexpialidocious!"
+ << "Hello, world!";
+
+ colorStrings << "aliceblue"
+ << "antiquewhite"
+ << "aqua"
+ << "darkkhaki"
+ << "darkolivegreen"
+ << "dimgray"
+ << "palevioletred"
+ << "lightsteelblue"
+ << "#000000"
+ << "#AAAAAA"
+ << "#FFFFFF"
+ << "#2AC05F";
+}
+
+void tst_qfxtextinput::text()
+{
+ {
+ QmlComponent textinputComponent(&engine, "import Qt 4.6\nTextInput { text: \"\" }", QUrl());
+ QFxTextInput *textinputObject = qobject_cast<QFxTextInput*>(textinputComponent.create());
+
+ QVERIFY(textinputObject != 0);
+ QCOMPARE(textinputObject->text(), QString(""));
+ }
+
+ for (int i = 0; i < standard.size(); i++)
+ {
+ QString componentStr = "import Qt 4.6\nTextInput { text: \"" + standard.at(i) + "\" }";
+ QmlComponent textinputComponent(&engine, componentStr.toLatin1(), QUrl());
+ QFxTextInput *textinputObject = qobject_cast<QFxTextInput*>(textinputComponent.create());
+
+ QVERIFY(textinputObject != 0);
+ QCOMPARE(textinputObject->text(), standard.at(i));
+ }
+
+}
+
+void tst_qfxtextinput::width()
+{
+ // uses Font metrics to find the width for standard
+ {
+ QmlComponent textinputComponent(&engine, "import Qt 4.6\nTextInput { text: \"\" }", QUrl());
+ QFxTextInput *textinputObject = qobject_cast<QFxTextInput*>(textinputComponent.create());
+
+ QVERIFY(textinputObject != 0);
+ QCOMPARE(textinputObject->width(), 1.);//1 for the cursor
+ }
+
+ for (int i = 0; i < standard.size(); i++)
+ {
+ QFont f;
+ QFontMetrics fm(f);
+ int metricWidth = fm.size(Qt::TextExpandTabs && Qt::TextShowMnemonic, standard.at(i)).width();
+
+ QString componentStr = "import Qt 4.6\nTextInput { text: \"" + standard.at(i) + "\" }";
+ QmlComponent textinputComponent(&engine, componentStr.toLatin1(), QUrl());
+ QFxTextInput *textinputObject = qobject_cast<QFxTextInput*>(textinputComponent.create());
+
+ QVERIFY(textinputObject != 0);
+ QCOMPARE(textinputObject->width(), qreal(metricWidth) + 1.);//1 for the cursor
+ }
+}
+
+void tst_qfxtextinput::font()
+{
+ //test size, then bold, then italic, then family
+ {
+ QString componentStr = "import Qt 4.6\nTextInput { font.pointSize: 40; text: \"Hello World\" }";
+ QmlComponent textinputComponent(&engine, componentStr.toLatin1(), QUrl());
+ QFxTextInput *textinputObject = qobject_cast<QFxTextInput*>(textinputComponent.create());
+
+ QVERIFY(textinputObject != 0);
+ QCOMPARE(textinputObject->font().pointSize(), 40);
+ QCOMPARE(textinputObject->font().bold(), false);
+ QCOMPARE(textinputObject->font().italic(), false);
+ }
+
+ {
+ QString componentStr = "import Qt 4.6\nTextInput { font.bold: true; text: \"Hello World\" }";
+ QmlComponent textinputComponent(&engine, componentStr.toLatin1(), QUrl());
+ QFxTextInput *textinputObject = qobject_cast<QFxTextInput*>(textinputComponent.create());
+
+ QVERIFY(textinputObject != 0);
+ QCOMPARE(textinputObject->font().bold(), true);
+ QCOMPARE(textinputObject->font().italic(), false);
+ }
+
+ {
+ QString componentStr = "import Qt 4.6\nTextInput { font.italic: true; text: \"Hello World\" }";
+ QmlComponent textinputComponent(&engine, componentStr.toLatin1(), QUrl());
+ QFxTextInput *textinputObject = qobject_cast<QFxTextInput*>(textinputComponent.create());
+
+ QVERIFY(textinputObject != 0);
+ QCOMPARE(textinputObject->font().italic(), true);
+ QCOMPARE(textinputObject->font().bold(), false);
+ }
+
+ {
+ QString componentStr = "import Qt 4.6\nTextInput { font.family: \"Helvetica\"; text: \"Hello World\" }";
+ QmlComponent textinputComponent(&engine, componentStr.toLatin1(), QUrl());
+ QFxTextInput *textinputObject = qobject_cast<QFxTextInput*>(textinputComponent.create());
+
+ QVERIFY(textinputObject != 0);
+ QCOMPARE(textinputObject->font().family(), QString("Helvetica"));
+ QCOMPARE(textinputObject->font().bold(), false);
+ QCOMPARE(textinputObject->font().italic(), false);
+ }
+
+ {
+ QString componentStr = "import Qt 4.6\nTextInput { font.family: \"\"; text: \"Hello World\" }";
+ QmlComponent textinputComponent(&engine, componentStr.toLatin1(), QUrl());
+ QFxTextInput *textinputObject = qobject_cast<QFxTextInput*>(textinputComponent.create());
+
+ QVERIFY(textinputObject != 0);
+ QCOMPARE(textinputObject->font().family(), QString(""));
+ }
+}
+
+void tst_qfxtextinput::color()
+{
+ //test style
+ for (int i = 0; i < colorStrings.size(); i++)
+ {
+ QString componentStr = "import Qt 4.6\nTextInput { color: \"" + colorStrings.at(i) + "\"; text: \"Hello World\" }";
+ QmlComponent textinputComponent(&engine, componentStr.toLatin1(), QUrl());
+ QFxTextInput *textinputObject = qobject_cast<QFxTextInput*>(textinputComponent.create());
+ //qDebug() << "textinputObject: " << textinputObject->color() << "vs. " << QColor(colorStrings.at(i));
+ QVERIFY(textinputObject != 0);
+ QCOMPARE(textinputObject->color(), QColor(colorStrings.at(i)));
+ }
+
+ {
+ QString colorStr = "#AA001234";
+ QColor testColor("#001234");
+ testColor.setAlpha(170);
+
+ QString componentStr = "import Qt 4.6\nTextInput { color: \"" + colorStr + "\"; text: \"Hello World\" }";
+ QmlComponent textinputComponent(&engine, componentStr.toLatin1(), QUrl());
+ QFxTextInput *textinputObject = qobject_cast<QFxTextInput*>(textinputComponent.create());
+
+ QVERIFY(textinputObject != 0);
+ QCOMPARE(textinputObject->color(), testColor);
+ }
+}
+
+void tst_qfxtextinput::selection()
+{
+ QString testStr = standard[0];
+ QString componentStr = "import Qt 4.6\nTextInput { text: \""+ testStr +"\"; }";
+ QmlComponent textinputComponent(&engine, componentStr.toLatin1(), QUrl());
+ QFxTextInput *textinputObject = qobject_cast<QFxTextInput*>(textinputComponent.create());
+ QVERIFY(textinputObject != 0);
+
+
+ //Test selection follows cursor
+ for(int i=0; i<= testStr.size(); i++) {
+ textinputObject->setCursorPosition(i);
+ QCOMPARE(textinputObject->cursorPosition(), i);
+ QCOMPARE(textinputObject->selectionStart(), i);
+ QCOMPARE(textinputObject->selectionEnd(), i);
+ QVERIFY(textinputObject->selectedText().isNull());
+ }
+
+ textinputObject->setCursorPosition(0);
+ QVERIFY(textinputObject->cursorPosition() == 0);
+ QVERIFY(textinputObject->selectionStart() == 0);
+ QVERIFY(textinputObject->selectionEnd() == 0);
+ QVERIFY(textinputObject->selectedText().isNull());
+
+ //Test selection
+ for(int i=0; i<= testStr.size(); i++) {
+ textinputObject->setSelectionEnd(i);
+ QCOMPARE(testStr.mid(0,i), textinputObject->selectedText());
+ }
+ for(int i=0; i<= testStr.size(); i++) {
+ textinputObject->setSelectionStart(i);
+ QCOMPARE(testStr.mid(i,testStr.size()-i), textinputObject->selectedText());
+ }
+
+ textinputObject->setCursorPosition(0);
+ QVERIFY(textinputObject->cursorPosition() == 0);
+ QVERIFY(textinputObject->selectionStart() == 0);
+ QVERIFY(textinputObject->selectionEnd() == 0);
+ QVERIFY(textinputObject->selectedText().isNull());
+
+ for(int i=0; i< testStr.size(); i++) {
+ textinputObject->setSelectionStart(i);
+ QCOMPARE(textinputObject->selectionEnd(), i);
+ QCOMPARE(testStr.mid(i,0), textinputObject->selectedText());
+ textinputObject->setSelectionEnd(i+1);
+ QCOMPARE(textinputObject->selectionStart(), i);
+ QCOMPARE(testStr.mid(i,1), textinputObject->selectedText());
+ }
+
+ for(int i= testStr.size() - 1; i>0; i--) {
+ textinputObject->setSelectionEnd(i);
+ QCOMPARE(testStr.mid(i,0), textinputObject->selectedText());
+ textinputObject->setSelectionStart(i-1);
+ QCOMPARE(testStr.mid(i-1,1), textinputObject->selectedText());
+ }
+
+ //Test Error Ignoring behaviour
+ textinputObject->setCursorPosition(0);
+ QVERIFY(textinputObject->selectedText().isNull());
+ textinputObject->setSelectionStart(-10);
+ QVERIFY(textinputObject->selectedText().isNull());
+ textinputObject->setSelectionStart(100);
+ QVERIFY(textinputObject->selectedText().isNull());
+ textinputObject->setSelectionEnd(-10);
+ QVERIFY(textinputObject->selectedText().isNull());
+ textinputObject->setSelectionEnd(100);
+ QVERIFY(textinputObject->selectedText().isNull());
+ textinputObject->setSelectionStart(0);
+ textinputObject->setSelectionEnd(10);
+ QVERIFY(textinputObject->selectedText().size() == 10);
+ textinputObject->setSelectionStart(-10);
+ QVERIFY(textinputObject->selectedText().size() == 10);
+ textinputObject->setSelectionStart(100);
+ QVERIFY(textinputObject->selectedText().size() == 10);
+ textinputObject->setSelectionEnd(-10);
+ QVERIFY(textinputObject->selectedText().size() == 10);
+ textinputObject->setSelectionEnd(100);
+ QVERIFY(textinputObject->selectedText().size() == 10);
+}
+
+void tst_qfxtextinput::maxLength()
+{
+ QFxView *canvas = createView(SRCDIR "/data/navigation.qml");
+ canvas->execute();
+ canvas->show();
+
+ QVERIFY(canvas->root() != 0);
+
+ QFxItem *input = qobject_cast<QFxItem *>(qvariant_cast<QObject *>(canvas->root()->property("myInput")));
+
+ QVERIFY(input != 0);
+ //TODO: Me
+}
+
+void tst_qfxtextinput::masks()
+{
+ QFxView *canvas = createView(SRCDIR "/data/navigation.qml");
+ canvas->execute();
+ canvas->show();
+
+ QVERIFY(canvas->root() != 0);
+
+ QFxItem *input = qobject_cast<QFxItem *>(qvariant_cast<QObject *>(canvas->root()->property("myInput")));
+
+ QVERIFY(input != 0);
+ //TODO: Me
+}
+
+void tst_qfxtextinput::validators()
+{
+ QFxView *canvas = createView(SRCDIR "/data/navigation.qml");
+ canvas->execute();
+ canvas->show();
+
+ QVERIFY(canvas->root() != 0);
+
+ QFxItem *input = qobject_cast<QFxItem *>(qvariant_cast<QObject *>(canvas->root()->property("myInput")));
+
+ QVERIFY(input != 0);
+ //TODO: Me
}
/*
@@ -41,7 +323,7 @@ void tst_qfxtextinput::navigation()
QFxItem *input = qobject_cast<QFxItem *>(qvariant_cast<QObject *>(canvas->root()->property("myInput")));
QVERIFY(input != 0);
- QVERIFY(input->hasFocus() == true);
+ QTRY_VERIFY(input->hasFocus() == true);
simulateKey(canvas, Qt::Key_Left);
QVERIFY(input->hasFocus() == false);
simulateKey(canvas, Qt::Key_Right);
@@ -52,6 +334,11 @@ void tst_qfxtextinput::navigation()
QVERIFY(input->hasFocus() == true);
}
+void tst_qfxtextinput::cursorDelegate()
+{
+ //TODO:Get the QFxTextInput test passing first
+}
+
void tst_qfxtextinput::simulateKey(QFxView *view, int key)
{
QKeyEvent press(QKeyEvent::KeyPress, key, 0);
diff --git a/tests/auto/declarative/qmlparser/Alias.qml b/tests/auto/declarative/qmlparser/Alias.qml
new file mode 100644
index 0000000..8264e0d
--- /dev/null
+++ b/tests/auto/declarative/qmlparser/Alias.qml
@@ -0,0 +1,8 @@
+import Qt 4.6
+
+Object {
+ id: Root
+ property int value: 1892
+ property alias aliasValue: Root.value
+}
+
diff --git a/tests/auto/declarative/qmlparser/alias.1.qml b/tests/auto/declarative/qmlparser/alias.1.qml
new file mode 100644
index 0000000..492d99a
--- /dev/null
+++ b/tests/auto/declarative/qmlparser/alias.1.qml
@@ -0,0 +1,8 @@
+import Test 1.0
+import Qt 4.6
+
+Object {
+ id: Root
+ property int value: 10
+ property alias valueAlias: Root.value
+}
diff --git a/tests/auto/declarative/qmlparser/alias.2.qml b/tests/auto/declarative/qmlparser/alias.2.qml
new file mode 100644
index 0000000..aa4d103
--- /dev/null
+++ b/tests/auto/declarative/qmlparser/alias.2.qml
@@ -0,0 +1,8 @@
+import Test 1.0
+
+MyQmlObject {
+ id: Root
+ property alias aliasObject: Root.qmlobjectProperty
+
+ qmlobjectProperty: MyQmlObject { value : 10 }
+}
diff --git a/tests/auto/declarative/qmlparser/alias.3.qml b/tests/auto/declarative/qmlparser/alias.3.qml
new file mode 100644
index 0000000..e25fbae
--- /dev/null
+++ b/tests/auto/declarative/qmlparser/alias.3.qml
@@ -0,0 +1,10 @@
+import Qt 4.6
+
+Object {
+ property var other
+ other: Alias { id: MyAliasObject }
+
+ property alias value: MyAliasObject.aliasValue
+ property alias value2: MyAliasObject.value
+}
+
diff --git a/tests/auto/declarative/qmlparser/testtypes.h b/tests/auto/declarative/qmlparser/testtypes.h
index 3b5d3ae..e3e9aae 100644
--- a/tests/auto/declarative/qmlparser/testtypes.h
+++ b/tests/auto/declarative/qmlparser/testtypes.h
@@ -59,9 +59,11 @@ class MyQmlObject : public QObject, public MyInterface, public QmlParserStatus
Q_PROPERTY(MyInterface *interfaceProperty READ interface WRITE setInterface)
Q_PROPERTY(int onLiteralSignal READ onLiteralSignal WRITE setOnLiteralSignal);
Q_PROPERTY(MyCustomVariantType customType READ customType WRITE setCustomType);
+ Q_PROPERTY(MyQmlObject *qmlobjectProperty READ qmlobject WRITE setQmlobject)
+
Q_INTERFACES(MyInterface QmlParserStatus)
public:
- MyQmlObject() : m_value(-1), m_interface(0) { qRegisterMetaType<MyCustomVariantType>("MyCustomVariantType"); }
+ MyQmlObject() : m_value(-1), m_interface(0), m_qmlobject(0) { qRegisterMetaType<MyCustomVariantType>("MyCustomVariantType"); }
int value() const { return m_value; }
void setValue(int v) { m_value = v; }
@@ -88,6 +90,9 @@ public:
int onLiteralSignal() const { return m_value; }
void setOnLiteralSignal(int v) { m_value = v; }
+ MyQmlObject *qmlobject() const { return m_qmlobject; }
+ void setQmlobject(MyQmlObject *o) { m_qmlobject = o; }
+
MyCustomVariantType customType() const { return m_custom; }
void setCustomType(const MyCustomVariantType &v) { m_custom = v; }
public slots:
@@ -100,6 +105,7 @@ private:
friend class tst_qmlparser;
int m_value;
MyInterface *m_interface;
+ MyQmlObject *m_qmlobject;
MyCustomVariantType m_custom;
};
QML_DECLARE_TYPE(MyQmlObject);
diff --git a/tests/auto/declarative/qmlparser/tst_qmlparser.cpp b/tests/auto/declarative/qmlparser/tst_qmlparser.cpp
index 25dfd27..b8bd0e7 100644
--- a/tests/auto/declarative/qmlparser/tst_qmlparser.cpp
+++ b/tests/auto/declarative/qmlparser/tst_qmlparser.cpp
@@ -48,6 +48,7 @@ private slots:
void customVariantTypes();
void valueTypes();
void cppnamespace();
+ void aliasProperties();
void importsBuiltin_data();
void importsBuiltin();
@@ -519,6 +520,76 @@ void tst_qmlparser::cppnamespace()
delete object;
}
+void tst_qmlparser::aliasProperties()
+{
+ // Simple "int" alias
+ {
+ QmlComponent component(&engine, TEST_FILE("alias.1.qml"));
+ VERIFY_ERRORS(0);
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+
+ // Read through alias
+ QCOMPARE(object->property("valueAlias").toInt(), 10);
+ object->setProperty("value", QVariant(13));
+ QCOMPARE(object->property("valueAlias").toInt(), 13);
+
+ // Write throught alias
+ object->setProperty("valueAlias", QVariant(19));
+ QCOMPARE(object->property("valueAlias").toInt(), 19);
+ QCOMPARE(object->property("value").toInt(), 19);
+
+ delete object;
+ }
+
+ // Complex object alias
+ {
+ QmlComponent component(&engine, TEST_FILE("alias.2.qml"));
+ VERIFY_ERRORS(0);
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+
+ // Read through alias
+ MyQmlObject *v =
+ qvariant_cast<MyQmlObject *>(object->property("aliasObject"));
+ QVERIFY(v != 0);
+ QCOMPARE(v->value(), 10);
+
+ // Write through alias
+ MyQmlObject *v2 = new MyQmlObject();
+ v2->setParent(object);
+ object->setProperty("aliasObject", qVariantFromValue(v2));
+ MyQmlObject *v3 =
+ qvariant_cast<MyQmlObject *>(object->property("aliasObject"));
+ QVERIFY(v3 != 0);
+ QCOMPARE(v3, v2);
+
+ delete object;
+ }
+
+ // Nested aliases
+ {
+ QmlComponent component(&engine, TEST_FILE("alias.3.qml"));
+ VERIFY_ERRORS(0);
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+
+ QCOMPARE(object->property("value").toInt(), 1892);
+ QCOMPARE(object->property("value2").toInt(), 1892);
+
+ object->setProperty("value", QVariant(1313));
+ QCOMPARE(object->property("value").toInt(), 1313);
+ QCOMPARE(object->property("value2").toInt(), 1313);
+
+ object->setProperty("value2", QVariant(8080));
+ QCOMPARE(object->property("value").toInt(), 8080);
+ QCOMPARE(object->property("value2").toInt(), 8080);
+
+ delete object;
+ }
+
+}
+
class TestType : public QObject {
Q_OBJECT
public: