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
****************************************************************************/
44
#include <QQmlComponent>
45
#include <private/qqmlengine_p.h>
46
#include <private/qquickrectangle_p.h>
50
class tst_script : public QObject
60
void property_getter_js();
62
//no native functions for now
63
void property_getter();
64
void property_getter_qobject();
65
void property_getter_qmetaproperty();
67
void property_qobject();
68
void property_qmlobject();
70
void setproperty_js();
71
void setproperty_qmlobject();
75
//no native functions for now
78
void function_qobject();
79
void function_qmlobject();
81
void function_args_js();
83
//no native functions for now
84
void function_args_cpp();
86
void function_args_qobject();
87
void function_args_qmlobject();
89
void signal_unconnected();
92
void signal_unusedArgs();
93
void signal_heavyArgsAccess();
94
void signal_heavyIdAccess();
97
void slot_simple_js();
99
void slot_complex_js();
104
void global_property_js();
105
void global_property_qml();
106
void global_property_qml_js();
108
void scriptfile_property();
111
void namespacedEnums();
115
inline QUrl TEST_FILE(const QString &filename)
117
return QUrl::fromLocalFile(QLatin1String(SRCDIR) + QLatin1String("/data/") + filename);
120
class TestObject : public QObject
123
Q_PROPERTY(int x READ x WRITE setX)
126
TestObject(QObject *parent = 0);
129
void setX(int x) { m_x = x; }
131
void emitMySignal() { emit mySignal(); }
132
void emitMySignalWithArgs(int n) { emit mySignalWithArgs(n); }
136
void mySignalWithArgs(int n);
143
int methodArgs(int val) {
150
QML_DECLARE_TYPE(TestObject);
152
TestObject::TestObject(QObject *parent)
153
: QObject(parent), m_x(0)
162
void tst_script::initTestCase()
164
qmlRegisterType<TestObject>("Qt.test", 1, 0, "TestObject");
168
#define PROPERTY_PROGRAM \
169
"(function(testObject) { return (function() { " \
171
" for (var ii = 0; ii < 10000; ++ii) { " \
172
" test += testObject.x; " \
177
void tst_script::property_js()
181
QJSValue v = engine.newObject();
182
v.setProperty(QLatin1String("x"), 10);
186
QJSValue prog = engine.evaluate(PROPERTY_PROGRAM).call(args);
190
prog.call().toNumber();
195
static QJSValue property_getter_method(QScriptContext *, QJSEngine *engine)
198
return QJSValue(engine,x++);
201
void tst_script::property_getter()
205
QJSValue v = engine.newObject();
206
v.setProperty(QLatin1String("x"), engine.newFunction(property_getter_method),
207
QJSValue::PropertyGetter);
211
QJSValue prog = engine.evaluate(PROPERTY_PROGRAM).call(args);
219
static TestObject *property_getter_qobject_object = 0;
220
static QJSValue property_getter_qobject_method(QScriptContext *, QJSEngine *)
224
idx = TestObject::staticMetaObject.indexOfProperty("x");
227
void *args[] = { &value, 0 };
228
QMetaObject::metacall(property_getter_qobject_object, QMetaObject::ReadProperty, idx, args);
230
return QJSValue(value);
233
static QJSValue property_getter_qmetaproperty_method(QScriptContext *, QJSEngine *)
237
idx = TestObject::staticMetaObject.indexOfProperty("x");
240
value = property_getter_qobject_object->metaObject()->property(idx).read(property_getter_qobject_object).toInt();
242
return QJSValue(value);
245
void tst_script::property_getter_qobject()
250
property_getter_qobject_object = &to;
251
QJSValue v = engine.newObject();
252
v.setProperty(QLatin1String("x"), engine.newFunction(property_getter_qobject_method),
253
QJSValue::PropertyGetter);
257
QJSValue prog = engine.evaluate(PROPERTY_PROGRAM).call(args);
263
property_getter_qobject_object = 0;
266
void tst_script::property_getter_qmetaproperty()
271
property_getter_qobject_object = &to;
272
QJSValue v = engine.newObject();
273
v.setProperty(QLatin1String("x"), engine.newFunction(property_getter_qmetaproperty_method),
274
QJSValue::PropertyGetter);
278
QJSValue prog = engine.evaluate(PROPERTY_PROGRAM).call(args);
284
property_getter_qobject_object = 0;
288
void tst_script::property_getter_js()
292
QJSValue v = engine.evaluate("(function() { var o = new Object; o._x = 0; o.__defineGetter__(\"x\", function() { return this._x++; }); return o; })").call();
296
QJSValue prog = engine.evaluate(PROPERTY_PROGRAM).call(args);
304
void tst_script::property_qobject()
309
QJSValue v = engine.newQObject(&to);
313
QJSValue prog = engine.evaluate(PROPERTY_PROGRAM).call(args);
321
void tst_script::property_qmlobject()
323
QQmlEngine qmlengine;
326
QV8Engine *engine = QQmlEnginePrivate::getV8Engine(&qmlengine);
327
v8::HandleScope handle_scope;
328
v8::Context::Scope scope(engine->context());
329
QJSValue v = engine->scriptValueFromInternal(engine->qobjectWrapper()->newQObject(&to));
333
QJSValue prog = qmlengine.evaluate(PROPERTY_PROGRAM).call(args);
341
#define SETPROPERTY_PROGRAM \
342
"(function(testObject) { return (function() { " \
343
" for (var ii = 0; ii < 10000; ++ii) { " \
344
" testObject.x = ii; " \
348
void tst_script::setproperty_js()
352
QJSValue v = engine.newObject();
353
v.setProperty(QLatin1String("x"), 0);
357
QJSValue prog = engine.evaluate(SETPROPERTY_PROGRAM).call(args);
365
void tst_script::setproperty_qmlobject()
367
QQmlEngine qmlengine;
371
QV8Engine *engine = QQmlEnginePrivate::getV8Engine(&qmlengine);
372
v8::HandleScope handle_scope;
373
v8::Context::Scope scope(engine->context());
374
QJSValue v = engine->scriptValueFromInternal(engine->qobjectWrapper()->newQObject(&to));
378
QJSValue prog = qmlengine.evaluate(SETPROPERTY_PROGRAM).call(args);
386
#define FUNCTION_PROGRAM \
387
"(function(testObject) { return (function() { " \
389
" for (var ii = 0; ii < 10000; ++ii) { " \
390
" test += testObject.method(); " \
395
void tst_script::function_js()
399
QJSValue v = engine.evaluate("(function() { var o = new Object; o._x = 0; o.method = (function() { return this._x++; }); return o; })").call();
403
QJSValue prog = engine.evaluate(FUNCTION_PROGRAM).call(args);
412
static QJSValue function_method(QScriptContext *, QJSEngine *)
415
return QJSValue(x++);
418
void tst_script::function_cpp()
422
QJSValue v = engine.newObject();
423
v.setProperty(QLatin1String("method"), engine.newFunction(function_method));
427
QJSValue prog = engine.evaluate(FUNCTION_PROGRAM).call(args);
436
void tst_script::function_qobject()
441
QJSValue v = engine.newQObject(&to);
445
QJSValue prog = engine.evaluate(FUNCTION_PROGRAM).call(args);
453
void tst_script::function_qmlobject()
455
QQmlEngine qmlengine;
459
QV8Engine *engine = QQmlEnginePrivate::getV8Engine(&qmlengine);
460
v8::HandleScope handle_scope;
461
v8::Context::Scope scope(engine->context());
462
QJSValue v = engine->scriptValueFromInternal(engine->qobjectWrapper()->newQObject(&to));
466
QJSValue prog = qmlengine.evaluate(FUNCTION_PROGRAM).call(args);
474
#define FUNCTION_ARGS_PROGRAM \
475
"(function(testObject) { return (function() { " \
477
" for (var ii = 0; ii < 10000; ++ii) { " \
478
" test += testObject.methodArgs(ii); " \
483
void tst_script::function_args_js()
487
QJSValue v = engine.evaluate("(function() { var o = new Object; o._x = 0; o.methodArgs = (function(a) { return a + this._x++; }); return o; })").call();
491
QJSValue prog = engine.evaluate(FUNCTION_ARGS_PROGRAM).call(args);
500
static QJSValue function_args_method(QScriptContext *ctxt, QJSEngine *)
503
return QJSValue(ctxt->argument(0).toNumber() + x++);
506
void tst_script::function_args_cpp()
510
QJSValue v = engine.newObject();
511
v.setProperty(QLatin1String("methodArgs"), engine.newFunction(function_args_method));
515
QJSValue prog = engine.evaluate(FUNCTION_ARGS_PROGRAM).call(args);
524
void tst_script::function_args_qobject()
529
QJSValue v = engine.newQObject(&to);
533
QJSValue prog = engine.evaluate(FUNCTION_ARGS_PROGRAM).call(args);
541
void tst_script::function_args_qmlobject()
543
QQmlEngine qmlengine;
547
QV8Engine *engine = QQmlEnginePrivate::getV8Engine(&qmlengine);
548
v8::HandleScope handle_scope;
549
v8::Context::Scope scope(engine->context());
550
QJSValue v = engine->scriptValueFromInternal(engine->qobjectWrapper()->newQObject(&to));
554
QJSValue prog = qmlengine.evaluate(FUNCTION_ARGS_PROGRAM).call(args);
562
void tst_script::signal_unconnected()
565
QQmlComponent component(&engine, TEST_FILE("signal_unconnected.qml"));
566
TestObject *object = qobject_cast<TestObject *>(component.create());
567
QVERIFY(object != 0);
570
object->emitMySignal();
576
void tst_script::signal_qml()
579
QQmlComponent component(&engine, TEST_FILE("signal_qml.qml"));
580
TestObject *object = qobject_cast<TestObject *>(component.create());
581
QVERIFY(object != 0);
584
object->emitMySignal();
590
void tst_script::signal_args()
593
QQmlComponent component(&engine, TEST_FILE("signal_args.qml"));
594
TestObject *object = qobject_cast<TestObject *>(component.create());
595
QVERIFY(object != 0);
598
object->emitMySignalWithArgs(11);
604
void tst_script::signal_unusedArgs()
607
QQmlComponent component(&engine, TEST_FILE("signal_unusedArgs.qml"));
608
TestObject *object = qobject_cast<TestObject *>(component.create());
609
QVERIFY(object != 0);
612
object->emitMySignalWithArgs(11);
618
void tst_script::signal_heavyArgsAccess()
621
QQmlComponent component(&engine, TEST_FILE("signal_heavyArgsAccess.qml"));
622
TestObject *object = qobject_cast<TestObject *>(component.create());
623
QVERIFY(object != 0);
626
object->emitMySignalWithArgs(11);
632
void tst_script::signal_heavyIdAccess()
635
QQmlComponent component(&engine, TEST_FILE("signal_heavyIdAccess.qml"));
636
TestObject *object = qobject_cast<TestObject *>(component.create());
637
QVERIFY(object != 0);
640
object->emitMySignalWithArgs(11);
646
void tst_script::slot_simple()
649
QQmlComponent component(&engine, TEST_FILE("slot_simple.qml"));
650
TestObject *object = qobject_cast<TestObject *>(component.create());
651
QVERIFY(object != 0);
654
object->emitMySignal();
660
void tst_script::slot_simple_js()
663
QQmlComponent component(&engine, TEST_FILE("slot_simple_js.qml"));
664
TestObject *object = qobject_cast<TestObject *>(component.create());
665
QVERIFY(object != 0);
668
object->emitMySignal();
674
void tst_script::slot_complex()
677
QQmlComponent component(&engine, TEST_FILE("slot_complex.qml"));
678
TestObject *object = qobject_cast<TestObject *>(component.create());
679
QVERIFY(object != 0);
682
object->emitMySignal();
688
void tst_script::slot_complex_js()
691
QQmlComponent component(&engine, TEST_FILE("slot_complex_js.qml"));
692
TestObject *object = qobject_cast<TestObject *>(component.create());
693
QVERIFY(object != 0);
696
object->emitMySignal();
702
void tst_script::block_data()
704
QTest::addColumn<QString>("methodName");
705
QTest::newRow("direct") << "doSomethingDirect()";
706
QTest::newRow("localObj") << "doSomethingLocalObj()";
707
QTest::newRow("local") << "doSomethingLocal()";
710
void tst_script::block()
712
QFETCH(QString, methodName);
714
QQmlComponent component(&engine, TEST_FILE("block.qml"));
715
QQuickRectangle *rect = qobject_cast<QQuickRectangle *>(component.create());
718
int index = rect->metaObject()->indexOfMethod(methodName.toUtf8());
719
QVERIFY(index != -1);
720
QMetaMethod method = rect->metaObject()->method(index);
723
method.invoke(rect, Qt::DirectConnection);
729
#define GLOBALPROPERTY_PROGRAM \
731
" for (var ii = 0; ii < 10000; ++ii) { " \
736
void tst_script::global_property_js()
740
QJSValue prog = engine.evaluate(GLOBALPROPERTY_PROGRAM);
748
void tst_script::global_property_qml()
750
QQmlEngine qmlengine;
752
QJSValue prog = qmlengine.evaluate(GLOBALPROPERTY_PROGRAM);
760
void tst_script::global_property_qml_js()
763
QQmlComponent component(&engine, TEST_FILE("global_prop.qml"));
764
QQuickRectangle *rect = qobject_cast<QQuickRectangle *>(component.create());
767
int index = rect->metaObject()->indexOfMethod("triggered()");
768
QVERIFY(index != -1);
769
QMetaMethod method = rect->metaObject()->method(index);
772
method.invoke(rect, Qt::DirectConnection);
778
void tst_script::scriptfile_property()
781
QQmlComponent component(&engine, TEST_FILE("global_prop.qml"));
782
QQuickRectangle *rect = qobject_cast<QQuickRectangle *>(component.create());
785
int index = rect->metaObject()->indexOfMethod("incrementTriggered()");
786
QVERIFY(index != -1);
787
QMetaMethod method = rect->metaObject()->method(index);
790
method.invoke(rect, Qt::DirectConnection);
796
void tst_script::enums()
799
QQmlComponent component(&engine, TEST_FILE("enums.qml"));
800
QObject *o = component.create();
803
int index = o->metaObject()->indexOfMethod("runtest()");
804
QVERIFY(index != -1);
805
QMetaMethod method = o->metaObject()->method(index);
808
method.invoke(o, Qt::DirectConnection);
814
void tst_script::namespacedEnums()
817
QQmlComponent component(&engine, TEST_FILE("namespacedEnums.qml"));
818
QObject *o = component.create();
821
int index = o->metaObject()->indexOfMethod("runtest()");
822
QVERIFY(index != -1);
823
QMetaMethod method = o->metaObject()->method(index);
826
method.invoke(o, Qt::DirectConnection);
832
void tst_script::scriptCall()
835
QQmlComponent component(&engine, TEST_FILE("scriptCall.qml"));
836
QObject *o = component.create();
839
int index = o->metaObject()->indexOfMethod("runtest()");
840
QVERIFY(index != -1);
841
QMetaMethod method = o->metaObject()->method(index);
844
method.invoke(o, Qt::DirectConnection);
850
QTEST_MAIN(tst_script)
852
#include "tst_script.moc"