1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the test suite of the Qt Toolkit.
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.
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.
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.
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.
40 ****************************************************************************/
42 #include <QtTest/QtTest>
43 #include <QtQml/qqmlcomponent.h>
44 #include <QtQml/qqmlengine.h>
45 #include "../../shared/util.h"
47 Q_DECLARE_METATYPE(QMetaMethod::MethodType)
49 class MyQmlObject : public QObject
53 QML_DECLARE_TYPE(MyQmlObject)
55 class tst_QQmlMetaObject : public QQmlDataTest
67 MyQmlObject myQmlObject;
70 void tst_QQmlMetaObject::initTestCase()
72 QQmlDataTest::initTestCase();
74 qmlRegisterType<MyQmlObject>("Qt.test", 1,0, "MyQmlObject");
77 void tst_QQmlMetaObject::property_data()
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");
87 QTest::newRow("int") << "property.int.qml"
88 << QByteArray("int") << int(QMetaType::Int)
90 << QVariant(19) << true << QVariant(42);
91 QTest::newRow("bool") << "property.bool.qml"
92 << QByteArray("bool") << int(QMetaType::Bool)
94 << QVariant(true) << true << QVariant(false);
95 QTest::newRow("double") << "property.double.qml"
96 << QByteArray("double") << int(QMetaType::Double)
98 << QVariant(double(1234567890.))
100 << QVariant(double(1.23456789));
101 QTest::newRow("real") << "property.real.qml"
102 << QByteArray("double") << int(QMetaType::Double)
104 << QVariant(double(1234567890.))
106 << QVariant(double(1.23456789));
107 QTest::newRow("string") << "property.string.qml"
108 << QByteArray("QString") << int(QMetaType::QString)
110 << QVariant(QString::fromLatin1("dog"))
112 << QVariant(QString::fromLatin1("food"));
113 QTest::newRow("url") << "property.url.qml"
114 << QByteArray("QUrl") << int(QMetaType::QUrl)
116 << QVariant(QUrl("http://foo.bar"))
118 << QVariant(QUrl("http://bar.baz"));
119 QTest::newRow("color") << "property.color.qml"
120 << QByteArray("QColor") << int(QMetaType::QColor)
122 << QVariant(QColor("#ff0000"))
124 << QVariant(QColor("#00ff00"));
125 QTest::newRow("date") << "property.date.qml"
126 << QByteArray("QDateTime") << int(QMetaType::QDateTime)
128 << QVariant(QDateTime(QDate(2012, 2, 7)))
130 << QVariant(QDateTime(QDate(2010, 7, 2)));
131 QTest::newRow("variant") << "property.variant.qml"
132 << QByteArray("QVariant") << int(QMetaType::QVariant)
134 << QVariant(QPointF(12, 34))
136 << QVariant(QSizeF(45, 67));
137 QTest::newRow("var") << "property.var.qml"
138 << QByteArray("QVariant") << int(QMetaType::QVariant)
140 << QVariant(QVariantList() << 5 << true << "ciao")
142 << QVariant(QVariantList() << 17.0);
143 QTest::newRow("QtObject") << "property.QtObject.qml"
144 << QByteArray("QObject*") << int(QMetaType::QObjectStar)
148 << QVariant::fromValue(static_cast<QObject*>(this));
149 QTest::newRow("list<QtObject>") << "property.list.QtObject.qml"
150 << QByteArray("QQmlListProperty<QObject>")
151 << qMetaTypeId<QQmlListProperty<QObject> >()
156 QTest::newRow("MyQmlObject") << "property.MyQmlObject.qml"
157 << QByteArray("MyQmlObject*") << qMetaTypeId<MyQmlObject*>()
161 << QVariant::fromValue(&myQmlObject);
162 QTest::newRow("list<MyQmlObject>") << "property.list.MyQmlObject.qml"
163 << QByteArray("QQmlListProperty<MyQmlObject>")
164 << qMetaTypeId<QQmlListProperty<MyQmlObject> >()
169 QTest::newRow("alias") << "property.alias.qml"
170 << QByteArray("QString") << int(QMetaType::QString)
172 << QVariant(QString::fromLatin1("Joe"))
174 << QVariant(QString::fromLatin1("Bob"));
175 QTest::newRow("alias-2") << "property.alias.2.qml"
176 << QByteArray("QObject*") << int(QMetaType::QObjectStar)
181 QTest::newRow("alias-3") << "property.alias.3.qml"
182 << QByteArray("QString") << int(QMetaType::QString)
184 << QVariant(QString::fromLatin1("Arial"))
186 << QVariant(QString::fromLatin1("Helvetica"));
189 void tst_QQmlMetaObject::property()
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);
200 QQmlComponent component(&engine, testFileUrl(testFile));
201 QObject *object = component.create();
202 QVERIFY(object != 0);
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);
210 QMetaProperty prop = mo->property(mo->propertyOffset());
211 QCOMPARE(prop.name(), "test");
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);
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);
233 QCOMPARE(mo->classInfoOffset(), mo->superClass()->classInfoCount());
234 QCOMPARE(mo->classInfoCount(), mo->superClass()->classInfoCount() + (isDefault ? 1 : 0));
236 QMetaClassInfo info = mo->classInfo(mo->classInfoOffset());
237 QCOMPARE(info.name(), "DefaultProperty");
238 QCOMPARE(info.value(), "test");
241 QCOMPARE(mo->methodOffset(), mo->superClass()->methodCount());
242 QCOMPARE(mo->methodCount(), mo->superClass()->methodCount() + 1); // the signal
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(), "");
254 QSignalSpy changedSpy(object, SIGNAL(testChanged()));
255 QObject::connect(object, SIGNAL(testChanged()), object, SLOT(deleteLater()));
257 if (expectedValue.isValid())
258 QCOMPARE(prop.read(object), expectedValue);
260 QVERIFY(prop.read(object).isValid());
261 QCOMPARE(changedSpy.count(), 0);
264 QVERIFY(prop.write(object, newValue));
265 QCOMPARE(changedSpy.count(), 1);
266 QCOMPARE(prop.read(object), newValue);
268 QVERIFY(!prop.write(object, prop.read(object)));
269 QCOMPARE(changedSpy.count(), 0);
275 void tst_QQmlMetaObject::method_data()
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");
284 QTest::newRow("testFunction()") << "method.1.qml"
288 << QList<QByteArray>()
289 << QList<QByteArray>();
290 QTest::newRow("testFunction(foo)") << "method.2.qml"
291 << "testFunction(QVariant)"
294 << (QList<QByteArray>() << "QVariant")
295 << (QList<QByteArray>() << "foo");
296 QTest::newRow("testFunction(foo, bar, baz)") << "method.3.qml"
297 << "testFunction(QVariant,QVariant,QVariant)"
300 << (QList<QByteArray>() << "QVariant" << "QVariant" << "QVariant")
301 << (QList<QByteArray>() << "foo" << "bar" << "baz");
302 QTest::newRow("testSignal") << "signal.1.qml"
304 << QMetaMethod::Signal
306 << QList<QByteArray>()
307 << QList<QByteArray>();
308 QTest::newRow("testSignal(string foo)") << "signal.2.qml"
309 << "testSignal(QString)"
310 << QMetaMethod::Signal
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
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
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
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
336 << (QList<QByteArray>() << "double")
337 << (QList<QByteArray>() << "foo");
340 void tst_QQmlMetaObject::method()
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);
349 QCOMPARE(parameterTypeNames.size(), parameterNames.size());
352 QQmlComponent component(&engine, testFileUrl(testFile));
353 QObject *object = component.create();
354 QVERIFY(object != 0);
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);
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);
374 QTEST_MAIN(tst_QQmlMetaObject)
376 #include "tst_qqmlmetaobject.moc"