Changeset 64130 in webkit for trunk/JavaScriptCore/qt/tests


Ignore:
Timestamp:
Jul 27, 2010, 8:37:25 AM (15 years ago)
Author:
[email protected]
Message:

2010-07-27 Caio Marcelo de Oliveira Filho <[email protected]>

Reviewed by Kenneth Rohde Christiansen.

[Qt] Implement QScriptEngine::newFunction() parts that doesn't depend on QScriptContext
https://bugs.webkit.org/show_bug.cgi?id=42174

Since our function can be called in Javascript both as a function
and as a constructor, we couldn't use the existing
JSObjectMakeFunctionWithCallback() and JSObjectMakeConstructor().

Instead, a JSClassRef was created, implementing the needed
callbacks (the callAsConstructor is not there yet because its
behaviour depends on QScriptContext).

For the moment, QScriptContext is defined as a void type, since we
still don't use it.

The variant of newFunction() that also takes an external argument
was also implemented. The details of implementation were added to
the qscriptfunction{.c,_p.h} files.

This commit also adds tests, some of them from Qt's upstream.

  • api/QtScript.pro:
  • api/qscriptengine.cpp: (QScriptEngine::newFunction):
  • api/qscriptengine.h:
  • api/qscriptengine_p.cpp: (QScriptEnginePrivate::QScriptEnginePrivate): (QScriptEnginePrivate::~QScriptEnginePrivate): (QScriptEnginePrivate::newFunction):
  • api/qscriptengine_p.h:
  • api/qscriptfunction.cpp: Added. (qt_NativeFunction_finalize): (qt_NativeFunction_callAsFunction): (qt_NativeFunctionWithArg_finalize): (qt_NativeFunctionWithArg_callAsFunction):
  • api/qscriptfunction_p.h: Added. (QNativeFunctionData::QNativeFunctionData): (QNativeFunctionWithArgData::QNativeFunctionWithArgData):
  • api/qscriptoriginalglobalobject_p.h: (QScriptOriginalGlobalObject::QScriptOriginalGlobalObject): (QScriptOriginalGlobalObject::~QScriptOriginalGlobalObject): (QScriptOriginalGlobalObject::functionPrototype):
  • tests/qscriptengine/tst_qscriptengine.cpp: (myFunction): (myFunctionWithArg): (myFunctionThatReturns): (myFunctionThatReturnsWithoutEngine): (myFunctionThatReturnsWrongEngine): (tst_QScriptEngine::newFunction):
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/qt/tests/qscriptengine/tst_qscriptengine.cpp

    r62661 r64130  
    3636
    3737private slots:
     38    void newFunction();
    3839    void newObject();
    3940    void globalObject();
     
    5859    QVERIFY2(engine.evaluate("1+1").isValid(), "the expression should be evaluated and an valid result should be returned");
    5960    QVERIFY2(engine.evaluate("ping").isValid(), "Script throwing an unhandled exception should return an exception value");
     61}
     62
     63static QScriptValue myFunction(QScriptContext*, QScriptEngine* eng)
     64{
     65    return eng->nullValue();
     66}
     67
     68static QScriptValue myFunctionWithArg(QScriptContext*, QScriptEngine* eng, void* arg)
     69{
     70    int* result = reinterpret_cast<int*>(arg);
     71    return QScriptValue(eng, *result);
     72}
     73
     74static QScriptValue myFunctionThatReturns(QScriptContext*, QScriptEngine* eng)
     75{
     76    return QScriptValue(eng, 42);
     77}
     78
     79static QScriptValue myFunctionThatReturnsWithoutEngine(QScriptContext*, QScriptEngine*)
     80{
     81    return QScriptValue(1024);
     82}
     83
     84static QScriptValue myFunctionThatReturnsWrongEngine(QScriptContext*, QScriptEngine*, void* arg)
     85{
     86    QScriptEngine* wrongEngine = reinterpret_cast<QScriptEngine*>(arg);
     87    return QScriptValue(wrongEngine, 42);
     88}
     89
     90void tst_QScriptEngine::newFunction()
     91{
     92    QScriptEngine eng;
     93    {
     94        QScriptValue fun = eng.newFunction(myFunction);
     95        QCOMPARE(fun.isValid(), true);
     96        QCOMPARE(fun.isFunction(), true);
     97        QCOMPARE(fun.isObject(), true);
     98        // QCOMPARE(fun.scriptClass(), (QScriptClass*)0);
     99        // a prototype property is automatically constructed
     100        {
     101            QScriptValue prot = fun.property("prototype", QScriptValue::ResolveLocal);
     102            QVERIFY(prot.isObject());
     103            QVERIFY(prot.property("constructor").strictlyEquals(fun));
     104            QEXPECT_FAIL("", "JSCallbackObject::getOwnPropertyDescriptor() doesn't return correct information yet", Continue);
     105            QCOMPARE(fun.propertyFlags("prototype"), QScriptValue::Undeletable);
     106            QEXPECT_FAIL("", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
     107            QCOMPARE(prot.propertyFlags("constructor"), QScriptValue::PropertyFlags(QScriptValue::Undeletable | QScriptValue::SkipInEnumeration));
     108        }
     109        // prototype should be Function.prototype
     110        QCOMPARE(fun.prototype().isValid(), true);
     111        QCOMPARE(fun.prototype().isFunction(), true);
     112        QCOMPARE(fun.prototype().strictlyEquals(eng.evaluate("Function.prototype")), true);
     113
     114        QCOMPARE(fun.call().isNull(), true);
     115        // QCOMPARE(fun.construct().isObject(), true);
     116    }
     117    // the overload that takes an extra argument
     118    {
     119        int expectedResult = 42;
     120        QScriptValue fun = eng.newFunction(myFunctionWithArg, reinterpret_cast<void*>(&expectedResult));
     121        QVERIFY(fun.isFunction());
     122        // QCOMPARE(fun.scriptClass(), (QScriptClass*)0);
     123        // a prototype property is automatically constructed
     124        {
     125            QScriptValue prot = fun.property("prototype", QScriptValue::ResolveLocal);
     126            QVERIFY(prot.isObject());
     127            QVERIFY(prot.property("constructor").strictlyEquals(fun));
     128            QEXPECT_FAIL("", "JSCallbackObject::getOwnPropertyDescriptor() doesn't return correct information yet", Continue);
     129            QCOMPARE(fun.propertyFlags("prototype"), QScriptValue::Undeletable);
     130            QEXPECT_FAIL("", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
     131            QCOMPARE(prot.propertyFlags("constructor"), QScriptValue::PropertyFlags(QScriptValue::Undeletable | QScriptValue::SkipInEnumeration));
     132        }
     133        // prototype should be Function.prototype
     134        QCOMPARE(fun.prototype().isValid(), true);
     135        QCOMPARE(fun.prototype().isFunction(), true);
     136        QCOMPARE(fun.prototype().strictlyEquals(eng.evaluate("Function.prototype")), true);
     137
     138        QScriptValue result = fun.call();
     139        QCOMPARE(result.isNumber(), true);
     140        QCOMPARE(result.toInt32(), expectedResult);
     141    }
     142    // the overload that takes a prototype
     143    {
     144        QScriptValue proto = eng.newObject();
     145        QScriptValue fun = eng.newFunction(myFunction, proto);
     146        QCOMPARE(fun.isValid(), true);
     147        QCOMPARE(fun.isFunction(), true);
     148        QCOMPARE(fun.isObject(), true);
     149        // internal prototype should be Function.prototype
     150        QCOMPARE(fun.prototype().isValid(), true);
     151        QCOMPARE(fun.prototype().isFunction(), true);
     152        QCOMPARE(fun.prototype().strictlyEquals(eng.evaluate("Function.prototype")), true);
     153        // public prototype should be the one we passed
     154        QCOMPARE(fun.property("prototype").strictlyEquals(proto), true);
     155        QEXPECT_FAIL("", "JSCallbackObject::getOwnPropertyDescriptor() doesn't return correct information yet", Continue);
     156        QCOMPARE(fun.propertyFlags("prototype"), QScriptValue::Undeletable);
     157        QCOMPARE(proto.property("constructor").strictlyEquals(fun), true);
     158        QEXPECT_FAIL("", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue);
     159        QCOMPARE(proto.propertyFlags("constructor"), QScriptValue::PropertyFlags(QScriptValue::Undeletable | QScriptValue::SkipInEnumeration));
     160
     161        QCOMPARE(fun.call().isNull(), true);
     162        // QCOMPARE(fun.construct().isObject(), true);
     163    }
     164    // whether the return value is correct
     165    {
     166        QScriptValue fun = eng.newFunction(myFunctionThatReturns);
     167        QCOMPARE(fun.isValid(), true);
     168        QCOMPARE(fun.isFunction(), true);
     169        QCOMPARE(fun.isObject(), true);
     170
     171        QScriptValue result = fun.call();
     172        QCOMPARE(result.isNumber(), true);
     173        QCOMPARE(result.toInt32(), 42);
     174    }
     175    // whether the return value is assigned to the correct engine
     176    {
     177        QScriptValue fun = eng.newFunction(myFunctionThatReturnsWithoutEngine);
     178        QCOMPARE(fun.isValid(), true);
     179        QCOMPARE(fun.isFunction(), true);
     180        QCOMPARE(fun.isObject(), true);
     181
     182        QScriptValue result = fun.call();
     183        QCOMPARE(result.engine(), &eng);
     184        QCOMPARE(result.isNumber(), true);
     185        QCOMPARE(result.toInt32(), 1024);
     186    }
     187    // whether the return value is undefined when returning a value with wrong engine
     188    {
     189        QScriptEngine wrongEngine;
     190
     191        QScriptValue fun = eng.newFunction(myFunctionThatReturnsWrongEngine, reinterpret_cast<void*>(&wrongEngine));
     192        QCOMPARE(fun.isValid(), true);
     193        QCOMPARE(fun.isFunction(), true);
     194        QCOMPARE(fun.isObject(), true);
     195
     196        QTest::ignoreMessage(QtWarningMsg, "Value from different engine returned from native function, returning undefined value instead.");
     197        QScriptValue result = fun.call();
     198        QCOMPARE(result.isValid(), true);
     199        QCOMPARE(result.isUndefined(), true);
     200    }
    60201}
    61202
Note: See TracChangeset for help on using the changeset viewer.