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 ****************************************************************************/
43 #include <QDeclarativeEngine>
44 #include <QDeclarativeComponent>
45 #include <private/qdeclarativeengine_p.h>
46 #include <private/qdeclarativeobjectscriptclass_p.h>
47 #include <private/qdeclarativerectangle_p.h>
48 #include <QScriptEngine>
49 #include <QScriptValue>
51 class tst_script : public QObject
61 void property_getter();
62 void property_getter_js();
63 void property_getter_qobject();
64 void property_getter_qmetaproperty();
65 void property_qobject();
66 void property_qmlobject();
68 void setproperty_js();
69 void setproperty_qmlobject();
73 void function_qobject();
74 void function_qmlobject();
76 void function_args_js();
77 void function_args_cpp();
78 void function_args_qobject();
79 void function_args_qmlobject();
81 void signal_unconnected();
84 void signal_unusedArgs();
87 void slot_simple_js();
89 void slot_complex_js();
94 void global_property_js();
95 void global_property_qml();
96 void global_property_qml_js();
98 void scriptfile_property();
101 void namespacedEnums();
105 inline QUrl TEST_FILE(const QString &filename)
107 return QUrl::fromLocalFile(QLatin1String(SRCDIR) + QLatin1String("/data/") + filename);
110 class TestObject : public QObject
113 Q_PROPERTY(int x READ x WRITE setX)
116 TestObject(QObject *parent = 0);
119 void setX(int x) { m_x = x; }
121 void emitMySignal() { emit mySignal(); }
122 void emitMySignalWithArgs(int n) { emit mySignalWithArgs(n); }
126 void mySignalWithArgs(int n);
133 int methodArgs(int val) {
140 QML_DECLARE_TYPE(TestObject);
142 TestObject::TestObject(QObject *parent)
143 : QObject(parent), m_x(0)
152 void tst_script::initTestCase()
154 qmlRegisterType<TestObject>("Qt.test", 1, 0, "TestObject");
158 #define PROPERTY_PROGRAM \
159 "(function(testObject) { return (function() { " \
161 " for (var ii = 0; ii < 10000; ++ii) { " \
162 " test += testObject.x; " \
167 void tst_script::property_js()
169 QScriptEngine engine;
171 QScriptValue v = engine.newObject();
172 v.setProperty(QLatin1String("x"), 10);
174 QScriptValueList args;
176 QScriptValue prog = engine.evaluate(PROPERTY_PROGRAM).call(engine.globalObject(), args);
180 prog.call().toNumber();
184 static QScriptValue property_getter_method(QScriptContext *, QScriptEngine *engine)
187 return QScriptValue(engine,x++);
190 void tst_script::property_getter()
192 QScriptEngine engine;
194 QScriptValue v = engine.newObject();
195 v.setProperty(QLatin1String("x"), engine.newFunction(property_getter_method),
196 QScriptValue::PropertyGetter);
198 QScriptValueList args;
200 QScriptValue prog = engine.evaluate(PROPERTY_PROGRAM).call(engine.globalObject(), args);
208 static TestObject *property_getter_qobject_object = 0;
209 static QScriptValue property_getter_qobject_method(QScriptContext *, QScriptEngine *)
213 idx = TestObject::staticMetaObject.indexOfProperty("x");
216 void *args[] = { &value, 0 };
217 QMetaObject::metacall(property_getter_qobject_object, QMetaObject::ReadProperty, idx, args);
219 return QScriptValue(value);
222 static QScriptValue property_getter_qmetaproperty_method(QScriptContext *, QScriptEngine *)
226 idx = TestObject::staticMetaObject.indexOfProperty("x");
229 value = property_getter_qobject_object->metaObject()->property(idx).read(property_getter_qobject_object).toInt();
231 return QScriptValue(value);
234 void tst_script::property_getter_qobject()
236 QScriptEngine engine;
239 property_getter_qobject_object = &to;
240 QScriptValue v = engine.newObject();
241 v.setProperty(QLatin1String("x"), engine.newFunction(property_getter_qobject_method),
242 QScriptValue::PropertyGetter);
244 QScriptValueList args;
246 QScriptValue prog = engine.evaluate(PROPERTY_PROGRAM).call(engine.globalObject(), args);
252 property_getter_qobject_object = 0;
255 void tst_script::property_getter_qmetaproperty()
257 QScriptEngine engine;
260 property_getter_qobject_object = &to;
261 QScriptValue v = engine.newObject();
262 v.setProperty(QLatin1String("x"), engine.newFunction(property_getter_qmetaproperty_method),
263 QScriptValue::PropertyGetter);
265 QScriptValueList args;
267 QScriptValue prog = engine.evaluate(PROPERTY_PROGRAM).call(engine.globalObject(), args);
273 property_getter_qobject_object = 0;
277 void tst_script::property_getter_js()
279 QScriptEngine engine;
281 QScriptValue v = engine.evaluate("(function() { var o = new Object; o._x = 0; o.__defineGetter__(\"x\", function() { return this._x++; }); return o; })").call();
283 QScriptValueList args;
285 QScriptValue prog = engine.evaluate(PROPERTY_PROGRAM).call(engine.globalObject(), args);
293 void tst_script::property_qobject()
295 QScriptEngine engine;
298 QScriptValue v = engine.newQObject(&to);
300 QScriptValueList args;
302 QScriptValue prog = engine.evaluate(PROPERTY_PROGRAM).call(engine.globalObject(), args);
310 void tst_script::property_qmlobject()
312 QDeclarativeEngine qmlengine;
314 QScriptEngine *engine = QDeclarativeEnginePrivate::getScriptEngine(&qmlengine);
317 QScriptValue v = QDeclarativeEnginePrivate::get(&qmlengine)->objectClass->newQObject(&to);
319 QScriptValueList args;
321 QScriptValue prog = engine->evaluate(PROPERTY_PROGRAM).call(engine->globalObject(), args);
329 #define SETPROPERTY_PROGRAM \
330 "(function(testObject) { return (function() { " \
331 " for (var ii = 0; ii < 10000; ++ii) { " \
332 " testObject.x = ii; " \
336 void tst_script::setproperty_js()
338 QScriptEngine engine;
340 QScriptValue v = engine.newObject();
341 v.setProperty(QLatin1String("x"), 0);
343 QScriptValueList args;
345 QScriptValue prog = engine.evaluate(SETPROPERTY_PROGRAM).call(engine.globalObject(), args);
353 void tst_script::setproperty_qmlobject()
355 QDeclarativeEngine qmlengine;
357 QScriptEngine *engine = QDeclarativeEnginePrivate::getScriptEngine(&qmlengine);
360 QScriptValue v = QDeclarativeEnginePrivate::get(&qmlengine)->objectClass->newQObject(&to);
362 QScriptValueList args;
364 QScriptValue prog = engine->evaluate(SETPROPERTY_PROGRAM).call(engine->globalObject(), args);
372 #define FUNCTION_PROGRAM \
373 "(function(testObject) { return (function() { " \
375 " for (var ii = 0; ii < 10000; ++ii) { " \
376 " test += testObject.method(); " \
381 void tst_script::function_js()
383 QScriptEngine engine;
385 QScriptValue v = engine.evaluate("(function() { var o = new Object; o._x = 0; o.method = (function() { return this._x++; }); return o; })").call();
387 QScriptValueList args;
389 QScriptValue prog = engine.evaluate(FUNCTION_PROGRAM).call(engine.globalObject(), args);
397 static QScriptValue function_method(QScriptContext *, QScriptEngine *)
400 return QScriptValue(x++);
403 void tst_script::function_cpp()
405 QScriptEngine engine;
407 QScriptValue v = engine.newObject();
408 v.setProperty(QLatin1String("method"), engine.newFunction(function_method));
410 QScriptValueList args;
412 QScriptValue prog = engine.evaluate(FUNCTION_PROGRAM).call(engine.globalObject(), args);
420 void tst_script::function_qobject()
422 QScriptEngine engine;
425 QScriptValue v = engine.newQObject(&to);
427 QScriptValueList args;
429 QScriptValue prog = engine.evaluate(FUNCTION_PROGRAM).call(engine.globalObject(), args);
437 void tst_script::function_qmlobject()
439 QDeclarativeEngine qmlengine;
441 QScriptEngine *engine = QDeclarativeEnginePrivate::getScriptEngine(&qmlengine);
444 QScriptValue v = QDeclarativeEnginePrivate::get(&qmlengine)->objectClass->newQObject(&to);
446 QScriptValueList args;
448 QScriptValue prog = engine->evaluate(FUNCTION_PROGRAM).call(engine->globalObject(), args);
456 #define FUNCTION_ARGS_PROGRAM \
457 "(function(testObject) { return (function() { " \
459 " for (var ii = 0; ii < 10000; ++ii) { " \
460 " test += testObject.methodArgs(ii); " \
465 void tst_script::function_args_js()
467 QScriptEngine engine;
469 QScriptValue v = engine.evaluate("(function() { var o = new Object; o._x = 0; o.methodArgs = (function(a) { return a + this._x++; }); return o; })").call();
471 QScriptValueList args;
473 QScriptValue prog = engine.evaluate(FUNCTION_ARGS_PROGRAM).call(engine.globalObject(), args);
481 static QScriptValue function_args_method(QScriptContext *ctxt, QScriptEngine *)
484 return QScriptValue(ctxt->argument(0).toNumber() + x++);
487 void tst_script::function_args_cpp()
489 QScriptEngine engine;
491 QScriptValue v = engine.newObject();
492 v.setProperty(QLatin1String("methodArgs"), engine.newFunction(function_args_method));
494 QScriptValueList args;
496 QScriptValue prog = engine.evaluate(FUNCTION_ARGS_PROGRAM).call(engine.globalObject(), args);
504 void tst_script::function_args_qobject()
506 QScriptEngine engine;
509 QScriptValue v = engine.newQObject(&to);
511 QScriptValueList args;
513 QScriptValue prog = engine.evaluate(FUNCTION_ARGS_PROGRAM).call(engine.globalObject(), args);
521 void tst_script::function_args_qmlobject()
523 QDeclarativeEngine qmlengine;
525 QScriptEngine *engine = QDeclarativeEnginePrivate::getScriptEngine(&qmlengine);
528 QScriptValue v = QDeclarativeEnginePrivate::get(&qmlengine)->objectClass->newQObject(&to);
530 QScriptValueList args;
532 QScriptValue prog = engine->evaluate(FUNCTION_ARGS_PROGRAM).call(engine->globalObject(), args);
540 void tst_script::signal_unconnected()
542 QDeclarativeEngine engine;
543 QDeclarativeComponent component(&engine, TEST_FILE("signal_unconnected.qml"));
544 TestObject *object = qobject_cast<TestObject *>(component.create());
545 QVERIFY(object != 0);
548 object->emitMySignal();
554 void tst_script::signal_qml()
556 QDeclarativeEngine engine;
557 QDeclarativeComponent component(&engine, TEST_FILE("signal_qml.qml"));
558 TestObject *object = qobject_cast<TestObject *>(component.create());
559 QVERIFY(object != 0);
562 object->emitMySignal();
568 void tst_script::signal_args()
570 QDeclarativeEngine engine;
571 QDeclarativeComponent component(&engine, TEST_FILE("signal_args.qml"));
572 TestObject *object = qobject_cast<TestObject *>(component.create());
573 QVERIFY(object != 0);
576 object->emitMySignalWithArgs(11);
582 void tst_script::signal_unusedArgs()
584 QDeclarativeEngine engine;
585 QDeclarativeComponent component(&engine, TEST_FILE("signal_unusedArgs.qml"));
586 TestObject *object = qobject_cast<TestObject *>(component.create());
587 QVERIFY(object != 0);
590 object->emitMySignalWithArgs(11);
596 void tst_script::slot_simple()
598 QDeclarativeEngine engine;
599 QDeclarativeComponent component(&engine, TEST_FILE("slot_simple.qml"));
600 TestObject *object = qobject_cast<TestObject *>(component.create());
601 QVERIFY(object != 0);
604 object->emitMySignal();
610 void tst_script::slot_simple_js()
612 QDeclarativeEngine engine;
613 QDeclarativeComponent component(&engine, TEST_FILE("slot_simple_js.qml"));
614 TestObject *object = qobject_cast<TestObject *>(component.create());
615 QVERIFY(object != 0);
618 object->emitMySignal();
624 void tst_script::slot_complex()
626 QDeclarativeEngine engine;
627 QDeclarativeComponent component(&engine, TEST_FILE("slot_complex.qml"));
628 TestObject *object = qobject_cast<TestObject *>(component.create());
629 QVERIFY(object != 0);
632 object->emitMySignal();
638 void tst_script::slot_complex_js()
640 QDeclarativeEngine engine;
641 QDeclarativeComponent component(&engine, TEST_FILE("slot_complex_js.qml"));
642 TestObject *object = qobject_cast<TestObject *>(component.create());
643 QVERIFY(object != 0);
646 object->emitMySignal();
652 void tst_script::block_data()
654 QTest::addColumn<QString>("methodName");
655 QTest::newRow("direct") << "doSomethingDirect()";
656 QTest::newRow("localObj") << "doSomethingLocalObj()";
657 QTest::newRow("local") << "doSomethingLocal()";
660 void tst_script::block()
662 QFETCH(QString, methodName);
663 QDeclarativeEngine engine;
664 QDeclarativeComponent component(&engine, TEST_FILE("block.qml"));
665 QDeclarativeRectangle *rect = qobject_cast<QDeclarativeRectangle *>(component.create());
668 int index = rect->metaObject()->indexOfMethod(methodName.toUtf8());
669 QVERIFY(index != -1);
670 QMetaMethod method = rect->metaObject()->method(index);
673 method.invoke(rect, Qt::DirectConnection);
679 #define GLOBALPROPERTY_PROGRAM \
681 " for (var ii = 0; ii < 10000; ++ii) { " \
686 void tst_script::global_property_js()
688 QScriptEngine engine;
690 QScriptValue prog = engine.evaluate(GLOBALPROPERTY_PROGRAM);
698 void tst_script::global_property_qml()
700 QDeclarativeEngine qmlengine;
702 QScriptEngine *engine = QDeclarativeEnginePrivate::getScriptEngine(&qmlengine);
703 QScriptValue prog = engine->evaluate(GLOBALPROPERTY_PROGRAM);
711 void tst_script::global_property_qml_js()
713 QDeclarativeEngine engine;
714 QDeclarativeComponent component(&engine, TEST_FILE("global_prop.qml"));
715 QDeclarativeRectangle *rect = qobject_cast<QDeclarativeRectangle *>(component.create());
718 int index = rect->metaObject()->indexOfMethod("triggered()");
719 QVERIFY(index != -1);
720 QMetaMethod method = rect->metaObject()->method(index);
723 method.invoke(rect, Qt::DirectConnection);
729 void tst_script::scriptfile_property()
731 QDeclarativeEngine engine;
732 QDeclarativeComponent component(&engine, TEST_FILE("global_prop.qml"));
733 QDeclarativeRectangle *rect = qobject_cast<QDeclarativeRectangle *>(component.create());
736 int index = rect->metaObject()->indexOfMethod("incrementTriggered()");
737 QVERIFY(index != -1);
738 QMetaMethod method = rect->metaObject()->method(index);
741 method.invoke(rect, Qt::DirectConnection);
747 void tst_script::enums()
749 QDeclarativeEngine engine;
750 QDeclarativeComponent component(&engine, TEST_FILE("enums.qml"));
751 QObject *o = component.create();
754 int index = o->metaObject()->indexOfMethod("runtest()");
755 QVERIFY(index != -1);
756 QMetaMethod method = o->metaObject()->method(index);
759 method.invoke(o, Qt::DirectConnection);
765 void tst_script::namespacedEnums()
767 QDeclarativeEngine engine;
768 QDeclarativeComponent component(&engine, TEST_FILE("namespacedEnums.qml"));
769 QObject *o = component.create();
772 int index = o->metaObject()->indexOfMethod("runtest()");
773 QVERIFY(index != -1);
774 QMetaMethod method = o->metaObject()->method(index);
777 method.invoke(o, Qt::DirectConnection);
783 void tst_script::scriptCall()
785 QDeclarativeEngine engine;
786 QDeclarativeComponent component(&engine, TEST_FILE("scriptCall.qml"));
787 QObject *o = component.create();
790 int index = o->metaObject()->indexOfMethod("runtest()");
791 QVERIFY(index != -1);
792 QMetaMethod method = o->metaObject()->method(index);
795 method.invoke(o, Qt::DirectConnection);
801 QTEST_MAIN(tst_script)
803 #include "tst_script.moc"