Adapt to Qt5 meta-object changes
[profile/ivi/qtdeclarative.git] / tests / auto / qml / qqmlmetaobject / tst_qqmlmetaobject.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the test suite of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include <QtTest/QtTest>
43 #include <QtQml/qqmlcomponent.h>
44 #include <QtQml/qqmlengine.h>
45 #include "../../shared/util.h"
46
47 Q_DECLARE_METATYPE(QMetaMethod::MethodType)
48
49 class MyQmlObject : public QObject
50 {
51     Q_OBJECT
52 };
53 QML_DECLARE_TYPE(MyQmlObject)
54
55 class tst_QQmlMetaObject : public QQmlDataTest
56 {
57     Q_OBJECT
58 private slots:
59     void initTestCase();
60
61     void property_data();
62     void property();
63     void method_data();
64     void method();
65
66 private:
67     MyQmlObject myQmlObject;
68 };
69
70 void tst_QQmlMetaObject::initTestCase()
71 {
72     QQmlDataTest::initTestCase();
73
74     qmlRegisterType<MyQmlObject>("Qt.test", 1,0, "MyQmlObject");
75 }
76
77 void tst_QQmlMetaObject::property_data()
78 {
79     QTest::addColumn<QString>("testFile");
80     QTest::addColumn<QByteArray>("cppTypeName");
81     QTest::addColumn<int>("cppType");
82     QTest::addColumn<bool>("isDefault");
83     QTest::addColumn<QVariant>("expectedValue");
84     QTest::addColumn<bool>("isWritable");
85     QTest::addColumn<QVariant>("newValue");
86
87     QTest::newRow("int") << "property.int.qml"
88             << QByteArray("int") << int(QMetaType::Int)
89             << false // default
90             << QVariant(19) << true << QVariant(42);
91     QTest::newRow("bool") << "property.bool.qml"
92             << QByteArray("bool") << int(QMetaType::Bool)
93             << true // default
94             << QVariant(true) << true << QVariant(false);
95     QTest::newRow("double") << "property.double.qml"
96              << QByteArray("double") << int(QMetaType::Double)
97              << false // default
98              << QVariant(double(1234567890.))
99              << true // writable
100              << QVariant(double(1.23456789));
101     QTest::newRow("real") << "property.real.qml"
102             << QByteArray("double") << int(QMetaType::Double)
103             << false // default
104             << QVariant(double(1234567890.))
105             << true // writable
106             << QVariant(double(1.23456789));
107     QTest::newRow("string") << "property.string.qml"
108             << QByteArray("QString") << int(QMetaType::QString)
109             << true // default
110             << QVariant(QString::fromLatin1("dog"))
111             << true // writable
112             << QVariant(QString::fromLatin1("food"));
113     QTest::newRow("url") << "property.url.qml"
114             << QByteArray("QUrl") << int(QMetaType::QUrl)
115             << false // default
116             << QVariant(QUrl("http://foo.bar"))
117             << true //writable
118             << QVariant(QUrl("http://bar.baz"));
119     QTest::newRow("color") << "property.color.qml"
120             << QByteArray("QColor") << int(QMetaType::QColor)
121             << true // default
122             << QVariant(QColor("#ff0000"))
123             << true // writable
124             << QVariant(QColor("#00ff00"));
125     QTest::newRow("date") << "property.date.qml"
126             << QByteArray("QDateTime") << int(QMetaType::QDateTime)
127             << false // default
128             << QVariant(QDateTime(QDate(2012, 2, 7)))
129             << true // writable
130             << QVariant(QDateTime(QDate(2010, 7, 2)));
131     QTest::newRow("variant") << "property.variant.qml"
132             << QByteArray("QVariant") << int(QMetaType::QVariant)
133             << true // default
134             << QVariant(QPointF(12, 34))
135             << true // writable
136             << QVariant(QSizeF(45, 67));
137     QTest::newRow("var") << "property.var.qml"
138             << QByteArray("QVariant") << int(QMetaType::QVariant)
139             << false // default
140             << QVariant(QVariantList() << 5 << true << "ciao")
141             << true // writable
142             << QVariant(QVariantList() << 17.0);
143     QTest::newRow("QtObject") << "property.QtObject.qml"
144             << QByteArray("QObject*") << int(QMetaType::QObjectStar)
145             << false // default
146             << QVariant()
147             << true // writable
148             << QVariant::fromValue(static_cast<QObject*>(this));
149     QTest::newRow("list<QtObject>") << "property.list.QtObject.qml"
150             << QByteArray("QQmlListProperty<QObject>")
151             << qMetaTypeId<QQmlListProperty<QObject> >()
152             << false // default
153             << QVariant()
154             << false // writable
155             << QVariant();
156     QTest::newRow("MyQmlObject") << "property.MyQmlObject.qml"
157             << QByteArray("MyQmlObject*") << qMetaTypeId<MyQmlObject*>()
158             << false // default
159             << QVariant()
160             << true // writable
161             << QVariant::fromValue(&myQmlObject);
162     QTest::newRow("list<MyQmlObject>") << "property.list.MyQmlObject.qml"
163             << QByteArray("QQmlListProperty<MyQmlObject>")
164             << qMetaTypeId<QQmlListProperty<MyQmlObject> >()
165             << false // default
166             << QVariant()
167             << false // writable
168             << QVariant();
169     QTest::newRow("alias") << "property.alias.qml"
170             << QByteArray("QString") << int(QMetaType::QString)
171             << false // default
172             << QVariant(QString::fromLatin1("Joe"))
173             << true // writable
174             << QVariant(QString::fromLatin1("Bob"));
175     QTest::newRow("alias-2") << "property.alias.2.qml"
176             << QByteArray("QObject*") << int(QMetaType::QObjectStar)
177             << false // default
178             << QVariant()
179             << false // writable
180             << QVariant();
181     QTest::newRow("alias-3") << "property.alias.3.qml"
182             << QByteArray("QString") << int(QMetaType::QString)
183             << false // default
184             << QVariant(QString::fromLatin1("Arial"))
185             << true // writable
186             << QVariant(QString::fromLatin1("Helvetica"));
187 }
188
189 void tst_QQmlMetaObject::property()
190 {
191     QFETCH(QString, testFile);
192     QFETCH(QByteArray, cppTypeName);
193     QFETCH(int, cppType);
194     QFETCH(bool, isDefault);
195     QFETCH(QVariant, expectedValue);
196     QFETCH(bool, isWritable);
197     QFETCH(QVariant, newValue);
198
199     QQmlEngine engine;
200     QQmlComponent component(&engine, testFileUrl(testFile));
201     QObject *object = component.create();
202     QVERIFY(object != 0);
203
204     const QMetaObject *mo = object->metaObject();
205     QVERIFY(mo->superClass() != 0);
206     QVERIFY(QByteArray(mo->className()).contains("_QML_"));
207     QCOMPARE(mo->propertyOffset(), mo->superClass()->propertyCount());
208     QCOMPARE(mo->propertyCount(), mo->superClass()->propertyCount() + 1);
209
210     QMetaProperty prop = mo->property(mo->propertyOffset());
211     QCOMPARE(prop.name(), "test");
212
213     QCOMPARE(QByteArray(prop.typeName()), cppTypeName);
214     QEXPECT_FAIL("QtObject", "prop.type() returns UserType for QtObject properties", Continue);
215     QEXPECT_FAIL("alias-2", "prop.type() returns UserType for QtObject properties", Continue);
216     if (prop.userType() < QMetaType::User)
217         QCOMPARE(prop.type(), QVariant::Type(cppType));
218     QCOMPARE(prop.userType(), cppType);
219
220     QVERIFY(!prop.isConstant());
221     QVERIFY(!prop.isDesignable());
222     QVERIFY(!prop.isEnumType());
223     QVERIFY(!prop.isFinal());
224     QVERIFY(!prop.isFlagType());
225     QVERIFY(prop.isReadable());
226     QVERIFY(!prop.isResettable());
227     QVERIFY(prop.isScriptable());
228     QVERIFY(!prop.isStored());
229     QVERIFY(!prop.isUser());
230     QVERIFY(prop.isValid());
231     QCOMPARE(prop.isWritable(), isWritable);
232
233     QCOMPARE(mo->classInfoOffset(), mo->superClass()->classInfoCount());
234     QCOMPARE(mo->classInfoCount(), mo->superClass()->classInfoCount() + (isDefault ? 1 : 0));
235     if (isDefault) {
236         QMetaClassInfo info = mo->classInfo(mo->classInfoOffset());
237         QCOMPARE(info.name(), "DefaultProperty");
238         QCOMPARE(info.value(), "test");
239     }
240
241     QCOMPARE(mo->methodOffset(), mo->superClass()->methodCount());
242     QCOMPARE(mo->methodCount(), mo->superClass()->methodCount() + 1); // the signal
243
244     QVERIFY(prop.notifySignalIndex() != -1);
245     QMetaMethod signal = prop.notifySignal();
246     QCOMPARE(signal.methodType(), QMetaMethod::Signal);
247     QCOMPARE(signal.methodSignature(), QByteArray("testChanged()"));
248     QCOMPARE(signal.access(), QMetaMethod::Protected);
249     QCOMPARE(signal.parameterTypes(), QList<QByteArray>());
250     QCOMPARE(signal.parameterNames(), QList<QByteArray>());
251     QCOMPARE(signal.tag(), "");
252     QCOMPARE(signal.typeName(), "");
253
254     QSignalSpy changedSpy(object, SIGNAL(testChanged()));
255     QObject::connect(object, SIGNAL(testChanged()), object, SLOT(deleteLater()));
256
257     if (expectedValue.isValid())
258         QCOMPARE(prop.read(object), expectedValue);
259     else
260         QVERIFY(prop.read(object).isValid());
261     QCOMPARE(changedSpy.count(), 0);
262
263     if (isWritable) {
264         QVERIFY(prop.write(object, newValue));
265         QCOMPARE(changedSpy.count(), 1);
266         QCOMPARE(prop.read(object), newValue);
267     } else {
268         QVERIFY(!prop.write(object, prop.read(object)));
269         QCOMPARE(changedSpy.count(), 0);
270     }
271
272     delete object;
273 }
274
275 void tst_QQmlMetaObject::method_data()
276 {
277     QTest::addColumn<QString>("testFile");
278     QTest::addColumn<QString>("signature");
279     QTest::addColumn<QMetaMethod::MethodType>("methodType");
280     QTest::addColumn<QString>("returnTypeName");
281     QTest::addColumn<QList<QByteArray> >("parameterTypeNames");
282     QTest::addColumn<QList<QByteArray> >("parameterNames");
283
284     QTest::newRow("testFunction()") << "method.1.qml"
285             << "testFunction()"
286             << QMetaMethod::Slot
287             << "QVariant"
288             << QList<QByteArray>()
289             << QList<QByteArray>();
290     QTest::newRow("testFunction(foo)") << "method.2.qml"
291             << "testFunction(QVariant)"
292             << QMetaMethod::Slot
293             << "QVariant"
294             << (QList<QByteArray>() << "QVariant")
295             << (QList<QByteArray>() << "foo");
296     QTest::newRow("testFunction(foo, bar, baz)") << "method.3.qml"
297             << "testFunction(QVariant,QVariant,QVariant)"
298             << QMetaMethod::Slot
299             << "QVariant"
300             << (QList<QByteArray>() << "QVariant" << "QVariant" << "QVariant")
301             << (QList<QByteArray>() << "foo" << "bar" << "baz");
302     QTest::newRow("testSignal") << "signal.1.qml"
303             << "testSignal()"
304             << QMetaMethod::Signal
305             << ""
306             << QList<QByteArray>()
307             << QList<QByteArray>();
308     QTest::newRow("testSignal(string foo)") << "signal.2.qml"
309             << "testSignal(QString)"
310             << QMetaMethod::Signal
311             << ""
312             << (QList<QByteArray>() << "QString")
313             << (QList<QByteArray>() << "foo");
314     QTest::newRow("testSignal(int foo, bool bar, real baz)") << "signal.3.qml"
315             << "testSignal(int,bool,double)"
316             << QMetaMethod::Signal
317             << ""
318             << (QList<QByteArray>() << "int" << "bool" << "double")
319             << (QList<QByteArray>() << "foo" << "bar" << "baz");
320     QTest::newRow("testSignal(variant foo, var bar)") << "signal.4.qml"
321             << "testSignal(QVariant,QVariant)"
322             << QMetaMethod::Signal
323             << ""
324             << (QList<QByteArray>() << "QVariant" << "QVariant")
325             << (QList<QByteArray>() << "foo" << "bar");
326     QTest::newRow("testSignal(color foo, date bar, url baz)") << "signal.5.qml"
327             << "testSignal(QColor,QDateTime,QUrl)"
328             << QMetaMethod::Signal
329             << ""
330             << (QList<QByteArray>() << "QColor" << "QDateTime" << "QUrl")
331             << (QList<QByteArray>() << "foo" << "bar" << "baz");
332     QTest::newRow("testSignal(double foo)") << "signal.6.qml"
333             << "testSignal(double)"
334             << QMetaMethod::Signal
335             << ""
336             << (QList<QByteArray>() << "double")
337             << (QList<QByteArray>() << "foo");
338 }
339
340 void tst_QQmlMetaObject::method()
341 {
342     QFETCH(QString, testFile);
343     QFETCH(QString, signature);
344     QFETCH(QMetaMethod::MethodType, methodType);
345     QFETCH(QString, returnTypeName);
346     QFETCH(QList<QByteArray>, parameterTypeNames);
347     QFETCH(QList<QByteArray>, parameterNames);
348
349     QCOMPARE(parameterTypeNames.size(), parameterNames.size());
350
351     QQmlEngine engine;
352     QQmlComponent component(&engine, testFileUrl(testFile));
353     QObject *object = component.create();
354     QVERIFY(object != 0);
355
356     const QMetaObject *mo = object->metaObject();
357     QVERIFY(mo->superClass() != 0);
358     QVERIFY(QByteArray(mo->className()).contains("_QML_"));
359     QCOMPARE(mo->methodOffset(), mo->superClass()->methodCount());
360     QCOMPARE(mo->methodCount(), mo->superClass()->methodCount() + 1);
361
362     QMetaMethod method = mo->method(mo->methodOffset());
363     QCOMPARE(method.methodType(), methodType);
364     QCOMPARE(QString::fromUtf8(method.methodSignature().constData()), signature);
365     QCOMPARE(method.access(), QMetaMethod::Protected);
366     QCOMPARE(method.parameterTypes(), parameterTypeNames);
367     QCOMPARE(method.parameterNames(), parameterNames);
368     QCOMPARE(method.tag(), "");
369     QCOMPARE(QString::fromUtf8(method.typeName()), returnTypeName);
370
371     delete object;
372 }
373
374 QTEST_MAIN(tst_QQmlMetaObject)
375
376 #include "tst_qqmlmetaobject.moc"