1 /****************************************************************************
3 ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
6 ** This file is part of the test suite of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
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 if (prop.userType() < QMetaType::User)
215 QCOMPARE(prop.type(), QVariant::Type(cppType));
217 QCOMPARE(prop.type(), QVariant::UserType);
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.name(), QByteArray("testChanged"));
248 QCOMPARE(signal.methodSignature(), QByteArray("testChanged()"));
249 QCOMPARE(signal.access(), QMetaMethod::Protected);
250 QCOMPARE(signal.parameterCount(), 0);
251 QCOMPARE(signal.parameterTypes(), QList<QByteArray>());
252 QCOMPARE(signal.parameterNames(), QList<QByteArray>());
253 QCOMPARE(signal.tag(), "");
254 QCOMPARE(signal.typeName(), "void");
255 QCOMPARE(signal.returnType(), int(QMetaType::Void));
257 QSignalSpy changedSpy(object, SIGNAL(testChanged()));
258 QObject::connect(object, SIGNAL(testChanged()), object, SLOT(deleteLater()));
260 if (expectedValue.isValid())
261 QCOMPARE(prop.read(object), expectedValue);
263 QVERIFY(prop.read(object).isValid());
264 QCOMPARE(changedSpy.count(), 0);
267 QVERIFY(prop.write(object, newValue));
268 QCOMPARE(changedSpy.count(), 1);
269 QCOMPARE(prop.read(object), newValue);
271 QVERIFY(!prop.write(object, prop.read(object)));
272 QCOMPARE(changedSpy.count(), 0);
278 void tst_QQmlMetaObject::method_data()
280 QTest::addColumn<QString>("testFile");
281 QTest::addColumn<QString>("signature");
282 QTest::addColumn<QMetaMethod::MethodType>("methodType");
283 QTest::addColumn<int>("returnType");
284 QTest::addColumn<QString>("returnTypeName");
285 QTest::addColumn<QList<int> >("parameterTypes");
286 QTest::addColumn<QList<QByteArray> >("parameterTypeNames");
287 QTest::addColumn<QList<QByteArray> >("parameterNames");
289 QTest::newRow("testFunction()") << "method.1.qml"
292 << int(QMetaType::QVariant) << "QVariant"
294 << QList<QByteArray>()
295 << QList<QByteArray>();
296 QTest::newRow("testFunction(foo)") << "method.2.qml"
297 << "testFunction(QVariant)"
299 << int(QMetaType::QVariant) << "QVariant"
300 << (QList<int>() << QMetaType::QVariant)
301 << (QList<QByteArray>() << "QVariant")
302 << (QList<QByteArray>() << "foo");
303 QTest::newRow("testFunction(foo, bar, baz)") << "method.3.qml"
304 << "testFunction(QVariant,QVariant,QVariant)"
306 << int(QMetaType::QVariant) << "QVariant"
307 << (QList<int>() << QMetaType::QVariant << QMetaType::QVariant << QMetaType::QVariant)
308 << (QList<QByteArray>() << "QVariant" << "QVariant" << "QVariant")
309 << (QList<QByteArray>() << "foo" << "bar" << "baz");
310 QTest::newRow("testSignal") << "signal.1.qml"
312 << QMetaMethod::Signal
313 << int(QMetaType::Void) << "void"
315 << QList<QByteArray>()
316 << QList<QByteArray>();
317 QTest::newRow("testSignal(string foo)") << "signal.2.qml"
318 << "testSignal(QString)"
319 << QMetaMethod::Signal
320 << int(QMetaType::Void) << "void"
321 << (QList<int>() << QMetaType::QString)
322 << (QList<QByteArray>() << "QString")
323 << (QList<QByteArray>() << "foo");
324 QTest::newRow("testSignal(int foo, bool bar, real baz)") << "signal.3.qml"
325 << "testSignal(int,bool,double)"
326 << QMetaMethod::Signal
327 << int(QMetaType::Void) << "void"
328 << (QList<int>() << QMetaType::Int << QMetaType::Bool << QMetaType::Double)
329 << (QList<QByteArray>() << "int" << "bool" << "double")
330 << (QList<QByteArray>() << "foo" << "bar" << "baz");
331 QTest::newRow("testSignal(variant foo, var bar)") << "signal.4.qml"
332 << "testSignal(QVariant,QVariant)"
333 << QMetaMethod::Signal
334 << int(QMetaType::Void) << "void"
335 << (QList<int>() << QMetaType::QVariant << QMetaType::QVariant)
336 << (QList<QByteArray>() << "QVariant" << "QVariant")
337 << (QList<QByteArray>() << "foo" << "bar");
338 QTest::newRow("testSignal(color foo, date bar, url baz)") << "signal.5.qml"
339 << "testSignal(QColor,QDateTime,QUrl)"
340 << QMetaMethod::Signal
341 << int(QMetaType::Void) << "void"
342 << (QList<int>() << QMetaType::QColor << QMetaType::QDateTime << QMetaType::QUrl)
343 << (QList<QByteArray>() << "QColor" << "QDateTime" << "QUrl")
344 << (QList<QByteArray>() << "foo" << "bar" << "baz");
345 QTest::newRow("testSignal(double foo)") << "signal.6.qml"
346 << "testSignal(double)"
347 << QMetaMethod::Signal
348 << int(QMetaType::Void) << "void"
349 << (QList<int>() << QMetaType::Double)
350 << (QList<QByteArray>() << "double")
351 << (QList<QByteArray>() << "foo");
354 void tst_QQmlMetaObject::method()
356 QFETCH(QString, testFile);
357 QFETCH(QString, signature);
358 QFETCH(QMetaMethod::MethodType, methodType);
359 QFETCH(int, returnType);
360 QFETCH(QString, returnTypeName);
361 QFETCH(QList<int>, parameterTypes);
362 QFETCH(QList<QByteArray>, parameterTypeNames);
363 QFETCH(QList<QByteArray>, parameterNames);
365 QCOMPARE(parameterTypes.size(), parameterTypeNames.size());
366 QCOMPARE(parameterTypeNames.size(), parameterNames.size());
369 QQmlComponent component(&engine, testFileUrl(testFile));
370 QObject *object = component.create();
371 QVERIFY(object != 0);
373 const QMetaObject *mo = object->metaObject();
374 QVERIFY(mo->superClass() != 0);
375 QVERIFY(QByteArray(mo->className()).contains("_QML_"));
376 QCOMPARE(mo->methodOffset(), mo->superClass()->methodCount());
377 QCOMPARE(mo->methodCount(), mo->superClass()->methodCount() + 1);
379 QMetaMethod method = mo->method(mo->methodOffset());
380 QCOMPARE(method.methodType(), methodType);
381 QCOMPARE(QString::fromUtf8(method.methodSignature().constData()), signature);
382 QCOMPARE(method.access(), QMetaMethod::Protected);
384 QString computedName = signature.left(signature.indexOf('('));
385 QCOMPARE(QString::fromUtf8(method.name()), computedName);
387 QCOMPARE(method.parameterCount(), parameterTypes.size());
388 for (int i = 0; i < parameterTypes.size(); ++i)
389 QCOMPARE(method.parameterType(i), parameterTypes.at(i));
390 QCOMPARE(method.parameterTypes(), parameterTypeNames);
391 QCOMPARE(method.tag(), "");
393 QCOMPARE(QString::fromUtf8(method.typeName()), returnTypeName);
394 QCOMPARE(method.returnType(), returnType);
399 QTEST_MAIN(tst_QQmlMetaObject)
401 #include "tst_qqmlmetaobject.moc"