1d0825bca7fe65beaee391d30da42e937db621564Steve Block/*
2d0825bca7fe65beaee391d30da42e937db621564Steve Block    Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
3d0825bca7fe65beaee391d30da42e937db621564Steve Block
4d0825bca7fe65beaee391d30da42e937db621564Steve Block    This library is free software; you can redistribute it and/or
5d0825bca7fe65beaee391d30da42e937db621564Steve Block    modify it under the terms of the GNU Library General Public
6d0825bca7fe65beaee391d30da42e937db621564Steve Block    License as published by the Free Software Foundation; either
7d0825bca7fe65beaee391d30da42e937db621564Steve Block    version 2 of the License, or (at your option) any later version.
8d0825bca7fe65beaee391d30da42e937db621564Steve Block
9d0825bca7fe65beaee391d30da42e937db621564Steve Block    This library is distributed in the hope that it will be useful,
10d0825bca7fe65beaee391d30da42e937db621564Steve Block    but WITHOUT ANY WARRANTY; without even the implied warranty of
11d0825bca7fe65beaee391d30da42e937db621564Steve Block    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12d0825bca7fe65beaee391d30da42e937db621564Steve Block    Library General Public License for more details.
13d0825bca7fe65beaee391d30da42e937db621564Steve Block
14d0825bca7fe65beaee391d30da42e937db621564Steve Block    You should have received a copy of the GNU Library General Public License
15d0825bca7fe65beaee391d30da42e937db621564Steve Block    along with this library; see the file COPYING.LIB.  If not, write to
16d0825bca7fe65beaee391d30da42e937db621564Steve Block    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17d0825bca7fe65beaee391d30da42e937db621564Steve Block    Boston, MA 02110-1301, USA.
18d0825bca7fe65beaee391d30da42e937db621564Steve Block*/
19d0825bca7fe65beaee391d30da42e937db621564Steve Block
20d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "qscriptengine.h"
21dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "qscriptprogram.h"
22dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "qscriptsyntaxcheckresult.h"
23d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "qscriptvalue.h"
24bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#include <QtCore/qnumeric.h>
25d0825bca7fe65beaee391d30da42e937db621564Steve Block#include <QtTest/qtest.h>
26d0825bca7fe65beaee391d30da42e937db621564Steve Block
27d0825bca7fe65beaee391d30da42e937db621564Steve Blockclass tst_QScriptEngine : public QObject {
28d0825bca7fe65beaee391d30da42e937db621564Steve Block    Q_OBJECT
29d0825bca7fe65beaee391d30da42e937db621564Steve Block
30d0825bca7fe65beaee391d30da42e937db621564Steve Blockpublic:
31d0825bca7fe65beaee391d30da42e937db621564Steve Block    tst_QScriptEngine() {}
32d0825bca7fe65beaee391d30da42e937db621564Steve Block    virtual ~tst_QScriptEngine() {}
33d0825bca7fe65beaee391d30da42e937db621564Steve Block
34d0825bca7fe65beaee391d30da42e937db621564Steve Blockpublic slots:
35d0825bca7fe65beaee391d30da42e937db621564Steve Block    void init() {}
36d0825bca7fe65beaee391d30da42e937db621564Steve Block    void cleanup() {}
37d0825bca7fe65beaee391d30da42e937db621564Steve Block
38d0825bca7fe65beaee391d30da42e937db621564Steve Blockprivate slots:
390617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    void newFunction();
40545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    void newObject();
41dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    void globalObject();
42d0825bca7fe65beaee391d30da42e937db621564Steve Block    void evaluate();
43d0825bca7fe65beaee391d30da42e937db621564Steve Block    void collectGarbage();
44dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    void reportAdditionalMemoryCost();
458a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    void nullValue();
468a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    void undefinedValue();
47dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    void evaluateProgram();
48dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    void checkSyntax_data();
49dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    void checkSyntax();
506c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    void toObject();
516c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    void toObjectTwoEngines();
52ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    void newArray();
53ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    void uncaughtException();
54bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    void newDate();
55d0825bca7fe65beaee391d30da42e937db621564Steve Block};
56d0825bca7fe65beaee391d30da42e937db621564Steve Block
57d0825bca7fe65beaee391d30da42e937db621564Steve Block/* Evaluating a script that throw an unhandled exception should return an invalid value. */
58d0825bca7fe65beaee391d30da42e937db621564Steve Blockvoid tst_QScriptEngine::evaluate()
59d0825bca7fe65beaee391d30da42e937db621564Steve Block{
60d0825bca7fe65beaee391d30da42e937db621564Steve Block    QScriptEngine engine;
61d0825bca7fe65beaee391d30da42e937db621564Steve Block    QVERIFY2(engine.evaluate("1+1").isValid(), "the expression should be evaluated and an valid result should be returned");
62d0825bca7fe65beaee391d30da42e937db621564Steve Block    QVERIFY2(engine.evaluate("ping").isValid(), "Script throwing an unhandled exception should return an exception value");
63d0825bca7fe65beaee391d30da42e937db621564Steve Block}
64d0825bca7fe65beaee391d30da42e937db621564Steve Block
650617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsenstatic QScriptValue myFunction(QScriptContext*, QScriptEngine* eng)
660617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen{
670617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    return eng->nullValue();
680617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen}
690617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen
700617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsenstatic QScriptValue myFunctionWithArg(QScriptContext*, QScriptEngine* eng, void* arg)
710617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen{
720617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    int* result = reinterpret_cast<int*>(arg);
730617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    return QScriptValue(eng, *result);
740617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen}
750617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen
760617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsenstatic QScriptValue myFunctionThatReturns(QScriptContext*, QScriptEngine* eng)
770617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen{
780617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    return QScriptValue(eng, 42);
790617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen}
800617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen
810617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsenstatic QScriptValue myFunctionThatReturnsWithoutEngine(QScriptContext*, QScriptEngine*)
820617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen{
830617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    return QScriptValue(1024);
840617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen}
850617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen
860617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsenstatic QScriptValue myFunctionThatReturnsWrongEngine(QScriptContext*, QScriptEngine*, void* arg)
870617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen{
880617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    QScriptEngine* wrongEngine = reinterpret_cast<QScriptEngine*>(arg);
890617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    return QScriptValue(wrongEngine, 42);
900617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen}
910617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen
920617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsenvoid tst_QScriptEngine::newFunction()
930617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen{
940617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    QScriptEngine eng;
950617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    {
960617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QScriptValue fun = eng.newFunction(myFunction);
970617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QCOMPARE(fun.isValid(), true);
980617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QCOMPARE(fun.isFunction(), true);
990617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QCOMPARE(fun.isObject(), true);
1000617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        // QCOMPARE(fun.scriptClass(), (QScriptClass*)0);
1010617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        // a prototype property is automatically constructed
1020617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        {
1030617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen            QScriptValue prot = fun.property("prototype", QScriptValue::ResolveLocal);
1040617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen            QVERIFY(prot.isObject());
1050617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen            QVERIFY(prot.property("constructor").strictlyEquals(fun));
1060617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen            QEXPECT_FAIL("", "JSCallbackObject::getOwnPropertyDescriptor() doesn't return correct information yet", Continue);
1070617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen            QCOMPARE(fun.propertyFlags("prototype"), QScriptValue::Undeletable);
1080617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen            QEXPECT_FAIL("", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1090617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen            QCOMPARE(prot.propertyFlags("constructor"), QScriptValue::PropertyFlags(QScriptValue::Undeletable | QScriptValue::SkipInEnumeration));
1100617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        }
1110617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        // prototype should be Function.prototype
1120617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QCOMPARE(fun.prototype().isValid(), true);
1130617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QCOMPARE(fun.prototype().isFunction(), true);
1140617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QCOMPARE(fun.prototype().strictlyEquals(eng.evaluate("Function.prototype")), true);
1150617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen
1160617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QCOMPARE(fun.call().isNull(), true);
1170617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        // QCOMPARE(fun.construct().isObject(), true);
1180617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    }
1190617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    // the overload that takes an extra argument
1200617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    {
1210617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        int expectedResult = 42;
1220617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QScriptValue fun = eng.newFunction(myFunctionWithArg, reinterpret_cast<void*>(&expectedResult));
1230617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QVERIFY(fun.isFunction());
1240617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        // QCOMPARE(fun.scriptClass(), (QScriptClass*)0);
1250617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        // a prototype property is automatically constructed
1260617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        {
1270617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen            QScriptValue prot = fun.property("prototype", QScriptValue::ResolveLocal);
1280617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen            QVERIFY(prot.isObject());
1290617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen            QVERIFY(prot.property("constructor").strictlyEquals(fun));
1300617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen            QEXPECT_FAIL("", "JSCallbackObject::getOwnPropertyDescriptor() doesn't return correct information yet", Continue);
1310617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen            QCOMPARE(fun.propertyFlags("prototype"), QScriptValue::Undeletable);
1320617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen            QEXPECT_FAIL("", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1330617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen            QCOMPARE(prot.propertyFlags("constructor"), QScriptValue::PropertyFlags(QScriptValue::Undeletable | QScriptValue::SkipInEnumeration));
1340617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        }
1350617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        // prototype should be Function.prototype
1360617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QCOMPARE(fun.prototype().isValid(), true);
1370617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QCOMPARE(fun.prototype().isFunction(), true);
1380617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QCOMPARE(fun.prototype().strictlyEquals(eng.evaluate("Function.prototype")), true);
1390617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen
1400617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QScriptValue result = fun.call();
1410617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QCOMPARE(result.isNumber(), true);
1420617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QCOMPARE(result.toInt32(), expectedResult);
1430617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    }
1440617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    // the overload that takes a prototype
1450617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    {
1460617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QScriptValue proto = eng.newObject();
1470617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QScriptValue fun = eng.newFunction(myFunction, proto);
1480617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QCOMPARE(fun.isValid(), true);
1490617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QCOMPARE(fun.isFunction(), true);
1500617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QCOMPARE(fun.isObject(), true);
1510617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        // internal prototype should be Function.prototype
1520617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QCOMPARE(fun.prototype().isValid(), true);
1530617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QCOMPARE(fun.prototype().isFunction(), true);
1540617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QCOMPARE(fun.prototype().strictlyEquals(eng.evaluate("Function.prototype")), true);
1550617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        // public prototype should be the one we passed
1560617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QCOMPARE(fun.property("prototype").strictlyEquals(proto), true);
1570617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QEXPECT_FAIL("", "JSCallbackObject::getOwnPropertyDescriptor() doesn't return correct information yet", Continue);
1580617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QCOMPARE(fun.propertyFlags("prototype"), QScriptValue::Undeletable);
1590617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QCOMPARE(proto.property("constructor").strictlyEquals(fun), true);
1600617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QEXPECT_FAIL("", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
1610617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QCOMPARE(proto.propertyFlags("constructor"), QScriptValue::PropertyFlags(QScriptValue::Undeletable | QScriptValue::SkipInEnumeration));
1620617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen
1630617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QCOMPARE(fun.call().isNull(), true);
1640617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        // QCOMPARE(fun.construct().isObject(), true);
1650617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    }
1660617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    // whether the return value is correct
1670617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    {
1680617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QScriptValue fun = eng.newFunction(myFunctionThatReturns);
1690617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QCOMPARE(fun.isValid(), true);
1700617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QCOMPARE(fun.isFunction(), true);
1710617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QCOMPARE(fun.isObject(), true);
1720617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen
1730617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QScriptValue result = fun.call();
1740617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QCOMPARE(result.isNumber(), true);
1750617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QCOMPARE(result.toInt32(), 42);
1760617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    }
1770617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    // whether the return value is assigned to the correct engine
1780617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    {
1790617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QScriptValue fun = eng.newFunction(myFunctionThatReturnsWithoutEngine);
1800617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QCOMPARE(fun.isValid(), true);
1810617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QCOMPARE(fun.isFunction(), true);
1820617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QCOMPARE(fun.isObject(), true);
1830617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen
1840617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QScriptValue result = fun.call();
1850617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QCOMPARE(result.engine(), &eng);
1860617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QCOMPARE(result.isNumber(), true);
1870617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QCOMPARE(result.toInt32(), 1024);
1880617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    }
1890617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    // whether the return value is undefined when returning a value with wrong engine
1900617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    {
1910617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QScriptEngine wrongEngine;
1920617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen
1930617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QScriptValue fun = eng.newFunction(myFunctionThatReturnsWrongEngine, reinterpret_cast<void*>(&wrongEngine));
1940617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QCOMPARE(fun.isValid(), true);
1950617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QCOMPARE(fun.isFunction(), true);
1960617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QCOMPARE(fun.isObject(), true);
1970617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen
1980617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QTest::ignoreMessage(QtWarningMsg, "Value from different engine returned from native function, returning undefined value instead.");
1990617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QScriptValue result = fun.call();
2000617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QCOMPARE(result.isValid(), true);
2010617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        QCOMPARE(result.isUndefined(), true);
2020617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    }
2030617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen}
2040617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen
205545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdochvoid tst_QScriptEngine::newObject()
206545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch{
207545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    QScriptEngine engine;
208545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    QScriptValue object = engine.newObject();
209545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    QVERIFY(object.isObject());
210545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    QVERIFY(object.engine() == &engine);
211545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    QVERIFY(!object.isError());
212545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    QVERIFY(!object.equals(engine.newObject()));
213545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    QVERIFY(!object.strictlyEquals(engine.newObject()));
214545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch    QCOMPARE(object.toString(), QString::fromAscii("[object Object]"));
215545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch}
216545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch
217dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid tst_QScriptEngine::globalObject()
218dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
219dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    QScriptEngine engine;
220dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    QScriptValue global = engine.globalObject();
221dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    QScriptValue self = engine.evaluate("this");
222dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    QVERIFY(global.isObject());
223dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    QVERIFY(engine.globalObject().equals(engine.evaluate("this")));
224dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    QVERIFY(engine.globalObject().strictlyEquals(self));
225dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
226dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
227d0825bca7fe65beaee391d30da42e937db621564Steve Block/* Test garbage collection, at least try to not crash. */
228d0825bca7fe65beaee391d30da42e937db621564Steve Blockvoid tst_QScriptEngine::collectGarbage()
229d0825bca7fe65beaee391d30da42e937db621564Steve Block{
230d0825bca7fe65beaee391d30da42e937db621564Steve Block    QScriptEngine engine;
231d0825bca7fe65beaee391d30da42e937db621564Steve Block    QScriptValue foo = engine.evaluate("( function foo() {return 'pong';} )");
232d0825bca7fe65beaee391d30da42e937db621564Steve Block    QVERIFY(foo.isFunction());
233d0825bca7fe65beaee391d30da42e937db621564Steve Block    engine.collectGarbage();
234d0825bca7fe65beaee391d30da42e937db621564Steve Block    QCOMPARE(foo.call().toString(), QString::fromAscii("pong"));
235d0825bca7fe65beaee391d30da42e937db621564Steve Block}
2368a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
237dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid tst_QScriptEngine::reportAdditionalMemoryCost()
238dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
239dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // There isn't any easy way to test the responsiveness of the GC;
240dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // just try to call the function a few times with various sizes.
241dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    QScriptEngine eng;
242dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    for (int i = 0; i < 100; ++i) {
243dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        eng.reportAdditionalMemoryCost(0);
244dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        eng.reportAdditionalMemoryCost(10);
245dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        eng.reportAdditionalMemoryCost(1000);
246dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        eng.reportAdditionalMemoryCost(10000);
247dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        eng.reportAdditionalMemoryCost(100000);
248dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        eng.reportAdditionalMemoryCost(1000000);
249dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        eng.reportAdditionalMemoryCost(10000000);
250dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        eng.reportAdditionalMemoryCost(-1);
251dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        eng.reportAdditionalMemoryCost(-1000);
252dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        QScriptValue obj = eng.evaluate("new Object");
253dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        eng.collectGarbage();
254dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
255dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
256dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
2578a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Blockvoid tst_QScriptEngine::nullValue()
2588a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block{
2598a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    QScriptEngine engine;
2608a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    QScriptValue value = engine.nullValue();
2618a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    QVERIFY(value.isValid());
2628a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    QVERIFY(value.isNull());
2638a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block}
2648a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
2658a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Blockvoid tst_QScriptEngine::undefinedValue()
2668a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block{
2678a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    QScriptEngine engine;
2688a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    QScriptValue value = engine.undefinedValue();
2698a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    QVERIFY(value.isValid());
2708a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    QVERIFY(value.isUndefined());
2718a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block}
2728a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
273dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid tst_QScriptEngine::evaluateProgram()
274dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
275dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    QScriptEngine eng;
276dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
277dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        QString code("1 + 2");
278dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        QString fileName("hello.js");
279dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        int lineNumber = 123;
280dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        QScriptProgram program(code, fileName, lineNumber);
281dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        QVERIFY(!program.isNull());
282dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        QCOMPARE(program.sourceCode(), code);
283dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        QCOMPARE(program.fileName(), fileName);
284dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        QCOMPARE(program.firstLineNumber(), lineNumber);
285dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
286dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        QScriptValue expected = eng.evaluate(code);
287dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        for (int x = 0; x < 10; ++x) {
288dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            QScriptValue ret = eng.evaluate(program);
289dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            QVERIFY(ret.equals(expected));
290dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        }
291dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
292dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        // operator=
293dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        QScriptProgram sameProgram = program;
294dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        QVERIFY(sameProgram == program);
295dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        QVERIFY(eng.evaluate(sameProgram).equals(expected));
296dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
297dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        // copy constructor
298dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        QScriptProgram sameProgram2(program);
299dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        QVERIFY(sameProgram2 == program);
300dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        QVERIFY(eng.evaluate(sameProgram2).equals(expected));
301dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
302dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        QScriptProgram differentProgram("2 + 3");
303dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        QVERIFY(differentProgram != program);
304dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        QVERIFY(!eng.evaluate(differentProgram).equals(expected));
305dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
306dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
307dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // Program that accesses variable in the scope
308dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
309dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        QScriptProgram program("a");
310dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        QVERIFY(!program.isNull());
311dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        {
312dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            QScriptValue ret = eng.evaluate(program);
313dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            QVERIFY(ret.isError());
314dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            QCOMPARE(ret.toString(), QString::fromLatin1("ReferenceError: Can't find variable: a"));
315dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        }
316dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        {
317dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            QScriptValue ret = eng.evaluate(program);
318dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            QVERIFY(ret.isError());
319dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        }
320dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        eng.evaluate("a = 456");
321dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        {
322dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            QScriptValue ret = eng.evaluate(program);
323dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            QVERIFY(!ret.isError());
324dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            QCOMPARE(ret.toNumber(), 456.0);
325dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        }
326dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
327dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
328dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // Program that creates closure
329dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
330dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        QScriptProgram program("(function() { var count = 0; return function() { return count++; }; })");
331dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        QVERIFY(!program.isNull());
332dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        QScriptValue createCounter = eng.evaluate(program);
333dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        QVERIFY(createCounter.isFunction());
334dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        QScriptValue counter = createCounter.call();
335dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        QVERIFY(counter.isFunction());
336dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        {
337dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            QScriptValue ret = counter.call();
338dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            QVERIFY(ret.isNumber());
339dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        }
340dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        QScriptValue counter2 = createCounter.call();
341dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        QVERIFY(counter2.isFunction());
342dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        QVERIFY(!counter2.equals(counter));
343dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        {
344dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            QScriptValue ret = counter2.call();
345dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            QVERIFY(ret.isNumber());
346dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        }
347dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
348dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
349dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // Same program run in different engines
350dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
351dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        QString code("1 + 2");
352dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        QScriptProgram program(code);
353dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        QVERIFY(!program.isNull());
354dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        double expected = eng.evaluate(program).toNumber();
355dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        for (int x = 0; x < 2; ++x) {
356dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            QScriptEngine eng2;
357dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            for (int y = 0; y < 2; ++y) {
358dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                double ret = eng2.evaluate(program).toNumber();
359dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                QCOMPARE(ret, expected);
360dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            }
361dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        }
362dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
363dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
364dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // No program
365dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
366dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        QScriptProgram program;
367dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        QVERIFY(program.isNull());
368dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        QScriptValue ret = eng.evaluate(program);
369dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        QVERIFY(!ret.isValid());
370dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
371dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
372dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
373dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid tst_QScriptEngine::checkSyntax_data()
374dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
375dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    QTest::addColumn<QString>("code");
376dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    QTest::addColumn<int>("expectedState");
377dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    QTest::addColumn<int>("errorLineNumber");
378dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    QTest::addColumn<int>("errorColumnNumber");
379dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    QTest::addColumn<QString>("errorMessage");
380dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
381dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    QTest::newRow("0")
382dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        << QString("0") << int(QScriptSyntaxCheckResult::Valid)
383dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        << -1 << -1 << "";
384dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    QTest::newRow("if (")
385dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        << QString("if (\n") << int(QScriptSyntaxCheckResult::Intermediate)
386dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        << 1 << 4 << "";
387dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    QTest::newRow("if else")
388dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        << QString("\nif else") << int(QScriptSyntaxCheckResult::Error)
389dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        << 2 << 4 << "SyntaxError: Parse error";
390dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    QTest::newRow("{if}")
391dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            << QString("{\n{\nif\n}\n") << int(QScriptSyntaxCheckResult::Error)
392dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        << 4 << 1 << "SyntaxError: Parse error";
393dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    QTest::newRow("foo[")
394dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        << QString("foo[") << int(QScriptSyntaxCheckResult::Error)
395dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        << 1 << 4 << "SyntaxError: Parse error";
396dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    QTest::newRow("foo['bar']")
397dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        << QString("foo['bar']") << int(QScriptSyntaxCheckResult::Valid)
398dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        << -1 << -1 << "";
399dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
400dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    QTest::newRow("/*")
401dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        << QString("/*") << int(QScriptSyntaxCheckResult::Intermediate)
402dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        << 1 << 1 << "Unclosed comment at end of file";
403dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    QTest::newRow("/*\nMy comment")
404dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        << QString("/*\nMy comment") << int(QScriptSyntaxCheckResult::Intermediate)
405dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        << 1 << 1 << "Unclosed comment at end of file";
406dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    QTest::newRow("/*\nMy comment */\nfoo = 10")
407dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        << QString("/*\nMy comment */\nfoo = 10") << int(QScriptSyntaxCheckResult::Valid)
408dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        << -1 << -1 << "";
409dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    QTest::newRow("foo = 10 /*")
410dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        << QString("foo = 10 /*") << int(QScriptSyntaxCheckResult::Intermediate)
411dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        << -1 << -1 << "";
412dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    QTest::newRow("foo = 10; /*")
413dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        << QString("foo = 10; /*") << int(QScriptSyntaxCheckResult::Intermediate)
414dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        << 1 << 11 << "Expected `end of file'";
415dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    QTest::newRow("foo = 10 /* My comment */")
416dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        << QString("foo = 10 /* My comment */") << int(QScriptSyntaxCheckResult::Valid)
417dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        << -1 << -1 << "";
418dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
419dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    QTest::newRow("/=/")
420dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        << QString("/=/") << int(QScriptSyntaxCheckResult::Valid) << -1 << -1 << "";
421dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    QTest::newRow("/=/g")
422dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        << QString("/=/g") << int(QScriptSyntaxCheckResult::Valid) << -1 << -1 << "";
423dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    QTest::newRow("/a/")
424dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        << QString("/a/") << int(QScriptSyntaxCheckResult::Valid) << -1 << -1 << "";
425dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    QTest::newRow("/a/g")
426dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        << QString("/a/g") << int(QScriptSyntaxCheckResult::Valid) << -1 << -1 << "";
427dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
428dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
429dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid tst_QScriptEngine::checkSyntax()
430dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
431dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    QFETCH(QString, code);
432dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    QFETCH(int, expectedState);
433dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    QFETCH(int, errorLineNumber);
434dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    QFETCH(int, errorColumnNumber);
435dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    QFETCH(QString, errorMessage);
436dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
437dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    QScriptSyntaxCheckResult result = QScriptEngine::checkSyntax(code);
438dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
439dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // assignment
440dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
441dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        QScriptSyntaxCheckResult copy = result;
442dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        QCOMPARE(copy.state(), result.state());
443dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        QCOMPARE(copy.errorLineNumber(), result.errorLineNumber());
444dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        QCOMPARE(copy.errorColumnNumber(), result.errorColumnNumber());
445dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        QCOMPARE(copy.errorMessage(), result.errorMessage());
446dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
447dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
448dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        QScriptSyntaxCheckResult copy(result);
449dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        QCOMPARE(copy.state(), result.state());
450dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        QCOMPARE(copy.errorLineNumber(), result.errorLineNumber());
451dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        QCOMPARE(copy.errorColumnNumber(), result.errorColumnNumber());
452dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        QCOMPARE(copy.errorMessage(), result.errorMessage());
453dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
454dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
455dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (expectedState == QScriptSyntaxCheckResult::Intermediate)
456dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        QEXPECT_FAIL("", "QScriptSyntaxCheckResult::state() doesn't return the Intermediate state", Abort);
457dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    QCOMPARE(result.state(), QScriptSyntaxCheckResult::State(expectedState));
458dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    QCOMPARE(result.errorLineNumber(), errorLineNumber);
459dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (expectedState != QScriptSyntaxCheckResult::Valid && errorColumnNumber != 1)
460dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            QEXPECT_FAIL("", "QScriptSyntaxCheckResult::errorColumnNumber() doesn't return correct value", Continue);
461dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    QCOMPARE(result.errorColumnNumber(), errorColumnNumber);
462dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    QCOMPARE(result.errorMessage(), errorMessage);
463dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
464dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
4656c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenvoid tst_QScriptEngine::toObject()
4666c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen{
4676c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    QScriptEngine eng;
4686c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    QVERIFY(!eng.toObject(eng.undefinedValue()).isValid());
4696c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    QVERIFY(!eng.toObject(eng.nullValue()).isValid());
4706c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    QVERIFY(!eng.toObject(QScriptValue()).isValid());
4716c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
4726c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    QScriptValue falskt(false);
4736c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    {
4746c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        QScriptValue tmp = eng.toObject(falskt);
4756c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        QVERIFY(tmp.isObject());
4766c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        QVERIFY(!falskt.isObject());
4776c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        QVERIFY(!falskt.engine());
4786c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        QCOMPARE(tmp.toNumber(), falskt.toNumber());
4796c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    }
4806c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
4816c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    QScriptValue sant(true);
4826c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    {
4836c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        QScriptValue tmp = eng.toObject(sant);
4846c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        QVERIFY(tmp.isObject());
4856c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        QVERIFY(!sant.isObject());
4866c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        QVERIFY(!sant.engine());
4876c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        QCOMPARE(tmp.toNumber(), sant.toNumber());
4886c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    }
4896c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
4906c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    QScriptValue number(123.0);
4916c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    {
4926c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        QScriptValue tmp = eng.toObject(number);
4936c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        QVERIFY(tmp.isObject());
4946c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        QVERIFY(!number.isObject());
4956c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        QVERIFY(!number.engine());
4966c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        QCOMPARE(tmp.toNumber(), number.toNumber());
4976c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    }
4986c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
4996c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    QScriptValue str = QScriptValue(&eng, QString("ciao"));
5006c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    {
5016c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        QScriptValue tmp = eng.toObject(str);
5026c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        QVERIFY(tmp.isObject());
5036c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        QVERIFY(!str.isObject());
5046c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        QCOMPARE(tmp.toString(), str.toString());
5056c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    }
5066c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
5076c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    QScriptValue object = eng.evaluate("new Object");
5086c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    {
5096c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        QScriptValue tmp = eng.toObject(object);
5106c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        QVERIFY(tmp.isObject());
5116c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        QVERIFY(object.isObject());
5126c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        QVERIFY(tmp.strictlyEquals(object));
5136c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    }
5146c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen}
5156c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
5166c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsenvoid tst_QScriptEngine::toObjectTwoEngines()
5176c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen{
5186c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    QScriptEngine engine1;
5196c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    QScriptEngine engine2;
5206c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
5216c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    {
5226c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        QScriptValue null = engine1.nullValue();
5236c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        QTest::ignoreMessage(QtWarningMsg, "QScriptEngine::toObject: cannot convert value created in a different engine");
5246c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        QVERIFY(!engine2.toObject(null).isValid());
5256c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        QVERIFY(null.isValid());
5266c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        QTest::ignoreMessage(QtWarningMsg, "QScriptEngine::toObject: cannot convert value created in a different engine");
5276c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        QVERIFY(engine2.toObject(null).engine() != &engine2);
5286c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    }
5296c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    {
5306c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        QScriptValue undefined = engine1.undefinedValue();
5316c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        QTest::ignoreMessage(QtWarningMsg, "QScriptEngine::toObject: cannot convert value created in a different engine");
5326c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        QVERIFY(!engine2.toObject(undefined).isValid());
5336c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        QVERIFY(undefined.isValid());
5346c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        QTest::ignoreMessage(QtWarningMsg, "QScriptEngine::toObject: cannot convert value created in a different engine");
5356c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        QVERIFY(engine2.toObject(undefined).engine() != &engine2);
5366c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    }
5376c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    {
5386c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        QScriptValue value = engine1.evaluate("1");
5396c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        QTest::ignoreMessage(QtWarningMsg, "QScriptEngine::toObject: cannot convert value created in a different engine");
5406c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        QVERIFY(engine2.toObject(value).engine() != &engine2);
5416c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        QVERIFY(!value.isObject());
5426c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    }
5436c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    {
5446c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        QScriptValue string = engine1.evaluate("'Qt'");
5456c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        QTest::ignoreMessage(QtWarningMsg, "QScriptEngine::toObject: cannot convert value created in a different engine");
5466c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        QVERIFY(engine2.toObject(string).engine() != &engine2);
5476c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        QVERIFY(!string.isObject());
5486c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    }
5496c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    {
5506c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        QScriptValue object = engine1.evaluate("new Object");
5516c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        QTest::ignoreMessage(QtWarningMsg, "QScriptEngine::toObject: cannot convert value created in a different engine");
5526c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        QVERIFY(engine2.toObject(object).engine() != &engine2);
5536c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        QVERIFY(object.isObject());
5546c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    }
5556c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen}
556dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
557ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Blockvoid tst_QScriptEngine::newArray()
558ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block{
559ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    QScriptEngine eng;
560ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    QScriptValue array = eng.newArray();
561ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    QCOMPARE(array.isValid(), true);
562e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    QCOMPARE(array.isArray(), true);
563ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    QCOMPARE(array.isObject(), true);
564ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    QVERIFY(!array.isFunction());
565ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    // QCOMPARE(array.scriptClass(), (QScriptClass*)0);
566ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
567ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    // Prototype should be Array.prototype.
568ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    QCOMPARE(array.prototype().isValid(), true);
569e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    QCOMPARE(array.prototype().isArray(), true);
570ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    QCOMPARE(array.prototype().strictlyEquals(eng.evaluate("Array.prototype")), true);
571ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
572ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    QScriptValue arrayWithSize = eng.newArray(42);
573ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    QCOMPARE(arrayWithSize.isValid(), true);
574e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    QCOMPARE(arrayWithSize.isArray(), true);
575ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    QCOMPARE(arrayWithSize.isObject(), true);
576ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    QCOMPARE(arrayWithSize.property("length").toInt32(), 42);
577e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
578e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    // task 218092
579e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    {
580e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        QScriptValue ret = eng.evaluate("[].splice(0, 0, 'a')");
581e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        QVERIFY(ret.isArray());
582e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        QCOMPARE(ret.property("length").toInt32(), 0);
583e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
584e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    {
585e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        QScriptValue ret = eng.evaluate("['a'].splice(0, 1, 'b')");
586e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        QVERIFY(ret.isArray());
587e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        QCOMPARE(ret.property("length").toInt32(), 1);
588e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
589e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    {
590e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        QScriptValue ret = eng.evaluate("['a', 'b'].splice(0, 1, 'c')");
591e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        QVERIFY(ret.isArray());
592e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        QCOMPARE(ret.property("length").toInt32(), 1);
593e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
594e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    {
595e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        QScriptValue ret = eng.evaluate("['a', 'b', 'c'].splice(0, 2, 'd')");
596e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        QVERIFY(ret.isArray());
597e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        QCOMPARE(ret.property("length").toInt32(), 2);
598e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
599e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    {
600e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        QScriptValue ret = eng.evaluate("['a', 'b', 'c'].splice(1, 2, 'd', 'e', 'f')");
601e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        QVERIFY(ret.isArray());
602e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        QCOMPARE(ret.property("length").toInt32(), 2);
603e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
604ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block}
605ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
606ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Blockvoid tst_QScriptEngine::uncaughtException()
607ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block{
608ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    QScriptEngine eng;
609ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    QScriptValue fun = eng.evaluate("(function foo () { return null; });");
610ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    QVERIFY(!eng.uncaughtException().isValid());
611ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    QVERIFY(fun.isFunction());
612ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    QScriptValue throwFun = eng.evaluate("( function() { throw new Error('Pong'); });");
613ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    QVERIFY(throwFun.isFunction());
614ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    {
615ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        eng.evaluate("a = 10");
616ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        QVERIFY(!eng.hasUncaughtException());
617ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        QVERIFY(!eng.uncaughtException().isValid());
618ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    }
619ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    {
620ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        eng.evaluate("1 = 2");
621ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        QVERIFY(eng.hasUncaughtException());
622ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        eng.clearExceptions();
623ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        QVERIFY(!eng.hasUncaughtException());
624ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    }
625ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    {
626ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        // Check if the call or toString functions can remove the last exception.
627ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        QVERIFY(throwFun.call().isError());
628ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        QVERIFY(eng.hasUncaughtException());
629ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        QScriptValue exception = eng.uncaughtException();
630ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        fun.call();
631ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        exception.toString();
632ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        QVERIFY(eng.hasUncaughtException());
633ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        QVERIFY(eng.uncaughtException().strictlyEquals(exception));
634ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    }
635ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    eng.clearExceptions();
636ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    {
637ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        // Check if in the call function a new exception can override an existing one.
638ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        throwFun.call();
639ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        QVERIFY(eng.hasUncaughtException());
640ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        QScriptValue exception = eng.uncaughtException();
641ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        throwFun.call();
642ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        QVERIFY(eng.hasUncaughtException());
643ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        QVERIFY(!exception.strictlyEquals(eng.uncaughtException()));
644ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    }
645ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    {
646ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        eng.evaluate("throwFun = (function foo () { throw new Error('bla') });");
647ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        eng.evaluate("1;\nthrowFun();");
648ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        QVERIFY(eng.hasUncaughtException());
649ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        QCOMPARE(eng.uncaughtExceptionLineNumber(), 1);
650ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        eng.clearExceptions();
651ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        QVERIFY(!eng.hasUncaughtException());
652ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    }
653ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    for (int x = 1; x < 4; ++x) {
654ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        QScriptValue ret = eng.evaluate("a = 10;\nb = 20;\n0 = 0;\n",
655ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block                                        QString::fromLatin1("FooScript") + QString::number(x),
656ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block                                        /* lineNumber */ x);
657ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        QVERIFY(eng.hasUncaughtException());
658ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        QCOMPARE(eng.uncaughtExceptionLineNumber(), x + 2);
659ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        QVERIFY(eng.uncaughtException().strictlyEquals(ret));
660ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        QVERIFY(eng.hasUncaughtException());
661ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        QVERIFY(eng.uncaughtException().strictlyEquals(ret));
662ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        QString backtrace = QString::fromLatin1("<anonymous>()@FooScript") + QString::number(x) + ":" + QString::number(x + 2);
663ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        QCOMPARE(eng.uncaughtExceptionBacktrace().join(""), backtrace);
664ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        QVERIFY(fun.call().isNull());
665ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        QVERIFY(eng.hasUncaughtException());
666ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        QCOMPARE(eng.uncaughtExceptionLineNumber(), x + 2);
667ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        QVERIFY(eng.uncaughtException().strictlyEquals(ret));
668ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        eng.clearExceptions();
669ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        QVERIFY(!eng.hasUncaughtException());
670ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        QCOMPARE(eng.uncaughtExceptionLineNumber(), -1);
671ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        QVERIFY(!eng.uncaughtException().isValid());
672ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        eng.evaluate("2 = 3");
673ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        QVERIFY(eng.hasUncaughtException());
674ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        QScriptValue ret2 = throwFun.call();
675ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        QVERIFY(ret2.isError());
676ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        QVERIFY(eng.hasUncaughtException());
677ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        QVERIFY(eng.uncaughtException().strictlyEquals(ret2));
678ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        QCOMPARE(eng.uncaughtExceptionLineNumber(), 1);
679ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        eng.clearExceptions();
680ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        QVERIFY(!eng.hasUncaughtException());
681ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        eng.evaluate("1 + 2");
682ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        QVERIFY(!eng.hasUncaughtException());
683ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    }
684ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block}
685ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
686bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenvoid tst_QScriptEngine::newDate()
687bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen{
688bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    QScriptEngine eng;
689bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    {
690bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        QScriptValue date = eng.newDate(0);
691bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        QCOMPARE(date.isValid(), true);
692bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        QCOMPARE(date.isDate(), true);
693bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        QCOMPARE(date.isObject(), true);
694bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        QVERIFY(!date.isFunction());
695bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        // prototype should be Date.prototype
696bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        QCOMPARE(date.prototype().isValid(), true);
697bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        QCOMPARE(date.prototype().isDate(), true);
698bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        QCOMPARE(date.prototype().strictlyEquals(eng.evaluate("Date.prototype")), true);
699bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    }
700bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    {
701bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        QDateTime dt = QDateTime(QDate(1, 2, 3), QTime(4, 5, 6, 7), Qt::LocalTime);
702bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        QScriptValue date = eng.newDate(dt);
703bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        QCOMPARE(date.isValid(), true);
704bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        QCOMPARE(date.isDate(), true);
705bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        QCOMPARE(date.isObject(), true);
706bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        // prototype should be Date.prototype
707bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        QCOMPARE(date.prototype().isValid(), true);
708bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        QCOMPARE(date.prototype().isDate(), true);
709bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        QCOMPARE(date.prototype().strictlyEquals(eng.evaluate("Date.prototype")), true);
710bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
711bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        QCOMPARE(date.toDateTime(), dt);
712bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    }
713bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    {
714bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        QDateTime dt = QDateTime(QDate(1, 2, 3), QTime(4, 5, 6, 7), Qt::UTC);
715bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        QScriptValue date = eng.newDate(dt);
716bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        // toDateTime() result should be in local time
717bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        QCOMPARE(date.toDateTime(), dt.toLocalTime());
718bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    }
719bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // Date.parse() should return NaN when it fails
720bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    {
721bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        QScriptValue ret = eng.evaluate("Date.parse()");
722bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        QVERIFY(ret.isNumber());
723bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        QVERIFY(qIsNaN(ret.toNumber()));
724bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    }
725bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // Date.parse() should be able to parse the output of Date().toString()
726bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    {
727bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        QScriptValue ret = eng.evaluate("var x = new Date(); var s = x.toString(); s == new Date(Date.parse(s)).toString()");
728bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        QVERIFY(ret.isBoolean());
729bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        QCOMPARE(ret.toBoolean(), true);
730bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    }
731bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen}
732bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
733d0825bca7fe65beaee391d30da42e937db621564Steve BlockQTEST_MAIN(tst_QScriptEngine)
734d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "tst_qscriptengine.moc"
735