diff options
author | Steve Block <steveblock@google.com> | 2011-05-06 11:45:16 +0100 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2011-05-12 13:44:10 +0100 |
commit | cad810f21b803229eb11403f9209855525a25d57 (patch) | |
tree | 29a6fd0279be608e0fe9ffe9841f722f0f4e4269 /Source/JavaScriptCore/qt | |
parent | 121b0cf4517156d0ac5111caf9830c51b69bae8f (diff) | |
download | external_webkit-cad810f21b803229eb11403f9209855525a25d57.zip external_webkit-cad810f21b803229eb11403f9209855525a25d57.tar.gz external_webkit-cad810f21b803229eb11403f9209855525a25d57.tar.bz2 |
Merge WebKit at r75315: Initial merge by git.
Change-Id: I570314b346ce101c935ed22a626b48c2af266b84
Diffstat (limited to 'Source/JavaScriptCore/qt')
47 files changed, 13506 insertions, 0 deletions
diff --git a/Source/JavaScriptCore/qt/ChangeLog b/Source/JavaScriptCore/qt/ChangeLog new file mode 100644 index 0000000..11018b4 --- /dev/null +++ b/Source/JavaScriptCore/qt/ChangeLog @@ -0,0 +1,447 @@ +2010-09-29 Caio Marcelo de Oliveira Filho <caio.oliveira@openbossa.org> + + Reviewed by Andreas Kling. + + [Qt] QScriptEngine should have an API for creating Date objects + https://bugs.webkit.org/show_bug.cgi?id=41667 + + Implement newDate(), isDate() and toDateTime() functions. Use the + QDateTime::{to,set}MSecsSinceEpoch() functions to do the + calculations. + + * api/qscriptengine.cpp: + (QScriptEngine::newDate): + * api/qscriptengine.h: + * api/qscriptengine_p.cpp: + (QScriptEnginePrivate::newDate): + * api/qscriptengine_p.h: + (QScriptEnginePrivate::isDate): + + * api/qscriptoriginalglobalobject_p.h: + (QScriptOriginalGlobalObject::QScriptOriginalGlobalObject): need + to keep track of Date Constructor and Prototype. + (QScriptOriginalGlobalObject::~QScriptOriginalGlobalObject): ditto. + (QScriptOriginalGlobalObject::isDate): use the Date Constructor + and Prototype to identify Date values. + + * api/qscriptvalue.cpp: + (QScriptValue::isDate): + (QScriptValue::toDateTime): + * api/qscriptvalue.h: + * api/qscriptvalue_p.h: + (QScriptValuePrivate::isDate): + (QScriptValuePrivate::toDateTime): + * tests/qscriptengine/tst_qscriptengine.cpp: + (tst_QScriptEngine::newDate): + +2010-07-27 Jedrzej Nowacki <jedrzej.nowacki@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + Update the QScriptValue autotests suite. + + QScriptValue generated files were updated, changes are: + - More tested values (for example QSE::newObject() and QSE::newArray()) + - Tested values are recreated before each test and are not reused. + The change implies better code coverage and some expected result changes. + - A new test to check copy and assign functions. + - Tests are using standard QTestLib interface, without any custom macros. + + [Qt] Improve test coverage for the QScriptValue + https://bugs.webkit.org/show_bug.cgi?id=42366 + + * tests/qscriptvalue/tst_qscriptvalue.cpp: + (tst_QScriptValue::tst_QScriptValue): + (tst_QScriptValue::~tst_QScriptValue): + (tst_QScriptValue::assignAndCopyConstruct_data): + (tst_QScriptValue::assignAndCopyConstruct): + * tests/qscriptvalue/tst_qscriptvalue.h: + * tests/qscriptvalue/tst_qscriptvalue_generated_comparison.cpp: + (tst_QScriptValue::equals_data): + (tst_QScriptValue::equals): + (tst_QScriptValue::strictlyEquals_data): + (tst_QScriptValue::strictlyEquals): + (tst_QScriptValue::instanceOf_data): + (tst_QScriptValue::instanceOf): + * tests/qscriptvalue/tst_qscriptvalue_generated_init.cpp: + (tst_QScriptValue::initScriptValues): + * tests/qscriptvalue/tst_qscriptvalue_generated_istype.cpp: + (tst_QScriptValue::isValid_data): + (tst_QScriptValue::isValid): + (tst_QScriptValue::isBool_data): + (tst_QScriptValue::isBool): + (tst_QScriptValue::isBoolean_data): + (tst_QScriptValue::isBoolean): + (tst_QScriptValue::isNumber_data): + (tst_QScriptValue::isNumber): + (tst_QScriptValue::isFunction_data): + (tst_QScriptValue::isFunction): + (tst_QScriptValue::isNull_data): + (tst_QScriptValue::isNull): + (tst_QScriptValue::isString_data): + (tst_QScriptValue::isString): + (tst_QScriptValue::isUndefined_data): + (tst_QScriptValue::isUndefined): + (tst_QScriptValue::isObject_data): + (tst_QScriptValue::isObject): + (tst_QScriptValue::isArray_data): + (tst_QScriptValue::isArray): + (tst_QScriptValue::isError_data): + (tst_QScriptValue::isError): + * tests/qscriptvalue/tst_qscriptvalue_generated_totype.cpp: + (tst_QScriptValue::toString_data): + (tst_QScriptValue::toString): + (tst_QScriptValue::toNumber_data): + (tst_QScriptValue::toNumber): + (tst_QScriptValue::toBool_data): + (tst_QScriptValue::toBool): + (tst_QScriptValue::toBoolean_data): + (tst_QScriptValue::toBoolean): + (tst_QScriptValue::toInteger_data): + (tst_QScriptValue::toInteger): + (tst_QScriptValue::toInt32_data): + (tst_QScriptValue::toInt32): + (tst_QScriptValue::toUInt32_data): + (tst_QScriptValue::toUInt32): + (tst_QScriptValue::toUInt16_data): + (tst_QScriptValue::toUInt16): + +2010-07-27 Caio Marcelo de Oliveira Filho <caio.oliveira@openbossa.org> + + 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): + +2010-07-23 Jedrzej Nowacki <jedrzej.nowacki@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + QScriptValue::equals benchmark crash fix. + + Patch changes QScriptValue::equals implementation to cover + more edge cases. + + Problem exposes an issue in our autotests (all values got + bound to an engine too fast - bug 42366). + + [Qt] QScriptValue::equals asserts + https://bugs.webkit.org/show_bug.cgi?id=42363 + + * api/qscriptvalue_p.h: + (QScriptValuePrivate::equals): + +2010-07-14 Jedrzej Nowacki <jedrzej.nowacki@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + Introduce QScriptOriginalGlobalObject. + + QtScript exposes more functionality than JSC C API. Sometimes it is + necessary to take a shortcut in implementation. Really often we have + to use a standard JS function. These function could be changed or + even deleted by a script, so a backup of a reference to an object is needed. + + In them same time this is rather a workaround then real fix, so the code + should be separated and changed easily in future. It is why we need + the new internal class. + + The patch fixes a few crashes. + + [Qt] QScriptEngine should work correctly even after global object changes + https://bugs.webkit.org/show_bug.cgi?id=41839 + + * api/QtScript.pro: + * api/qscriptengine_p.cpp: + (QScriptEnginePrivate::QScriptEnginePrivate): + (QScriptEnginePrivate::~QScriptEnginePrivate): + * api/qscriptengine_p.h: + (QScriptEnginePrivate::isArray): + (QScriptEnginePrivate::isError): + (QScriptEnginePrivate::objectHasOwnProperty): + (QScriptEnginePrivate::objectGetOwnPropertyNames): + * api/qscriptoriginalglobalobject_p.h: Added. + (QScriptOriginalGlobalObject::QScriptOriginalGlobalObject): + (QScriptOriginalGlobalObject::initializeMember): + (QScriptOriginalGlobalObject::~QScriptOriginalGlobalObject): + (QScriptOriginalGlobalObject::objectHasOwnProperty): + (QScriptOriginalGlobalObject::objectGetOwnPropertyNames): + (QScriptOriginalGlobalObject::isArray): + (QScriptOriginalGlobalObject::isError): + (QScriptOriginalGlobalObject::isType): + * api/qscriptvalue_p.h: + (QScriptValuePrivate::isError): + (QScriptValuePrivate::hasOwnProperty): + * api/qscriptvalueiterator_p.h: + (QScriptValueIteratorPrivate::QScriptValueIteratorPrivate): + * tests/qscriptvalue/tst_qscriptvalue.cpp: + (tst_QScriptValue::globalObjectChanges): + * tests/qscriptvalue/tst_qscriptvalue.h: + +2010-07-13 Jedrzej Nowacki <jedrzej.nowacki@nokia.com> + + Reviewed by Simon Hausmann. + + Introduce QScriptValueIterator. + + The QScriptValueIterator class permits to iterate over a QScriptValue's properties. + + [Qt] QtScript should provide an API for enumerating a JS object's properties + https://bugs.webkit.org/show_bug.cgi?id=41680 + + * api/QtScript.pro: + * api/qscriptvalueiterator.cpp: Added. + (QScriptValueIterator::QScriptValueIterator): + (QScriptValueIterator::~QScriptValueIterator): + (QScriptValueIterator::hasNext): + (QScriptValueIterator::next): + (QScriptValueIterator::hasPrevious): + (QScriptValueIterator::previous): + (QScriptValueIterator::toFront): + (QScriptValueIterator::toBack): + (QScriptValueIterator::name): + (QScriptValueIterator::scriptName): + (QScriptValueIterator::value): + (QScriptValueIterator::setValue): + (QScriptValueIterator::remove): + (QScriptValueIterator::flags): + (QScriptValueIterator::operator=): + * api/qscriptvalueiterator.h: Added. + * api/qscriptvalueiterator_p.h: Added. + (QScriptValueIteratorPrivate::QScriptValueIteratorPrivate): + (QScriptValueIteratorPrivate::~QScriptValueIteratorPrivate): + (QScriptValueIteratorPrivate::hasNext): + (QScriptValueIteratorPrivate::next): + (QScriptValueIteratorPrivate::hasPrevious): + (QScriptValueIteratorPrivate::previous): + (QScriptValueIteratorPrivate::name): + (QScriptValueIteratorPrivate::scriptName): + (QScriptValueIteratorPrivate::value): + (QScriptValueIteratorPrivate::setValue): + (QScriptValueIteratorPrivate::remove): + (QScriptValueIteratorPrivate::toFront): + (QScriptValueIteratorPrivate::toBack): + (QScriptValueIteratorPrivate::flags): + (QScriptValueIteratorPrivate::isValid): + (QScriptValueIteratorPrivate::engine): + * tests/qscriptvalueiterator/qscriptvalueiterator.pro: Added. + * tests/qscriptvalueiterator/tst_qscriptvalueiterator.cpp: Added. + (tst_QScriptValueIterator::tst_QScriptValueIterator): + (tst_QScriptValueIterator::~tst_QScriptValueIterator): + (tst_QScriptValueIterator::iterateForward_data): + (tst_QScriptValueIterator::iterateForward): + (tst_QScriptValueIterator::iterateBackward_data): + (tst_QScriptValueIterator::iterateBackward): + (tst_QScriptValueIterator::iterateArray_data): + (tst_QScriptValueIterator::iterateArray): + (tst_QScriptValueIterator::iterateBackAndForth): + (tst_QScriptValueIterator::setValue): + (tst_QScriptValueIterator::remove): + (tst_QScriptValueIterator::removeMixed): + (tst_QScriptValueIterator::removeUndeletable): + (tst_QScriptValueIterator::iterateString): + (tst_QScriptValueIterator::assignObjectToIterator): + * tests/tests.pro: + +2010-07-09 Jedrzej Nowacki <jedrzej.nowacki@nokia.com> + + Reviewed by Simon Hausmann. + + Implementation of the QScriptValue::propertyFlags function. + + The function returns the flags of a property with the given name, + using a given mode to resolve the property. This is a simple + implementation that is sufficient to test the QScriptValueIterator. + + [Qt] QScriptValue API should have a property flag accessor. + https://bugs.webkit.org/show_bug.cgi?id=41769 + + * api/qscriptvalue.cpp: + (QScriptValue::propertyFlags): + * api/qscriptvalue.h: + * api/qscriptvalue_p.h: + (QScriptValuePrivate::propertyFlags): + * tests/qscriptvalue/tst_qscriptvalue.cpp: + (tst_QScriptValue::propertyFlag_data): + (tst_QScriptValue::propertyFlag): + * tests/qscriptvalue/tst_qscriptvalue.h: + +2010-07-07 Caio Marcelo de Oliveira Filho <caio.oliveira@openbossa.org> + + Reviewed by Kenneth Rohde Christiansen. + + Implementation of QScriptValue::isArray() + https://bugs.webkit.org/show_bug.cgi?id=41713 + + Since we don't have access to the [[Class]] internal property of + builtins (including Array), the solution was to keep the original 'Array' + (constructor) and 'Array.prototype' objects and use them to identify + if a given object is an Array. + + Also uncomment some tests and add some tests of newArray() that + depended on isArray(). + + * api/qscriptengine_p.cpp: + (QScriptEnginePrivate::QScriptEnginePrivate): + (QScriptEnginePrivate::~QScriptEnginePrivate): + * api/qscriptengine_p.h: + (QScriptEnginePrivate::isArray): + * api/qscriptvalue.cpp: + (QScriptValue::isArray): + * api/qscriptvalue.h: + * api/qscriptvalue_p.h: + (QScriptValuePrivate::isArray): + * tests/qscriptengine/tst_qscriptengine.cpp: + (tst_QScriptEngine::newArray): + +2010-07-06 Jedrzej Nowacki <jedrzej.nowacki@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + Implementation of QScriptValue properties accessors. + + The patch contains implementation of the QScriptValue::property() and + the QScriptValue::setProperty(). It is not full functionality, as these + method are too complex for one patch, but it is enough to cover about + 95% of use cases. + + Missing functionality: + - Few of the PropertyFlags are ignored. + - Only a public part of the ResolveFlags can be used (ResolveLocal, + ResolvePrototype). + + A lot of new test cases were added. + + [Qt] QScriptValue should have API for accessing object properties + https://bugs.webkit.org/show_bug.cgi?id=40903 + + * api/qscriptconverter_p.h: + (QScriptConverter::toPropertyFlags): + * api/qscriptstring_p.h: + (QScriptStringPrivate::operator JSStringRef): + * api/qscriptvalue.cpp: + (QScriptValue::property): + (QScriptValue::setProperty): + * api/qscriptvalue.h: + (QScriptValue::): + * api/qscriptvalue_p.h: + (QScriptValuePrivate::assignEngine): + (QScriptValuePrivate::property): + (QScriptValuePrivate::hasOwnProperty): + (QScriptValuePrivate::setProperty): + (QScriptValuePrivate::deleteProperty): + * tests/qscriptvalue/tst_qscriptvalue.cpp: + (tst_QScriptValue::getPropertySimple_data): + (tst_QScriptValue::getPropertySimple): + (tst_QScriptValue::setPropertySimple): + (tst_QScriptValue::getPropertyResolveFlag): + (tst_QScriptValue::getSetProperty): + (tst_QScriptValue::setProperty_data): + (tst_QScriptValue::setProperty): + * tests/qscriptvalue/tst_qscriptvalue.h: + +2010-07-02 Jedrzej Nowacki <jedrzej.nowacki@nokia.com> + + Reviewed by Simon Hausmann. + + Compilation fix. + + QScriptEnginePrivate::newArray can't be const because it can + throw an exception. + + [Qt] QScriptEnginePrivate compilation fix + https://bugs.webkit.org/show_bug.cgi?id=41520 + + * api/qscriptengine_p.cpp: + (QScriptEnginePrivate::newArray): + * api/qscriptengine_p.h: + +2010-06-28 Jedrzej Nowacki <jedrzej.nowacki@nokia.com> + + Reviewed by Simon Hausmann. + + Implement exception reporting in the QtScript API. + + The exception should be accessible through the API by the uncaughtException + function. Functions; hasUncaughtException, clearExceptions, uncaughtExceptionLineNumber, + uncaughtExceptionBacktrace were added to facilitate error checking and debugging. + + [Qt] QtScript API should be exceptions aware. + https://bugs.webkit.org/show_bug.cgi?id=41199 + + * api/qscriptengine.cpp: + (QScriptEngine::hasUncaughtException): + (QScriptEngine::uncaughtException): + (QScriptEngine::clearExceptions): + (QScriptEngine::uncaughtExceptionLineNumber): + (QScriptEngine::uncaughtExceptionBacktrace): + * api/qscriptengine.h: + * api/qscriptengine_p.cpp: + (QScriptEnginePrivate::QScriptEnginePrivate): + (QScriptEnginePrivate::~QScriptEnginePrivate): + (QScriptEnginePrivate::uncaughtException): + * api/qscriptengine_p.h: + (QScriptEnginePrivate::): + (QScriptEnginePrivate::evaluate): + (QScriptEnginePrivate::hasUncaughtException): + (QScriptEnginePrivate::clearExceptions): + (QScriptEnginePrivate::setException): + (QScriptEnginePrivate::uncaughtExceptionLineNumber): + (QScriptEnginePrivate::uncaughtExceptionBacktrace): + * api/qscriptvalue_p.h: + (QScriptValuePrivate::toString): + (QScriptValuePrivate::toNumber): + (QScriptValuePrivate::toObject): + (QScriptValuePrivate::equals): + (QScriptValuePrivate::instanceOf): + (QScriptValuePrivate::call): + (QScriptValuePrivate::inherits): + * tests/qscriptengine/tst_qscriptengine.cpp: + (tst_QScriptEngine::uncaughtException): + diff --git a/Source/JavaScriptCore/qt/api/QtScript.pro b/Source/JavaScriptCore/qt/api/QtScript.pro new file mode 100644 index 0000000..490758c --- /dev/null +++ b/Source/JavaScriptCore/qt/api/QtScript.pro @@ -0,0 +1,51 @@ +TARGET = QtScript +TEMPLATE = lib +QT = core + +INCLUDEPATH += $$PWD + +CONFIG += building-libs + +isEmpty(JSC_GENERATED_SOURCES_DIR):JSC_GENERATED_SOURCES_DIR = ../../generated +!CONFIG(release, debug|release) { + OBJECTS_DIR = obj/debug +} else { # Release + OBJECTS_DIR = obj/release +} + +isEmpty(OUTPUT_DIR): OUTPUT_DIR = ../../.. +include($$PWD/../../../WebKit.pri) + +include($$PWD/../../JavaScriptCore.pri) +addJavaScriptCoreLib(../..) + +INCLUDEPATH += $$PWD/../../API + +SOURCES += $$PWD/qscriptengine.cpp \ + $$PWD/qscriptengine_p.cpp \ + $$PWD/qscriptvalue.cpp \ + $$PWD/qscriptvalueiterator.cpp \ + $$PWD/qscriptstring.cpp \ + $$PWD/qscriptprogram.cpp \ + $$PWD/qscriptsyntaxcheckresult.cpp \ + $$PWD/qscriptfunction.cpp + +HEADERS += $$PWD/qtscriptglobal.h \ + $$PWD/qscriptengine.h \ + $$PWD/qscriptengine_p.h \ + $$PWD/qscriptvalue.h \ + $$PWD/qscriptvalue_p.h \ + $$PWD/qscriptvalueiterator.h \ + $$PWD/qscriptvalueiterator_p.h \ + $$PWD/qscriptconverter_p.h \ + $$PWD/qscriptstring.h \ + $$PWD/qscriptstring_p.h \ + $$PWD/qscriptprogram.h \ + $$PWD/qscriptprogram_p.h \ + $$PWD/qscriptsyntaxcheckresult.h \ + $$PWD/qscriptoriginalglobalobject_p.h \ + $$PWD/qscriptfunction_p.h + +!static: DEFINES += QT_MAKEDLL + +DESTDIR = $$OUTPUT_DIR/lib diff --git a/Source/JavaScriptCore/qt/api/qscriptconverter_p.h b/Source/JavaScriptCore/qt/api/qscriptconverter_p.h new file mode 100644 index 0000000..0c57d95 --- /dev/null +++ b/Source/JavaScriptCore/qt/api/qscriptconverter_p.h @@ -0,0 +1,146 @@ +/* + Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef qscriptconverter_p_h +#define qscriptconverter_p_h + +#include "qscriptvalue.h" +#include <JavaScriptCore/JavaScript.h> +#include <QtCore/qglobal.h> +#include <QtCore/qnumeric.h> +#include <QtCore/qstring.h> +#include <QtCore/qvarlengtharray.h> + +extern char *qdtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve, char **digits_str); + +/* + \internal + \class QScriptConverter + QScriptValue and QScriptEngine helper class. This class's responsibility is to convert values + between JS values and Qt/C++ values. + + This is a nice way to inline these functions in both QScriptValue and QScriptEngine. +*/ +class QScriptConverter { +public: + static quint32 toArrayIndex(const JSStringRef jsstring) + { + // FIXME this function should be exported by JSC C API. + QString qstring = toString(jsstring); + + bool ok; + quint32 idx = qstring.toUInt(&ok); + if (!ok || toString(idx) != qstring) + idx = 0xffffffff; + + return idx; + } + + static QString toString(const JSStringRef str) + { + return QString(reinterpret_cast<const QChar*>(JSStringGetCharactersPtr(str)), JSStringGetLength(str)); + } + static JSStringRef toString(const QString& str) + { + return JSStringCreateWithUTF8CString(str.toUtf8().constData()); + } + static JSStringRef toString(const char* str) + { + return JSStringCreateWithUTF8CString(str); + } + static QString toString(double value) + { + // FIXME this should be easier. The ideal fix is to create + // a new function in JSC C API which could cover the functionality. + + if (qIsNaN(value)) + return QString::fromLatin1("NaN"); + if (qIsInf(value)) + return QString::fromLatin1(value < 0 ? "-Infinity" : "Infinity"); + if (!value) + return QString::fromLatin1("0"); + + QVarLengthArray<char, 25> buf; + int decpt; + int sign; + char* result = 0; + char* endresult; + (void)qdtoa(value, 0, 0, &decpt, &sign, &endresult, &result); + + if (!result) + return QString(); + + int resultLen = endresult - result; + if (decpt <= 0 && decpt > -6) { + buf.resize(-decpt + 2 + sign); + qMemSet(buf.data(), '0', -decpt + 2 + sign); + if (sign) // fix the sign. + buf[0] = '-'; + buf[sign + 1] = '.'; + buf.append(result, resultLen); + } else { + if (sign) + buf.append('-'); + int length = buf.size() - sign + resultLen; + if (decpt <= 21 && decpt > 0) { + if (length <= decpt) { + const char* zeros = "0000000000000000000000000"; + buf.append(result, resultLen); + buf.append(zeros, decpt - length); + } else { + buf.append(result, decpt); + buf.append('.'); + buf.append(result + decpt, resultLen - decpt); + } + } else if (result[0] >= '0' && result[0] <= '9') { + if (length > 1) { + buf.append(result, 1); + buf.append('.'); + buf.append(result + 1, resultLen - 1); + } else + buf.append(result, resultLen); + buf.append('e'); + buf.append(decpt >= 0 ? '+' : '-'); + int e = qAbs(decpt - 1); + if (e >= 100) + buf.append('0' + e / 100); + if (e >= 10) + buf.append('0' + (e % 100) / 10); + buf.append('0' + e % 10); + } + } + free(result); + buf.append(0); + return QString::fromLatin1(buf.constData()); + } + + static JSPropertyAttributes toPropertyFlags(const QFlags<QScriptValue::PropertyFlag>& flags) + { + JSPropertyAttributes attr = 0; + if (flags.testFlag(QScriptValue::ReadOnly)) + attr |= kJSPropertyAttributeReadOnly; + if (flags.testFlag(QScriptValue::Undeletable)) + attr |= kJSPropertyAttributeDontDelete; + if (flags.testFlag(QScriptValue::SkipInEnumeration)) + attr |= kJSPropertyAttributeDontEnum; + return attr; + } +}; + +#endif // qscriptconverter_p_h diff --git a/Source/JavaScriptCore/qt/api/qscriptengine.cpp b/Source/JavaScriptCore/qt/api/qscriptengine.cpp new file mode 100644 index 0000000..607b0b9 --- /dev/null +++ b/Source/JavaScriptCore/qt/api/qscriptengine.cpp @@ -0,0 +1,426 @@ +/* + Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" + +#include "qscriptengine.h" + +#include "qscriptengine_p.h" +#include "qscriptprogram_p.h" +#include "qscriptsyntaxcheckresult_p.h" +#include "qscriptvalue_p.h" +#include <QtCore/qdatetime.h> +#include <QtCore/qnumeric.h> + +/*! + Constructs a QScriptEngine object. + + The globalObject() is initialized to have properties as described in ECMA-262, Section 15.1. +*/ +QScriptEngine::QScriptEngine() + : d_ptr(new QScriptEnginePrivate(this)) +{ +} + +/*! + Destroys this QScriptEngine. +*/ +QScriptEngine::~QScriptEngine() +{ +} + +/*! + Checks the syntax of the given \a program. Returns a + QScriptSyntaxCheckResult object that contains the result of the check. +*/ +QScriptSyntaxCheckResult QScriptEngine::checkSyntax(const QString &program) +{ + // FIXME This is not optimal. + // The JSC C API needs a context to perform a syntax check, it means that a QScriptEnginePrivate + // had to be created. This function is static so we have to create QScriptEnginePrivate for each + // call. We can't remove the "static" for compatibility reason, at least up to Qt5. + // QScriptSyntaxCheckResultPrivate takes ownership of newly created engine. The engine will be + // kept as long as it is needed for lazy evaluation of properties of + // the QScriptSyntaxCheckResultPrivate. + QScriptEnginePrivate* engine = new QScriptEnginePrivate(/* q_ptr */ 0); + return QScriptSyntaxCheckResultPrivate::get(engine->checkSyntax(program)); +} + +/*! + Evaluates \a program, using \a lineNumber as the base line number, + and returns the result of the evaluation. + + The script code will be evaluated in the current context. + + The evaluation of \a program can cause an exception in the + engine; in this case the return value will be the exception + that was thrown (typically an \c{Error} object). You can call + hasUncaughtException() to determine if an exception occurred in + the last call to evaluate(). + + \a lineNumber is used to specify a starting line number for \a + program; line number information reported by the engine that pertain + to this evaluation (e.g. uncaughtExceptionLineNumber()) will be + based on this argument. For example, if \a program consists of two + lines of code, and the statement on the second line causes a script + exception, uncaughtExceptionLineNumber() would return the given \a + lineNumber plus one. When no starting line number is specified, line + numbers will be 1-based. + + \a fileName is used for error reporting. For example in error objects + the file name is accessible through the "fileName" property if it's + provided with this function. +*/ +QScriptValue QScriptEngine::evaluate(const QString& program, const QString& fileName, int lineNumber) +{ + return QScriptValuePrivate::get(d_ptr->evaluate(program, fileName, lineNumber)); +} + +QScriptValue QScriptEngine::evaluate(const QScriptProgram& program) +{ + return QScriptValuePrivate::get(d_ptr->evaluate(QScriptProgramPrivate::get(program))); +} + +/*! + Returns true if the last script evaluation resulted in an uncaught + exception; otherwise returns false. + + The exception state is cleared when evaluate() is called. + + \sa uncaughtException(), uncaughtExceptionLineNumber(), + uncaughtExceptionBacktrace() +*/ +bool QScriptEngine::hasUncaughtException() const +{ + return d_ptr->hasUncaughtException(); +} + +/*! + Returns the current uncaught exception, or an invalid QScriptValue + if there is no uncaught exception. + + The exception value is typically an \c{Error} object; in that case, + you can call toString() on the return value to obtain an error + message. + + \sa hasUncaughtException(), uncaughtExceptionLineNumber(), + uncaughtExceptionBacktrace() +*/ +QScriptValue QScriptEngine::uncaughtException() const +{ + return QScriptValuePrivate::get(d_ptr->uncaughtException()); +} + +/*! + Clears any uncaught exceptions in this engine. + + \sa hasUncaughtException() +*/ +void QScriptEngine::clearExceptions() +{ + d_ptr->clearExceptions(); +} + +/*! + Returns the line number where the last uncaught exception occurred. + + Line numbers are 1-based, unless a different base was specified as + the second argument to evaluate(). + + \sa hasUncaughtException(), uncaughtExceptionBacktrace() +*/ +int QScriptEngine::uncaughtExceptionLineNumber() const +{ + return d_ptr->uncaughtExceptionLineNumber(); +} + +/*! + Returns a human-readable backtrace of the last uncaught exception. + + Each line is of the form \c{<function-name>(<arguments>)@<file-name>:<line-number>}. + + \sa uncaughtException() +*/ +QStringList QScriptEngine::uncaughtExceptionBacktrace() const +{ + return d_ptr->uncaughtExceptionBacktrace(); +} + +/*! + Runs the garbage collector. + + The garbage collector will attempt to reclaim memory by locating and disposing of objects that are + no longer reachable in the script environment. + + Normally you don't need to call this function; the garbage collector will automatically be invoked + when the QScriptEngine decides that it's wise to do so (i.e. when a certain number of new objects + have been created). However, you can call this function to explicitly request that garbage + collection should be performed as soon as possible. + + \sa reportAdditionalMemoryCost() +*/ +void QScriptEngine::collectGarbage() +{ + d_ptr->collectGarbage(); +} + +/*! + Reports an additional memory cost of the given \a size, measured in + bytes, to the garbage collector. + + This function can be called to indicate that a JavaScript object has + memory associated with it that isn't managed by Qt Script itself. + Reporting the additional cost makes it more likely that the garbage + collector will be triggered. + + Note that if the additional memory is shared with objects outside + the scripting environment, the cost should not be reported, since + collecting the JavaScript object would not cause the memory to be + freed anyway. + + Negative \a size values are ignored, i.e. this function can't be + used to report that the additional memory has been deallocated. + + \sa collectGarbage() +*/ +void QScriptEngine::reportAdditionalMemoryCost(int cost) +{ + d_ptr->reportAdditionalMemoryCost(cost); +} + +/*! + Returns a handle that represents the given string, \a str. + + QScriptString can be used to quickly look up properties, and + compare property names, of script objects. + + \sa QScriptValue::property() +*/ +QScriptString QScriptEngine::toStringHandle(const QString& str) +{ + return QScriptStringPrivate::get(d_ptr->toStringHandle(str)); +} + +/*! + Converts the given \a value to an object, if such a conversion is + possible; otherwise returns an invalid QScriptValue. The conversion + is performed according to the following table: + + \table + \header \o Input Type \o Result + \row \o Undefined \o An invalid QScriptValue. + \row \o Null \o An invalid QScriptValue. + \row \o Boolean \o A new Boolean object whose internal value is set to the value of the boolean. + \row \o Number \o A new Number object whose internal value is set to the value of the number. + \row \o String \o A new String object whose internal value is set to the value of the string. + \row \o Object \o The result is the object itself (no conversion). + \endtable + + \sa newObject() +*/ +QScriptValue QScriptEngine::toObject(const QScriptValue& value) +{ + return QScriptValuePrivate::get(QScriptValuePrivate::get(value)->toObject(d_ptr.data())); +} + +/*! + Returns a QScriptValue of the primitive type Null. + + \sa undefinedValue() +*/ +QScriptValue QScriptEngine::nullValue() +{ + return QScriptValue(this, QScriptValue::NullValue); +} + +/*! + Returns a QScriptValue of the primitive type Undefined. + + \sa nullValue() +*/ +QScriptValue QScriptEngine::undefinedValue() +{ + return QScriptValue(this, QScriptValue::UndefinedValue); +} + +/*! + Creates a QScriptValue that wraps a native (C++) function. \a fun + must be a C++ function with signature QScriptEngine::FunctionSignature. + \a length is the number of arguments that \a fun expects; this becomes + the \c{length} property of the created QScriptValue. + + Note that \a length only gives an indication of the number of + arguments that the function expects; an actual invocation of a + function can include any number of arguments. You can check the + \l{QScriptContext::argumentCount()}{argumentCount()} of the + QScriptContext associated with the invocation to determine the + actual number of arguments passed. + + A \c{prototype} property is automatically created for the resulting + function object, to provide for the possibility that the function + will be used as a constructor. + + By combining newFunction() and the property flags + QScriptValue::PropertyGetter and QScriptValue::PropertySetter, you + can create script object properties that behave like normal + properties in script code, but are in fact accessed through + functions (analogous to how properties work in \l{Qt's Property + System}). Example: + + \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 11 + + When the property \c{foo} of the script object is subsequently + accessed in script code, \c{getSetFoo()} will be invoked to handle + the access. In this particular case, we chose to store the "real" + value of \c{foo} as a property of the accessor function itself; you + are of course free to do whatever you like in this function. + + In the above example, a single native function was used to handle + both reads and writes to the property; the argument count is used to + determine if we are handling a read or write. You can also use two + separate functions; just specify the relevant flag + (QScriptValue::PropertyGetter or QScriptValue::PropertySetter) when + setting the property, e.g.: + + \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 12 + + \sa QScriptValue::call() +*/ +QScriptValue QScriptEngine::newFunction(QScriptEngine::FunctionSignature fun, int length) +{ + return QScriptValuePrivate::get(d_ptr->newFunction(fun, 0, length)); +} + +/*! + Creates a constructor function from \a fun, with the given \a length. + The \c{prototype} property of the resulting function is set to be the + given \a prototype. The \c{constructor} property of \a prototype is + set to be the resulting function. + + When a function is called as a constructor (e.g. \c{new Foo()}), the + `this' object associated with the function call is the new object + that the function is expected to initialize; the prototype of this + default constructed object will be the function's public + \c{prototype} property. If you always want the function to behave as + a constructor (e.g. \c{Foo()} should also create a new object), or + if you need to create your own object rather than using the default + `this' object, you should make sure that the prototype of your + object is set correctly; either by setting it manually, or, when + wrapping a custom type, by having registered the defaultPrototype() + of that type. Example: + + \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 9 + + To wrap a custom type and provide a constructor for it, you'd typically + do something like this: + + \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 10 +*/ +QScriptValue QScriptEngine::newFunction(QScriptEngine::FunctionSignature fun, const QScriptValue& prototype, int length) +{ + return QScriptValuePrivate::get(d_ptr->newFunction(fun, QScriptValuePrivate::get(prototype), length)); +} + +/*! + \internal + \since 4.4 +*/ +QScriptValue QScriptEngine::newFunction(QScriptEngine::FunctionWithArgSignature fun, void* arg) +{ + return QScriptValuePrivate::get(d_ptr->newFunction(fun, arg)); +} + +/*! + Creates a QtScript object of class Object. + + The prototype of the created object will be the Object + prototype object. + + \sa newArray(), QScriptValue::setProperty() +*/ +QScriptValue QScriptEngine::newObject() +{ + return QScriptValuePrivate::get(d_ptr->newObject()); +} + +/*! + Creates a QtScript object of class Array with the given \a length. + + \sa newObject() +*/ +QScriptValue QScriptEngine::newArray(uint length) +{ + return QScriptValuePrivate::get(d_ptr->newArray(length)); +} + +/*! + Creates a QtScript object of class Date with the given \a value + (the number of milliseconds since 01 January 1970, UTC). +*/ +QScriptValue QScriptEngine::newDate(qsreal value) +{ + return QScriptValuePrivate::get(d_ptr->newDate(value)); +} + +/*! + Creates a QtScript object of class Date from the given \a value. + + \sa QScriptValue::toDateTime() +*/ +QScriptValue QScriptEngine::newDate(const QDateTime& value) +{ + if (value.isValid()) + return QScriptValuePrivate::get(d_ptr->newDate(qsreal(value.toMSecsSinceEpoch()))); + return QScriptValuePrivate::get(d_ptr->newDate(qSNaN())); +} + +/*! + Returns this engine's Global Object. + + By default, the Global Object contains the built-in objects that are + part of \l{ECMA-262}, such as Math, Date and String. Additionally, + you can set properties of the Global Object to make your own + extensions available to all script code. Non-local variables in + script code will be created as properties of the Global Object, as + well as local variables in global code. +*/ +QScriptValue QScriptEngine::globalObject() const +{ + return QScriptValuePrivate::get(d_ptr->globalObject()); +} + +/*! + \typedef QScriptEngine::FunctionSignature + \relates QScriptEngine + + The function signature \c{QScriptValue f(QScriptContext *, QScriptEngine *)}. + + A function with such a signature can be passed to + QScriptEngine::newFunction() to wrap the function. +*/ + +/*! + \typedef QScriptEngine::FunctionWithArgSignature + \relates QScriptEngine + + The function signature \c{QScriptValue f(QScriptContext *, QScriptEngine *, void *)}. + + A function with such a signature can be passed to + QScriptEngine::newFunction() to wrap the function. +*/ diff --git a/Source/JavaScriptCore/qt/api/qscriptengine.h b/Source/JavaScriptCore/qt/api/qscriptengine.h new file mode 100644 index 0000000..281707f --- /dev/null +++ b/Source/JavaScriptCore/qt/api/qscriptengine.h @@ -0,0 +1,82 @@ +/* + Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef qscriptengine_h +#define qscriptengine_h + +#include "qscriptprogram.h" +#include "qscriptstring.h" +#include "qscriptsyntaxcheckresult.h" +#include "qscriptvalue.h" +#include <QtCore/qobject.h> +#include <QtCore/qshareddata.h> +#include <QtCore/qstring.h> + +class QDateTime; +class QScriptEnginePrivate; + +// FIXME: Remove this once QScriptContext is properly defined. +typedef void QScriptContext; + +// Internal typedef +typedef QExplicitlySharedDataPointer<QScriptEnginePrivate> QScriptEnginePtr; + +class QScriptEngine : public QObject { +public: + QScriptEngine(); + ~QScriptEngine(); + + static QScriptSyntaxCheckResult checkSyntax(const QString& program); + QScriptValue evaluate(const QString& program, const QString& fileName = QString(), int lineNumber = 1); + QScriptValue evaluate(const QScriptProgram& program); + + bool hasUncaughtException() const; + QScriptValue uncaughtException() const; + void clearExceptions(); + int uncaughtExceptionLineNumber() const; + QStringList uncaughtExceptionBacktrace() const; + + void collectGarbage(); + void reportAdditionalMemoryCost(int cost); + + QScriptString toStringHandle(const QString& str); + QScriptValue toObject(const QScriptValue& value); + + QScriptValue nullValue(); + QScriptValue undefinedValue(); + + typedef QScriptValue (*FunctionSignature)(QScriptContext *, QScriptEngine *); + typedef QScriptValue (*FunctionWithArgSignature)(QScriptContext *, QScriptEngine *, void *); + + QScriptValue newFunction(FunctionSignature fun, int length = 0); + QScriptValue newFunction(FunctionSignature fun, const QScriptValue& prototype, int length = 0); + QScriptValue newFunction(FunctionWithArgSignature fun, void* arg); + + QScriptValue newObject(); + QScriptValue newArray(uint length = 0); + QScriptValue newDate(qsreal value); + QScriptValue newDate(const QDateTime& value); + QScriptValue globalObject() const; +private: + friend class QScriptEnginePrivate; + + QScriptEnginePtr d_ptr; +}; + +#endif diff --git a/Source/JavaScriptCore/qt/api/qscriptengine_p.cpp b/Source/JavaScriptCore/qt/api/qscriptengine_p.cpp new file mode 100644 index 0000000..89054c0 --- /dev/null +++ b/Source/JavaScriptCore/qt/api/qscriptengine_p.cpp @@ -0,0 +1,167 @@ +/* + Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" + +#include "qscriptengine_p.h" + +#include "qscriptfunction_p.h" +#include "qscriptprogram_p.h" +#include "qscriptvalue_p.h" + +/*! + Constructs a default QScriptEnginePrivate object, a new global context will be created. + \internal +*/ +QScriptEnginePrivate::QScriptEnginePrivate(const QScriptEngine* engine) + : q_ptr(const_cast<QScriptEngine*>(engine)) + , m_context(JSGlobalContextCreate(0)) + , m_exception(0) + , m_originalGlobalObject(m_context) + , m_nativeFunctionClass(JSClassCreate(&qt_NativeFunctionClass)) + , m_nativeFunctionWithArgClass(JSClassCreate(&qt_NativeFunctionWithArgClass)) +{ +} + +QScriptEnginePrivate::~QScriptEnginePrivate() +{ + JSClassRelease(m_nativeFunctionClass); + JSClassRelease(m_nativeFunctionWithArgClass); + if (m_exception) + JSValueUnprotect(m_context, m_exception); + JSGlobalContextRelease(m_context); +} + +QScriptSyntaxCheckResultPrivate* QScriptEnginePrivate::checkSyntax(const QString& program) +{ + JSValueRef exception; + JSStringRef source = QScriptConverter::toString(program); + bool syntaxIsCorrect = JSCheckScriptSyntax(m_context, source, /* url */ 0, /* starting line */ 1, &exception); + JSStringRelease(source); + if (syntaxIsCorrect) { + return new QScriptSyntaxCheckResultPrivate(this); + } + JSValueProtect(m_context, exception); + return new QScriptSyntaxCheckResultPrivate(this, const_cast<JSObjectRef>(exception)); +} + +/*! + Evaluates program and returns the result of the evaluation. + \internal +*/ +QScriptValuePrivate* QScriptEnginePrivate::evaluate(const QString& program, const QString& fileName, int lineNumber) +{ + JSStringRef script = QScriptConverter::toString(program); + JSStringRef file = QScriptConverter::toString(fileName); + QScriptValuePrivate* result = new QScriptValuePrivate(this, evaluate(script, file, lineNumber)); + JSStringRelease(script); + JSStringRelease(file); + return result; +} + +/*! + Evaluates program and returns the result of the evaluation. + \internal +*/ +QScriptValuePrivate* QScriptEnginePrivate::evaluate(const QScriptProgramPrivate* program) +{ + if (program->isNull()) + return new QScriptValuePrivate; + return new QScriptValuePrivate(this, evaluate(*program, program->file(), program->line())); +} + +QScriptValuePrivate* QScriptEnginePrivate::uncaughtException() const +{ + return m_exception ? new QScriptValuePrivate(this, m_exception) : new QScriptValuePrivate(); +} + +QScriptValuePrivate* QScriptEnginePrivate::newFunction(QScriptEngine::FunctionSignature fun, QScriptValuePrivate* prototype, int length) +{ + // Note that this private data will be deleted in the object finalize function. + QNativeFunctionData* data = new QNativeFunctionData(this, fun); + JSObjectRef funJS = JSObjectMake(m_context, m_nativeFunctionClass, reinterpret_cast<void*>(data)); + QScriptValuePrivate* proto = prototype ? prototype : newObject(); + return newFunction(funJS, proto); +} + +QScriptValuePrivate* QScriptEnginePrivate::newFunction(QScriptEngine::FunctionWithArgSignature fun, void* arg) +{ + // Note that this private data will be deleted in the object finalize function. + QNativeFunctionWithArgData* data = new QNativeFunctionWithArgData(this, fun, arg); + JSObjectRef funJS = JSObjectMake(m_context, m_nativeFunctionWithArgClass, reinterpret_cast<void*>(data)); + QScriptValuePrivate* proto = newObject(); + return newFunction(funJS, proto); +} + +QScriptValuePrivate* QScriptEnginePrivate::newFunction(JSObjectRef funJS, QScriptValuePrivate* prototype) +{ + JSObjectSetPrototype(m_context, funJS, m_originalGlobalObject.functionPrototype()); + + QScriptValuePrivate* result = new QScriptValuePrivate(this, funJS); + static JSStringRef protoName = QScriptConverter::toString("prototype"); + static JSStringRef constructorName = QScriptConverter::toString("constructor"); + result->setProperty(protoName, prototype, QScriptValue::Undeletable); + prototype->setProperty(constructorName, result, QScriptValue::PropertyFlags(QScriptValue::Undeletable | QScriptValue::SkipInEnumeration)); + + return result; +} + +QScriptValuePrivate* QScriptEnginePrivate::newObject() const +{ + return new QScriptValuePrivate(this, JSObjectMake(m_context, /* jsClass */ 0, /* userData */ 0)); +} + +QScriptValuePrivate* QScriptEnginePrivate::newArray(uint length) +{ + JSValueRef exception = 0; + JSObjectRef array = JSObjectMakeArray(m_context, /* argumentCount */ 0, /* arguments */ 0, &exception); + + if (!exception) { + if (length > 0) { + JSRetainPtr<JSStringRef> lengthRef(Adopt, JSStringCreateWithUTF8CString("length")); + // array is an Array instance, so an exception should not occure here. + JSObjectSetProperty(m_context, array, lengthRef.get(), JSValueMakeNumber(m_context, length), kJSPropertyAttributeNone, /* exception */ 0); + } + } else { + setException(exception, NotNullException); + return new QScriptValuePrivate(); + } + + return new QScriptValuePrivate(this, array); +} + +QScriptValuePrivate* QScriptEnginePrivate::newDate(qsreal value) +{ + JSValueRef exception = 0; + JSValueRef argument = JSValueMakeNumber(m_context, value); + JSObjectRef result = JSObjectMakeDate(m_context, /* argumentCount */ 1, &argument, &exception); + + if (exception) { + setException(exception, NotNullException); + return new QScriptValuePrivate(); + } + + return new QScriptValuePrivate(this, result); +} + +QScriptValuePrivate* QScriptEnginePrivate::globalObject() const +{ + JSObjectRef globalObject = JSContextGetGlobalObject(m_context); + return new QScriptValuePrivate(this, globalObject); +} diff --git a/Source/JavaScriptCore/qt/api/qscriptengine_p.h b/Source/JavaScriptCore/qt/api/qscriptengine_p.h new file mode 100644 index 0000000..4603b91 --- /dev/null +++ b/Source/JavaScriptCore/qt/api/qscriptengine_p.h @@ -0,0 +1,259 @@ +/* + Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef qscriptengine_p_h +#define qscriptengine_p_h + +#include "qscriptconverter_p.h" +#include "qscriptengine.h" +#include "qscriptoriginalglobalobject_p.h" +#include "qscriptstring_p.h" +#include "qscriptsyntaxcheckresult_p.h" +#include "qscriptvalue.h" +#include <JavaScriptCore/JavaScript.h> +#include <JavaScriptCore/JSRetainPtr.h> +#include <JSBasePrivate.h> +#include <QtCore/qshareddata.h> +#include <QtCore/qstring.h> +#include <QtCore/qstringlist.h> + +class QScriptEngine; +class QScriptSyntaxCheckResultPrivate; + +class QScriptEnginePrivate : public QSharedData { +public: + static QScriptEnginePrivate* get(const QScriptEngine* q) { Q_ASSERT(q); return q->d_ptr.data(); } + static QScriptEngine* get(const QScriptEnginePrivate* d) { Q_ASSERT(d); return d->q_ptr; } + + QScriptEnginePrivate(const QScriptEngine*); + ~QScriptEnginePrivate(); + + enum SetExceptionFlag { + IgnoreNullException = 0x01, + NotNullException = 0x02, + }; + + QScriptSyntaxCheckResultPrivate* checkSyntax(const QString& program); + QScriptValuePrivate* evaluate(const QString& program, const QString& fileName, int lineNumber); + QScriptValuePrivate* evaluate(const QScriptProgramPrivate* program); + inline JSValueRef evaluate(JSStringRef program, JSStringRef fileName, int lineNumber); + + inline bool hasUncaughtException() const; + QScriptValuePrivate* uncaughtException() const; + inline void clearExceptions(); + inline void setException(JSValueRef exception, const /* SetExceptionFlags */ unsigned flags = IgnoreNullException); + inline int uncaughtExceptionLineNumber() const; + inline QStringList uncaughtExceptionBacktrace() const; + + inline void collectGarbage(); + inline void reportAdditionalMemoryCost(int cost); + + inline JSValueRef makeJSValue(double number) const; + inline JSValueRef makeJSValue(int number) const; + inline JSValueRef makeJSValue(uint number) const; + inline JSValueRef makeJSValue(const QString& string) const; + inline JSValueRef makeJSValue(bool number) const; + inline JSValueRef makeJSValue(QScriptValue::SpecialValue value) const; + + QScriptValuePrivate* newFunction(QScriptEngine::FunctionSignature fun, QScriptValuePrivate* prototype, int length); + QScriptValuePrivate* newFunction(QScriptEngine::FunctionWithArgSignature fun, void* arg); + QScriptValuePrivate* newFunction(JSObjectRef funObject, QScriptValuePrivate* prototype); + + QScriptValuePrivate* newObject() const; + QScriptValuePrivate* newArray(uint length); + QScriptValuePrivate* newDate(qsreal value); + QScriptValuePrivate* globalObject() const; + + inline QScriptStringPrivate* toStringHandle(const QString& str) const; + + inline operator JSGlobalContextRef() const; + + inline bool isDate(JSValueRef value) const; + inline bool isArray(JSValueRef value) const; + inline bool isError(JSValueRef value) const; + inline bool objectHasOwnProperty(JSObjectRef object, JSStringRef property) const; + inline QVector<JSStringRef> objectGetOwnPropertyNames(JSObjectRef object) const; + +private: + QScriptEngine* q_ptr; + JSGlobalContextRef m_context; + JSValueRef m_exception; + + QScriptOriginalGlobalObject m_originalGlobalObject; + + JSClassRef m_nativeFunctionClass; + JSClassRef m_nativeFunctionWithArgClass; +}; + + +/*! + Evaluates given JavaScript program and returns result of the evaluation. + \attention this function doesn't take ownership of the parameters. + \internal +*/ +JSValueRef QScriptEnginePrivate::evaluate(JSStringRef program, JSStringRef fileName, int lineNumber) +{ + JSValueRef exception; + JSValueRef result = JSEvaluateScript(m_context, program, /* Global Object */ 0, fileName, lineNumber, &exception); + if (!result) { + setException(exception, NotNullException); + return exception; // returns an exception + } + clearExceptions(); + return result; +} + +bool QScriptEnginePrivate::hasUncaughtException() const +{ + return m_exception; +} + +void QScriptEnginePrivate::clearExceptions() +{ + if (m_exception) + JSValueUnprotect(m_context, m_exception); + m_exception = 0; +} + +void QScriptEnginePrivate::setException(JSValueRef exception, const /* SetExceptionFlags */ unsigned flags) +{ + if (!((flags & NotNullException) || exception)) + return; + Q_ASSERT(exception); + + if (m_exception) + JSValueUnprotect(m_context, m_exception); + JSValueProtect(m_context, exception); + m_exception = exception; +} + +int QScriptEnginePrivate::uncaughtExceptionLineNumber() const +{ + if (!hasUncaughtException() || !JSValueIsObject(m_context, m_exception)) + return -1; + + JSValueRef exception = 0; + JSRetainPtr<JSStringRef> lineNumberPropertyName(Adopt, QScriptConverter::toString("line")); + JSValueRef lineNumber = JSObjectGetProperty(m_context, const_cast<JSObjectRef>(m_exception), lineNumberPropertyName.get(), &exception); + int result = JSValueToNumber(m_context, lineNumber, &exception); + return exception ? -1 : result; +} + +QStringList QScriptEnginePrivate::uncaughtExceptionBacktrace() const +{ + if (!hasUncaughtException() || !JSValueIsObject(m_context, m_exception)) + return QStringList(); + + JSValueRef exception = 0; + JSRetainPtr<JSStringRef> fileNamePropertyName(Adopt, QScriptConverter::toString("sourceURL")); + JSRetainPtr<JSStringRef> lineNumberPropertyName(Adopt, QScriptConverter::toString("line")); + JSValueRef jsFileName = JSObjectGetProperty(m_context, const_cast<JSObjectRef>(m_exception), fileNamePropertyName.get(), &exception); + JSValueRef jsLineNumber = JSObjectGetProperty(m_context, const_cast<JSObjectRef>(m_exception), lineNumberPropertyName.get(), &exception); + JSRetainPtr<JSStringRef> fileName(Adopt, JSValueToStringCopy(m_context, jsFileName, &exception)); + int lineNumber = JSValueToNumber(m_context, jsLineNumber, &exception); + return QStringList(QString::fromLatin1("<anonymous>()@%0:%1") + .arg(QScriptConverter::toString(fileName.get())) + .arg(QScriptConverter::toString(exception ? -1 : lineNumber))); +} + +void QScriptEnginePrivate::collectGarbage() +{ + JSGarbageCollect(m_context); +} + +void QScriptEnginePrivate::reportAdditionalMemoryCost(int cost) +{ + if (cost > 0) + JSReportExtraMemoryCost(m_context, cost); +} + +JSValueRef QScriptEnginePrivate::makeJSValue(double number) const +{ + return JSValueMakeNumber(m_context, number); +} + +JSValueRef QScriptEnginePrivate::makeJSValue(int number) const +{ + return JSValueMakeNumber(m_context, number); +} + +JSValueRef QScriptEnginePrivate::makeJSValue(uint number) const +{ + return JSValueMakeNumber(m_context, number); +} + +JSValueRef QScriptEnginePrivate::makeJSValue(const QString& string) const +{ + JSStringRef tmp = QScriptConverter::toString(string); + JSValueRef result = JSValueMakeString(m_context, tmp); + JSStringRelease(tmp); + return result; +} + +JSValueRef QScriptEnginePrivate::makeJSValue(bool value) const +{ + return JSValueMakeBoolean(m_context, value); +} + +JSValueRef QScriptEnginePrivate::makeJSValue(QScriptValue::SpecialValue value) const +{ + if (value == QScriptValue::NullValue) + return JSValueMakeNull(m_context); + return JSValueMakeUndefined(m_context); +} + +QScriptStringPrivate* QScriptEnginePrivate::toStringHandle(const QString& str) const +{ + return new QScriptStringPrivate(str); +} + +QScriptEnginePrivate::operator JSGlobalContextRef() const +{ + Q_ASSERT(this); + return m_context; +} + +bool QScriptEnginePrivate::isDate(JSValueRef value) const +{ + return m_originalGlobalObject.isDate(value); +} + +bool QScriptEnginePrivate::isArray(JSValueRef value) const +{ + return m_originalGlobalObject.isArray(value); +} + +bool QScriptEnginePrivate::isError(JSValueRef value) const +{ + return m_originalGlobalObject.isError(value); +} + +inline bool QScriptEnginePrivate::objectHasOwnProperty(JSObjectRef object, JSStringRef property) const +{ + // FIXME We need a JSC C API function for this. + return m_originalGlobalObject.objectHasOwnProperty(object, property); +} + +inline QVector<JSStringRef> QScriptEnginePrivate::objectGetOwnPropertyNames(JSObjectRef object) const +{ + // FIXME We can't use C API function JSObjectGetPropertyNames as it returns only enumerable properties. + return m_originalGlobalObject.objectGetOwnPropertyNames(object); +} + +#endif diff --git a/Source/JavaScriptCore/qt/api/qscriptfunction.cpp b/Source/JavaScriptCore/qt/api/qscriptfunction.cpp new file mode 100644 index 0000000..9fe37e6 --- /dev/null +++ b/Source/JavaScriptCore/qt/api/qscriptfunction.cpp @@ -0,0 +1,145 @@ +/* + Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +// Contains the necessary helper structures to make possible expose +// C/C++ functions to JavaScript environment. + +#include "config.h" + +#include "qscriptfunction_p.h" + +static void qt_NativeFunction_finalize(JSObjectRef object) +{ + void* priv = JSObjectGetPrivate(object); + delete reinterpret_cast<QNativeFunctionData*>(priv); +} + +static JSValueRef qt_NativeFunction_callAsFunction(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + QNativeFunctionData* data = reinterpret_cast<QNativeFunctionData*>(JSObjectGetPrivate(object)); + + // TODO: build a QScriptContext and use it in the native call. + QScriptContext* scriptContext = 0; + Q_UNUSED(context); + Q_UNUSED(thisObject); + Q_UNUSED(argumentCount); + Q_UNUSED(arguments); + Q_UNUSED(exception); + + QScriptEnginePrivate* engine = data->engine; + QScriptValuePrivate* result = QScriptValuePrivate::get(data->fun(scriptContext, QScriptEnginePrivate::get(engine))); + if (!result->isValid()) { + qWarning("Invalid value returned from native function, returning undefined value instead."); + return engine->makeJSValue(QScriptValue::UndefinedValue); + } + + // Make sure that the result will be assigned to the correct engine. + if (!result->engine()) { + Q_ASSERT(result->isValid()); + result->assignEngine(engine); + } else if (result->engine() != engine) { + qWarning("Value from different engine returned from native function, returning undefined value instead."); + return engine->makeJSValue(QScriptValue::UndefinedValue); + } + + return *result; +} + +JSClassDefinition qt_NativeFunctionClass = { + 0, // version + kJSClassAttributeNoAutomaticPrototype, // attributes + + "", // className + 0, // parentClass + + 0, // staticValues + 0, // staticFunctions + + 0, // initialize + qt_NativeFunction_finalize, // finalize + 0, // hasProperty + 0, // getProperty + 0, // setProperty + 0, // deleteProperty + 0, // getPropertyNames + qt_NativeFunction_callAsFunction, // callAsFunction + 0, // callAsConstructor + 0, // hasInstance + 0 // convertToType +}; + +static void qt_NativeFunctionWithArg_finalize(JSObjectRef object) +{ + void* priv = JSObjectGetPrivate(object); + delete reinterpret_cast<QNativeFunctionWithArgData*>(priv); +} + +static JSValueRef qt_NativeFunctionWithArg_callAsFunction(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + QNativeFunctionWithArgData* data = reinterpret_cast<QNativeFunctionWithArgData*>(JSObjectGetPrivate(object)); + + // TODO: build a QScriptContext and use it in the native call. + QScriptContext* scriptContext = 0; + Q_UNUSED(context); + Q_UNUSED(thisObject); + Q_UNUSED(argumentCount); + Q_UNUSED(arguments); + Q_UNUSED(exception); + + QScriptEnginePrivate* engine = data->engine; + QScriptValuePrivate* result = QScriptValuePrivate::get(data->fun(scriptContext, QScriptEnginePrivate::get(engine), data->arg)); + if (!result->isValid()) { + qWarning("Invalid value returned from native function, returning undefined value instead."); + return engine->makeJSValue(QScriptValue::UndefinedValue); + } + + // Make sure that the result will be assigned to the correct engine. + if (!result->engine()) { + Q_ASSERT(result->isValid()); + result->assignEngine(engine); + } else if (result->engine() != engine) { + qWarning("Value from different engine returned from native function, returning undefined value instead."); + return engine->makeJSValue(QScriptValue::UndefinedValue); + } + + return *result; +} + +JSClassDefinition qt_NativeFunctionWithArgClass = { + 0, // version + kJSClassAttributeNoAutomaticPrototype, // attributes + + "", // className + 0, // parentClass + + 0, // staticValues + 0, // staticFunctions + + 0, // initialize + qt_NativeFunctionWithArg_finalize, // finalize + 0, // hasProperty + 0, // getProperty + 0, // setProperty + 0, // deleteProperty + 0, // getPropertyNames + qt_NativeFunctionWithArg_callAsFunction, // callAsFunction + 0, // callAsConstructor + 0, // hasInstance + 0 // convertToType +}; diff --git a/Source/JavaScriptCore/qt/api/qscriptfunction_p.h b/Source/JavaScriptCore/qt/api/qscriptfunction_p.h new file mode 100644 index 0000000..65b6046 --- /dev/null +++ b/Source/JavaScriptCore/qt/api/qscriptfunction_p.h @@ -0,0 +1,57 @@ +/* + Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef qscriptfunction_p_h +#define qscriptfunction_p_h + +#include "config.h" + +#include "qscriptengine.h" +#include "qscriptvalue_p.h" + +extern JSClassDefinition qt_NativeFunctionClass; +extern JSClassDefinition qt_NativeFunctionWithArgClass; + +struct QNativeFunctionData +{ + QNativeFunctionData(QScriptEnginePrivate* engine, QScriptEngine::FunctionSignature fun) + : engine(engine) + , fun(fun) + { + } + + QScriptEnginePrivate* engine; + QScriptEngine::FunctionSignature fun; +}; + +struct QNativeFunctionWithArgData +{ + QNativeFunctionWithArgData(QScriptEnginePrivate* engine, QScriptEngine::FunctionWithArgSignature fun, void* arg) + : engine(engine) + , fun(fun) + , arg(arg) + { + } + + QScriptEnginePrivate* engine; + QScriptEngine::FunctionWithArgSignature fun; + void* arg; +}; + +#endif diff --git a/Source/JavaScriptCore/qt/api/qscriptoriginalglobalobject_p.h b/Source/JavaScriptCore/qt/api/qscriptoriginalglobalobject_p.h new file mode 100644 index 0000000..2bd945f --- /dev/null +++ b/Source/JavaScriptCore/qt/api/qscriptoriginalglobalobject_p.h @@ -0,0 +1,209 @@ +/* + Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef qscriptoriginalglobalobject_p_h +#define qscriptoriginalglobalobject_p_h + +#include <JavaScriptCore/JavaScript.h> +#include <JavaScriptCore/JSRetainPtr.h> +#include <QtCore/qvector.h> + +/*! + \internal + This class is a workaround for missing JSC C API functionality. This class keeps all important + properties of an original (default) global object, so we can use it even if the global object was + changed. + + FIXME this class is a container for workarounds :-) it should be replaced by proper JSC C API calls. + + The class have to be created on the QScriptEnginePrivate creation time (before any change got applied to + global object). +*/ +class QScriptOriginalGlobalObject { +public: + inline QScriptOriginalGlobalObject(JSGlobalContextRef context); + inline ~QScriptOriginalGlobalObject(); + + inline bool objectHasOwnProperty(JSObjectRef object, JSStringRef property) const; + inline QVector<JSStringRef> objectGetOwnPropertyNames(JSObjectRef object) const; + + inline bool isDate(JSValueRef value) const; + inline bool isArray(JSValueRef value) const; + inline bool isError(JSValueRef value) const; + + inline JSValueRef functionPrototype() const; +private: + inline bool isType(JSValueRef value, JSObjectRef constructor, JSValueRef prototype) const; + inline void initializeMember(JSObjectRef globalObject, JSStringRef prototypeName, const char* type, JSObjectRef& constructor, JSValueRef& prototype); + + // Copy of the global context reference (the same as in QScriptEnginePrivate). + JSGlobalContextRef m_context; + + // Copy of constructors and prototypes used in isType functions. + JSObjectRef m_arrayConstructor; + JSValueRef m_arrayPrototype; + JSObjectRef m_errorConstructor; + JSValueRef m_errorPrototype; + JSObjectRef m_functionConstructor; + JSValueRef m_functionPrototype; + JSObjectRef m_dateConstructor; + JSValueRef m_datePrototype; + + // Reference to standard JS functions that are not exposed by JSC C API. + JSObjectRef m_hasOwnPropertyFunction; + JSObjectRef m_getOwnPropertyNamesFunction; +}; + +QScriptOriginalGlobalObject::QScriptOriginalGlobalObject(JSGlobalContextRef context) + : m_context(JSGlobalContextRetain(context)) +{ + JSObjectRef globalObject = JSContextGetGlobalObject(m_context); + JSValueRef exception = 0; + JSRetainPtr<JSStringRef> propertyName; + + propertyName.adopt(JSStringCreateWithUTF8CString("prototype")); + initializeMember(globalObject, propertyName.get(), "Array", m_arrayConstructor, m_arrayPrototype); + initializeMember(globalObject, propertyName.get(), "Error", m_errorConstructor, m_errorPrototype); + initializeMember(globalObject, propertyName.get(), "Function", m_functionConstructor, m_functionPrototype); + initializeMember(globalObject, propertyName.get(), "Date", m_dateConstructor, m_datePrototype); + + propertyName.adopt(JSStringCreateWithUTF8CString("hasOwnProperty")); + m_hasOwnPropertyFunction = const_cast<JSObjectRef>(JSObjectGetProperty(m_context, globalObject, propertyName.get(), &exception)); + JSValueProtect(m_context, m_hasOwnPropertyFunction); + Q_ASSERT(JSValueIsObject(m_context, m_hasOwnPropertyFunction)); + Q_ASSERT(JSObjectIsFunction(m_context, m_hasOwnPropertyFunction)); + Q_ASSERT(!exception); + + propertyName.adopt(JSStringCreateWithUTF8CString("Object")); + JSObjectRef objectConstructor + = const_cast<JSObjectRef>(JSObjectGetProperty(m_context, globalObject, propertyName.get(), &exception)); + propertyName.adopt(JSStringCreateWithUTF8CString("getOwnPropertyNames")); + m_getOwnPropertyNamesFunction + = const_cast<JSObjectRef>(JSObjectGetProperty(m_context, objectConstructor, propertyName.get(), &exception)); + JSValueProtect(m_context, m_getOwnPropertyNamesFunction); + Q_ASSERT(JSValueIsObject(m_context, m_getOwnPropertyNamesFunction)); + Q_ASSERT(JSObjectIsFunction(m_context, m_getOwnPropertyNamesFunction)); + Q_ASSERT(!exception); +} + +inline void QScriptOriginalGlobalObject::initializeMember(JSObjectRef globalObject, JSStringRef prototypeName, const char* type, JSObjectRef& constructor, JSValueRef& prototype) +{ + JSRetainPtr<JSStringRef> typeName(Adopt, JSStringCreateWithUTF8CString(type)); + JSValueRef exception = 0; + + // Save references to the Type constructor and prototype. + JSValueRef typeConstructor = JSObjectGetProperty(m_context, globalObject, typeName.get(), &exception); + Q_ASSERT(JSValueIsObject(m_context, typeConstructor)); + constructor = JSValueToObject(m_context, typeConstructor, &exception); + JSValueProtect(m_context, constructor); + + // Note that this is not the [[Prototype]] internal property (which we could + // get via JSObjectGetPrototype), but the Type.prototype, that will be set + // as [[Prototype]] of Type instances. + prototype = JSObjectGetProperty(m_context, constructor, prototypeName, &exception); + Q_ASSERT(JSValueIsObject(m_context, prototype)); + JSValueProtect(m_context, prototype); + Q_ASSERT(!exception); +} + +QScriptOriginalGlobalObject::~QScriptOriginalGlobalObject() +{ + JSValueUnprotect(m_context, m_arrayConstructor); + JSValueUnprotect(m_context, m_arrayPrototype); + JSValueUnprotect(m_context, m_errorConstructor); + JSValueUnprotect(m_context, m_errorPrototype); + JSValueUnprotect(m_context, m_functionConstructor); + JSValueUnprotect(m_context, m_functionPrototype); + JSValueUnprotect(m_context, m_dateConstructor); + JSValueUnprotect(m_context, m_datePrototype); + JSValueUnprotect(m_context, m_hasOwnPropertyFunction); + JSValueUnprotect(m_context, m_getOwnPropertyNamesFunction); + JSGlobalContextRelease(m_context); +} + +inline bool QScriptOriginalGlobalObject::objectHasOwnProperty(JSObjectRef object, JSStringRef property) const +{ + // FIXME This function should be replaced by JSC C API. + JSValueRef exception = 0; + JSValueRef propertyName[] = { JSValueMakeString(m_context, property) }; + JSValueRef result = JSObjectCallAsFunction(m_context, m_hasOwnPropertyFunction, object, 1, propertyName, &exception); + return exception ? false : JSValueToBoolean(m_context, result); +} + +/*! + \internal + This method gives ownership of all JSStringRefs. +*/ +inline QVector<JSStringRef> QScriptOriginalGlobalObject::objectGetOwnPropertyNames(JSObjectRef object) const +{ + JSValueRef exception = 0; + JSObjectRef propertyNames + = const_cast<JSObjectRef>(JSObjectCallAsFunction(m_context, + m_getOwnPropertyNamesFunction, + /* thisObject */ 0, + /* argumentCount */ 1, + &object, + &exception)); + Q_ASSERT(JSValueIsObject(m_context, propertyNames)); + Q_ASSERT(!exception); + JSStringRef lengthName = QScriptConverter::toString("length"); + int count = JSValueToNumber(m_context, JSObjectGetProperty(m_context, propertyNames, lengthName, &exception), &exception); + + Q_ASSERT(!exception); + QVector<JSStringRef> names; + names.reserve(count); + for (int i = 0; i < count; ++i) { + JSValueRef tmp = JSObjectGetPropertyAtIndex(m_context, propertyNames, i, &exception); + names.append(JSValueToStringCopy(m_context, tmp, &exception)); + Q_ASSERT(!exception); + } + return names; +} + +inline bool QScriptOriginalGlobalObject::isDate(JSValueRef value) const +{ + return isType(value, m_dateConstructor, m_datePrototype); +} + +inline bool QScriptOriginalGlobalObject::isArray(JSValueRef value) const +{ + return isType(value, m_arrayConstructor, m_arrayPrototype); +} + +inline bool QScriptOriginalGlobalObject::isError(JSValueRef value) const +{ + return isType(value, m_errorConstructor, m_errorPrototype); +} + +inline JSValueRef QScriptOriginalGlobalObject::functionPrototype() const +{ + return m_functionPrototype; +} + +inline bool QScriptOriginalGlobalObject::isType(JSValueRef value, JSObjectRef constructor, JSValueRef prototype) const +{ + // JSC API doesn't export the [[Class]] information for the builtins. But we know that a value + // is an object of the Type if it was created with the Type constructor or if it is the Type.prototype. + JSValueRef exception = 0; + bool result = JSValueIsInstanceOfConstructor(m_context, value, constructor, &exception) || JSValueIsStrictEqual(m_context, value, prototype); + Q_ASSERT(!exception); + return result; +} + +#endif // qscriptoriginalglobalobject_p_h diff --git a/Source/JavaScriptCore/qt/api/qscriptprogram.cpp b/Source/JavaScriptCore/qt/api/qscriptprogram.cpp new file mode 100644 index 0000000..d7d4948 --- /dev/null +++ b/Source/JavaScriptCore/qt/api/qscriptprogram.cpp @@ -0,0 +1,136 @@ +/* + Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" + +#include "qscriptprogram.h" + +#include "qscriptprogram_p.h" + +/*! + \internal + + \class QScriptProgram + + \brief The QScriptProgram class encapsulates a Qt Script program. + + \ingroup script + + QScriptProgram retains the compiled representation of the script if + possible. Thus, QScriptProgram can be used to evaluate the same + script multiple times more efficiently. + + \code + QScriptEngine engine; + QScriptProgram program("1 + 2"); + QScriptValue result = engine.evaluate(program); + \endcode +*/ + +/*! + Constructs a null QScriptProgram. +*/ +QScriptProgram::QScriptProgram() + : d_ptr(new QScriptProgramPrivate) +{} + +/*! + Constructs a new QScriptProgram with the given \a sourceCode, \a + fileName and \a firstLineNumber. +*/ +QScriptProgram::QScriptProgram(const QString& sourceCode, + const QString fileName, + int firstLineNumber) + : d_ptr(new QScriptProgramPrivate(sourceCode, fileName, firstLineNumber)) +{} + +/*! + Destroys this QScriptProgram. +*/ +QScriptProgram::~QScriptProgram() +{} + +/*! + Constructs a new QScriptProgram that is a copy of \a other. +*/ +QScriptProgram::QScriptProgram(const QScriptProgram& other) +{ + d_ptr = other.d_ptr; +} + +/*! + Assigns the \a other value to this QScriptProgram. +*/ +QScriptProgram& QScriptProgram::operator=(const QScriptProgram& other) +{ + d_ptr = other.d_ptr; + return *this; +} + +/*! + Returns true if this QScriptProgram is null; otherwise + returns false. +*/ +bool QScriptProgram::isNull() const +{ + return d_ptr->isNull(); +} + +/*! + Returns the source code of this program. +*/ +QString QScriptProgram::sourceCode() const +{ + return d_ptr->sourceCode(); +} + +/*! + Returns the filename associated with this program. +*/ +QString QScriptProgram::fileName() const +{ + return d_ptr->fileName(); +} + +/*! + Returns the line number associated with this program. +*/ +int QScriptProgram::firstLineNumber() const +{ + return d_ptr->firstLineNumber(); +} + +/*! + Returns true if this QScriptProgram is equal to \a other; + otherwise returns false. +*/ +bool QScriptProgram::operator==(const QScriptProgram& other) const +{ + return d_ptr == other.d_ptr || *d_ptr == *other.d_ptr; +} + +/*! + Returns true if this QScriptProgram is not equal to \a other; + otherwise returns false. +*/ +bool QScriptProgram::operator!=(const QScriptProgram& other) const +{ + return d_ptr != other.d_ptr && *d_ptr != *other.d_ptr; +} + diff --git a/Source/JavaScriptCore/qt/api/qscriptprogram.h b/Source/JavaScriptCore/qt/api/qscriptprogram.h new file mode 100644 index 0000000..93c8a3c --- /dev/null +++ b/Source/JavaScriptCore/qt/api/qscriptprogram.h @@ -0,0 +1,53 @@ +/* + Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef qscriptprogram_h +#define qscriptprogram_h + +#include "qtscriptglobal.h" +#include <QtCore/qshareddata.h> +#include <QtCore/qstring.h> + +class QScriptProgramPrivate; +class Q_JAVASCRIPT_EXPORT QScriptProgram { +public: + QScriptProgram(); + QScriptProgram(const QString& sourceCode, + const QString fileName = QString(), + int firstLineNumber = 1); + QScriptProgram(const QScriptProgram& other); + ~QScriptProgram(); + + QScriptProgram& operator=(const QScriptProgram& other); + + bool isNull() const; + + QString sourceCode() const; + QString fileName() const; + int firstLineNumber() const; + + bool operator==(const QScriptProgram& other) const; + bool operator!=(const QScriptProgram& other) const; + +private: + QExplicitlySharedDataPointer<QScriptProgramPrivate> d_ptr; + Q_DECLARE_PRIVATE(QScriptProgram) +}; + +#endif // qscriptprogram_h diff --git a/Source/JavaScriptCore/qt/api/qscriptprogram_p.h b/Source/JavaScriptCore/qt/api/qscriptprogram_p.h new file mode 100644 index 0000000..f6882c5 --- /dev/null +++ b/Source/JavaScriptCore/qt/api/qscriptprogram_p.h @@ -0,0 +1,133 @@ +/* + Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef qscriptprogram_p_h +#define qscriptprogram_p_h + +#include "qscriptconverter_p.h" +#include "qscriptprogram.h" +#include <JavaScriptCore/JavaScript.h> +#include <QtCore/qshareddata.h> +#include <QtCore/qstring.h> + +/* + FIXME The QScriptProgramPrivate potentially could be much faster. In current implementation we + gain CPU time only by avoiding QString -> JSStringRef conversion. In the ideal world we should + have a function inside the JSC C API that could provide us "parse once, execute multiple times" + functionality. +*/ + +class QScriptProgramPrivate : public QSharedData { +public: + inline static QScriptProgramPrivate* get(const QScriptProgram& program); + inline QScriptProgramPrivate(); + inline QScriptProgramPrivate(const QString& sourceCode, + const QString fileName, + int firstLineNumber); + + inline ~QScriptProgramPrivate(); + + inline bool isNull() const; + + inline QString sourceCode() const; + inline QString fileName() const; + inline int firstLineNumber() const; + + inline bool operator==(const QScriptProgramPrivate& other) const; + inline bool operator!=(const QScriptProgramPrivate& other) const; + + inline operator JSStringRef() const; + inline JSStringRef file() const; + inline int line() const; +private: + JSStringRef m_program; + JSStringRef m_fileName; + int m_line; +}; + +QScriptProgramPrivate* QScriptProgramPrivate::get(const QScriptProgram& program) +{ + return const_cast<QScriptProgramPrivate*>(program.d_ptr.constData()); +} + +QScriptProgramPrivate::QScriptProgramPrivate() + : m_program(0) + , m_fileName(0) + , m_line(-1) +{} + +QScriptProgramPrivate::QScriptProgramPrivate(const QString& sourceCode, + const QString fileName, + int firstLineNumber) + : m_program(QScriptConverter::toString(sourceCode)) + , m_fileName(QScriptConverter::toString(fileName)) + , m_line(firstLineNumber) +{} + +QScriptProgramPrivate::~QScriptProgramPrivate() +{ + if (!isNull()) { + JSStringRelease(m_program); + JSStringRelease(m_fileName); + } +} + +bool QScriptProgramPrivate::isNull() const +{ + return !m_program; +} + +QString QScriptProgramPrivate::sourceCode() const +{ + return QScriptConverter::toString(m_program); +} + +QString QScriptProgramPrivate::fileName() const +{ + return QScriptConverter::toString(m_fileName); +} + +int QScriptProgramPrivate::firstLineNumber() const +{ + return m_line; +} + +bool QScriptProgramPrivate::operator==(const QScriptProgramPrivate& other) const +{ + return m_line == other.m_line + && JSStringIsEqual(m_fileName, other.m_fileName) + && JSStringIsEqual(m_program, other.m_program); +} + +bool QScriptProgramPrivate::operator!=(const QScriptProgramPrivate& other) const +{ + return m_line != other.m_line + || !JSStringIsEqual(m_fileName, other.m_fileName) + || !JSStringIsEqual(m_program, other.m_program); +} + +QScriptProgramPrivate::operator JSStringRef() const +{ + return m_program; +} + +JSStringRef QScriptProgramPrivate::file() const {return m_fileName; } +int QScriptProgramPrivate::line() const { return m_line; } + +#endif // qscriptprogram_p_h diff --git a/Source/JavaScriptCore/qt/api/qscriptstring.cpp b/Source/JavaScriptCore/qt/api/qscriptstring.cpp new file mode 100644 index 0000000..83c03c5 --- /dev/null +++ b/Source/JavaScriptCore/qt/api/qscriptstring.cpp @@ -0,0 +1,131 @@ +/* + Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" + +#include "qscriptstring.h" + +#include "qscriptstring_p.h" +#include <QtCore/qhash.h> + +/*! + Constructs an invalid QScriptString. +*/ +QScriptString::QScriptString() + : d_ptr(new QScriptStringPrivate()) +{ +} +/*! + Constructs an QScriptString from internal representation + \internal +*/ +QScriptString::QScriptString(QScriptStringPrivate* d) + : d_ptr(d) +{ +} + +/*! + Constructs a new QScriptString that is a copy of \a other. +*/ +QScriptString::QScriptString(const QScriptString& other) +{ + d_ptr = other.d_ptr; +} + +/*! + Destroys this QScriptString. +*/ +QScriptString::~QScriptString() +{ +} + +/*! + Assigns the \a other value to this QScriptString. +*/ +QScriptString& QScriptString::operator=(const QScriptString& other) +{ + d_ptr = other.d_ptr; + return *this; +} + +/*! + Returns true if this QScriptString is valid; otherwise + returns false. +*/ +bool QScriptString::isValid() const +{ + return d_ptr->isValid(); +} + +/*! + Returns true if this QScriptString is equal to \a other; + otherwise returns false. +*/ +bool QScriptString::operator==(const QScriptString& other) const +{ + return d_ptr == other.d_ptr || *d_ptr == *(other.d_ptr); +} + +/*! + Returns true if this QScriptString is not equal to \a other; + otherwise returns false. +*/ +bool QScriptString::operator!=(const QScriptString& other) const +{ + return d_ptr != other.d_ptr || *d_ptr != *(other.d_ptr); +} + +/*! + Attempts to convert this QScriptString to a QtScript array index, + and returns the result. + + If a conversion error occurs, *\a{ok} is set to false; otherwise + *\a{ok} is set to true. +*/ +quint32 QScriptString::toArrayIndex(bool* ok) const +{ + return d_ptr->toArrayIndex(ok); +} + +/*! + Returns the string that this QScriptString represents, or a + null string if this QScriptString is not valid. + + \sa isValid() +*/ +QString QScriptString::toString() const +{ + return d_ptr->toString(); +} + +/*! + Returns the string that this QScriptString represents, or a + null string if this QScriptString is not valid. + + \sa toString() +*/ +QScriptString::operator QString() const +{ + return d_ptr->toString(); +} + +uint qHash(const QScriptString& key) +{ + return qHash(QScriptStringPrivate::get(key)->id()); +} diff --git a/Source/JavaScriptCore/qt/api/qscriptstring.h b/Source/JavaScriptCore/qt/api/qscriptstring.h new file mode 100644 index 0000000..16593bc --- /dev/null +++ b/Source/JavaScriptCore/qt/api/qscriptstring.h @@ -0,0 +1,58 @@ +/* + Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef qscriptstring_h +#define qscriptstring_h + +#include "qtscriptglobal.h" +#include <QtCore/qshareddata.h> +#include <QtCore/qstring.h> + +class QScriptStringPrivate; +typedef QExplicitlySharedDataPointer<QScriptStringPrivate> QScriptStringPtr; + +class Q_JAVASCRIPT_EXPORT QScriptString { +public: + QScriptString(); + QScriptString(const QScriptString& other); + ~QScriptString(); + + QScriptString& operator=(const QScriptString& other); + + bool isValid() const; + + bool operator==(const QScriptString& other) const; + bool operator!=(const QScriptString& other) const; + + quint32 toArrayIndex(bool* ok = 0) const; + + QString toString() const; + operator QString() const; + +private: + QScriptString(QScriptStringPrivate* d); + + QScriptStringPtr d_ptr; + + friend class QScriptStringPrivate; +}; + +uint qHash(const QScriptString& key); + +#endif // qscriptstring_h diff --git a/Source/JavaScriptCore/qt/api/qscriptstring_p.h b/Source/JavaScriptCore/qt/api/qscriptstring_p.h new file mode 100644 index 0000000..fe84f4d --- /dev/null +++ b/Source/JavaScriptCore/qt/api/qscriptstring_p.h @@ -0,0 +1,124 @@ +/* + Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef qscriptstring_p_h +#define qscriptstring_p_h + +#include "qscriptconverter_p.h" +#include "qscriptstring.h" +#include <JavaScriptCore/JavaScript.h> +#include <QtCore/qnumeric.h> +#include <QtCore/qshareddata.h> + +class QScriptStringPrivate : public QSharedData { +public: + inline QScriptStringPrivate(); + inline QScriptStringPrivate(const QString& qtstring); + inline ~QScriptStringPrivate(); + + static inline QScriptString get(QScriptStringPrivate* d); + static inline QScriptStringPtr get(const QScriptString& p); + + inline bool isValid() const; + + inline bool operator==(const QScriptStringPrivate& other) const; + inline bool operator!=(const QScriptStringPrivate& other) const; + + inline quint32 toArrayIndex(bool* ok = 0) const; + + inline QString toString() const; + + inline quint64 id() const; + + inline operator JSStringRef() const; + +private: + JSStringRef m_string; +}; + + +QScriptStringPrivate::QScriptStringPrivate() + : m_string(0) +{} + +QScriptStringPrivate::QScriptStringPrivate(const QString& qtstring) + : m_string(QScriptConverter::toString(qtstring)) +{} + +QScriptStringPrivate::~QScriptStringPrivate() +{ + if (isValid()) + JSStringRelease(m_string); +} + +QScriptString QScriptStringPrivate::get(QScriptStringPrivate* d) +{ + Q_ASSERT(d); + return QScriptString(d); +} + +QScriptStringPtr QScriptStringPrivate::get(const QScriptString& p) +{ + return p.d_ptr; +} + +bool QScriptStringPrivate::isValid() const +{ + return m_string; +} + +bool QScriptStringPrivate::operator==(const QScriptStringPrivate& other) const +{ + return isValid() && other.isValid() && JSStringIsEqual(m_string, other.m_string); +} + +bool QScriptStringPrivate::operator!=(const QScriptStringPrivate& other) const +{ + return isValid() && other.isValid() && !JSStringIsEqual(m_string, other.m_string); +} + +quint32 QScriptStringPrivate::toArrayIndex(bool* ok) const +{ + quint32 idx = QScriptConverter::toArrayIndex(m_string); + if (ok) + *ok = (idx != 0xffffffff); + return idx; +} + +QString QScriptStringPrivate::toString() const +{ + return QScriptConverter::toString(m_string); +} + +quint64 QScriptStringPrivate::id() const +{ + return reinterpret_cast<quint32>(m_string); +} + +/*! + \internal + This method should be used for invoking JSC functions. + \note This method keeps ownership of an internal JSStringRef. +*/ +QScriptStringPrivate::operator JSStringRef() const +{ + return m_string; +} + +#endif // qscriptstring_p_h diff --git a/Source/JavaScriptCore/qt/api/qscriptsyntaxcheckresult.cpp b/Source/JavaScriptCore/qt/api/qscriptsyntaxcheckresult.cpp new file mode 100644 index 0000000..3948c5d --- /dev/null +++ b/Source/JavaScriptCore/qt/api/qscriptsyntaxcheckresult.cpp @@ -0,0 +1,148 @@ +/* + Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" + +#include "qscriptsyntaxcheckresult.h" +#include "qscriptsyntaxcheckresult_p.h" + +/*! + \class QScriptSyntaxCheckResult + + \brief The QScriptSyntaxCheckResult class provides the result of a script syntax check. + + \ingroup script + \mainclass + + QScriptSyntaxCheckResult is returned by QScriptEngine::checkSyntax() to + provide information about the syntactical (in)correctness of a script. +*/ + +/*! + \enum QScriptSyntaxCheckResult::State + + This enum specifies the state of a syntax check. + + \value Error The program contains a syntax error. + \value Intermediate The program is incomplete. + \value Valid The program is a syntactically correct Qt Script program. +*/ + +/*! + Constructs a new QScriptSyntaxCheckResult from the \a other result. +*/ +QScriptSyntaxCheckResult::QScriptSyntaxCheckResult(const QScriptSyntaxCheckResult& other) + : d_ptr(other.d_ptr) +{} + +/*! + Constructs a new QScriptSyntaxCheckResult from an internal representation. + \internal +*/ +QScriptSyntaxCheckResult::QScriptSyntaxCheckResult(QScriptSyntaxCheckResultPrivate* d) + : d_ptr(d) +{} + +/*! + Destroys this QScriptSyntaxCheckResult. +*/ +QScriptSyntaxCheckResult::~QScriptSyntaxCheckResult() +{} + +/*! + Assigns the \a other result to this QScriptSyntaxCheckResult, and returns a + reference to this QScriptSyntaxCheckResult. +*/ +QScriptSyntaxCheckResult& QScriptSyntaxCheckResult::operator=(const QScriptSyntaxCheckResult& other) +{ + d_ptr = other.d_ptr; + return *this; +} + +/*! + Returns the state of this QScriptSyntaxCheckResult. +*/ +QScriptSyntaxCheckResult::State QScriptSyntaxCheckResult::state() const +{ + return d_ptr->state(); +} + +/*! + Returns the error line number of this QScriptSyntaxCheckResult, or -1 if + there is no error. + + \sa state(), errorMessage() +*/ +int QScriptSyntaxCheckResult::errorLineNumber() const +{ + return d_ptr->errorLineNumber(); +} + +/*! + Returns the error column number of this QScriptSyntaxCheckResult, or -1 if + there is no error. + + \sa state(), errorLineNumber() +*/ +int QScriptSyntaxCheckResult::errorColumnNumber() const +{ + return d_ptr->errorColumnNumber(); +} + +/*! + Returns the error message of this QScriptSyntaxCheckResult, or an empty + string if there is no error. + + \sa state(), errorLineNumber() +*/ +QString QScriptSyntaxCheckResult::errorMessage() const +{ + return d_ptr->errorMessage(); +} + +QScriptSyntaxCheckResultPrivate::~QScriptSyntaxCheckResultPrivate() +{ + if (m_exception) + JSValueUnprotect(*m_engine, m_exception); +} + +QString QScriptSyntaxCheckResultPrivate::errorMessage() const +{ + if (!m_exception) + return QString(); + + JSStringRef tmp = JSValueToStringCopy(*m_engine, m_exception, /* exception */ 0); + QString message = QScriptConverter::toString(tmp); + JSStringRelease(tmp); + return message; +} + +int QScriptSyntaxCheckResultPrivate::errorLineNumber() const +{ + if (!m_exception) + return -1; + // m_exception is an instance of the Exception so it has "line" attribute. + JSStringRef lineAttrName = QScriptConverter::toString("line"); + JSValueRef line = JSObjectGetProperty(*m_engine, + m_exception, + lineAttrName, + /* exceptions */0); + JSStringRelease(lineAttrName); + return JSValueToNumber(*m_engine, line, /* exceptions */0); +} diff --git a/Source/JavaScriptCore/qt/api/qscriptsyntaxcheckresult.h b/Source/JavaScriptCore/qt/api/qscriptsyntaxcheckresult.h new file mode 100644 index 0000000..aa57744 --- /dev/null +++ b/Source/JavaScriptCore/qt/api/qscriptsyntaxcheckresult.h @@ -0,0 +1,50 @@ +/* + Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef qscriptsyntaxcheckresult_h +#define qscriptsyntaxcheckresult_h + +#include "qtscriptglobal.h" +#include <QtCore/qshareddata.h> + +class QScriptSyntaxCheckResultPrivate; +class Q_JAVASCRIPT_EXPORT QScriptSyntaxCheckResult { +public: + enum State { + Error, + Intermediate, + Valid + }; + + QScriptSyntaxCheckResult(const QScriptSyntaxCheckResult& other); + ~QScriptSyntaxCheckResult(); + QScriptSyntaxCheckResult& operator=(const QScriptSyntaxCheckResult& other); + + State state() const; + int errorLineNumber() const; + int errorColumnNumber() const; + QString errorMessage() const; + +private: + QScriptSyntaxCheckResult(QScriptSyntaxCheckResultPrivate* d); + QExplicitlySharedDataPointer<QScriptSyntaxCheckResultPrivate> d_ptr; + + friend class QScriptSyntaxCheckResultPrivate; +}; +#endif // qscriptsyntaxcheckresult_h diff --git a/Source/JavaScriptCore/qt/api/qscriptsyntaxcheckresult_p.h b/Source/JavaScriptCore/qt/api/qscriptsyntaxcheckresult_p.h new file mode 100644 index 0000000..6e1a131 --- /dev/null +++ b/Source/JavaScriptCore/qt/api/qscriptsyntaxcheckresult_p.h @@ -0,0 +1,73 @@ +/* + Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef qscriptsyntaxcheckresult_p_h +#define qscriptsyntaxcheckresult_p_h + +#include "qscriptconverter_p.h" +#include "qscriptengine_p.h" +#include "qscriptsyntaxcheckresult.h" +#include <JavaScriptCore/JavaScript.h> +#include <QtCore/qshareddata.h> + +class QScriptSyntaxCheckResultPrivate : public QSharedData { +public: + static inline QScriptSyntaxCheckResult get(QScriptSyntaxCheckResultPrivate* p); + inline QScriptSyntaxCheckResultPrivate(const QScriptEnginePrivate* engine); + inline QScriptSyntaxCheckResultPrivate(const QScriptEnginePrivate* engine, JSObjectRef value); + ~QScriptSyntaxCheckResultPrivate(); + + inline QScriptSyntaxCheckResult::State state() const; + int errorLineNumber() const; + inline int errorColumnNumber() const; + QString errorMessage() const; +private: + JSObjectRef m_exception; + QScriptEnginePtr m_engine; +}; + +QScriptSyntaxCheckResult QScriptSyntaxCheckResultPrivate::get(QScriptSyntaxCheckResultPrivate* p) +{ + return QScriptSyntaxCheckResult(p); +} + +QScriptSyntaxCheckResultPrivate::QScriptSyntaxCheckResultPrivate(const QScriptEnginePrivate* engine) + : m_exception(0) + , m_engine(const_cast<QScriptEnginePrivate*>(engine)) +{} + +QScriptSyntaxCheckResultPrivate::QScriptSyntaxCheckResultPrivate(const QScriptEnginePrivate* engine, JSObjectRef value) + : m_exception(value) + , m_engine(const_cast<QScriptEnginePrivate*>(engine)) +{} + +QScriptSyntaxCheckResult::State QScriptSyntaxCheckResultPrivate::state() const +{ + // FIXME This function doesn't return QScriptSyntaxCheckResult::Intermediate + return m_exception ? QScriptSyntaxCheckResult::Error : QScriptSyntaxCheckResult::Valid; +} + +int QScriptSyntaxCheckResultPrivate::errorColumnNumber() const +{ + // FIXME JSC C API doesn't expose the error column number. + return m_exception ? 1 : -1; +} + + +#endif // qscriptsyntaxcheckresult_p_h diff --git a/Source/JavaScriptCore/qt/api/qscriptvalue.cpp b/Source/JavaScriptCore/qt/api/qscriptvalue.cpp new file mode 100644 index 0000000..8a7a6c4 --- /dev/null +++ b/Source/JavaScriptCore/qt/api/qscriptvalue.cpp @@ -0,0 +1,802 @@ +/* + Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" + +#include "qscriptvalue.h" + +#include "qscriptengine.h" +#include "qscriptengine_p.h" +#include "qscriptvalue_p.h" +#include <QtCore/qdebug.h> + +/*! + Constructs an invalid value. +*/ +QScriptValue::QScriptValue() + : d_ptr(new QScriptValuePrivate()) +{ +} + +/*! + Constructs a new QScriptValue with a boolean \a value. +*/ +QScriptValue::QScriptValue(bool value) + : d_ptr(new QScriptValuePrivate(value)) +{ +} + +/*! + Constructs a new QScriptValue with a number \a value. +*/ +QScriptValue::QScriptValue(int value) + : d_ptr(new QScriptValuePrivate(value)) +{ +} + +/*! + Constructs a new QScriptValue with a number \a value. +*/ +QScriptValue::QScriptValue(uint value) + : d_ptr(new QScriptValuePrivate(value)) +{ +} + +/*! + Constructs a new QScriptValue with a number \a value. +*/ +QScriptValue::QScriptValue(qsreal value) + : d_ptr(new QScriptValuePrivate(value)) +{ +} + +/*! + Constructs a new QScriptValue with a string \a value. +*/ +QScriptValue::QScriptValue(const QString& value) + : d_ptr(new QScriptValuePrivate(value)) +{ +} + +/*! + Constructs a new QScriptValue with a special \a value. +*/ +QScriptValue::QScriptValue(SpecialValue value) + : d_ptr(new QScriptValuePrivate(value)) +{ +} + +/*! + Constructs a new QScriptValue with a string \a value. +*/ +QScriptValue::QScriptValue(const char* value) + : d_ptr(new QScriptValuePrivate(QString::fromUtf8(value))) +{ +} + +/*! + Block automatic convertion to bool + \internal +*/ +QScriptValue::QScriptValue(void* d) +{ + Q_ASSERT(false); +} + +/*! + Constructs a new QScriptValue from private + \internal +*/ +QScriptValue::QScriptValue(QScriptValuePrivate* d) + : d_ptr(d) +{ +} + +/*! + \obsolete + + Constructs a new QScriptValue with the boolean \a value and + registers it with the script \a engine. +*/ +QScriptValue::QScriptValue(QScriptEngine* engine, bool value) +{ + if (engine) + d_ptr = new QScriptValuePrivate(QScriptEnginePrivate::get(engine), value); + else + d_ptr = new QScriptValuePrivate(value); +} + +/*! + \obsolete + + Constructs a new QScriptValue with the integer \a value and + registers it with the script \a engine. +*/ +QScriptValue::QScriptValue(QScriptEngine* engine, int value) +{ + if (engine) + d_ptr = new QScriptValuePrivate(QScriptEnginePrivate::get(engine), value); + else + d_ptr = new QScriptValuePrivate(value); +} + +/*! + \obsolete + + Constructs a new QScriptValue with the unsigned integer \a value and + registers it with the script \a engine. + */ +QScriptValue::QScriptValue(QScriptEngine* engine, uint value) +{ + if (engine) + d_ptr = new QScriptValuePrivate(QScriptEnginePrivate::get(engine), value); + else + d_ptr = new QScriptValuePrivate(value); +} + +/*! + \obsolete + + Constructs a new QScriptValue with the qsreal \a value and + registers it with the script \a engine. +*/ +QScriptValue::QScriptValue(QScriptEngine* engine, qsreal value) +{ + if (engine) + d_ptr = new QScriptValuePrivate(QScriptEnginePrivate::get(engine), value); + else + d_ptr = new QScriptValuePrivate(value); +} + +/*! + \obsolete + + Constructs a new QScriptValue with the string \a value and + registers it with the script \a engine. +*/ +QScriptValue::QScriptValue(QScriptEngine* engine, const QString& value) +{ + if (engine) + d_ptr = new QScriptValuePrivate(QScriptEnginePrivate::get(engine), value); + else + d_ptr = new QScriptValuePrivate(value); +} + +/*! + \obsolete + + Constructs a new QScriptValue with the string \a value and + registers it with the script \a engine. +*/ +QScriptValue::QScriptValue(QScriptEngine* engine, const char* value) +{ + if (engine) + d_ptr = new QScriptValuePrivate(QScriptEnginePrivate::get(engine), QString::fromUtf8(value)); + else + d_ptr = new QScriptValuePrivate(QString::fromUtf8(value)); +} + +/*! + \obsolete + + Constructs a new QScriptValue with the special \a value and + registers it with the script \a engine. +*/ +QScriptValue::QScriptValue(QScriptEngine* engine, SpecialValue value) +{ + if (engine) + d_ptr = new QScriptValuePrivate(QScriptEnginePrivate::get(engine), value); + else + d_ptr = new QScriptValuePrivate(value); +} + +/*! + Constructs a new QScriptValue that is a copy of \a other. + + Note that if \a other is an object (i.e., isObject() would return + true), then only a reference to the underlying object is copied into + the new script value (i.e., the object itself is not copied). +*/ +QScriptValue::QScriptValue(const QScriptValue& other) + : d_ptr(other.d_ptr) +{ +} + +/*! + Destroys this QScriptValue. +*/ +QScriptValue::~QScriptValue() +{ +} + +/*! + Returns true if this QScriptValue is valid; otherwise returns + false. +*/ +bool QScriptValue::isValid() const +{ + return d_ptr->isValid(); +} + +/*! + Returns true if this QScriptValue is of the primitive type Boolean; + otherwise returns false. + + \sa toBool() +*/ +bool QScriptValue::isBool() const +{ + return d_ptr->isBool(); +} + +/*! + \obsolete + + Use isBool() instead. + Returns true if this QScriptValue is of the primitive type Boolean; + otherwise returns false. +*/ +bool QScriptValue::isBoolean() const +{ + return d_ptr->isBool(); +} + +/*! + Returns true if this QScriptValue is of the primitive type Number; + otherwise returns false. + + \sa toNumber() +*/ +bool QScriptValue::isNumber() const +{ + return d_ptr->isNumber(); +} + +/*! + Returns true if this QScriptValue is of the primitive type Null; + otherwise returns false. + + \sa QScriptEngine::nullValue() +*/ +bool QScriptValue::isNull() const +{ + return d_ptr->isNull(); +} + +/*! + Returns true if this QScriptValue is of the primitive type String; + otherwise returns false. + + \sa toString() +*/ +bool QScriptValue::isString() const +{ + return d_ptr->isString(); +} + +/*! + Returns true if this QScriptValue is of the primitive type Undefined; + otherwise returns false. + + \sa QScriptEngine::undefinedValue() +*/ +bool QScriptValue::isUndefined() const +{ + return d_ptr->isUndefined(); +} + +/*! + Returns true if this QScriptValue is an object of the Error class; + otherwise returns false. + + \sa QScriptContext::throwError() +*/ +bool QScriptValue::isError() const +{ + return d_ptr->isError(); +} + +/*! + Returns true if this QScriptValue is an object of the Array class; + otherwise returns false. + + \sa QScriptEngine::newArray() +*/ +bool QScriptValue::isArray() const +{ + return d_ptr->isArray(); +} + +/*! + Returns true if this QScriptValue is an object of the Date class; + otherwise returns false. + + \sa QScriptEngine::newDate() +*/ +bool QScriptValue::isDate() const +{ + return d_ptr->isDate(); +} + +/*! + Returns true if this QScriptValue is of the Object type; otherwise + returns false. + + Note that function values, variant values, and QObject values are + objects, so this function returns true for such values. + + \sa toObject(), QScriptEngine::newObject() +*/ +bool QScriptValue::isObject() const +{ + return d_ptr->isObject(); +} + +/*! + Returns true if this QScriptValue is a function; otherwise returns + false. + + \sa call() +*/ +bool QScriptValue::isFunction() const +{ + return d_ptr->isFunction(); +} + +/*! + Returns the string value of this QScriptValue, as defined in + \l{ECMA-262} section 9.8, "ToString". + + Note that if this QScriptValue is an object, calling this function + has side effects on the script engine, since the engine will call + the object's toString() function (and possibly valueOf()) in an + attempt to convert the object to a primitive value (possibly + resulting in an uncaught script exception). + + \sa isString() +*/ +QString QScriptValue::toString() const +{ + return d_ptr->toString(); +} + +/*! + Returns the number value of this QScriptValue, as defined in + \l{ECMA-262} section 9.3, "ToNumber". + + Note that if this QScriptValue is an object, calling this function + has side effects on the script engine, since the engine will call + the object's valueOf() function (and possibly toString()) in an + attempt to convert the object to a primitive value (possibly + resulting in an uncaught script exception). + + \sa isNumber(), toInteger(), toInt32(), toUInt32(), toUInt16() +*/ +qsreal QScriptValue::toNumber() const +{ + return d_ptr->toNumber(); +} + +/*! + Returns the boolean value of this QScriptValue, using the conversion + rules described in \l{ECMA-262} section 9.2, "ToBoolean". + + Note that if this QScriptValue is an object, calling this function + has side effects on the script engine, since the engine will call + the object's valueOf() function (and possibly toString()) in an + attempt to convert the object to a primitive value (possibly + resulting in an uncaught script exception). + + \sa isBool() +*/ +bool QScriptValue::toBool() const +{ + return d_ptr->toBool(); +} + +/*! + \obsolete + + Use toBool() instead. +*/ +bool QScriptValue::toBoolean() const +{ + return d_ptr->toBool(); +} + +/*! + Returns the integer value of this QScriptValue, using the conversion + rules described in \l{ECMA-262} section 9.4, "ToInteger". + + Note that if this QScriptValue is an object, calling this function + has side effects on the script engine, since the engine will call + the object's valueOf() function (and possibly toString()) in an + attempt to convert the object to a primitive value (possibly + resulting in an uncaught script exception). + + \sa toNumber() +*/ +qsreal QScriptValue::toInteger() const +{ + return d_ptr->toInteger(); +} + +/*! + Returns the signed 32-bit integer value of this QScriptValue, using + the conversion rules described in \l{ECMA-262} section 9.5, "ToInt32". + + Note that if this QScriptValue is an object, calling this function + has side effects on the script engine, since the engine will call + the object's valueOf() function (and possibly toString()) in an + attempt to convert the object to a primitive value (possibly + resulting in an uncaught script exception). + + \sa toNumber(), toUInt32() +*/ +qint32 QScriptValue::toInt32() const +{ + return d_ptr->toInt32(); +} + +/*! + Returns the unsigned 32-bit integer value of this QScriptValue, using + the conversion rules described in \l{ECMA-262} section 9.6, "ToUint32". + + Note that if this QScriptValue is an object, calling this function + has side effects on the script engine, since the engine will call + the object's valueOf() function (and possibly toString()) in an + attempt to convert the object to a primitive value (possibly + resulting in an uncaught script exception). + + \sa toNumber(), toInt32() +*/ +quint32 QScriptValue::toUInt32() const +{ + return d_ptr->toUInt32(); +} + +/*! + Returns the unsigned 16-bit integer value of this QScriptValue, using + the conversion rules described in \l{ECMA-262} section 9.7, "ToUint16". + + Note that if this QScriptValue is an object, calling this function + has side effects on the script engine, since the engine will call + the object's valueOf() function (and possibly toString()) in an + attempt to convert the object to a primitive value (possibly + resulting in an uncaught script exception). + + \sa toNumber() +*/ +quint16 QScriptValue::toUInt16() const +{ + return d_ptr->toUInt16(); +} + +/*! + \obsolete + + This function is obsolete; use QScriptEngine::toObject() instead. +*/ +QScriptValue QScriptValue::toObject() const +{ + return QScriptValuePrivate::get(d_ptr->toObject()); +} + +/*! + Returns a QDateTime representation of this value, in local time. + If this QScriptValue is not a date, or the value of the date is + NaN (Not-a-Number), an invalid QDateTime is returned. + + \sa isDate() +*/ +QDateTime QScriptValue::toDateTime() const +{ + return d_ptr->toDateTime(); +} + +/*! + Calls this QScriptValue as a function, using \a thisObject as + the `this' object in the function call, and passing \a args + as arguments to the function. Returns the value returned from + the function. + + If this QScriptValue is not a function, call() does nothing + and returns an invalid QScriptValue. + + Note that if \a thisObject is not an object, the global object + (see \l{QScriptEngine::globalObject()}) will be used as the + `this' object. + + Calling call() can cause an exception to occur in the script engine; + in that case, call() returns the value that was thrown (typically an + \c{Error} object). You can call + QScriptEngine::hasUncaughtException() to determine if an exception + occurred. + + \snippet doc/src/snippets/code/src_script_qscriptvalue.cpp 2 + + \sa construct() +*/ +QScriptValue QScriptValue::call(const QScriptValue& thisObject, const QScriptValueList& args) +{ + return d_ptr->call(thisObject.d_ptr.data(), args); +} + +/*! + Returns the QScriptEngine that created this QScriptValue, + or 0 if this QScriptValue is invalid or the value is not + associated with a particular engine. +*/ +QScriptEngine* QScriptValue::engine() const +{ + QScriptEnginePrivate* engine = d_ptr->engine(); + if (engine) + return QScriptEnginePrivate::get(engine); + return 0; +} + +/*! + If this QScriptValue is an object, returns the internal prototype + (\c{__proto__} property) of this object; otherwise returns an + invalid QScriptValue. + + \sa setPrototype(), isObject() +*/ +QScriptValue QScriptValue::prototype() const +{ + return QScriptValuePrivate::get(d_ptr->prototype()); +} + +/*! + If this QScriptValue is an object, sets the internal prototype + (\c{__proto__} property) of this object to be \a prototype; + otherwise does nothing. + + The internal prototype should not be confused with the public + property with name "prototype"; the public prototype is usually + only set on functions that act as constructors. + + \sa prototype(), isObject() +*/ +void QScriptValue::setPrototype(const QScriptValue& prototype) +{ + d_ptr->setPrototype(QScriptValuePrivate::get(prototype)); +} + +/*! + Assigns the \a other value to this QScriptValue. + + Note that if \a other is an object (isObject() returns true), + only a reference to the underlying object will be assigned; + the object itself will not be copied. +*/ +QScriptValue& QScriptValue::operator=(const QScriptValue& other) +{ + d_ptr = other.d_ptr; + return *this; +} + +/*! + Returns true if this QScriptValue is equal to \a other, otherwise + returns false. The comparison follows the behavior described in + \l{ECMA-262} section 11.9.3, "The Abstract Equality Comparison + Algorithm". + + This function can return true even if the type of this QScriptValue + is different from the type of the \a other value; i.e. the + comparison is not strict. For example, comparing the number 9 to + the string "9" returns true; comparing an undefined value to a null + value returns true; comparing a \c{Number} object whose primitive + value is 6 to a \c{String} object whose primitive value is "6" + returns true; and comparing the number 1 to the boolean value + \c{true} returns true. If you want to perform a comparison + without such implicit value conversion, use strictlyEquals(). + + Note that if this QScriptValue or the \a other value are objects, + calling this function has side effects on the script engine, since + the engine will call the object's valueOf() function (and possibly + toString()) in an attempt to convert the object to a primitive value + (possibly resulting in an uncaught script exception). + + \sa strictlyEquals(), lessThan() +*/ +bool QScriptValue::equals(const QScriptValue& other) const +{ + return d_ptr->equals(QScriptValuePrivate::get(other)); +} + +/*! + Returns true if this QScriptValue is equal to \a other using strict + comparison (no conversion), otherwise returns false. The comparison + follows the behavior described in \l{ECMA-262} section 11.9.6, "The + Strict Equality Comparison Algorithm". + + If the type of this QScriptValue is different from the type of the + \a other value, this function returns false. If the types are equal, + the result depends on the type, as shown in the following table: + + \table + \header \o Type \o Result + \row \o Undefined \o true + \row \o Null \o true + \row \o Boolean \o true if both values are true, false otherwise + \row \o Number \o false if either value is NaN (Not-a-Number); true if values are equal, false otherwise + \row \o String \o true if both values are exactly the same sequence of characters, false otherwise + \row \o Object \o true if both values refer to the same object, false otherwise + \endtable + + \sa equals() +*/ +bool QScriptValue::strictlyEquals(const QScriptValue& other) const +{ + return d_ptr->strictlyEquals(QScriptValuePrivate::get(other)); +} + +/*! + Returns true if this QScriptValue is an instance of + \a other; otherwise returns false. + + This QScriptValue is considered to be an instance of \a other if + \a other is a function and the value of the \c{prototype} + property of \a other is in the prototype chain of this + QScriptValue. +*/ +bool QScriptValue::instanceOf(const QScriptValue& other) const +{ + return d_ptr->instanceOf(QScriptValuePrivate::get(other)); +} + +/*! + Returns the value of this QScriptValue's property with the given \a name, + using the given \a mode to resolve the property. + + If no such property exists, an invalid QScriptValue is returned. + + If the property is implemented using a getter function (i.e. has the + PropertyGetter flag set), calling property() has side-effects on the + script engine, since the getter function will be called (possibly + resulting in an uncaught script exception). If an exception + occurred, property() returns the value that was thrown (typically + an \c{Error} object). + + \sa setProperty(), propertyFlags(), QScriptValueIterator +*/ +QScriptValue QScriptValue::property(const QString& name, const ResolveFlags& mode) const +{ + return QScriptValuePrivate::get(d_ptr->property(name, mode)); +} + +/*! + \overload + + Returns the value of this QScriptValue's property with the given \a name, + using the given \a mode to resolve the property. + + This overload of property() is useful when you need to look up the + same property repeatedly, since the lookup can be performed faster + when the name is represented as an interned string. + + \sa QScriptEngine::toStringHandle(), setProperty() +*/ +QScriptValue QScriptValue::property(const QScriptString& name, const ResolveFlags& mode) const +{ + return QScriptValuePrivate::get(d_ptr->property(QScriptStringPrivate::get(name).constData(), mode)); +} + +/*! + \overload + + Returns the property at the given \a arrayIndex, using the given \a + mode to resolve the property. + + This function is provided for convenience and performance when + working with array objects. + + If this QScriptValue is not an Array object, this function behaves + as if property() was called with the string representation of \a + arrayIndex. +*/ +QScriptValue QScriptValue::property(quint32 arrayIndex, const ResolveFlags& mode) const +{ + return QScriptValuePrivate::get(d_ptr->property(arrayIndex, mode)); +} + +/*! + Sets the value of this QScriptValue's property with the given \a name to + the given \a value. + + If this QScriptValue is not an object, this function does nothing. + + If this QScriptValue does not already have a property with name \a name, + a new property is created; the given \a flags then specify how this + property may be accessed by script code. + + If \a value is invalid, the property is removed. + + If the property is implemented using a setter function (i.e. has the + PropertySetter flag set), calling setProperty() has side-effects on + the script engine, since the setter function will be called with the + given \a value as argument (possibly resulting in an uncaught script + exception). + + Note that you cannot specify custom getter or setter functions for + built-in properties, such as the \c{length} property of Array objects + or meta properties of QObject objects. + + \sa property() +*/ +void QScriptValue::setProperty(const QString& name, const QScriptValue& value, const PropertyFlags& flags) +{ + d_ptr->setProperty(name, QScriptValuePrivate::get(value), flags); +} + +/*! + \overload + + Sets the property at the given \a arrayIndex to the given \a value. + + This function is provided for convenience and performance when + working with array objects. + + If this QScriptValue is not an Array object, this function behaves + as if setProperty() was called with the string representation of \a + arrayIndex. +*/ +void QScriptValue::setProperty(quint32 arrayIndex, const QScriptValue& value, const PropertyFlags& flags) +{ + d_ptr->setProperty(arrayIndex, QScriptValuePrivate::get(value), flags); +} + +/*! + Sets the value of this QScriptValue's property with the given \a + name to the given \a value. The given \a flags specify how this + property may be accessed by script code. + + This overload of setProperty() is useful when you need to set the + same property repeatedly, since the operation can be performed + faster when the name is represented as an interned string. + + \sa QScriptEngine::toStringHandle() +*/ +void QScriptValue::setProperty(const QScriptString& name, const QScriptValue& value, const PropertyFlags& flags) +{ + d_ptr->setProperty(QScriptStringPrivate::get(name).constData(), QScriptValuePrivate::get(value), flags); +} + +/*! + Returns the flags of the property with the given \a name, using the + given \a mode to resolve the property. + + \sa property() +*/ +QScriptValue::PropertyFlags QScriptValue::propertyFlags(const QString& name, const ResolveFlags& mode) const +{ + return d_ptr->propertyFlags(name, mode); +} + +/*! + Returns the flags of the property with the given \a name, using the + given \a mode to resolve the property. + + \sa property() +*/ +QScriptValue::PropertyFlags QScriptValue::propertyFlags(const QScriptString& name, const ResolveFlags& mode) const +{ + return d_ptr->propertyFlags(QScriptStringPrivate::get(name).constData(), mode); +} diff --git a/Source/JavaScriptCore/qt/api/qscriptvalue.h b/Source/JavaScriptCore/qt/api/qscriptvalue.h new file mode 100644 index 0000000..bd33849 --- /dev/null +++ b/Source/JavaScriptCore/qt/api/qscriptvalue.h @@ -0,0 +1,140 @@ +/* + Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef qscriptvalue_h +#define qscriptvalue_h + +#include "qscriptstring.h" +#include <QtCore/qlist.h> +#include <QtCore/qshareddata.h> + +class QScriptEngine; +class QScriptValuePrivate; +class QDateTime; + +class QScriptValue; +typedef QList<QScriptValue> QScriptValueList; + +typedef double qsreal; + +class QScriptValue { +public: + enum ResolveFlag { + ResolveLocal = 0x00, + ResolvePrototype = 0x01, + ResolveScope = 0x02, + ResolveFull = ResolvePrototype | ResolveScope + }; + Q_DECLARE_FLAGS(ResolveFlags, ResolveFlag) + + enum PropertyFlag { + ReadOnly = 0x00000001, + Undeletable = 0x00000002, + SkipInEnumeration = 0x00000004, + PropertyGetter = 0x00000008, + PropertySetter = 0x00000010, + QObjectMember = 0x00000020, + KeepExistingFlags = 0x00000800, + UserRange = 0xff000000 // Users may use these as they see fit. + }; + Q_DECLARE_FLAGS(PropertyFlags, PropertyFlag) + + enum SpecialValue { + NullValue, + UndefinedValue + }; + + QScriptValue(); + QScriptValue(bool value); + QScriptValue(int value); + QScriptValue(uint value); + QScriptValue(qsreal value); + QScriptValue(const QString& value); + QScriptValue(const char* value); + QScriptValue(SpecialValue value); + QScriptValue(const QScriptValue& other); + + QScriptValue(QScriptEngine* engine, bool value); + QScriptValue(QScriptEngine* engine, int value); + QScriptValue(QScriptEngine* engine, uint value); + QScriptValue(QScriptEngine* engine, qsreal value); + QScriptValue(QScriptEngine* engine, const QString& value); + QScriptValue(QScriptEngine* engine, const char* value); + QScriptValue(QScriptEngine* engine, SpecialValue value); + + ~QScriptValue(); + + QScriptValue& operator=(const QScriptValue& other); + + QScriptValue prototype() const; + void setPrototype(const QScriptValue& prototype); + + bool equals(const QScriptValue& other) const; + bool strictlyEquals(const QScriptValue& other) const; + bool instanceOf(const QScriptValue& other) const; + + QScriptValue property(const QString& name, const ResolveFlags& mode = ResolvePrototype) const; + QScriptValue property(const QScriptString& name, const ResolveFlags& mode = ResolvePrototype) const; + QScriptValue property(quint32 arrayIndex, const ResolveFlags& mode = ResolvePrototype) const; + + void setProperty(const QString& name, const QScriptValue& value, const PropertyFlags& flags = KeepExistingFlags); + void setProperty(quint32 arrayIndex, const QScriptValue& value, const PropertyFlags& flags = KeepExistingFlags); + void setProperty(const QScriptString& name, const QScriptValue& value, const PropertyFlags& flags = KeepExistingFlags); + + PropertyFlags propertyFlags(const QString& name, const ResolveFlags& mode = ResolvePrototype) const; + PropertyFlags propertyFlags(const QScriptString& name, const ResolveFlags& mode = ResolvePrototype) const; + + QScriptEngine* engine() const; + + bool isValid() const; + bool isBool() const; + bool isBoolean() const; + bool isNumber() const; + bool isFunction() const; + bool isNull() const; + bool isString() const; + bool isUndefined() const; + bool isObject() const; + bool isError() const; + bool isArray() const; + bool isDate() const; + + QString toString() const; + qsreal toNumber() const; + bool toBool() const; + bool toBoolean() const; + qsreal toInteger() const; + qint32 toInt32() const; + quint32 toUInt32() const; + quint16 toUInt16() const; + QScriptValue toObject() const; + QDateTime toDateTime() const; + + QScriptValue call(const QScriptValue& thisObject = QScriptValue(), + const QScriptValueList& args = QScriptValueList()); +private: + QScriptValue(void*); + QScriptValue(QScriptValuePrivate*); + + QExplicitlySharedDataPointer<QScriptValuePrivate> d_ptr; + + friend class QScriptValuePrivate; +}; + +#endif // qscriptvalue_h diff --git a/Source/JavaScriptCore/qt/api/qscriptvalue_p.h b/Source/JavaScriptCore/qt/api/qscriptvalue_p.h new file mode 100644 index 0000000..f98a06a --- /dev/null +++ b/Source/JavaScriptCore/qt/api/qscriptvalue_p.h @@ -0,0 +1,1220 @@ +/* + Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef qscriptvalue_p_h +#define qscriptvalue_p_h + +#include "qscriptconverter_p.h" +#include "qscriptengine_p.h" +#include "qscriptvalue.h" +#include <JavaScriptCore/JavaScript.h> +#include <JavaScriptCore/JSRetainPtr.h> +#include <JSObjectRefPrivate.h> +#include <QtCore/qdatetime.h> +#include <QtCore/qmath.h> +#include <QtCore/qnumeric.h> +#include <QtCore/qshareddata.h> +#include <QtCore/qvarlengtharray.h> + +class QScriptEngine; +class QScriptValue; + +/* + \internal + \class QScriptValuePrivate + + Implementation of QScriptValue. + The implementation is based on a state machine. The states names are included in + QScriptValuePrivate::State. Each method should check for the current state and then perform a + correct action. + + State: + Invalid -> QSVP is invalid, no assumptions should be made about class members (apart from m_value). + CString -> QSVP is created from QString or const char* and no JSC engine has been associated yet. + Current value is kept in m_string, + CNumber -> QSVP is created from int, uint, double... and no JSC engine has been bind yet. Current + value is kept in m_number + CBool -> QSVP is created from bool and no JSC engine has been associated yet. Current value is kept + in m_bool + CNull -> QSVP is null, but a JSC engine hasn't been associated yet. + CUndefined -> QSVP is undefined, but a JSC engine hasn't been associated yet. + JSValue -> QSVP is associated with engine, but there is no information about real type, the state + have really short live cycle. Normally it is created as a function call result. + JSPrimitive -> QSVP is associated with engine, and it is sure that it isn't a JavaScript object. + JSObject -> QSVP is associated with engine, and it is sure that it is a JavaScript object. + + Each state keep all necessary information to invoke all methods, if not it should be changed to + a proper state. Changed state shouldn't be reverted. + + The QScriptValuePrivate use the JSC C API directly. The QSVP type is equal to combination of + the JSValueRef and the JSObjectRef, and it could be automatically casted to these types by cast + operators. +*/ + +class QScriptValuePrivate : public QSharedData { +public: + inline static QScriptValuePrivate* get(const QScriptValue& q); + inline static QScriptValue get(const QScriptValuePrivate* d); + inline static QScriptValue get(QScriptValuePrivate* d); + + inline ~QScriptValuePrivate(); + + inline QScriptValuePrivate(); + inline QScriptValuePrivate(const QString& string); + inline QScriptValuePrivate(bool value); + inline QScriptValuePrivate(int number); + inline QScriptValuePrivate(uint number); + inline QScriptValuePrivate(qsreal number); + inline QScriptValuePrivate(QScriptValue::SpecialValue value); + + inline QScriptValuePrivate(const QScriptEnginePrivate* engine, bool value); + inline QScriptValuePrivate(const QScriptEnginePrivate* engine, int value); + inline QScriptValuePrivate(const QScriptEnginePrivate* engine, uint value); + inline QScriptValuePrivate(const QScriptEnginePrivate* engine, qsreal value); + inline QScriptValuePrivate(const QScriptEnginePrivate* engine, const QString& value); + inline QScriptValuePrivate(const QScriptEnginePrivate* engine, QScriptValue::SpecialValue value); + + inline QScriptValuePrivate(const QScriptEnginePrivate* engine, JSValueRef value); + inline QScriptValuePrivate(const QScriptEnginePrivate* engine, JSObjectRef object); + + inline bool isValid() const; + inline bool isBool(); + inline bool isNumber(); + inline bool isNull(); + inline bool isString(); + inline bool isUndefined(); + inline bool isError(); + inline bool isObject(); + inline bool isFunction(); + inline bool isArray(); + inline bool isDate(); + + inline QString toString() const; + inline qsreal toNumber() const; + inline bool toBool() const; + inline qsreal toInteger() const; + inline qint32 toInt32() const; + inline quint32 toUInt32() const; + inline quint16 toUInt16() const; + + inline QScriptValuePrivate* toObject(QScriptEnginePrivate* engine); + inline QScriptValuePrivate* toObject(); + inline QDateTime toDateTime(); + inline QScriptValuePrivate* prototype(); + inline void setPrototype(QScriptValuePrivate* prototype); + + inline bool equals(QScriptValuePrivate* other); + inline bool strictlyEquals(QScriptValuePrivate* other); + inline bool instanceOf(QScriptValuePrivate* other); + inline bool assignEngine(QScriptEnginePrivate* engine); + + inline QScriptValuePrivate* property(const QString& name, const QScriptValue::ResolveFlags& mode); + inline QScriptValuePrivate* property(const QScriptStringPrivate* name, const QScriptValue::ResolveFlags& mode); + inline QScriptValuePrivate* property(quint32 arrayIndex, const QScriptValue::ResolveFlags& mode); + inline JSValueRef property(quint32 property, JSValueRef* exception); + inline JSValueRef property(JSStringRef property, JSValueRef* exception); + inline bool hasOwnProperty(quint32 property); + inline bool hasOwnProperty(JSStringRef property); + template<typename T> + inline QScriptValuePrivate* property(T name, const QScriptValue::ResolveFlags& mode); + + inline void setProperty(const QString& name, QScriptValuePrivate* value, const QScriptValue::PropertyFlags& flags); + inline void setProperty(const QScriptStringPrivate* name, QScriptValuePrivate* value, const QScriptValue::PropertyFlags& flags); + inline void setProperty(const quint32 indexArray, QScriptValuePrivate* value, const QScriptValue::PropertyFlags& flags); + inline void setProperty(quint32 property, JSValueRef value, JSPropertyAttributes flags, JSValueRef* exception); + inline void setProperty(JSStringRef property, JSValueRef value, JSPropertyAttributes flags, JSValueRef* exception); + inline void deleteProperty(quint32 property, JSValueRef* exception); + inline void deleteProperty(JSStringRef property, JSValueRef* exception); + template<typename T> + inline void setProperty(T name, QScriptValuePrivate* value, const QScriptValue::PropertyFlags& flags); + + QScriptValue::PropertyFlags propertyFlags(const QString& name, const QScriptValue::ResolveFlags& mode); + QScriptValue::PropertyFlags propertyFlags(const QScriptStringPrivate* name, const QScriptValue::ResolveFlags& mode); + QScriptValue::PropertyFlags propertyFlags(const JSStringRef name, const QScriptValue::ResolveFlags& mode); + + inline QScriptValuePrivate* call(const QScriptValuePrivate* , const QScriptValueList& args); + + inline operator JSValueRef() const; + inline operator JSObjectRef() const; + + inline QScriptEnginePrivate* engine() const; + +private: + // Please, update class documentation when you change the enum. + enum State { + Invalid = 0, + CString = 0x1000, + CNumber, + CBool, + CNull, + CUndefined, + JSValue = 0x2000, // JS values are equal or higher then this value. + JSPrimitive, + JSObject + } m_state; + QScriptEnginePtr m_engine; + union Value + { + bool m_bool; + qsreal m_number; + JSValueRef m_value; + JSObjectRef m_object; + QString* m_string; + + Value() : m_number(0) {} + Value(bool value) : m_bool(value) {} + Value(int number) : m_number(number) {} + Value(uint number) : m_number(number) {} + Value(qsreal number) : m_number(number) {} + Value(JSValueRef value) : m_value(value) {} + Value(JSObjectRef object) : m_object(object) {} + Value(QString* string) : m_string(string) {} + } u; + + inline State refinedJSValue(); + + inline bool isJSBased() const; + inline bool isNumberBased() const; + inline bool isStringBased() const; +}; + +QScriptValuePrivate* QScriptValuePrivate::get(const QScriptValue& q) { return q.d_ptr.data(); } + +QScriptValue QScriptValuePrivate::get(const QScriptValuePrivate* d) +{ + return QScriptValue(const_cast<QScriptValuePrivate*>(d)); +} + +QScriptValue QScriptValuePrivate::get(QScriptValuePrivate* d) +{ + return QScriptValue(d); +} + +QScriptValuePrivate::~QScriptValuePrivate() +{ + if (isJSBased()) + JSValueUnprotect(*m_engine, u.m_value); + else if (isStringBased()) + delete u.m_string; +} + +QScriptValuePrivate::QScriptValuePrivate() + : m_state(Invalid) +{ +} + +QScriptValuePrivate::QScriptValuePrivate(const QString& string) + : m_state(CString) + , u(new QString(string)) +{ +} + +QScriptValuePrivate::QScriptValuePrivate(bool value) + : m_state(CBool) + , u(value) +{ +} + +QScriptValuePrivate::QScriptValuePrivate(int number) + : m_state(CNumber) + , u(number) +{ +} + +QScriptValuePrivate::QScriptValuePrivate(uint number) + : m_state(CNumber) + , u(number) +{ +} + +QScriptValuePrivate::QScriptValuePrivate(qsreal number) + : m_state(CNumber) + , u(number) +{ +} + +QScriptValuePrivate::QScriptValuePrivate(QScriptValue::SpecialValue value) + : m_state(value == QScriptValue::NullValue ? CNull : CUndefined) +{ +} + +QScriptValuePrivate::QScriptValuePrivate(const QScriptEnginePrivate* engine, bool value) + : m_state(JSPrimitive) + , m_engine(const_cast<QScriptEnginePrivate*>(engine)) + , u(engine->makeJSValue(value)) +{ + Q_ASSERT(engine); + JSValueProtect(*m_engine, u.m_value); +} + +QScriptValuePrivate::QScriptValuePrivate(const QScriptEnginePrivate* engine, int value) + : m_state(JSPrimitive) + , m_engine(const_cast<QScriptEnginePrivate*>(engine)) + , u(m_engine->makeJSValue(value)) +{ + Q_ASSERT(engine); + JSValueProtect(*m_engine, u.m_value); +} + +QScriptValuePrivate::QScriptValuePrivate(const QScriptEnginePrivate* engine, uint value) + : m_state(JSPrimitive) + , m_engine(const_cast<QScriptEnginePrivate*>(engine)) + , u(m_engine->makeJSValue(value)) +{ + Q_ASSERT(engine); + JSValueProtect(*m_engine, u.m_value); +} + +QScriptValuePrivate::QScriptValuePrivate(const QScriptEnginePrivate* engine, qsreal value) + : m_state(JSPrimitive) + , m_engine(const_cast<QScriptEnginePrivate*>(engine)) + , u(m_engine->makeJSValue(value)) +{ + Q_ASSERT(engine); + JSValueProtect(*m_engine, u.m_value); +} + +QScriptValuePrivate::QScriptValuePrivate(const QScriptEnginePrivate* engine, const QString& value) + : m_state(JSPrimitive) + , m_engine(const_cast<QScriptEnginePrivate*>(engine)) + , u(m_engine->makeJSValue(value)) +{ + Q_ASSERT(engine); + JSValueProtect(*m_engine, u.m_value); +} + +QScriptValuePrivate::QScriptValuePrivate(const QScriptEnginePrivate* engine, QScriptValue::SpecialValue value) + : m_state(JSPrimitive) + , m_engine(const_cast<QScriptEnginePrivate*>(engine)) + , u(m_engine->makeJSValue(value)) +{ + Q_ASSERT(engine); + JSValueProtect(*m_engine, u.m_value); +} + +QScriptValuePrivate::QScriptValuePrivate(const QScriptEnginePrivate* engine, JSValueRef value) + : m_state(JSValue) + , m_engine(const_cast<QScriptEnginePrivate*>(engine)) + , u(value) +{ + Q_ASSERT(engine); + Q_ASSERT(value); + JSValueProtect(*m_engine, u.m_value); +} + +QScriptValuePrivate::QScriptValuePrivate(const QScriptEnginePrivate* engine, JSObjectRef object) + : m_state(JSObject) + , m_engine(const_cast<QScriptEnginePrivate*>(engine)) + , u(object) +{ + Q_ASSERT(engine); + Q_ASSERT(object); + JSValueProtect(*m_engine, object); +} + +bool QScriptValuePrivate::isValid() const { return m_state != Invalid; } + +bool QScriptValuePrivate::isBool() +{ + switch (m_state) { + case CBool: + return true; + case JSValue: + if (refinedJSValue() != JSPrimitive) + return false; + // Fall-through. + case JSPrimitive: + return JSValueIsBoolean(*m_engine, *this); + default: + return false; + } +} + +bool QScriptValuePrivate::isNumber() +{ + switch (m_state) { + case CNumber: + return true; + case JSValue: + if (refinedJSValue() != JSPrimitive) + return false; + // Fall-through. + case JSPrimitive: + return JSValueIsNumber(*m_engine, *this); + default: + return false; + } +} + +bool QScriptValuePrivate::isNull() +{ + switch (m_state) { + case CNull: + return true; + case JSValue: + if (refinedJSValue() != JSPrimitive) + return false; + // Fall-through. + case JSPrimitive: + return JSValueIsNull(*m_engine, *this); + default: + return false; + } +} + +bool QScriptValuePrivate::isString() +{ + switch (m_state) { + case CString: + return true; + case JSValue: + if (refinedJSValue() != JSPrimitive) + return false; + // Fall-through. + case JSPrimitive: + return JSValueIsString(*m_engine, *this); + default: + return false; + } +} + +bool QScriptValuePrivate::isUndefined() +{ + switch (m_state) { + case CUndefined: + return true; + case JSValue: + if (refinedJSValue() != JSPrimitive) + return false; + // Fall-through. + case JSPrimitive: + return JSValueIsUndefined(*m_engine, *this); + default: + return false; + } +} + +bool QScriptValuePrivate::isError() +{ + switch (m_state) { + case JSValue: + if (refinedJSValue() != JSObject) + return false; + // Fall-through. + case JSObject: + return m_engine->isError(*this); + default: + return false; + } +} + +bool QScriptValuePrivate::isObject() +{ + switch (m_state) { + case JSValue: + return refinedJSValue() == JSObject; + case JSObject: + return true; + + default: + return false; + } +} + +bool QScriptValuePrivate::isFunction() +{ + switch (m_state) { + case JSValue: + if (refinedJSValue() != JSObject) + return false; + // Fall-through. + case JSObject: + return JSObjectIsFunction(*m_engine, *this); + default: + return false; + } +} + +bool QScriptValuePrivate::isArray() +{ + switch (m_state) { + case JSValue: + if (refinedJSValue() != JSObject) + return false; + // Fall-through. + case JSObject: + return m_engine->isArray(*this); + default: + return false; + } +} + +bool QScriptValuePrivate::isDate() +{ + switch (m_state) { + case JSValue: + if (refinedJSValue() != JSObject) + return false; + // Fall-through. + case JSObject: + return m_engine->isDate(*this); + default: + return false; + } +} + +QString QScriptValuePrivate::toString() const +{ + switch (m_state) { + case Invalid: + return QString(); + case CBool: + return u.m_bool ? QString::fromLatin1("true") : QString::fromLatin1("false"); + case CString: + return *u.m_string; + case CNumber: + return QScriptConverter::toString(u.m_number); + case CNull: + return QString::fromLatin1("null"); + case CUndefined: + return QString::fromLatin1("undefined"); + case JSValue: + case JSPrimitive: + case JSObject: + JSValueRef exception = 0; + JSRetainPtr<JSStringRef> ptr(Adopt, JSValueToStringCopy(*m_engine, *this, &exception)); + m_engine->setException(exception); + return QScriptConverter::toString(ptr.get()); + } + + Q_ASSERT_X(false, "toString()", "Not all states are included in the previous switch statement."); + return QString(); // Avoid compiler warning. +} + +qsreal QScriptValuePrivate::toNumber() const +{ + switch (m_state) { + case JSValue: + case JSPrimitive: + case JSObject: + { + JSValueRef exception = 0; + qsreal result = JSValueToNumber(*m_engine, *this, &exception); + m_engine->setException(exception); + return result; + } + case CNumber: + return u.m_number; + case CBool: + return u.m_bool ? 1 : 0; + case CNull: + case Invalid: + return 0; + case CUndefined: + return qQNaN(); + case CString: + bool ok; + qsreal result = u.m_string->toDouble(&ok); + if (ok) + return result; + result = u.m_string->toInt(&ok, 0); // Try other bases. + if (ok) + return result; + if (*u.m_string == "Infinity" || *u.m_string == "-Infinity") + return qInf(); + return u.m_string->length() ? qQNaN() : 0; + } + + Q_ASSERT_X(false, "toNumber()", "Not all states are included in the previous switch statement."); + return 0; // Avoid compiler warning. +} + +bool QScriptValuePrivate::toBool() const +{ + switch (m_state) { + case JSValue: + case JSPrimitive: + return JSValueToBoolean(*m_engine, *this); + case JSObject: + return true; + case CNumber: + return !(qIsNaN(u.m_number) || !u.m_number); + case CBool: + return u.m_bool; + case Invalid: + case CNull: + case CUndefined: + return false; + case CString: + return u.m_string->length(); + } + + Q_ASSERT_X(false, "toBool()", "Not all states are included in the previous switch statement."); + return false; // Avoid compiler warning. +} + +qsreal QScriptValuePrivate::toInteger() const +{ + qsreal result = toNumber(); + if (qIsNaN(result)) + return 0; + if (qIsInf(result)) + return result; + return (result > 0) ? qFloor(result) : -1 * qFloor(-result); +} + +qint32 QScriptValuePrivate::toInt32() const +{ + qsreal result = toInteger(); + // Orginaly it should look like that (result == 0 || qIsInf(result) || qIsNaN(result)), but + // some of these operation are invoked in toInteger subcall. + if (qIsInf(result)) + return 0; + return result; +} + +quint32 QScriptValuePrivate::toUInt32() const +{ + qsreal result = toInteger(); + // Orginaly it should look like that (result == 0 || qIsInf(result) || qIsNaN(result)), but + // some of these operation are invoked in toInteger subcall. + if (qIsInf(result)) + return 0; + return result; +} + +quint16 QScriptValuePrivate::toUInt16() const +{ + return toInt32(); +} + +/*! + Creates a copy of this value and converts it to an object. If this value is an object + then pointer to this value will be returned. + \attention it should not happen but if this value is bounded to a different engine that the given, the first + one will be used. + \internal + */ +QScriptValuePrivate* QScriptValuePrivate::toObject(QScriptEnginePrivate* engine) +{ + switch (m_state) { + case Invalid: + case CNull: + case CUndefined: + return new QScriptValuePrivate; + case CString: + { + // Exception can't occur here. + JSObjectRef object = JSValueToObject(*engine, engine->makeJSValue(*u.m_string), /* exception */ 0); + Q_ASSERT(object); + return new QScriptValuePrivate(engine, object); + } + case CNumber: + { + // Exception can't occur here. + JSObjectRef object = JSValueToObject(*engine, engine->makeJSValue(u.m_number), /* exception */ 0); + Q_ASSERT(object); + return new QScriptValuePrivate(engine, object); + } + case CBool: + { + // Exception can't occure here. + JSObjectRef object = JSValueToObject(*engine, engine->makeJSValue(u.m_bool), /* exception */ 0); + Q_ASSERT(object); + return new QScriptValuePrivate(engine, object); + } + case JSValue: + if (refinedJSValue() != JSPrimitive) + break; + // Fall-through. + case JSPrimitive: + { + if (engine != this->engine()) + qWarning("QScriptEngine::toObject: cannot convert value created in a different engine"); + JSValueRef exception = 0; + JSObjectRef object = JSValueToObject(*m_engine, *this, &exception); + if (object) + return new QScriptValuePrivate(m_engine.constData(), object); + else + m_engine->setException(exception, QScriptEnginePrivate::NotNullException); + + } + return new QScriptValuePrivate; + case JSObject: + break; + } + + if (engine != this->engine()) + qWarning("QScriptEngine::toObject: cannot convert value created in a different engine"); + Q_ASSERT(m_state == JSObject); + return this; +} + +/*! + This method is created only for QScriptValue::toObject() purpose which is obsolete. + \internal + */ +QScriptValuePrivate* QScriptValuePrivate::toObject() +{ + if (isJSBased()) + return toObject(m_engine.data()); + + // Without an engine there is not much we can do. + return new QScriptValuePrivate; +} + +QDateTime QScriptValuePrivate::toDateTime() +{ + if (!isDate()) + return QDateTime(); + + JSValueRef exception = 0; + qsreal t = JSValueToNumber(*m_engine, *this, &exception); + + if (exception) { + m_engine->setException(exception, QScriptEnginePrivate::NotNullException); + return QDateTime(); + } + + QDateTime result; + result.setMSecsSinceEpoch(qint64(t)); + return result; +} + +inline QScriptValuePrivate* QScriptValuePrivate::prototype() +{ + if (isObject()) { + JSValueRef prototype = JSObjectGetPrototype(*m_engine, *this); + if (JSValueIsNull(*m_engine, prototype)) + return new QScriptValuePrivate(engine(), prototype); + // The prototype could be either a null or a JSObject, so it is safe to cast the prototype + // to the JSObjectRef here. + return new QScriptValuePrivate(engine(), const_cast<JSObjectRef>(prototype)); + } + return new QScriptValuePrivate; +} + +inline void QScriptValuePrivate::setPrototype(QScriptValuePrivate* prototype) +{ + if (isObject() && prototype->isValid() && (prototype->isObject() || prototype->isNull())) { + if (engine() != prototype->engine()) { + qWarning("QScriptValue::setPrototype() failed: cannot set a prototype created in a different engine"); + return; + } + // FIXME: This could be replaced by a new, faster API + // look at https://bugs.webkit.org/show_bug.cgi?id=40060 + JSObjectSetPrototype(*m_engine, *this, *prototype); + JSValueRef proto = JSObjectGetPrototype(*m_engine, *this); + if (!JSValueIsStrictEqual(*m_engine, proto, *prototype)) + qWarning("QScriptValue::setPrototype() failed: cyclic prototype value"); + } +} + +bool QScriptValuePrivate::equals(QScriptValuePrivate* other) +{ + if (!isValid()) + return !other->isValid(); + + if (!other->isValid()) + return false; + + if (!isJSBased() && !other->isJSBased()) { + switch (m_state) { + case CNull: + case CUndefined: + return other->isUndefined() || other->isNull(); + case CNumber: + switch (other->m_state) { + case CBool: + case CString: + return u.m_number == other->toNumber(); + case CNumber: + return u.m_number == other->u.m_number; + default: + return false; + } + case CBool: + switch (other->m_state) { + case CBool: + return u.m_bool == other->u.m_bool; + case CNumber: + return toNumber() == other->u.m_number; + case CString: + return toNumber() == other->toNumber(); + default: + return false; + } + case CString: + switch (other->m_state) { + case CBool: + return toNumber() == other->toNumber(); + case CNumber: + return toNumber() == other->u.m_number; + case CString: + return *u.m_string == *other->u.m_string; + default: + return false; + } + default: + Q_ASSERT_X(false, "equals()", "Not all states are included in the previous switch statement."); + } + } + + if (isJSBased() && !other->isJSBased()) { + if (!other->assignEngine(engine())) { + qWarning("equals(): Cannot compare to a value created in a different engine"); + return false; + } + } else if (!isJSBased() && other->isJSBased()) { + if (!assignEngine(other->engine())) { + qWarning("equals(): Cannot compare to a value created in a different engine"); + return false; + } + } + + JSValueRef exception = 0; + bool result = JSValueIsEqual(*m_engine, *this, *other, &exception); + m_engine->setException(exception); + return result; +} + +bool QScriptValuePrivate::strictlyEquals(QScriptValuePrivate* other) +{ + if (isJSBased()) { + // We can't compare these two values without binding to the same engine. + if (!other->isJSBased()) { + if (other->assignEngine(engine())) + return JSValueIsStrictEqual(*m_engine, *this, *other); + return false; + } + if (other->engine() != engine()) { + qWarning("strictlyEquals(): Cannot compare to a value created in a different engine"); + return false; + } + return JSValueIsStrictEqual(*m_engine, *this, *other); + } + if (isStringBased()) { + if (other->isStringBased()) + return *u.m_string == *(other->u.m_string); + if (other->isJSBased()) { + assignEngine(other->engine()); + return JSValueIsStrictEqual(*m_engine, *this, *other); + } + } + if (isNumberBased()) { + if (other->isNumberBased()) + return u.m_number == other->u.m_number; + if (other->isJSBased()) { + assignEngine(other->engine()); + return JSValueIsStrictEqual(*m_engine, *this, *other); + } + } + if (!isValid() && !other->isValid()) + return true; + + return false; +} + +inline bool QScriptValuePrivate::instanceOf(QScriptValuePrivate* other) +{ + if (!isJSBased() || !other->isObject()) + return false; + JSValueRef exception = 0; + bool result = JSValueIsInstanceOfConstructor(*m_engine, *this, *other, &exception); + m_engine->setException(exception); + return result; +} + +/*! + Tries to assign \a engine to this value. Returns true on success; otherwise returns false. +*/ +bool QScriptValuePrivate::assignEngine(QScriptEnginePrivate* engine) +{ + Q_ASSERT(engine); + JSValueRef value; + switch (m_state) { + case CBool: + value = engine->makeJSValue(u.m_bool); + break; + case CString: + value = engine->makeJSValue(*u.m_string); + delete u.m_string; + break; + case CNumber: + value = engine->makeJSValue(u.m_number); + break; + case CNull: + value = engine->makeJSValue(QScriptValue::NullValue); + break; + case CUndefined: + value = engine->makeJSValue(QScriptValue::UndefinedValue); + break; + default: + if (!isJSBased()) + Q_ASSERT_X(!isJSBased(), "assignEngine()", "Not all states are included in the previous switch statement."); + else + qWarning("JSValue can't be rassigned to an another engine."); + return false; + } + m_engine = engine; + m_state = JSPrimitive; + u.m_value = value; + JSValueProtect(*m_engine, value); + return true; +} + +inline QScriptValuePrivate* QScriptValuePrivate::property(const QString& name, const QScriptValue::ResolveFlags& mode) +{ + JSRetainPtr<JSStringRef> propertyName(Adopt, QScriptConverter::toString(name)); + return property<JSStringRef>(propertyName.get(), mode); +} + +inline QScriptValuePrivate* QScriptValuePrivate::property(const QScriptStringPrivate* name, const QScriptValue::ResolveFlags& mode) +{ + return property<JSStringRef>(*name, mode); +} + +inline QScriptValuePrivate* QScriptValuePrivate::property(quint32 arrayIndex, const QScriptValue::ResolveFlags& mode) +{ + return property<quint32>(arrayIndex, mode); +} + +/*! + \internal + This method was created to unify access to the JSObjectGetPropertyAtIndex and the JSObjectGetProperty. +*/ +inline JSValueRef QScriptValuePrivate::property(quint32 property, JSValueRef* exception) +{ + return JSObjectGetPropertyAtIndex(*m_engine, *this, property, exception); +} + +/*! + \internal + This method was created to unify access to the JSObjectGetPropertyAtIndex and the JSObjectGetProperty. +*/ +inline JSValueRef QScriptValuePrivate::property(JSStringRef property, JSValueRef* exception) +{ + return JSObjectGetProperty(*m_engine, *this, property, exception); +} + +/*! + \internal + This method was created to unify acccess to hasOwnProperty, same function for an array index + and a property name access. +*/ +inline bool QScriptValuePrivate::hasOwnProperty(quint32 property) +{ + Q_ASSERT(isObject()); + // FIXME it could be faster, but JSC C API doesn't expose needed functionality. + JSRetainPtr<JSStringRef> propertyName(Adopt, QScriptConverter::toString(QString::number(property))); + return hasOwnProperty(propertyName.get()); +} + +/*! + \internal + This method was created to unify acccess to hasOwnProperty, same function for an array index + and a property name access. +*/ +inline bool QScriptValuePrivate::hasOwnProperty(JSStringRef property) +{ + Q_ASSERT(isObject()); + return m_engine->objectHasOwnProperty(*this, property); +} + +/*! + \internal + This function gets property of an object. + \arg propertyName could be type of quint32 (an array index) or JSStringRef (a property name). +*/ +template<typename T> +inline QScriptValuePrivate* QScriptValuePrivate::property(T propertyName, const QScriptValue::ResolveFlags& mode) +{ + if (!isObject()) + return new QScriptValuePrivate(); + + if ((mode == QScriptValue::ResolveLocal) && (!hasOwnProperty(propertyName))) + return new QScriptValuePrivate(); + + JSValueRef exception = 0; + JSValueRef value = property(propertyName, &exception); + + if (exception) { + m_engine->setException(exception, QScriptEnginePrivate::NotNullException); + return new QScriptValuePrivate(engine(), exception); + } + if (JSValueIsUndefined(*m_engine, value)) + return new QScriptValuePrivate; + return new QScriptValuePrivate(engine(), value); +} + +inline void QScriptValuePrivate::setProperty(const QString& name, QScriptValuePrivate* value, const QScriptValue::PropertyFlags& flags) +{ + JSRetainPtr<JSStringRef> propertyName(Adopt, QScriptConverter::toString(name)); + setProperty<JSStringRef>(propertyName.get(), value, flags); +} + +inline void QScriptValuePrivate::setProperty(quint32 arrayIndex, QScriptValuePrivate* value, const QScriptValue::PropertyFlags& flags) +{ + setProperty<quint32>(arrayIndex, value, flags); +} + +inline void QScriptValuePrivate::setProperty(const QScriptStringPrivate* name, QScriptValuePrivate* value, const QScriptValue::PropertyFlags& flags) +{ + setProperty<JSStringRef>(*name, value, flags); +} + +/*! + \internal + This method was created to unify access to the JSObjectSetPropertyAtIndex and the JSObjectSetProperty. +*/ +inline void QScriptValuePrivate::setProperty(quint32 property, JSValueRef value, JSPropertyAttributes flags, JSValueRef* exception) +{ + Q_ASSERT(isObject()); + if (flags) { + // FIXME This could be better, but JSC C API doesn't expose needed functionality. It is + // not possible to create / modify a property attribute via an array index. + JSRetainPtr<JSStringRef> propertyName(Adopt, QScriptConverter::toString(QString::number(property))); + JSObjectSetProperty(*m_engine, *this, propertyName.get(), value, flags, exception); + return; + } + JSObjectSetPropertyAtIndex(*m_engine, *this, property, value, exception); +} + +/*! + \internal + This method was created to unify access to the JSObjectSetPropertyAtIndex and the JSObjectSetProperty. +*/ +inline void QScriptValuePrivate::setProperty(JSStringRef property, JSValueRef value, JSPropertyAttributes flags, JSValueRef* exception) +{ + Q_ASSERT(isObject()); + JSObjectSetProperty(*m_engine, *this, property, value, flags, exception); +} + +/*! + \internal + This method was created to unify access to the JSObjectDeleteProperty and a teoretical JSObjectDeletePropertyAtIndex + which doesn't exist now. +*/ +inline void QScriptValuePrivate::deleteProperty(quint32 property, JSValueRef* exception) +{ + // FIXME It could be faster, we need a JSC C API for deleting array index properties. + JSRetainPtr<JSStringRef> propertyName(Adopt, QScriptConverter::toString(QString::number(property))); + JSObjectDeleteProperty(*m_engine, *this, propertyName.get(), exception); +} + +/*! + \internal + This method was created to unify access to the JSObjectDeleteProperty and a teoretical JSObjectDeletePropertyAtIndex. +*/ +inline void QScriptValuePrivate::deleteProperty(JSStringRef property, JSValueRef* exception) +{ + Q_ASSERT(isObject()); + JSObjectDeleteProperty(*m_engine, *this, property, exception); +} + +template<typename T> +inline void QScriptValuePrivate::setProperty(T name, QScriptValuePrivate* value, const QScriptValue::PropertyFlags& flags) +{ + if (!isObject()) + return; + + if (!value->isJSBased()) + value->assignEngine(engine()); + + JSValueRef exception = 0; + if (!value->isValid()) { + // Remove the property. + deleteProperty(name, &exception); + m_engine->setException(exception); + return; + } + if (m_engine != value->m_engine) { + qWarning("QScriptValue::setProperty() failed: cannot set value created in a different engine"); + return; + } + + setProperty(name, *value, QScriptConverter::toPropertyFlags(flags), &exception); + m_engine->setException(exception); +} + +inline QScriptValue::PropertyFlags QScriptValuePrivate::propertyFlags(const QString& name, const QScriptValue::ResolveFlags& mode) +{ + JSRetainPtr<JSStringRef> propertyName(Adopt, QScriptConverter::toString(name)); + return propertyFlags(propertyName.get(), mode); +} + +inline QScriptValue::PropertyFlags QScriptValuePrivate::propertyFlags(const QScriptStringPrivate* name, const QScriptValue::ResolveFlags& mode) +{ + return propertyFlags(*name, mode); +} + +inline QScriptValue::PropertyFlags QScriptValuePrivate::propertyFlags(JSStringRef name, const QScriptValue::ResolveFlags& mode) +{ + unsigned flags = 0; + if (!isObject()) + return QScriptValue::PropertyFlags(flags); + + // FIXME It could be faster and nicer, but new JSC C API should be created. + static JSStringRef objectName = QScriptConverter::toString("Object"); + static JSStringRef propertyDescriptorName = QScriptConverter::toString("getOwnPropertyDescriptor"); + + // FIXME This is dangerous if global object was modified (bug 41839). + JSValueRef exception = 0; + JSObjectRef globalObject = JSContextGetGlobalObject(*m_engine); + JSValueRef objectConstructor = JSObjectGetProperty(*m_engine, globalObject, objectName, &exception); + Q_ASSERT(JSValueIsObject(*m_engine, objectConstructor)); + JSValueRef propertyDescriptorGetter = JSObjectGetProperty(*m_engine, const_cast<JSObjectRef>(objectConstructor), propertyDescriptorName, &exception); + Q_ASSERT(JSValueIsObject(*m_engine, propertyDescriptorGetter)); + + JSValueRef arguments[] = { *this, JSValueMakeString(*m_engine, name) }; + JSObjectRef propertyDescriptor + = const_cast<JSObjectRef>(JSObjectCallAsFunction(*m_engine, + const_cast<JSObjectRef>(propertyDescriptorGetter), + /* thisObject */ 0, + /* argumentCount */ 2, + arguments, + &exception)); + if (exception) { + // Invalid property. + return QScriptValue::PropertyFlags(flags); + } + + if (!JSValueIsObject(*m_engine, propertyDescriptor)) { + // Property isn't owned by this object. + JSObjectRef proto; + if (mode == QScriptValue::ResolveLocal + || ((proto = const_cast<JSObjectRef>(JSObjectGetPrototype(*m_engine, *this))) && JSValueIsNull(*m_engine, proto))) { + return QScriptValue::PropertyFlags(flags); + } + QScriptValuePrivate p(engine(), proto); + return p.propertyFlags(name, QScriptValue::ResolvePrototype); + } + + static JSStringRef writableName = QScriptConverter::toString("writable"); + static JSStringRef configurableName = QScriptConverter::toString("configurable"); + static JSStringRef enumerableName = QScriptConverter::toString("enumerable"); + + bool readOnly = !JSValueToBoolean(*m_engine, JSObjectGetProperty(*m_engine, propertyDescriptor, writableName, &exception)); + if (!exception && readOnly) + flags |= QScriptValue::ReadOnly; + bool undeletable = !JSValueToBoolean(*m_engine, JSObjectGetProperty(*m_engine, propertyDescriptor, configurableName, &exception)); + if (!exception && undeletable) + flags |= QScriptValue::Undeletable; + bool skipInEnum = !JSValueToBoolean(*m_engine, JSObjectGetProperty(*m_engine, propertyDescriptor, enumerableName, &exception)); + if (!exception && skipInEnum) + flags |= QScriptValue::SkipInEnumeration; + + return QScriptValue::PropertyFlags(flags); +} + +QScriptValuePrivate* QScriptValuePrivate::call(const QScriptValuePrivate*, const QScriptValueList& args) +{ + switch (m_state) { + case JSValue: + if (refinedJSValue() != JSObject) + return new QScriptValuePrivate; + // Fall-through. + case JSObject: + { + // Convert all arguments and bind to the engine. + int argc = args.size(); + QVarLengthArray<JSValueRef, 8> argv(argc); + QScriptValueList::const_iterator i = args.constBegin(); + for (int j = 0; i != args.constEnd(); j++, i++) { + QScriptValuePrivate* value = QScriptValuePrivate::get(*i); + if (!value->assignEngine(engine())) { + qWarning("QScriptValue::call() failed: cannot call function with values created in a different engine"); + return new QScriptValuePrivate; + } + argv[j] = *value; + } + + // Make the call + JSValueRef exception = 0; + JSValueRef result = JSObjectCallAsFunction(*m_engine, *this, /* thisObject */ 0, argc, argv.constData(), &exception); + if (!result && exception) { + m_engine->setException(exception); + return new QScriptValuePrivate(engine(), exception); + } + if (result && !exception) + return new QScriptValuePrivate(engine(), result); + } + // this QSV is not a function <-- !result && !exception. Fall-through. + default: + return new QScriptValuePrivate; + } +} + +QScriptEnginePrivate* QScriptValuePrivate::engine() const +{ + // As long as m_engine is an autoinitializated pointer we can safely return it without + // checking current state. + return m_engine.data(); +} + +QScriptValuePrivate::operator JSValueRef() const +{ + Q_ASSERT(isJSBased()); + Q_ASSERT(u.m_value); + return u.m_value; +} + +QScriptValuePrivate::operator JSObjectRef() const +{ + Q_ASSERT(m_state == JSObject); + Q_ASSERT(u.m_object); + return u.m_object; +} + +/*! + \internal + Refines the state of this QScriptValuePrivate. Returns the new state. +*/ +QScriptValuePrivate::State QScriptValuePrivate::refinedJSValue() +{ + Q_ASSERT(m_state == JSValue); + if (!JSValueIsObject(*m_engine, *this)) { + m_state = JSPrimitive; + } else { + // Difference between JSValueRef and JSObjectRef is only in their type, binarywise it is the same. + // As m_value and m_object are stored in the u union, it is enough to change the m_state only. + m_state = JSObject; + } + return m_state; +} + +/*! + \internal + Returns true if QSV have an engine associated. +*/ +bool QScriptValuePrivate::isJSBased() const { return m_state >= JSValue; } + +/*! + \internal + Returns true if current value of QSV is placed in m_number. +*/ +bool QScriptValuePrivate::isNumberBased() const { return m_state == CNumber || m_state == CBool; } + +/*! + \internal + Returns true if current value of QSV is placed in m_string. +*/ +bool QScriptValuePrivate::isStringBased() const { return m_state == CString; } + +#endif // qscriptvalue_p_h diff --git a/Source/JavaScriptCore/qt/api/qscriptvalueiterator.cpp b/Source/JavaScriptCore/qt/api/qscriptvalueiterator.cpp new file mode 100644 index 0000000..f1caa61 --- /dev/null +++ b/Source/JavaScriptCore/qt/api/qscriptvalueiterator.cpp @@ -0,0 +1,226 @@ +/* + Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" + +#include "qscriptvalueiterator.h" + +#include "qscriptvalue_p.h" +#include "qscriptvalueiterator_p.h" + +/*! + \class QScriptValueIterator + + \brief The QScriptValueIterator class provides a Java-style iterator for QScriptValue. + + \ingroup script + + + The QScriptValueIterator constructor takes a QScriptValue as + argument. After construction, the iterator is located at the very + beginning of the sequence of properties. Here's how to iterate over + all the properties of a QScriptValue: + + \snippet doc/src/snippets/code/src_script_qscriptvalueiterator.cpp 0 + + The next() advances the iterator. The name(), value() and flags() + functions return the name, value and flags of the last item that was + jumped over. + + If you want to remove properties as you iterate over the + QScriptValue, use remove(). If you want to modify the value of a + property, use setValue(). + + Note that QScriptValueIterator only iterates over the QScriptValue's + own properties; i.e. it does not follow the prototype chain. You can + use a loop like this to follow the prototype chain: + + \snippet doc/src/snippets/code/src_script_qscriptvalueiterator.cpp 1 + + Note that QScriptValueIterator will not automatically skip over + properties that have the QScriptValue::SkipInEnumeration flag set; + that flag only affects iteration in script code. If you want, you + can skip over such properties with code like the following: + + \snippet doc/src/snippets/code/src_script_qscriptvalueiterator.cpp 2 + + \sa QScriptValue::property() +*/ + +/*! + Constructs an iterator for traversing \a object. The iterator is + set to be at the front of the sequence of properties (before the + first property). +*/ +QScriptValueIterator::QScriptValueIterator(const QScriptValue& object) + : d_ptr(new QScriptValueIteratorPrivate(QScriptValuePrivate::get(object))) +{} + +/*! + Destroys the iterator. +*/ +QScriptValueIterator::~QScriptValueIterator() +{} + +/*! + Returns true if there is at least one item ahead of the iterator + (i.e. the iterator is \e not at the back of the property sequence); + otherwise returns false. + + \sa next(), hasPrevious() +*/ +bool QScriptValueIterator::hasNext() const +{ + return d_ptr->hasNext(); +} + +/*! + Advances the iterator by one position. + + Calling this function on an iterator located at the back of the + container leads to undefined results. + + \sa hasNext(), previous(), name() +*/ +void QScriptValueIterator::next() +{ + d_ptr->next(); +} + +/*! + Returns true if there is at least one item behind the iterator + (i.e. the iterator is \e not at the front of the property sequence); + otherwise returns false. + + \sa previous(), hasNext() +*/ +bool QScriptValueIterator::hasPrevious() const +{ + return d_ptr->hasPrevious(); +} + +/*! + Moves the iterator back by one position. + + Calling this function on an iterator located at the front of the + container leads to undefined results. + + \sa hasPrevious(), next(), name() +*/ +void QScriptValueIterator::previous() +{ + d_ptr->previous(); +} + +/*! + Moves the iterator to the front of the QScriptValue (before the + first property). + + \sa toBack(), next() +*/ +void QScriptValueIterator::toFront() +{ + d_ptr->toFront(); +} + +/*! + Moves the iterator to the back of the QScriptValue (after the + last property). + + \sa toFront(), previous() +*/ +void QScriptValueIterator::toBack() +{ + d_ptr->toBack(); +} + +/*! + Returns the name of the last property that was jumped over using + next() or previous(). + + \sa value(), flags() +*/ +QString QScriptValueIterator::name() const +{ + return d_ptr->name(); +} + +/*! + Returns the name of the last property that was jumped over using + next() or previous(). +*/ +QScriptString QScriptValueIterator::scriptName() const +{ + return QScriptStringPrivate::get(d_ptr->scriptName()); +} + +/*! + Returns the value of the last property that was jumped over using + next() or previous(). + + \sa setValue(), name() +*/ +QScriptValue QScriptValueIterator::value() const +{ + return QScriptValuePrivate::get(d_ptr->value()); +} + +/*! + Sets the \a value of the last property that was jumped over using + next() or previous(). + + \sa value(), name() +*/ +void QScriptValueIterator::setValue(const QScriptValue& value) +{ + d_ptr->setValue(QScriptValuePrivate::get(value)); +} + +/*! + Removes the last property that was jumped over using next() + or previous(). + + \sa setValue() +*/ +void QScriptValueIterator::remove() +{ + d_ptr->remove(); +} + +/*! + Returns the flags of the last property that was jumped over using + next() or previous(). + + \sa value() +*/ +QScriptValue::PropertyFlags QScriptValueIterator::flags() const +{ + return d_ptr->flags(); +} + +/*! + Makes the iterator operate on \a object. The iterator is set to be + at the front of the sequence of properties (before the first + property). +*/ +QScriptValueIterator& QScriptValueIterator::operator=(QScriptValue& object) +{ + d_ptr = new QScriptValueIteratorPrivate(QScriptValuePrivate::get(object)); + return *this; +} diff --git a/Source/JavaScriptCore/qt/api/qscriptvalueiterator.h b/Source/JavaScriptCore/qt/api/qscriptvalueiterator.h new file mode 100644 index 0000000..0c90661 --- /dev/null +++ b/Source/JavaScriptCore/qt/api/qscriptvalueiterator.h @@ -0,0 +1,63 @@ +/* + Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef qscriptvalueiterator_h +#define qscriptvalueiterator_h + +#include "qtscriptglobal.h" +#include "qscriptstring.h" +#include <QtCore/qshareddata.h> +#include "qscriptvalue.h" + +class QScriptValue; +class QScriptValueIteratorPrivate; + + +class Q_JAVASCRIPT_EXPORT QScriptValueIterator { +public: + QScriptValueIterator(const QScriptValue& value); + ~QScriptValueIterator(); + + bool hasNext() const; + void next(); + + bool hasPrevious() const; + void previous(); + + QString name() const; + QScriptString scriptName() const; + + QScriptValue value() const; + void setValue(const QScriptValue& value); + + void remove(); + QScriptValue::PropertyFlags flags() const; + + void toFront(); + void toBack(); + + QScriptValueIterator& operator=(QScriptValue& value); +private: + QExplicitlySharedDataPointer<QScriptValueIteratorPrivate> d_ptr; + + Q_DECLARE_PRIVATE(QScriptValueIterator) + Q_DISABLE_COPY(QScriptValueIterator) +}; + +#endif // qscriptvalueiterator_h diff --git a/Source/JavaScriptCore/qt/api/qscriptvalueiterator_p.h b/Source/JavaScriptCore/qt/api/qscriptvalueiterator_p.h new file mode 100644 index 0000000..b93b518 --- /dev/null +++ b/Source/JavaScriptCore/qt/api/qscriptvalueiterator_p.h @@ -0,0 +1,172 @@ +/* + Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef qscriptvalueiterator_p_h +#define qscriptvalueiterator_p_h + +#include "qscriptvalue_p.h" +#include <JavaScriptCore/JavaScript.h> +#include <JavaScriptCore/JSRetainPtr.h> +#include <QtCore/qshareddata.h> +#include <QtCore/qvector.h> + +class QScriptValueIteratorPrivate: public QSharedData { +public: + inline QScriptValueIteratorPrivate(const QScriptValuePrivate* value); + inline ~QScriptValueIteratorPrivate(); + + inline bool hasNext(); + inline void next(); + + inline bool hasPrevious(); + inline void previous(); + + inline QString name() const; + inline QScriptStringPrivate* scriptName() const; + + inline QScriptValuePrivate* value() const; + inline void setValue(const QScriptValuePrivate* value); + + inline void remove(); + + inline void toFront(); + inline void toBack(); + + QScriptValue::PropertyFlags flags() const; + + inline bool isValid() const; +private: + inline QScriptEnginePrivate* engine() const; + + QExplicitlySharedDataPointer<QScriptValuePrivate> m_object; + QVector<JSStringRef> m_names; + QMutableVectorIterator<JSStringRef> m_idx; +}; + +inline QScriptValueIteratorPrivate::QScriptValueIteratorPrivate(const QScriptValuePrivate* value) + : m_object(const_cast<QScriptValuePrivate*>(value)) + , m_idx(m_names) +{ + if (m_object->isObject()) { + m_names = engine()->objectGetOwnPropertyNames(*m_object); + m_idx = m_names; + } else + m_object = 0; +} + +inline QScriptValueIteratorPrivate::~QScriptValueIteratorPrivate() +{ + QVector<JSStringRef>::const_iterator i = m_names.constBegin(); + for (; i != m_names.constEnd(); ++i) + JSStringRelease(*i); +} + +inline bool QScriptValueIteratorPrivate::hasNext() +{ + return m_idx.hasNext(); +} + +inline void QScriptValueIteratorPrivate::next() +{ + // FIXME (Qt5) This method should return a value (QTBUG-11226). + m_idx.next(); +} + +inline bool QScriptValueIteratorPrivate::hasPrevious() +{ + return m_idx.hasPrevious(); +} + +inline void QScriptValueIteratorPrivate::previous() +{ + m_idx.previous(); +} + +inline QString QScriptValueIteratorPrivate::name() const +{ + if (!isValid()) + return QString(); + return QScriptConverter::toString(m_idx.value()); +} + +inline QScriptStringPrivate* QScriptValueIteratorPrivate::scriptName() const +{ + if (!isValid()) + return new QScriptStringPrivate(); + return new QScriptStringPrivate(QScriptConverter::toString(m_idx.value())); +} + +inline QScriptValuePrivate* QScriptValueIteratorPrivate::value() const +{ + if (!isValid()) + return new QScriptValuePrivate(); + JSValueRef exception = 0; + JSValueRef value = m_object->property(m_idx.value(), &exception); + engine()->setException(exception); + return new QScriptValuePrivate(engine(), value); +} + +inline void QScriptValueIteratorPrivate::setValue(const QScriptValuePrivate* value) +{ + if (!isValid()) + return; + JSValueRef exception = 0; + m_object->setProperty(m_idx.value(), *value, /* flags */ 0, &exception); + engine()->setException(exception); +} + +inline void QScriptValueIteratorPrivate::remove() +{ + if (!isValid()) + return; + JSValueRef exception = 0; + m_object->deleteProperty(m_idx.value(), &exception); + engine()->setException(exception); + m_idx.remove(); +} + +inline void QScriptValueIteratorPrivate::toFront() +{ + m_idx.toFront(); +} + +inline void QScriptValueIteratorPrivate::toBack() +{ + m_idx.toBack(); +} + +QScriptValue::PropertyFlags QScriptValueIteratorPrivate::flags() const +{ + if (!isValid()) + return QScriptValue::PropertyFlags(0); + return m_object->propertyFlags(m_idx.value(), QScriptValue::ResolveLocal); +} + +inline bool QScriptValueIteratorPrivate::isValid() const +{ + return m_object; +} + +inline QScriptEnginePrivate* QScriptValueIteratorPrivate::engine() const +{ + Q_ASSERT(isValid()); + return m_object->engine(); +} + +#endif // qscriptvalueiterator_p_h diff --git a/Source/JavaScriptCore/qt/api/qtscriptglobal.h b/Source/JavaScriptCore/qt/api/qtscriptglobal.h new file mode 100644 index 0000000..efdfc50 --- /dev/null +++ b/Source/JavaScriptCore/qt/api/qtscriptglobal.h @@ -0,0 +1,43 @@ +/* + Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef qtscriptglobal_h +#define qtscriptglobal_h + +#include <QtCore/qglobal.h> + +#if defined(QT_MAKEDLL) /* create a Qt DLL library */ +# if defined(QT_BUILD_JAVASCRIPT_LIB) +# define Q_JAVASCRIPT_EXPORT Q_DECL_EXPORT +# else +# define Q_JAVASCRIPT_EXPORT Q_DECL_IMPORT +# endif +#elif defined(QT_DLL) /* use a Qt DLL library */ +# define Q_JAVASCRIPT_EXPORT +#endif + +#if !defined(Q_JAVASCRIPT_EXPORT) +# if defined(QT_SHARED) +# define Q_JAVASCRIPT_EXPORT Q_DECL_EXPORT +# else +# define Q_JAVASCRIPT_EXPORT +# endif +#endif + +#endif diff --git a/Source/JavaScriptCore/qt/benchmarks/benchmarks.pri b/Source/JavaScriptCore/qt/benchmarks/benchmarks.pri new file mode 100644 index 0000000..5af3383 --- /dev/null +++ b/Source/JavaScriptCore/qt/benchmarks/benchmarks.pri @@ -0,0 +1,19 @@ +QMAKE_RPATHDIR = $$OUTPUT_DIR/lib $$QMAKE_RPATHDIR +QMAKE_LIBDIR = $$OUTPUT_DIR/lib $$QMAKE_LIBDIR +mac:!static:contains(QT_CONFIG, qt_framework):!CONFIG(webkit_no_framework) { + LIBS += -framework QtScript + QMAKE_FRAMEWORKPATH = $$OUTPUT_DIR/lib $$QMAKE_FRAMEWORKPATH +} else { + win32-*|wince* { + LIBS += -lQtScript$${QT_MAJOR_VERSION} + } else { + LIBS += -lQtScript + } +} + +CONFIG(release, debug|release) { + DEFINES += NDEBUG +} + +INCLUDEPATH += $$PWD/../api + diff --git a/Source/JavaScriptCore/qt/benchmarks/benchmarks.pro b/Source/JavaScriptCore/qt/benchmarks/benchmarks.pro new file mode 100644 index 0000000..85fa82c --- /dev/null +++ b/Source/JavaScriptCore/qt/benchmarks/benchmarks.pro @@ -0,0 +1,4 @@ +TEMPLATE = subdirs +SUBDIRS = qscriptengine \ + qscriptvalue \ + diff --git a/Source/JavaScriptCore/qt/benchmarks/qscriptengine/qscriptengine.pro b/Source/JavaScriptCore/qt/benchmarks/qscriptengine/qscriptengine.pro new file mode 100644 index 0000000..e94137d --- /dev/null +++ b/Source/JavaScriptCore/qt/benchmarks/qscriptengine/qscriptengine.pro @@ -0,0 +1,13 @@ +TEMPLATE = app +TARGET = tst_bench_qscriptengine + +SOURCES += tst_qscriptengine.cpp + +QT += testlib + +include(../benchmarks.pri) + +symbian* { + TARGET.EPOCHEAPSIZE = 0x20000 0x2000000 // Min 128kB, Max 32MB + TARGET.EPOCSTACKSIZE = 0x14000 +} diff --git a/Source/JavaScriptCore/qt/benchmarks/qscriptengine/tst_qscriptengine.cpp b/Source/JavaScriptCore/qt/benchmarks/qscriptengine/tst_qscriptengine.cpp new file mode 100644 index 0000000..0c447c6 --- /dev/null +++ b/Source/JavaScriptCore/qt/benchmarks/qscriptengine/tst_qscriptengine.cpp @@ -0,0 +1,142 @@ +/* + Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "qscriptengine.h" +#include "qscriptvalue.h" +#include <qtest.h> + +class tst_QScriptEngine : public QObject { + Q_OBJECT + +private slots: + void checkSyntax_data(); + void checkSyntax(); + void constructor(); + void evaluateString_data(); + void evaluateString(); + void evaluateProgram_data(); + void evaluateProgram(); + void newObject(); + void nullValue(); + void undefinedValue(); + void globalObject(); + void toStringHandle(); +}; + +void tst_QScriptEngine::checkSyntax_data() +{ + evaluateString_data(); +} + +void tst_QScriptEngine::checkSyntax() +{ + QFETCH(QString, code); + QScriptEngine engine; + QBENCHMARK { + engine.checkSyntax(code); + } +} + +void tst_QScriptEngine::constructor() +{ + QBENCHMARK { + QScriptEngine engine; + } +} + +void tst_QScriptEngine::evaluateString_data() +{ + QTest::addColumn<QString>("code"); + QTest::newRow("empty script") << QString::fromLatin1(""); + QTest::newRow("number literal") << QString::fromLatin1("123"); + QTest::newRow("string literal") << QString::fromLatin1("'ciao'"); + QTest::newRow("regexp literal") << QString::fromLatin1("/foo/gim"); + QTest::newRow("null literal") << QString::fromLatin1("null"); + QTest::newRow("undefined literal") << QString::fromLatin1("undefined"); + QTest::newRow("empty object literal") << QString::fromLatin1("{}"); + QTest::newRow("this") << QString::fromLatin1("this"); +} + +void tst_QScriptEngine::evaluateString() +{ + QFETCH(QString, code); + QScriptEngine engine; + QBENCHMARK { + engine.evaluate(code); + } +} + +void tst_QScriptEngine::evaluateProgram_data() +{ + evaluateString_data(); +} + +void tst_QScriptEngine::evaluateProgram() +{ + QFETCH(QString, code); + QScriptEngine engine; + QScriptProgram program(code); + QBENCHMARK { + engine.evaluate(program); + } +} + +void tst_QScriptEngine::newObject() +{ + QScriptEngine engine; + QBENCHMARK { + engine.newObject(); + } +} + +void tst_QScriptEngine::nullValue() +{ + QScriptEngine engine; + QBENCHMARK { + engine.nullValue(); + } +} + +void tst_QScriptEngine::undefinedValue() +{ + QScriptEngine engine; + QBENCHMARK { + engine.undefinedValue(); + } +} + +void tst_QScriptEngine::globalObject() +{ + QScriptEngine engine; + QBENCHMARK { + engine.globalObject(); + } +} + +void tst_QScriptEngine::toStringHandle() +{ + QScriptEngine engine; + QString str = QString::fromLatin1("foobarbaz"); + QBENCHMARK { + engine.toStringHandle(str); + } +} + +QTEST_MAIN(tst_QScriptEngine) +#include "tst_qscriptengine.moc" diff --git a/Source/JavaScriptCore/qt/benchmarks/qscriptvalue/qscriptvalue.pro b/Source/JavaScriptCore/qt/benchmarks/qscriptvalue/qscriptvalue.pro new file mode 100644 index 0000000..673fe65 --- /dev/null +++ b/Source/JavaScriptCore/qt/benchmarks/qscriptvalue/qscriptvalue.pro @@ -0,0 +1,9 @@ +TEMPLATE = app +TARGET = tst_bench_qscriptvalue +QT += testlib + +isEmpty(OUTPUT_DIR): OUTPUT_DIR = ../../../.. +include(../benchmarks.pri) + +SOURCES += tst_qscriptvalue.cpp + diff --git a/Source/JavaScriptCore/qt/benchmarks/qscriptvalue/tst_qscriptvalue.cpp b/Source/JavaScriptCore/qt/benchmarks/qscriptvalue/tst_qscriptvalue.cpp new file mode 100644 index 0000000..7c39b8e --- /dev/null +++ b/Source/JavaScriptCore/qt/benchmarks/qscriptvalue/tst_qscriptvalue.cpp @@ -0,0 +1,442 @@ +/* + Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "qscriptengine.h" +#include "qscriptstring.h" +#include "qscriptvalue.h" +#include <qtest.h> + +Q_DECLARE_METATYPE(QScriptValue); + +class tst_QScriptValue : public QObject { + Q_OBJECT + +public: + tst_QScriptValue() + : m_engine(0) + {} + + ~tst_QScriptValue() + { + if (m_engine) + delete m_engine; + } + +private slots: + void values_data(); + + void ctorBool(); + void ctorReal(); + void ctorNumber(); + void ctorQString(); + void ctorCString(); + void ctorSpecial(); + void ctorQScriptValue(); + + void isValid_data(); + void isValid(); + void isBool_data(); + void isBool(); + void isNumber_data(); + void isNumber(); + void isFunction_data(); + void isFunction(); + void isNull_data(); + void isNull(); + void isString_data(); + void isString(); + void isUndefined_data(); + void isUndefined(); + void isObject_data(); + void isObject(); + void isError_data(); + void isError(); + + void toString_data(); + void toString(); + void toNumber_data(); + void toNumber(); + void toBool_data(); + void toBool(); + void toInteger_data(); + void toInteger(); + void toInt32_data(); + void toInt32(); + void toUInt32_data(); + void toUInt32(); + void toUInt16_data(); + void toUInt16(); + void toObject_data(); + void toObject(); + + void equals_data(); + void equals(); + void strictlyEquals_data(); + void strictlyEquals(); + void instanceOf_data(); + void instanceOf(); + +private: + QScriptEngine* m_engine; +}; + +void tst_QScriptValue::values_data() +{ + if (m_engine) + delete m_engine; + m_engine = new QScriptEngine; + + QTest::addColumn<QScriptValue>("value"); + + QTest::newRow("invalid") << QScriptValue(); + + QTest::newRow("cbool") << QScriptValue(true); + QTest::newRow("cnumber") << QScriptValue(1234); + QTest::newRow("cstring") << QScriptValue("abc"); + QTest::newRow("cnull") << QScriptValue(QScriptValue::NullValue); + QTest::newRow("cundefined") << QScriptValue(QScriptValue::UndefinedValue); + + QTest::newRow("jsbool") << m_engine->evaluate("true"); + QTest::newRow("jsnumber") << m_engine->evaluate("12345"); + QTest::newRow("jsstring") << m_engine->evaluate("'go'"); + QTest::newRow("jsfunction") << m_engine->evaluate("(function {})"); + QTest::newRow("jsnull") << m_engine->nullValue(); + QTest::newRow("jsundefined") << m_engine->undefinedValue(); + QTest::newRow("jsobject") << m_engine->newObject(); + QTest::newRow("jserror") << m_engine->evaluate("new Error()"); +} + +void tst_QScriptValue::ctorBool() +{ + QBENCHMARK { + QScriptValue(true); + } +} + +void tst_QScriptValue::ctorReal() +{ + QBENCHMARK { + QScriptValue(12.3); + } +} + +void tst_QScriptValue::ctorNumber() +{ + QBENCHMARK { + QScriptValue(123); + } +} + +void tst_QScriptValue::ctorQString() +{ + QString str = QString::fromLatin1("ciao"); + QBENCHMARK { + QScriptValue(str); + } +} + +void tst_QScriptValue::ctorCString() +{ + QBENCHMARK { + QScriptValue("Pong!"); + } +} + +void tst_QScriptValue::ctorSpecial() +{ + QBENCHMARK { + (void)QScriptValue(QScriptValue::NullValue); + } +} + +void tst_QScriptValue::ctorQScriptValue() +{ + QScriptValue tmp(1234); + QBENCHMARK { + QScriptValue(tmp); + } +} + +void tst_QScriptValue::isValid_data() +{ + values_data(); +} + +void tst_QScriptValue::isValid() +{ + QFETCH(QScriptValue, value); + QBENCHMARK { + value.isValid(); + } +} + +void tst_QScriptValue::isBool_data() +{ + values_data(); +} + +void tst_QScriptValue::isBool() +{ + QFETCH(QScriptValue, value); + QBENCHMARK { + value.isBool(); + } +} + +void tst_QScriptValue::isNumber_data() +{ + values_data(); +} + +void tst_QScriptValue::isNumber() +{ + QFETCH(QScriptValue, value); + QBENCHMARK { + value.isNumber(); + } +} + +void tst_QScriptValue::isFunction_data() +{ + values_data(); +} + +void tst_QScriptValue::isFunction() +{ + QFETCH(QScriptValue, value); + QBENCHMARK { + value.isFunction(); + } +} + +void tst_QScriptValue::isNull_data() +{ + values_data(); +} + +void tst_QScriptValue::isNull() +{ + QFETCH(QScriptValue, value); + QBENCHMARK { + value.isNull(); + } +} + +void tst_QScriptValue::isString_data() +{ + values_data(); +} + +void tst_QScriptValue::isString() +{ + QFETCH(QScriptValue, value); + QBENCHMARK { + value.isString(); + } +} + +void tst_QScriptValue::isUndefined_data() +{ + values_data(); +} + +void tst_QScriptValue::isUndefined() +{ + QFETCH(QScriptValue, value); + QBENCHMARK { + value.isUndefined(); + } +} + +void tst_QScriptValue::isObject_data() +{ + values_data(); +} + +void tst_QScriptValue::isObject() +{ + QFETCH(QScriptValue, value); + QBENCHMARK { + value.isObject(); + } +} + +void tst_QScriptValue::isError_data() +{ + values_data(); +} + +void tst_QScriptValue::isError() +{ + QFETCH(QScriptValue, value); + QBENCHMARK { + value.isError(); + } +} + +void tst_QScriptValue::toString_data() +{ + values_data(); +} + +void tst_QScriptValue::toString() +{ + QFETCH(QScriptValue, value); + QBENCHMARK { + value.toString(); + } +} + +void tst_QScriptValue::toNumber_data() +{ + values_data(); +} + +void tst_QScriptValue::toNumber() +{ + QFETCH(QScriptValue, value); + QBENCHMARK { + value.toNumber(); + } +} + +void tst_QScriptValue::toBool_data() +{ + values_data(); +} + +void tst_QScriptValue::toBool() +{ + QFETCH(QScriptValue, value); + QBENCHMARK { + value.toBool(); + } +} + +void tst_QScriptValue::toInteger_data() +{ + values_data(); +} + +void tst_QScriptValue::toInteger() +{ + QFETCH(QScriptValue, value); + QBENCHMARK { + value.toInteger(); + } +} + +void tst_QScriptValue::toInt32_data() +{ + values_data(); +} + +void tst_QScriptValue::toInt32() +{ + QFETCH(QScriptValue, value); + QBENCHMARK { + value.toInt32(); + } +} + +void tst_QScriptValue::toUInt32_data() +{ + values_data(); +} + +void tst_QScriptValue::toUInt32() +{ + QFETCH(QScriptValue, value); + QBENCHMARK { + value.toUInt32(); + } +} + +void tst_QScriptValue::toUInt16_data() +{ + values_data(); +} + +void tst_QScriptValue::toUInt16() +{ + QFETCH(QScriptValue, value); + QBENCHMARK { + value.toUInt16(); + } +} + +void tst_QScriptValue::toObject_data() +{ + values_data(); +} + +void tst_QScriptValue::toObject() +{ + QFETCH(QScriptValue, value); + QBENCHMARK { + value.toObject(); + } +} + +void tst_QScriptValue::equals_data() +{ + values_data(); +} + +void tst_QScriptValue::equals() +{ + QFETCH(QScriptValue, value); + static QScriptValue previous; + QBENCHMARK { + value.equals(previous); + } + previous = value; +} + +void tst_QScriptValue::strictlyEquals_data() +{ + values_data(); +} + +void tst_QScriptValue::strictlyEquals() +{ + QFETCH(QScriptValue, value); + static QScriptValue previous; + QBENCHMARK { + value.strictlyEquals(previous); + } + previous = value; +} + +void tst_QScriptValue::instanceOf_data() +{ + values_data(); +} + +void tst_QScriptValue::instanceOf() +{ + QFETCH(QScriptValue, value); + static QScriptValue object = m_engine->newObject(); + QBENCHMARK { + value.instanceOf(object); + } +} + +QTEST_MAIN(tst_QScriptValue) +#include "tst_qscriptvalue.moc" diff --git a/Source/JavaScriptCore/qt/tests/qscriptengine/qscriptengine.pro b/Source/JavaScriptCore/qt/tests/qscriptengine/qscriptengine.pro new file mode 100644 index 0000000..d521dd8 --- /dev/null +++ b/Source/JavaScriptCore/qt/tests/qscriptengine/qscriptengine.pro @@ -0,0 +1,8 @@ +TEMPLATE = app +TARGET = tst_qscriptengine +QT += testlib +isEmpty(OUTPUT_DIR): OUTPUT_DIR = ../../../.. +include(../tests.pri) + +SOURCES += tst_qscriptengine.cpp + diff --git a/Source/JavaScriptCore/qt/tests/qscriptengine/tst_qscriptengine.cpp b/Source/JavaScriptCore/qt/tests/qscriptengine/tst_qscriptengine.cpp new file mode 100644 index 0000000..dabcfb2 --- /dev/null +++ b/Source/JavaScriptCore/qt/tests/qscriptengine/tst_qscriptengine.cpp @@ -0,0 +1,734 @@ +/* + Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "qscriptengine.h" +#include "qscriptprogram.h" +#include "qscriptsyntaxcheckresult.h" +#include "qscriptvalue.h" +#include <QtCore/qnumeric.h> +#include <QtTest/qtest.h> + +class tst_QScriptEngine : public QObject { + Q_OBJECT + +public: + tst_QScriptEngine() {} + virtual ~tst_QScriptEngine() {} + +public slots: + void init() {} + void cleanup() {} + +private slots: + void newFunction(); + void newObject(); + void globalObject(); + void evaluate(); + void collectGarbage(); + void reportAdditionalMemoryCost(); + void nullValue(); + void undefinedValue(); + void evaluateProgram(); + void checkSyntax_data(); + void checkSyntax(); + void toObject(); + void toObjectTwoEngines(); + void newArray(); + void uncaughtException(); + void newDate(); +}; + +/* Evaluating a script that throw an unhandled exception should return an invalid value. */ +void tst_QScriptEngine::evaluate() +{ + QScriptEngine engine; + QVERIFY2(engine.evaluate("1+1").isValid(), "the expression should be evaluated and an valid result should be returned"); + QVERIFY2(engine.evaluate("ping").isValid(), "Script throwing an unhandled exception should return an exception value"); +} + +static QScriptValue myFunction(QScriptContext*, QScriptEngine* eng) +{ + return eng->nullValue(); +} + +static QScriptValue myFunctionWithArg(QScriptContext*, QScriptEngine* eng, void* arg) +{ + int* result = reinterpret_cast<int*>(arg); + return QScriptValue(eng, *result); +} + +static QScriptValue myFunctionThatReturns(QScriptContext*, QScriptEngine* eng) +{ + return QScriptValue(eng, 42); +} + +static QScriptValue myFunctionThatReturnsWithoutEngine(QScriptContext*, QScriptEngine*) +{ + return QScriptValue(1024); +} + +static QScriptValue myFunctionThatReturnsWrongEngine(QScriptContext*, QScriptEngine*, void* arg) +{ + QScriptEngine* wrongEngine = reinterpret_cast<QScriptEngine*>(arg); + return QScriptValue(wrongEngine, 42); +} + +void tst_QScriptEngine::newFunction() +{ + QScriptEngine eng; + { + QScriptValue fun = eng.newFunction(myFunction); + QCOMPARE(fun.isValid(), true); + QCOMPARE(fun.isFunction(), true); + QCOMPARE(fun.isObject(), true); + // QCOMPARE(fun.scriptClass(), (QScriptClass*)0); + // a prototype property is automatically constructed + { + QScriptValue prot = fun.property("prototype", QScriptValue::ResolveLocal); + QVERIFY(prot.isObject()); + QVERIFY(prot.property("constructor").strictlyEquals(fun)); + QEXPECT_FAIL("", "JSCallbackObject::getOwnPropertyDescriptor() doesn't return correct information yet", Continue); + QCOMPARE(fun.propertyFlags("prototype"), QScriptValue::Undeletable); + QEXPECT_FAIL("", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QCOMPARE(prot.propertyFlags("constructor"), QScriptValue::PropertyFlags(QScriptValue::Undeletable | QScriptValue::SkipInEnumeration)); + } + // prototype should be Function.prototype + QCOMPARE(fun.prototype().isValid(), true); + QCOMPARE(fun.prototype().isFunction(), true); + QCOMPARE(fun.prototype().strictlyEquals(eng.evaluate("Function.prototype")), true); + + QCOMPARE(fun.call().isNull(), true); + // QCOMPARE(fun.construct().isObject(), true); + } + // the overload that takes an extra argument + { + int expectedResult = 42; + QScriptValue fun = eng.newFunction(myFunctionWithArg, reinterpret_cast<void*>(&expectedResult)); + QVERIFY(fun.isFunction()); + // QCOMPARE(fun.scriptClass(), (QScriptClass*)0); + // a prototype property is automatically constructed + { + QScriptValue prot = fun.property("prototype", QScriptValue::ResolveLocal); + QVERIFY(prot.isObject()); + QVERIFY(prot.property("constructor").strictlyEquals(fun)); + QEXPECT_FAIL("", "JSCallbackObject::getOwnPropertyDescriptor() doesn't return correct information yet", Continue); + QCOMPARE(fun.propertyFlags("prototype"), QScriptValue::Undeletable); + QEXPECT_FAIL("", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QCOMPARE(prot.propertyFlags("constructor"), QScriptValue::PropertyFlags(QScriptValue::Undeletable | QScriptValue::SkipInEnumeration)); + } + // prototype should be Function.prototype + QCOMPARE(fun.prototype().isValid(), true); + QCOMPARE(fun.prototype().isFunction(), true); + QCOMPARE(fun.prototype().strictlyEquals(eng.evaluate("Function.prototype")), true); + + QScriptValue result = fun.call(); + QCOMPARE(result.isNumber(), true); + QCOMPARE(result.toInt32(), expectedResult); + } + // the overload that takes a prototype + { + QScriptValue proto = eng.newObject(); + QScriptValue fun = eng.newFunction(myFunction, proto); + QCOMPARE(fun.isValid(), true); + QCOMPARE(fun.isFunction(), true); + QCOMPARE(fun.isObject(), true); + // internal prototype should be Function.prototype + QCOMPARE(fun.prototype().isValid(), true); + QCOMPARE(fun.prototype().isFunction(), true); + QCOMPARE(fun.prototype().strictlyEquals(eng.evaluate("Function.prototype")), true); + // public prototype should be the one we passed + QCOMPARE(fun.property("prototype").strictlyEquals(proto), true); + QEXPECT_FAIL("", "JSCallbackObject::getOwnPropertyDescriptor() doesn't return correct information yet", Continue); + QCOMPARE(fun.propertyFlags("prototype"), QScriptValue::Undeletable); + QCOMPARE(proto.property("constructor").strictlyEquals(fun), true); + QEXPECT_FAIL("", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QCOMPARE(proto.propertyFlags("constructor"), QScriptValue::PropertyFlags(QScriptValue::Undeletable | QScriptValue::SkipInEnumeration)); + + QCOMPARE(fun.call().isNull(), true); + // QCOMPARE(fun.construct().isObject(), true); + } + // whether the return value is correct + { + QScriptValue fun = eng.newFunction(myFunctionThatReturns); + QCOMPARE(fun.isValid(), true); + QCOMPARE(fun.isFunction(), true); + QCOMPARE(fun.isObject(), true); + + QScriptValue result = fun.call(); + QCOMPARE(result.isNumber(), true); + QCOMPARE(result.toInt32(), 42); + } + // whether the return value is assigned to the correct engine + { + QScriptValue fun = eng.newFunction(myFunctionThatReturnsWithoutEngine); + QCOMPARE(fun.isValid(), true); + QCOMPARE(fun.isFunction(), true); + QCOMPARE(fun.isObject(), true); + + QScriptValue result = fun.call(); + QCOMPARE(result.engine(), &eng); + QCOMPARE(result.isNumber(), true); + QCOMPARE(result.toInt32(), 1024); + } + // whether the return value is undefined when returning a value with wrong engine + { + QScriptEngine wrongEngine; + + QScriptValue fun = eng.newFunction(myFunctionThatReturnsWrongEngine, reinterpret_cast<void*>(&wrongEngine)); + QCOMPARE(fun.isValid(), true); + QCOMPARE(fun.isFunction(), true); + QCOMPARE(fun.isObject(), true); + + QTest::ignoreMessage(QtWarningMsg, "Value from different engine returned from native function, returning undefined value instead."); + QScriptValue result = fun.call(); + QCOMPARE(result.isValid(), true); + QCOMPARE(result.isUndefined(), true); + } +} + +void tst_QScriptEngine::newObject() +{ + QScriptEngine engine; + QScriptValue object = engine.newObject(); + QVERIFY(object.isObject()); + QVERIFY(object.engine() == &engine); + QVERIFY(!object.isError()); + QVERIFY(!object.equals(engine.newObject())); + QVERIFY(!object.strictlyEquals(engine.newObject())); + QCOMPARE(object.toString(), QString::fromAscii("[object Object]")); +} + +void tst_QScriptEngine::globalObject() +{ + QScriptEngine engine; + QScriptValue global = engine.globalObject(); + QScriptValue self = engine.evaluate("this"); + QVERIFY(global.isObject()); + QVERIFY(engine.globalObject().equals(engine.evaluate("this"))); + QVERIFY(engine.globalObject().strictlyEquals(self)); +} + +/* Test garbage collection, at least try to not crash. */ +void tst_QScriptEngine::collectGarbage() +{ + QScriptEngine engine; + QScriptValue foo = engine.evaluate("( function foo() {return 'pong';} )"); + QVERIFY(foo.isFunction()); + engine.collectGarbage(); + QCOMPARE(foo.call().toString(), QString::fromAscii("pong")); +} + +void tst_QScriptEngine::reportAdditionalMemoryCost() +{ + // There isn't any easy way to test the responsiveness of the GC; + // just try to call the function a few times with various sizes. + QScriptEngine eng; + for (int i = 0; i < 100; ++i) { + eng.reportAdditionalMemoryCost(0); + eng.reportAdditionalMemoryCost(10); + eng.reportAdditionalMemoryCost(1000); + eng.reportAdditionalMemoryCost(10000); + eng.reportAdditionalMemoryCost(100000); + eng.reportAdditionalMemoryCost(1000000); + eng.reportAdditionalMemoryCost(10000000); + eng.reportAdditionalMemoryCost(-1); + eng.reportAdditionalMemoryCost(-1000); + QScriptValue obj = eng.evaluate("new Object"); + eng.collectGarbage(); + } +} + +void tst_QScriptEngine::nullValue() +{ + QScriptEngine engine; + QScriptValue value = engine.nullValue(); + QVERIFY(value.isValid()); + QVERIFY(value.isNull()); +} + +void tst_QScriptEngine::undefinedValue() +{ + QScriptEngine engine; + QScriptValue value = engine.undefinedValue(); + QVERIFY(value.isValid()); + QVERIFY(value.isUndefined()); +} + +void tst_QScriptEngine::evaluateProgram() +{ + QScriptEngine eng; + { + QString code("1 + 2"); + QString fileName("hello.js"); + int lineNumber = 123; + QScriptProgram program(code, fileName, lineNumber); + QVERIFY(!program.isNull()); + QCOMPARE(program.sourceCode(), code); + QCOMPARE(program.fileName(), fileName); + QCOMPARE(program.firstLineNumber(), lineNumber); + + QScriptValue expected = eng.evaluate(code); + for (int x = 0; x < 10; ++x) { + QScriptValue ret = eng.evaluate(program); + QVERIFY(ret.equals(expected)); + } + + // operator= + QScriptProgram sameProgram = program; + QVERIFY(sameProgram == program); + QVERIFY(eng.evaluate(sameProgram).equals(expected)); + + // copy constructor + QScriptProgram sameProgram2(program); + QVERIFY(sameProgram2 == program); + QVERIFY(eng.evaluate(sameProgram2).equals(expected)); + + QScriptProgram differentProgram("2 + 3"); + QVERIFY(differentProgram != program); + QVERIFY(!eng.evaluate(differentProgram).equals(expected)); + } + + // Program that accesses variable in the scope + { + QScriptProgram program("a"); + QVERIFY(!program.isNull()); + { + QScriptValue ret = eng.evaluate(program); + QVERIFY(ret.isError()); + QCOMPARE(ret.toString(), QString::fromLatin1("ReferenceError: Can't find variable: a")); + } + { + QScriptValue ret = eng.evaluate(program); + QVERIFY(ret.isError()); + } + eng.evaluate("a = 456"); + { + QScriptValue ret = eng.evaluate(program); + QVERIFY(!ret.isError()); + QCOMPARE(ret.toNumber(), 456.0); + } + } + + // Program that creates closure + { + QScriptProgram program("(function() { var count = 0; return function() { return count++; }; })"); + QVERIFY(!program.isNull()); + QScriptValue createCounter = eng.evaluate(program); + QVERIFY(createCounter.isFunction()); + QScriptValue counter = createCounter.call(); + QVERIFY(counter.isFunction()); + { + QScriptValue ret = counter.call(); + QVERIFY(ret.isNumber()); + } + QScriptValue counter2 = createCounter.call(); + QVERIFY(counter2.isFunction()); + QVERIFY(!counter2.equals(counter)); + { + QScriptValue ret = counter2.call(); + QVERIFY(ret.isNumber()); + } + } + + // Same program run in different engines + { + QString code("1 + 2"); + QScriptProgram program(code); + QVERIFY(!program.isNull()); + double expected = eng.evaluate(program).toNumber(); + for (int x = 0; x < 2; ++x) { + QScriptEngine eng2; + for (int y = 0; y < 2; ++y) { + double ret = eng2.evaluate(program).toNumber(); + QCOMPARE(ret, expected); + } + } + } + + // No program + { + QScriptProgram program; + QVERIFY(program.isNull()); + QScriptValue ret = eng.evaluate(program); + QVERIFY(!ret.isValid()); + } +} + +void tst_QScriptEngine::checkSyntax_data() +{ + QTest::addColumn<QString>("code"); + QTest::addColumn<int>("expectedState"); + QTest::addColumn<int>("errorLineNumber"); + QTest::addColumn<int>("errorColumnNumber"); + QTest::addColumn<QString>("errorMessage"); + + QTest::newRow("0") + << QString("0") << int(QScriptSyntaxCheckResult::Valid) + << -1 << -1 << ""; + QTest::newRow("if (") + << QString("if (\n") << int(QScriptSyntaxCheckResult::Intermediate) + << 1 << 4 << ""; + QTest::newRow("if else") + << QString("\nif else") << int(QScriptSyntaxCheckResult::Error) + << 2 << 4 << "SyntaxError: Parse error"; + QTest::newRow("{if}") + << QString("{\n{\nif\n}\n") << int(QScriptSyntaxCheckResult::Error) + << 4 << 1 << "SyntaxError: Parse error"; + QTest::newRow("foo[") + << QString("foo[") << int(QScriptSyntaxCheckResult::Error) + << 1 << 4 << "SyntaxError: Parse error"; + QTest::newRow("foo['bar']") + << QString("foo['bar']") << int(QScriptSyntaxCheckResult::Valid) + << -1 << -1 << ""; + + QTest::newRow("/*") + << QString("/*") << int(QScriptSyntaxCheckResult::Intermediate) + << 1 << 1 << "Unclosed comment at end of file"; + QTest::newRow("/*\nMy comment") + << QString("/*\nMy comment") << int(QScriptSyntaxCheckResult::Intermediate) + << 1 << 1 << "Unclosed comment at end of file"; + QTest::newRow("/*\nMy comment */\nfoo = 10") + << QString("/*\nMy comment */\nfoo = 10") << int(QScriptSyntaxCheckResult::Valid) + << -1 << -1 << ""; + QTest::newRow("foo = 10 /*") + << QString("foo = 10 /*") << int(QScriptSyntaxCheckResult::Intermediate) + << -1 << -1 << ""; + QTest::newRow("foo = 10; /*") + << QString("foo = 10; /*") << int(QScriptSyntaxCheckResult::Intermediate) + << 1 << 11 << "Expected `end of file'"; + QTest::newRow("foo = 10 /* My comment */") + << QString("foo = 10 /* My comment */") << int(QScriptSyntaxCheckResult::Valid) + << -1 << -1 << ""; + + QTest::newRow("/=/") + << QString("/=/") << int(QScriptSyntaxCheckResult::Valid) << -1 << -1 << ""; + QTest::newRow("/=/g") + << QString("/=/g") << int(QScriptSyntaxCheckResult::Valid) << -1 << -1 << ""; + QTest::newRow("/a/") + << QString("/a/") << int(QScriptSyntaxCheckResult::Valid) << -1 << -1 << ""; + QTest::newRow("/a/g") + << QString("/a/g") << int(QScriptSyntaxCheckResult::Valid) << -1 << -1 << ""; +} + +void tst_QScriptEngine::checkSyntax() +{ + QFETCH(QString, code); + QFETCH(int, expectedState); + QFETCH(int, errorLineNumber); + QFETCH(int, errorColumnNumber); + QFETCH(QString, errorMessage); + + QScriptSyntaxCheckResult result = QScriptEngine::checkSyntax(code); + + // assignment + { + QScriptSyntaxCheckResult copy = result; + QCOMPARE(copy.state(), result.state()); + QCOMPARE(copy.errorLineNumber(), result.errorLineNumber()); + QCOMPARE(copy.errorColumnNumber(), result.errorColumnNumber()); + QCOMPARE(copy.errorMessage(), result.errorMessage()); + } + { + QScriptSyntaxCheckResult copy(result); + QCOMPARE(copy.state(), result.state()); + QCOMPARE(copy.errorLineNumber(), result.errorLineNumber()); + QCOMPARE(copy.errorColumnNumber(), result.errorColumnNumber()); + QCOMPARE(copy.errorMessage(), result.errorMessage()); + } + + if (expectedState == QScriptSyntaxCheckResult::Intermediate) + QEXPECT_FAIL("", "QScriptSyntaxCheckResult::state() doesn't return the Intermediate state", Abort); + QCOMPARE(result.state(), QScriptSyntaxCheckResult::State(expectedState)); + QCOMPARE(result.errorLineNumber(), errorLineNumber); + if (expectedState != QScriptSyntaxCheckResult::Valid && errorColumnNumber != 1) + QEXPECT_FAIL("", "QScriptSyntaxCheckResult::errorColumnNumber() doesn't return correct value", Continue); + QCOMPARE(result.errorColumnNumber(), errorColumnNumber); + QCOMPARE(result.errorMessage(), errorMessage); +} + +void tst_QScriptEngine::toObject() +{ + QScriptEngine eng; + QVERIFY(!eng.toObject(eng.undefinedValue()).isValid()); + QVERIFY(!eng.toObject(eng.nullValue()).isValid()); + QVERIFY(!eng.toObject(QScriptValue()).isValid()); + + QScriptValue falskt(false); + { + QScriptValue tmp = eng.toObject(falskt); + QVERIFY(tmp.isObject()); + QVERIFY(!falskt.isObject()); + QVERIFY(!falskt.engine()); + QCOMPARE(tmp.toNumber(), falskt.toNumber()); + } + + QScriptValue sant(true); + { + QScriptValue tmp = eng.toObject(sant); + QVERIFY(tmp.isObject()); + QVERIFY(!sant.isObject()); + QVERIFY(!sant.engine()); + QCOMPARE(tmp.toNumber(), sant.toNumber()); + } + + QScriptValue number(123.0); + { + QScriptValue tmp = eng.toObject(number); + QVERIFY(tmp.isObject()); + QVERIFY(!number.isObject()); + QVERIFY(!number.engine()); + QCOMPARE(tmp.toNumber(), number.toNumber()); + } + + QScriptValue str = QScriptValue(&eng, QString("ciao")); + { + QScriptValue tmp = eng.toObject(str); + QVERIFY(tmp.isObject()); + QVERIFY(!str.isObject()); + QCOMPARE(tmp.toString(), str.toString()); + } + + QScriptValue object = eng.evaluate("new Object"); + { + QScriptValue tmp = eng.toObject(object); + QVERIFY(tmp.isObject()); + QVERIFY(object.isObject()); + QVERIFY(tmp.strictlyEquals(object)); + } +} + +void tst_QScriptEngine::toObjectTwoEngines() +{ + QScriptEngine engine1; + QScriptEngine engine2; + + { + QScriptValue null = engine1.nullValue(); + QTest::ignoreMessage(QtWarningMsg, "QScriptEngine::toObject: cannot convert value created in a different engine"); + QVERIFY(!engine2.toObject(null).isValid()); + QVERIFY(null.isValid()); + QTest::ignoreMessage(QtWarningMsg, "QScriptEngine::toObject: cannot convert value created in a different engine"); + QVERIFY(engine2.toObject(null).engine() != &engine2); + } + { + QScriptValue undefined = engine1.undefinedValue(); + QTest::ignoreMessage(QtWarningMsg, "QScriptEngine::toObject: cannot convert value created in a different engine"); + QVERIFY(!engine2.toObject(undefined).isValid()); + QVERIFY(undefined.isValid()); + QTest::ignoreMessage(QtWarningMsg, "QScriptEngine::toObject: cannot convert value created in a different engine"); + QVERIFY(engine2.toObject(undefined).engine() != &engine2); + } + { + QScriptValue value = engine1.evaluate("1"); + QTest::ignoreMessage(QtWarningMsg, "QScriptEngine::toObject: cannot convert value created in a different engine"); + QVERIFY(engine2.toObject(value).engine() != &engine2); + QVERIFY(!value.isObject()); + } + { + QScriptValue string = engine1.evaluate("'Qt'"); + QTest::ignoreMessage(QtWarningMsg, "QScriptEngine::toObject: cannot convert value created in a different engine"); + QVERIFY(engine2.toObject(string).engine() != &engine2); + QVERIFY(!string.isObject()); + } + { + QScriptValue object = engine1.evaluate("new Object"); + QTest::ignoreMessage(QtWarningMsg, "QScriptEngine::toObject: cannot convert value created in a different engine"); + QVERIFY(engine2.toObject(object).engine() != &engine2); + QVERIFY(object.isObject()); + } +} + +void tst_QScriptEngine::newArray() +{ + QScriptEngine eng; + QScriptValue array = eng.newArray(); + QCOMPARE(array.isValid(), true); + QCOMPARE(array.isArray(), true); + QCOMPARE(array.isObject(), true); + QVERIFY(!array.isFunction()); + // QCOMPARE(array.scriptClass(), (QScriptClass*)0); + + // Prototype should be Array.prototype. + QCOMPARE(array.prototype().isValid(), true); + QCOMPARE(array.prototype().isArray(), true); + QCOMPARE(array.prototype().strictlyEquals(eng.evaluate("Array.prototype")), true); + + QScriptValue arrayWithSize = eng.newArray(42); + QCOMPARE(arrayWithSize.isValid(), true); + QCOMPARE(arrayWithSize.isArray(), true); + QCOMPARE(arrayWithSize.isObject(), true); + QCOMPARE(arrayWithSize.property("length").toInt32(), 42); + + // task 218092 + { + QScriptValue ret = eng.evaluate("[].splice(0, 0, 'a')"); + QVERIFY(ret.isArray()); + QCOMPARE(ret.property("length").toInt32(), 0); + } + { + QScriptValue ret = eng.evaluate("['a'].splice(0, 1, 'b')"); + QVERIFY(ret.isArray()); + QCOMPARE(ret.property("length").toInt32(), 1); + } + { + QScriptValue ret = eng.evaluate("['a', 'b'].splice(0, 1, 'c')"); + QVERIFY(ret.isArray()); + QCOMPARE(ret.property("length").toInt32(), 1); + } + { + QScriptValue ret = eng.evaluate("['a', 'b', 'c'].splice(0, 2, 'd')"); + QVERIFY(ret.isArray()); + QCOMPARE(ret.property("length").toInt32(), 2); + } + { + QScriptValue ret = eng.evaluate("['a', 'b', 'c'].splice(1, 2, 'd', 'e', 'f')"); + QVERIFY(ret.isArray()); + QCOMPARE(ret.property("length").toInt32(), 2); + } +} + +void tst_QScriptEngine::uncaughtException() +{ + QScriptEngine eng; + QScriptValue fun = eng.evaluate("(function foo () { return null; });"); + QVERIFY(!eng.uncaughtException().isValid()); + QVERIFY(fun.isFunction()); + QScriptValue throwFun = eng.evaluate("( function() { throw new Error('Pong'); });"); + QVERIFY(throwFun.isFunction()); + { + eng.evaluate("a = 10"); + QVERIFY(!eng.hasUncaughtException()); + QVERIFY(!eng.uncaughtException().isValid()); + } + { + eng.evaluate("1 = 2"); + QVERIFY(eng.hasUncaughtException()); + eng.clearExceptions(); + QVERIFY(!eng.hasUncaughtException()); + } + { + // Check if the call or toString functions can remove the last exception. + QVERIFY(throwFun.call().isError()); + QVERIFY(eng.hasUncaughtException()); + QScriptValue exception = eng.uncaughtException(); + fun.call(); + exception.toString(); + QVERIFY(eng.hasUncaughtException()); + QVERIFY(eng.uncaughtException().strictlyEquals(exception)); + } + eng.clearExceptions(); + { + // Check if in the call function a new exception can override an existing one. + throwFun.call(); + QVERIFY(eng.hasUncaughtException()); + QScriptValue exception = eng.uncaughtException(); + throwFun.call(); + QVERIFY(eng.hasUncaughtException()); + QVERIFY(!exception.strictlyEquals(eng.uncaughtException())); + } + { + eng.evaluate("throwFun = (function foo () { throw new Error('bla') });"); + eng.evaluate("1;\nthrowFun();"); + QVERIFY(eng.hasUncaughtException()); + QCOMPARE(eng.uncaughtExceptionLineNumber(), 1); + eng.clearExceptions(); + QVERIFY(!eng.hasUncaughtException()); + } + for (int x = 1; x < 4; ++x) { + QScriptValue ret = eng.evaluate("a = 10;\nb = 20;\n0 = 0;\n", + QString::fromLatin1("FooScript") + QString::number(x), + /* lineNumber */ x); + QVERIFY(eng.hasUncaughtException()); + QCOMPARE(eng.uncaughtExceptionLineNumber(), x + 2); + QVERIFY(eng.uncaughtException().strictlyEquals(ret)); + QVERIFY(eng.hasUncaughtException()); + QVERIFY(eng.uncaughtException().strictlyEquals(ret)); + QString backtrace = QString::fromLatin1("<anonymous>()@FooScript") + QString::number(x) + ":" + QString::number(x + 2); + QCOMPARE(eng.uncaughtExceptionBacktrace().join(""), backtrace); + QVERIFY(fun.call().isNull()); + QVERIFY(eng.hasUncaughtException()); + QCOMPARE(eng.uncaughtExceptionLineNumber(), x + 2); + QVERIFY(eng.uncaughtException().strictlyEquals(ret)); + eng.clearExceptions(); + QVERIFY(!eng.hasUncaughtException()); + QCOMPARE(eng.uncaughtExceptionLineNumber(), -1); + QVERIFY(!eng.uncaughtException().isValid()); + eng.evaluate("2 = 3"); + QVERIFY(eng.hasUncaughtException()); + QScriptValue ret2 = throwFun.call(); + QVERIFY(ret2.isError()); + QVERIFY(eng.hasUncaughtException()); + QVERIFY(eng.uncaughtException().strictlyEquals(ret2)); + QCOMPARE(eng.uncaughtExceptionLineNumber(), 1); + eng.clearExceptions(); + QVERIFY(!eng.hasUncaughtException()); + eng.evaluate("1 + 2"); + QVERIFY(!eng.hasUncaughtException()); + } +} + +void tst_QScriptEngine::newDate() +{ + QScriptEngine eng; + { + QScriptValue date = eng.newDate(0); + QCOMPARE(date.isValid(), true); + QCOMPARE(date.isDate(), true); + QCOMPARE(date.isObject(), true); + QVERIFY(!date.isFunction()); + // prototype should be Date.prototype + QCOMPARE(date.prototype().isValid(), true); + QCOMPARE(date.prototype().isDate(), true); + QCOMPARE(date.prototype().strictlyEquals(eng.evaluate("Date.prototype")), true); + } + { + QDateTime dt = QDateTime(QDate(1, 2, 3), QTime(4, 5, 6, 7), Qt::LocalTime); + QScriptValue date = eng.newDate(dt); + QCOMPARE(date.isValid(), true); + QCOMPARE(date.isDate(), true); + QCOMPARE(date.isObject(), true); + // prototype should be Date.prototype + QCOMPARE(date.prototype().isValid(), true); + QCOMPARE(date.prototype().isDate(), true); + QCOMPARE(date.prototype().strictlyEquals(eng.evaluate("Date.prototype")), true); + + QCOMPARE(date.toDateTime(), dt); + } + { + QDateTime dt = QDateTime(QDate(1, 2, 3), QTime(4, 5, 6, 7), Qt::UTC); + QScriptValue date = eng.newDate(dt); + // toDateTime() result should be in local time + QCOMPARE(date.toDateTime(), dt.toLocalTime()); + } + // Date.parse() should return NaN when it fails + { + QScriptValue ret = eng.evaluate("Date.parse()"); + QVERIFY(ret.isNumber()); + QVERIFY(qIsNaN(ret.toNumber())); + } + // Date.parse() should be able to parse the output of Date().toString() + { + QScriptValue ret = eng.evaluate("var x = new Date(); var s = x.toString(); s == new Date(Date.parse(s)).toString()"); + QVERIFY(ret.isBoolean()); + QCOMPARE(ret.toBoolean(), true); + } +} + +QTEST_MAIN(tst_QScriptEngine) +#include "tst_qscriptengine.moc" diff --git a/Source/JavaScriptCore/qt/tests/qscriptstring/qscriptstring.pro b/Source/JavaScriptCore/qt/tests/qscriptstring/qscriptstring.pro new file mode 100644 index 0000000..5ad9b7c --- /dev/null +++ b/Source/JavaScriptCore/qt/tests/qscriptstring/qscriptstring.pro @@ -0,0 +1,7 @@ +TEMPLATE = app +TARGET = tst_qscriptstring +QT += testlib +include(../tests.pri) + +SOURCES += tst_qscriptstring.cpp + diff --git a/Source/JavaScriptCore/qt/tests/qscriptstring/tst_qscriptstring.cpp b/Source/JavaScriptCore/qt/tests/qscriptstring/tst_qscriptstring.cpp new file mode 100644 index 0000000..ff31835 --- /dev/null +++ b/Source/JavaScriptCore/qt/tests/qscriptstring/tst_qscriptstring.cpp @@ -0,0 +1,175 @@ +/* + Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef tst_qscriptstring_h +#define tst_qscriptstring_h + +#include "qscriptengine.h" +#include "qscriptstring.h" +#include <QtCore/qhash.h> +#include <QtTest/QtTest> + +class tst_QScriptString : public QObject { + Q_OBJECT + +public: + tst_QScriptString(); + virtual ~tst_QScriptString(); + +private slots: + void test(); + void hash(); + void toArrayIndex_data(); + void toArrayIndex(); +}; + +tst_QScriptString::tst_QScriptString() +{ +} + +tst_QScriptString::~tst_QScriptString() +{ +} + +void tst_QScriptString::test() +{ + QScriptEngine eng; + { + QScriptString str; + QVERIFY(!str.isValid()); + QVERIFY(str == str); + QVERIFY(!(str != str)); + QVERIFY(str.toString().isNull()); + + QScriptString str1(str); + QVERIFY(!str1.isValid()); + + QScriptString str2 = str; + QVERIFY(!str2.isValid()); + + QCOMPARE(str.toArrayIndex(), quint32(0xffffffff)); + } + for (int x = 0; x < 2; ++x) { + QString ciao = QString::fromLatin1("ciao"); + QScriptString str = eng.toStringHandle(ciao); + QVERIFY(str.isValid()); + QVERIFY(str == str); + QVERIFY(!(str != str)); + QCOMPARE(str.toString(), ciao); + + QScriptString str1(str); + QCOMPARE(str, str1); + + QScriptString str2 = str; + QCOMPARE(str, str2); + + QScriptString str3 = eng.toStringHandle(ciao); + QVERIFY(str3.isValid()); + QCOMPARE(str, str3); + + eng.collectGarbage(); + + QVERIFY(str.isValid()); + QCOMPARE(str.toString(), ciao); + QVERIFY(str1.isValid()); + QCOMPARE(str1.toString(), ciao); + QVERIFY(str2.isValid()); + QCOMPARE(str2.toString(), ciao); + QVERIFY(str3.isValid()); + QCOMPARE(str3.toString(), ciao); + } + { + QScriptEngine* eng2 = new QScriptEngine; + QString one = QString::fromLatin1("one"); + QString two = QString::fromLatin1("two"); + QScriptString oneInterned = eng2->toStringHandle(one); + QCOMPARE(oneInterned.toString(), one); + QScriptString twoInterned = eng2->toStringHandle(two); + QCOMPARE(twoInterned.toString(), two); + QVERIFY(oneInterned != twoInterned); + QVERIFY(!(oneInterned == twoInterned)); + + delete eng2; + } +} + +void tst_QScriptString::hash() +{ + QScriptEngine engine; + QHash<QScriptString, int> stringToInt; + QScriptString foo = engine.toStringHandle("foo"); + + QScriptString bar = engine.toStringHandle("bar"); + QVERIFY(!stringToInt.contains(foo)); + for (int i = 0; i < 1000000; ++i) + stringToInt.insert(foo, 123); + QCOMPARE(stringToInt.value(foo), 123); + QVERIFY(!stringToInt.contains(bar)); + stringToInt.insert(bar, 456); + QCOMPARE(stringToInt.value(bar), 456); + QCOMPARE(stringToInt.value(foo), 123); +} + +void tst_QScriptString::toArrayIndex_data() +{ + QTest::addColumn<QString>("input"); + QTest::addColumn<bool>("expectSuccess"); + QTest::addColumn<quint32>("expectedIndex"); + QTest::newRow("foo") << QString::fromLatin1("foo") << false << quint32(0xffffffff); + QTest::newRow("empty") << QString::fromLatin1("") << false << quint32(0xffffffff); + QTest::newRow("0") << QString::fromLatin1("0") << true << quint32(0); + QTest::newRow("00") << QString::fromLatin1("00") << false << quint32(0xffffffff); + QTest::newRow("1") << QString::fromLatin1("1") << true << quint32(1); + QTest::newRow("123") << QString::fromLatin1("123") << true << quint32(123); + QTest::newRow("-1") << QString::fromLatin1("-1") << false << quint32(0xffffffff); + QTest::newRow("0a") << QString::fromLatin1("0a") << false << quint32(0xffffffff); + QTest::newRow("0x1") << QString::fromLatin1("0x1") << false << quint32(0xffffffff); + QTest::newRow("01") << QString::fromLatin1("01") << false << quint32(0xffffffff); + QTest::newRow("101a") << QString::fromLatin1("101a") << false << quint32(0xffffffff); + QTest::newRow("4294967294") << QString::fromLatin1("4294967294") << true << quint32(0xfffffffe); + QTest::newRow("4294967295") << QString::fromLatin1("4294967295") << false << quint32(0xffffffff); + QTest::newRow("11111111111") << QString::fromLatin1("11111111111") << false << quint32(0xffffffff); + QTest::newRow("0.0") << QString::fromLatin1("0.0") << false << quint32(0xffffffff); + QTest::newRow("1.0") << QString::fromLatin1("1.0") << false << quint32(0xffffffff); + QTest::newRow("1.5") << QString::fromLatin1("1.5") << false << quint32(0xffffffff); + QTest::newRow("1.") << QString::fromLatin1("1.") << false << quint32(0xffffffff); + QTest::newRow(".1") << QString::fromLatin1(".1") << false << quint32(0xffffffff); + QTest::newRow("1e0") << QString::fromLatin1("1e0") << false << quint32(0xffffffff); +} + +void tst_QScriptString::toArrayIndex() +{ + QFETCH(QString, input); + QFETCH(bool, expectSuccess); + QFETCH(quint32, expectedIndex); + QScriptEngine engine; + for (int x = 0; x < 2; ++x) { + bool isArrayIndex; + bool* ptr = (!x) ? &isArrayIndex : (bool*)0; + quint32 result = engine.toStringHandle(input).toArrayIndex(ptr); + if (!x) + QCOMPARE(isArrayIndex, expectSuccess); + QCOMPARE(result, expectedIndex); + } +} + +QTEST_MAIN(tst_QScriptString) +#include "tst_qscriptstring.moc" + +#endif // tst_qscriptstring_h diff --git a/Source/JavaScriptCore/qt/tests/qscriptvalue/qscriptvalue.pro b/Source/JavaScriptCore/qt/tests/qscriptvalue/qscriptvalue.pro new file mode 100644 index 0000000..02e94ec --- /dev/null +++ b/Source/JavaScriptCore/qt/tests/qscriptvalue/qscriptvalue.pro @@ -0,0 +1,15 @@ +TEMPLATE = app +TARGET = tst_qscriptvalue +QT += testlib +isEmpty(OUTPUT_DIR): OUTPUT_DIR = ../../../.. +include(../tests.pri) + +SOURCES += \ + tst_qscriptvalue.cpp \ + tst_qscriptvalue_generated_init.cpp \ + tst_qscriptvalue_generated_comparison.cpp \ + tst_qscriptvalue_generated_istype.cpp \ + tst_qscriptvalue_generated_totype.cpp \ + +HEADERS += \ + tst_qscriptvalue.h diff --git a/Source/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.cpp b/Source/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.cpp new file mode 100644 index 0000000..e04d3e9 --- /dev/null +++ b/Source/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.cpp @@ -0,0 +1,1296 @@ +/* + Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "tst_qscriptvalue.h" +#include <QtCore/qnumeric.h> + +tst_QScriptValue::tst_QScriptValue() + : m_engine(0) +{ +} + +tst_QScriptValue::~tst_QScriptValue() +{ + delete m_engine; +} + +void tst_QScriptValue::ctor() +{ + QScriptEngine eng; + { + QScriptValue v; + QCOMPARE(v.isValid(), false); + QCOMPARE(v.engine(), (QScriptEngine*)0); + } + { + QScriptValue v(&eng, QScriptValue::UndefinedValue); + QCOMPARE(v.isValid(), true); + QCOMPARE(v.isUndefined(), true); + QCOMPARE(v.isObject(), false); + QCOMPARE(v.engine(), &eng); + } + { + QScriptValue v(&eng, QScriptValue::NullValue); + QCOMPARE(v.isValid(), true); + QCOMPARE(v.isNull(), true); + QCOMPARE(v.isObject(), false); + QCOMPARE(v.engine(), &eng); + } + { + QScriptValue v(&eng, false); + QCOMPARE(v.isValid(), true); + QCOMPARE(v.isBoolean(), true); + QCOMPARE(v.isBool(), true); + QCOMPARE(v.isObject(), false); + QCOMPARE(v.toBoolean(), false); + QCOMPARE(v.engine(), &eng); + } + { + QScriptValue v(&eng, int(1)); + QCOMPARE(v.isValid(), true); + QCOMPARE(v.isNumber(), true); + QCOMPARE(v.isObject(), false); + QCOMPARE(v.toNumber(), 1.0); + QCOMPARE(v.engine(), &eng); + } + { + QScriptValue v(int(0x43211234)); + QVERIFY(v.isNumber()); + QCOMPARE(v.toInt32(), 0x43211234); + } + { + QScriptValue v(&eng, uint(1)); + QCOMPARE(v.isValid(), true); + QCOMPARE(v.isNumber(), true); + QCOMPARE(v.isObject(), false); + QCOMPARE(v.toNumber(), 1.0); + QCOMPARE(v.engine(), &eng); + } + { + QScriptValue v(uint(0x43211234)); + QVERIFY(v.isNumber()); + QCOMPARE(v.toUInt32(), uint(0x43211234)); + } + { + QScriptValue v(&eng, 1.0); + QCOMPARE(v.isValid(), true); + QCOMPARE(v.isNumber(), true); + QCOMPARE(v.isObject(), false); + QCOMPARE(v.toNumber(), 1.0); + QCOMPARE(v.engine(), &eng); + } + { + QScriptValue v(12345678910.5); + QVERIFY(v.isNumber()); + QCOMPARE(v.toNumber(), 12345678910.5); + } + { + QScriptValue v(&eng, "ciao"); + QCOMPARE(v.isValid(), true); + QCOMPARE(v.isString(), true); + QCOMPARE(v.isObject(), false); + QCOMPARE(v.toString(), QLatin1String("ciao")); + QCOMPARE(v.engine(), &eng); + } + { + QScriptValue v(&eng, QString("ciao")); + QCOMPARE(v.isValid(), true); + QCOMPARE(v.isString(), true); + QCOMPARE(v.isObject(), false); + QCOMPARE(v.toString(), QLatin1String("ciao")); + QCOMPARE(v.engine(), &eng); + } + // copy constructor, operator= + { + QScriptValue v(&eng, 1.0); + QScriptValue v2(v); + QCOMPARE(v2.strictlyEquals(v), true); + QCOMPARE(v2.engine(), &eng); + + QScriptValue v3(v); + QCOMPARE(v3.strictlyEquals(v), true); + QCOMPARE(v3.strictlyEquals(v2), true); + QCOMPARE(v3.engine(), &eng); + + QScriptValue v4(&eng, 2.0); + QCOMPARE(v4.strictlyEquals(v), false); + v3 = v4; + QCOMPARE(v3.strictlyEquals(v), false); + QCOMPARE(v3.strictlyEquals(v4), true); + + v2 = QScriptValue(); + QCOMPARE(v2.strictlyEquals(v), false); + QCOMPARE(v.toNumber(), 1.0); + + QScriptValue v5(v); + QCOMPARE(v5.strictlyEquals(v), true); + v = QScriptValue(); + QCOMPARE(v5.strictlyEquals(v), false); + QCOMPARE(v5.toNumber(), 1.0); + } + + // constructors that take no engine argument + { + QScriptValue v(QScriptValue::UndefinedValue); + QCOMPARE(v.isValid(), true); + QCOMPARE(v.isUndefined(), true); + QCOMPARE(v.isObject(), false); + QCOMPARE(v.engine(), (QScriptEngine*)0); + } + { + QScriptValue v(QScriptValue::NullValue); + QCOMPARE(v.isValid(), true); + QCOMPARE(v.isNull(), true); + QCOMPARE(v.isObject(), false); + QCOMPARE(v.engine(), (QScriptEngine*)0); + } + { + QScriptValue v(false); + QCOMPARE(v.isValid(), true); + QCOMPARE(v.isBoolean(), true); + QCOMPARE(v.isBool(), true); + QCOMPARE(v.isObject(), false); + QCOMPARE(v.toBoolean(), false); + QCOMPARE(v.engine(), (QScriptEngine*)0); + } + { + QScriptValue v(int(1)); + QCOMPARE(v.isValid(), true); + QCOMPARE(v.isNumber(), true); + QCOMPARE(v.isObject(), false); + QCOMPARE(v.toNumber(), 1.0); + QCOMPARE(v.engine(), (QScriptEngine*)0); + } + { + QScriptValue v(uint(1)); + QCOMPARE(v.isValid(), true); + QCOMPARE(v.isNumber(), true); + QCOMPARE(v.isObject(), false); + QCOMPARE(v.toNumber(), 1.0); + QCOMPARE(v.engine(), (QScriptEngine*)0); + } + { + QScriptValue v(1.0); + QCOMPARE(v.isValid(), true); + QCOMPARE(v.isNumber(), true); + QCOMPARE(v.isObject(), false); + QCOMPARE(v.toNumber(), 1.0); + QCOMPARE(v.engine(), (QScriptEngine*)0); + } + { + QScriptValue v("ciao"); + QCOMPARE(v.isValid(), true); + QCOMPARE(v.isString(), true); + QCOMPARE(v.isObject(), false); + QCOMPARE(v.toString(), QLatin1String("ciao")); + QCOMPARE(v.engine(), (QScriptEngine*)0); + } + { + QScriptValue v(QString("ciao")); + QCOMPARE(v.isValid(), true); + QCOMPARE(v.isString(), true); + QCOMPARE(v.isObject(), false); + QCOMPARE(v.toString(), QLatin1String("ciao")); + QCOMPARE(v.engine(), (QScriptEngine*)0); + } + // copy constructor, operator= + { + QScriptValue v(1.0); + QScriptValue v2(v); + QCOMPARE(v2.strictlyEquals(v), true); + QCOMPARE(v2.engine(), (QScriptEngine*)0); + + QScriptValue v3(v); + QCOMPARE(v3.strictlyEquals(v), true); + QCOMPARE(v3.strictlyEquals(v2), true); + QCOMPARE(v3.engine(), (QScriptEngine*)0); + + QScriptValue v4(2.0); + QCOMPARE(v4.strictlyEquals(v), false); + v3 = v4; + QCOMPARE(v3.strictlyEquals(v), false); + QCOMPARE(v3.strictlyEquals(v4), true); + + v2 = QScriptValue(); + QCOMPARE(v2.strictlyEquals(v), false); + QCOMPARE(v.toNumber(), 1.0); + + QScriptValue v5(v); + QCOMPARE(v5.strictlyEquals(v), true); + v = QScriptValue(); + QCOMPARE(v5.strictlyEquals(v), false); + QCOMPARE(v5.toNumber(), 1.0); + } + + // 0 engine + QVERIFY(QScriptValue(0, QScriptValue::UndefinedValue).isUndefined()); + QVERIFY(QScriptValue(0, QScriptValue::NullValue).isNull()); + QVERIFY(QScriptValue(0, false).isBool()); + QVERIFY(QScriptValue(0, int(1)).isNumber()); + QVERIFY(QScriptValue(0, uint(1)).isNumber()); + QVERIFY(QScriptValue(0, 1.0).isNumber()); + QVERIFY(QScriptValue(0, "ciao").isString()); + QVERIFY(QScriptValue(0, QString("ciao")).isString()); +} + +void tst_QScriptValue::getPropertySimple_data() +{ + QTest::addColumn<QString>("code"); + QTest::addColumn<QString>("propertyName"); + QTest::addColumn<QString>("desc"); + QTest::addColumn<bool>("isArrayIndex"); + + QTest::newRow("new Array()") + << QString::fromAscii("new Array()") + << QString::fromAscii("length") + << QString::fromAscii("0") + << false; + QTest::newRow("new Object().length") + << QString::fromAscii("new Object()") + << QString::fromAscii("length") + << QString::fromAscii("") // Undefined is an invalid property. + << false; + QTest::newRow("new Object().toString") + << QString::fromAscii("new Object()") + << QString::fromAscii("toString") + << QString::fromAscii("function toString() {\n [native code]\n}") + << false; + QTest::newRow("[1,2,3,4]") + << QString::fromAscii("[1,2,3,'s',4]") + << QString::fromAscii("2") + << QString::fromAscii("3") + << true; + QTest::newRow("[1,3,'a','b']") + << QString::fromAscii("[1,3,'a','b']") + << QString::fromAscii("3") + << QString::fromAscii("b") + << true; + QTest::newRow("[4,5]") + << QString::fromAscii("[4,5]") + << QString::fromAscii("123") + << QString::fromAscii("") // Undefined is an invalid property. + << true; + QTest::newRow("[1,3,4]") + << QString::fromAscii("[1,3,4]") + << QString::fromAscii("abc") + << QString::fromAscii("") // Undefined is an invalid property. + << true; +} + +void tst_QScriptValue::getPropertySimple() +{ + QFETCH(QString, code); + QFETCH(QString, propertyName); + QFETCH(QString, desc); + + QScriptEngine engine; + QScriptValue object = engine.evaluate(code); + QVERIFY(object.isValid()); + { + QScriptValue property = object.property(propertyName); + QCOMPARE(property.toString(), desc); + } + { + QScriptString name = engine.toStringHandle(propertyName); + QScriptValue property = object.property(name); + QCOMPARE(property.toString(), desc); + } + { + bool ok; + quint32 idx = engine.toStringHandle(propertyName).toArrayIndex(&ok); + if (ok) { + QScriptValue property = object.property(idx); + QCOMPARE(property.toString(), desc); + } + } +} + +void tst_QScriptValue::setPropertySimple() +{ + QScriptEngine engine; + { + QScriptValue invalid; + QScriptValue property(1234); + + invalid.setProperty("aaa", property); + invalid.setProperty(13, property); + invalid.setProperty(engine.toStringHandle("aaa"), property); + + QVERIFY(!invalid.property("aaa").isValid()); + QVERIFY(!invalid.property(13).isValid()); + QVERIFY(!invalid.property(engine.toStringHandle("aaa")).isValid()); + } + { + QScriptValue object = engine.newObject(); + QScriptValue property; + + object.setProperty(13, property); + object.setProperty("aaa", property); + object.setProperty(engine.toStringHandle("aaa"), property); + + QVERIFY(!object.property(13).isValid()); + QVERIFY(!object.property("aaa").isValid()); + QVERIFY(!object.property(engine.toStringHandle("aaa")).isValid()); + } + { + // Check if setting an invalid property works as deleteProperty. + QScriptValue object = engine.evaluate("o = {13: 0, 'aaa': 3, 'bbb': 1}"); + QScriptValue property; + + QVERIFY(object.property(13).isValid()); + QVERIFY(object.property("aaa").isValid()); + QVERIFY(object.property(engine.toStringHandle("aaa")).isValid()); + + object.setProperty(13, property); + object.setProperty("aaa", property); + object.setProperty(engine.toStringHandle("bbb"), property); + + QVERIFY(!object.property(13).isValid()); + QVERIFY(!object.property("aaa").isValid()); + QVERIFY(!object.property(engine.toStringHandle("aaa")).isValid()); + } + { + QScriptValue object = engine.evaluate("new Object"); + QVERIFY(object.isObject()); + QScriptValue property = object.property("foo"); + QVERIFY(!property.isValid()); + property = QScriptValue(2); + object.setProperty("foo", property); + QVERIFY(object.property("foo").isNumber()); + QVERIFY(object.property("foo").toNumber() == 2); + } + { + QScriptValue o1 = engine.evaluate("o1 = new Object; o1"); + QScriptValue o2 = engine.evaluate("o2 = new Object; o2"); + QVERIFY(engine.evaluate("o1.__proto__ = o2; o1.__proto__ === o2").toBool()); + QVERIFY(engine.evaluate("o2.foo = 22; o1.foo == 22").toBool()); + QVERIFY(o1.property("foo").toString() == "22"); + o2.setProperty("foo", QScriptValue(&engine, 456.0)); + QVERIFY(engine.evaluate("o1.foo == 456").toBool()); + QVERIFY(o1.property("foo").isNumber()); + } +} + +void tst_QScriptValue::getPropertyResolveFlag() +{ + QScriptEngine engine; + QScriptValue object1 = engine.evaluate("o1 = new Object();"); + QScriptValue object2 = engine.evaluate("o2 = new Object(); o1.__proto__ = o2; o2"); + QScriptValue number(&engine, 456.0); + QVERIFY(object1.isObject()); + QVERIFY(object2.isObject()); + QVERIFY(number.isNumber()); + + object2.setProperty("propertyInPrototype", number); + QVERIFY(object2.property("propertyInPrototype").isNumber()); + // default is ResolvePrototype + QCOMPARE(object1.property("propertyInPrototype").strictlyEquals(number), true); + QCOMPARE(object1.property("propertyInPrototype", QScriptValue::ResolvePrototype) + .strictlyEquals(number), true); + QCOMPARE(object1.property("propertyInPrototype", QScriptValue::ResolveLocal).isValid(), false); +} + +void tst_QScriptValue::getSetProperty() +{ + QScriptEngine eng; + + QScriptValue object = eng.newObject(); + + QScriptValue str = QScriptValue(&eng, "bar"); + object.setProperty("foo", str); + QCOMPARE(object.property("foo").toString(), str.toString()); + + QScriptValue num = QScriptValue(&eng, 123.0); + object.setProperty("baz", num); + QCOMPARE(object.property("baz").toNumber(), num.toNumber()); + + QScriptValue strstr = QScriptValue("bar"); + QCOMPARE(strstr.engine(), (QScriptEngine *)0); + object.setProperty("foo", strstr); + QCOMPARE(object.property("foo").toString(), strstr.toString()); + QCOMPARE(strstr.engine(), &eng); // the value has been bound to the engine + + QScriptValue numnum = QScriptValue(123.0); + object.setProperty("baz", numnum); + QCOMPARE(object.property("baz").toNumber(), numnum.toNumber()); + + QScriptValue inv; + inv.setProperty("foo", num); + QCOMPARE(inv.property("foo").isValid(), false); + + QScriptValue array = eng.newArray(); + array.setProperty(0, num); + QCOMPARE(array.property(0).toNumber(), num.toNumber()); + QCOMPARE(array.property("0").toNumber(), num.toNumber()); + QCOMPARE(array.property("length").toUInt32(), quint32(1)); + array.setProperty(1, str); + QCOMPARE(array.property(1).toString(), str.toString()); + QCOMPARE(array.property("1").toString(), str.toString()); + QCOMPARE(array.property("length").toUInt32(), quint32(2)); + array.setProperty("length", QScriptValue(&eng, 1)); + QCOMPARE(array.property("length").toUInt32(), quint32(1)); + QCOMPARE(array.property(1).isValid(), false); + + // task 162051 -- detecting whether the property is an array index or not + QVERIFY(eng.evaluate("a = []; a['00'] = 123; a['00']").strictlyEquals(QScriptValue(&eng, 123))); + QVERIFY(eng.evaluate("a.length").strictlyEquals(QScriptValue(&eng, 0))); + QVERIFY(eng.evaluate("a.hasOwnProperty('00')").strictlyEquals(QScriptValue(&eng, true))); + QVERIFY(eng.evaluate("a.hasOwnProperty('0')").strictlyEquals(QScriptValue(&eng, false))); + QVERIFY(eng.evaluate("a[0]").isUndefined()); + QVERIFY(eng.evaluate("a[0.5] = 456; a[0.5]").strictlyEquals(QScriptValue(&eng, 456))); + QVERIFY(eng.evaluate("a.length").strictlyEquals(QScriptValue(&eng, 0))); + QVERIFY(eng.evaluate("a.hasOwnProperty('0.5')").strictlyEquals(QScriptValue(&eng, true))); + QVERIFY(eng.evaluate("a[0]").isUndefined()); + QVERIFY(eng.evaluate("a[0] = 789; a[0]").strictlyEquals(QScriptValue(&eng, 789))); + QVERIFY(eng.evaluate("a.length").strictlyEquals(QScriptValue(&eng, 1))); + + // task 183072 -- 0x800000000 is not an array index + eng.evaluate("a = []; a[0x800000000] = 123"); + QVERIFY(eng.evaluate("a.length").strictlyEquals(QScriptValue(&eng, 0))); + QVERIFY(eng.evaluate("a[0]").isUndefined()); + QVERIFY(eng.evaluate("a[0x800000000]").strictlyEquals(QScriptValue(&eng, 123))); + + QScriptEngine otherEngine; + QScriptValue otherNum = QScriptValue(&otherEngine, 123); + QTest::ignoreMessage(QtWarningMsg, "QScriptValue::setProperty() failed: cannot set value created in a different engine"); + object.setProperty("oof", otherNum); + QCOMPARE(object.property("oof").isValid(), false); + + // test ResolveMode + QScriptValue object2 = eng.newObject(); + object.setPrototype(object2); + QScriptValue num2 = QScriptValue(&eng, 456.0); + object2.setProperty("propertyInPrototype", num2); + // default is ResolvePrototype + QCOMPARE(object.property("propertyInPrototype") + .strictlyEquals(num2), true); + QCOMPARE(object.property("propertyInPrototype", QScriptValue::ResolvePrototype) + .strictlyEquals(num2), true); + QCOMPARE(object.property("propertyInPrototype", QScriptValue::ResolveLocal) + .isValid(), false); + QEXPECT_FAIL("", "QScriptValue::ResolveScope is not implemented", Continue); + QCOMPARE(object.property("propertyInPrototype", QScriptValue::ResolveScope) + .strictlyEquals(num2), false); + QCOMPARE(object.property("propertyInPrototype", QScriptValue::ResolveFull) + .strictlyEquals(num2), true); + + // test property removal (setProperty(QScriptValue())) + QScriptValue object3 = eng.newObject(); + object3.setProperty("foo", num); + QCOMPARE(object3.property("foo").strictlyEquals(num), true); + object3.setProperty("bar", str); + QCOMPARE(object3.property("bar").strictlyEquals(str), true); + object3.setProperty("foo", QScriptValue()); + QCOMPARE(object3.property("foo").isValid(), false); + QCOMPARE(object3.property("bar").strictlyEquals(str), true); + object3.setProperty("foo", num); + QCOMPARE(object3.property("foo").strictlyEquals(num), true); + QCOMPARE(object3.property("bar").strictlyEquals(str), true); + object3.setProperty("bar", QScriptValue()); + QCOMPARE(object3.property("bar").isValid(), false); + QCOMPARE(object3.property("foo").strictlyEquals(num), true); + object3.setProperty("foo", QScriptValue()); + object3.setProperty("foo", QScriptValue()); + + eng.globalObject().setProperty("object3", object3); + QCOMPARE(eng.evaluate("object3.hasOwnProperty('foo')") + .strictlyEquals(QScriptValue(&eng, false)), true); + object3.setProperty("foo", num); + QCOMPARE(eng.evaluate("object3.hasOwnProperty('foo')") + .strictlyEquals(QScriptValue(&eng, true)), true); + eng.globalObject().setProperty("object3", QScriptValue()); + QCOMPARE(eng.evaluate("this.hasOwnProperty('object3')") + .strictlyEquals(QScriptValue(&eng, false)), true); + + eng.globalObject().setProperty("object", object); + + // ReadOnly + object.setProperty("readOnlyProperty", num, QScriptValue::ReadOnly); + // QCOMPARE(object.propertyFlags("readOnlyProperty"), QScriptValue::ReadOnly); + QCOMPARE(object.property("readOnlyProperty").strictlyEquals(num), true); + eng.evaluate("object.readOnlyProperty = !object.readOnlyProperty"); + QCOMPARE(object.property("readOnlyProperty").strictlyEquals(num), true); + // Should still be part of enumeration. + { + QScriptValue ret = eng.evaluate( + "found = false;" + "for (var p in object) {" + " if (p == 'readOnlyProperty') {" + " found = true; break;" + " }" + "} found"); + QCOMPARE(ret.strictlyEquals(QScriptValue(&eng, true)), true); + } + // should still be deletable + { + QScriptValue ret = eng.evaluate("delete object.readOnlyProperty"); + QCOMPARE(ret.strictlyEquals(QScriptValue(&eng, true)), true); + QCOMPARE(object.property("readOnlyProperty").isValid(), false); + } + + // Undeletable + object.setProperty("undeletableProperty", num, QScriptValue::Undeletable); + // QCOMPARE(object.propertyFlags("undeletableProperty"), QScriptValue::Undeletable); + QCOMPARE(object.property("undeletableProperty").strictlyEquals(num), true); + { + QScriptValue ret = eng.evaluate("delete object.undeletableProperty"); + QCOMPARE(ret.strictlyEquals(QScriptValue(&eng, true)), false); + QCOMPARE(object.property("undeletableProperty").strictlyEquals(num), true); + } + // should still be writable + eng.evaluate("object.undeletableProperty = object.undeletableProperty + 1"); + QCOMPARE(object.property("undeletableProperty").toNumber(), num.toNumber() + 1); + // should still be part of enumeration + { + QScriptValue ret = eng.evaluate( + "found = false;" + "for (var p in object) {" + " if (p == 'undeletableProperty') {" + " found = true; break;" + " }" + "} found"); + QCOMPARE(ret.strictlyEquals(QScriptValue(&eng, true)), true); + } + // should still be deletable from C++ + object.setProperty("undeletableProperty", QScriptValue()); + QEXPECT_FAIL("", "With JSC-based back-end, undeletable properties can't be deleted from C++", Continue); + QVERIFY(!object.property("undeletableProperty").isValid()); + // QEXPECT_FAIL("", "With JSC-based back-end, undeletable properties can't be deleted from C++", Continue); + // QCOMPARE(object.propertyFlags("undeletableProperty"), 0); + + // SkipInEnumeration + object.setProperty("dontEnumProperty", num, QScriptValue::SkipInEnumeration); + // QCOMPARE(object.propertyFlags("dontEnumProperty"), QScriptValue::SkipInEnumeration); + QCOMPARE(object.property("dontEnumProperty").strictlyEquals(num), true); + // should not be part of enumeration + { + QScriptValue ret = eng.evaluate( + "found = false;" + "for (var p in object) {" + " if (p == 'dontEnumProperty') {" + " found = true; break;" + " }" + "} found"); + QCOMPARE(ret.strictlyEquals(QScriptValue(&eng, false)), true); + } + // should still be writable + eng.evaluate("object.dontEnumProperty = object.dontEnumProperty + 1"); + QCOMPARE(object.property("dontEnumProperty").toNumber(), num.toNumber() + 1); + // should still be deletable + { + QScriptValue ret = eng.evaluate("delete object.dontEnumProperty"); + QCOMPARE(ret.strictlyEquals(QScriptValue(&eng, true)), true); + QCOMPARE(object.property("dontEnumProperty").isValid(), false); + } + + // change flags + object.setProperty("flagProperty", str); + // QCOMPARE(object.propertyFlags("flagProperty"), static_cast<QScriptValue::PropertyFlags>(0)); + + object.setProperty("flagProperty", str, QScriptValue::ReadOnly); + // QCOMPARE(object.propertyFlags("flagProperty"), QScriptValue::ReadOnly); + + // object.setProperty("flagProperty", str, object.propertyFlags("flagProperty") | QScriptValue::SkipInEnumeration); + // QCOMPARE(object.propertyFlags("flagProperty"), QScriptValue::ReadOnly | QScriptValue::SkipInEnumeration); + + object.setProperty("flagProperty", str, QScriptValue::KeepExistingFlags); + // QCOMPARE(object.propertyFlags("flagProperty"), QScriptValue::ReadOnly | QScriptValue::SkipInEnumeration); + + object.setProperty("flagProperty", str, QScriptValue::UserRange); + // QCOMPARE(object.propertyFlags("flagProperty"), QScriptValue::UserRange); + + // flags of property in the prototype + { + QScriptValue object2 = eng.newObject(); + object2.setPrototype(object); + // QCOMPARE(object2.propertyFlags("flagProperty", QScriptValue::ResolveLocal), 0); + // QCOMPARE(object2.propertyFlags("flagProperty"), QScriptValue::UserRange); + } + + // using interned strings + QScriptString foo = eng.toStringHandle("foo"); + + object.setProperty(foo, QScriptValue()); + QVERIFY(!object.property(foo).isValid()); + + object.setProperty(foo, num); + QVERIFY(object.property(foo).strictlyEquals(num)); + QVERIFY(object.property("foo").strictlyEquals(num)); + // QVERIFY(object.propertyFlags(foo) == 0); +} + +void tst_QScriptValue::toStringSimple_data() +{ + QTest::addColumn<QString>("code"); + QTest::addColumn<QString>("result"); + + QTest::newRow("string") << QString::fromAscii("'hello'") << QString::fromAscii("hello"); + QTest::newRow("string utf") << QString::fromUtf8("'ąśćżźółńę'") << QString::fromUtf8("ąśćżźółńę"); + QTest::newRow("expression") << QString::fromAscii("1 + 4") << QString::fromAscii("5"); + QTest::newRow("null") << QString::fromAscii("null") << QString::fromAscii("null"); + QTest::newRow("boolean") << QString::fromAscii("false") << QString::fromAscii("false"); + QTest::newRow("undefined") << QString::fromAscii("undefined") << QString::fromAscii("undefined"); + QTest::newRow("object") << QString::fromAscii("new Object") << QString::fromAscii("[object Object]"); +} + +/* Test conversion to string from different JSC types */ +void tst_QScriptValue::toStringSimple() +{ + QFETCH(QString, code); + QFETCH(QString, result); + + QScriptEngine engine; + QCOMPARE(engine.evaluate(code).toString(), result); +} + +void tst_QScriptValue::copyConstructor_data() +{ + QScriptEngine engine; + QScriptValue nnumber(123); + QScriptValue nstring("ping"); + QScriptValue number(engine.evaluate("1")); + QScriptValue string(engine.evaluate("'foo'")); + QScriptValue object(engine.evaluate("new Object")); + QScriptValue undefined(engine.evaluate("undefined")); + QScriptValue null(engine.evaluate("null")); + + QTest::addColumn<QScriptValue>("value"); + QTest::addColumn<QString>("result"); + + QTest::newRow("native number") << nnumber << QString::number(123); + QTest::newRow("native string") << nstring << QString("ping"); + QTest::newRow("number") << number << QString::fromAscii("1"); + QTest::newRow("string") << string << QString::fromAscii("foo"); + QTest::newRow("object") << object << QString::fromAscii("[object Object]"); + QTest::newRow("undefined") << undefined << QString::fromAscii("undefined"); + QTest::newRow("null") << null << QString::fromAscii("null"); +} + +void tst_QScriptValue::copyConstructor() +{ + QFETCH(QScriptValue, value); + QFETCH(QString, result); + + QVERIFY(value.isValid()); + QScriptValue tmp(value); + QVERIFY(tmp.isValid()); + QCOMPARE(tmp.toString(), result); +} + +void tst_QScriptValue::assignOperator_data() +{ + copyConstructor_data(); +} + +void tst_QScriptValue::assignOperator() +{ + QFETCH(QScriptValue, value); + QFETCH(QString, result); + + QScriptValue tmp; + tmp = value; + QVERIFY(tmp.isValid()); + QCOMPARE(tmp.toString(), result); +} + +/* Test internal data sharing between a diffrenet QScriptValue. */ +void tst_QScriptValue::dataSharing() +{ + QScriptEngine engine; + QScriptValue v1; + QScriptValue v2(v1); + + v1 = engine.evaluate("1"); // v1 == 1 ; v2 invalid. + QVERIFY(v1.isValid()); + QVERIFY(!v2.isValid()); + + v2 = v1; // v1 == 1; v2 == 1. + QVERIFY(v1.isValid()); + QVERIFY(v2.isValid()); + + v1 = engine.evaluate("obj = new Date"); // v1 == [object Date] ; v2 == 1. + QVERIFY(v1.isValid()); + QVERIFY(v2.isValid()); + QVERIFY(v2.toString() != v1.toString()); + + // TODO add object manipulation (v1 and v2 point to the same object). +} + +void tst_QScriptValue::constructors_data() +{ + QScriptEngine engine; + + QTest::addColumn<QScriptValue>("value"); + QTest::addColumn<QString>("string"); + QTest::addColumn<bool>("valid"); + QTest::addColumn<bool>("object"); + + QTest::newRow("invalid") << QScriptValue() << QString() << false << false; + QTest::newRow("number") << QScriptValue(-21) << QString::number(-21) << true << false; + QTest::newRow("bool") << QScriptValue(true) << QString::fromAscii("true") << true << false; + QTest::newRow("double") << QScriptValue(21.12) << QString::number(21.12) << true << false; + QTest::newRow("string") << QScriptValue("AlaMaKota") << QString::fromAscii("AlaMaKota") << true << false; + QTest::newRow("object") << engine.evaluate("new Object") << QString::fromAscii("[object Object]") << true << true; + QTest::newRow("null") << QScriptValue(QScriptValue::NullValue)<< QString::fromAscii("null") << true << false; + QTest::newRow("undef") << QScriptValue(QScriptValue::UndefinedValue)<< QString::fromAscii("undefined") << true << false; +} + +void tst_QScriptValue::constructors() +{ + QFETCH(QScriptValue, value); + QFETCH(QString, string); + QFETCH(bool, valid); + QFETCH(bool, object); + + QCOMPARE(value.isValid(), valid); + QCOMPARE(value.toString(), string); + QCOMPARE(value.isObject(), object); +} + +void tst_QScriptValue::call() +{ + QScriptEngine engine; + QScriptValue ping = engine.evaluate("( function() {return 'ping';} )"); + QScriptValue incr = engine.evaluate("( function(i) {return i + 1;} )"); + QScriptValue one(1); + QScriptValue five(5); + QScriptValue result; + + QVERIFY(one.isValid()); + QVERIFY(five.isValid()); + + QVERIFY(ping.isValid()); + QVERIFY(ping.isFunction()); + result = ping.call(); + QVERIFY(result.isValid()); + QCOMPARE(result.toString(), QString::fromUtf8("ping")); + + QVERIFY(incr.isValid()); + QVERIFY(incr.isFunction()); + result = incr.call(QScriptValue(), QScriptValueList() << one); + QVERIFY(result.isValid()); + QCOMPARE(result.toString(), QString("2")); + + QCOMPARE(incr.call(QScriptValue(), QScriptValueList() << five).toString(), QString::fromAscii("6")); + + QVERIFY(incr.call().isValid()); // Exception. +} + +void tst_QScriptValue::getSetPrototype() +{ + QScriptEngine engine; + QScriptValue object = engine.evaluate("new Object()"); + QScriptValue object2 = engine.evaluate("new Object()"); + object2.setPrototype(object); + QCOMPARE(object2.prototype().strictlyEquals(object), true); + + QScriptValue inv; + inv.setPrototype(object); + QCOMPARE(inv.prototype().isValid(), false); + + QScriptEngine otherEngine; + QScriptValue object3 = otherEngine.evaluate("new Object()"); + QTest::ignoreMessage(QtWarningMsg, "QScriptValue::setPrototype() failed: cannot set a prototype created in a different engine"); + object2.setPrototype(object3); + QCOMPARE(object2.prototype().strictlyEquals(object), true); + + // cyclic prototypes + { + QScriptValue ret = engine.evaluate("o = { }; p = { }; o.__proto__ = p; p.__proto__ = o"); + QCOMPARE(ret.isError(), true); + QCOMPARE(ret.toString(), QLatin1String("Error: cyclic __proto__ value")); + } + { + QScriptValue ret = engine.evaluate("p.__proto__ = { }"); + QCOMPARE(ret.isError(), false); + } + + QScriptValue old = object.prototype(); + QTest::ignoreMessage(QtWarningMsg, "QScriptValue::setPrototype() failed: cyclic prototype value"); + object.setPrototype(object); + QCOMPARE(object.prototype().strictlyEquals(old), true); + + object2.setPrototype(object); + QTest::ignoreMessage(QtWarningMsg, "QScriptValue::setPrototype() failed: cyclic prototype value"); + object.setPrototype(object2); + QCOMPARE(object.prototype().strictlyEquals(old), true); +} + +void tst_QScriptValue::toObjectSimple() +{ + QScriptEngine eng; + + QScriptValue undefined = eng.undefinedValue(); + QCOMPARE(undefined.toObject().isValid(), false); + QScriptValue null = eng.nullValue(); + QCOMPARE(null.toObject().isValid(), false); + QCOMPARE(QScriptValue().toObject().isValid(), false); + + QScriptValue falskt = QScriptValue(&eng, false); + { + QScriptValue tmp = falskt.toObject(); + QCOMPARE(tmp.isObject(), true); + QCOMPARE(falskt.isObject(), false); + QCOMPARE(tmp.toNumber(), falskt.toNumber()); + } + + QScriptValue sant = QScriptValue(&eng, true); + { + QScriptValue tmp = sant.toObject(); + QCOMPARE(tmp.isObject(), true); + QCOMPARE(sant.isObject(), false); + QCOMPARE(tmp.toNumber(), sant.toNumber()); + } + + QScriptValue number = QScriptValue(&eng, 123.0); + { + QScriptValue tmp = number.toObject(); + QCOMPARE(tmp.isObject(), true); + QCOMPARE(number.isObject(), false); + QCOMPARE(tmp.toNumber(), number.toNumber()); + } + + QScriptValue str = QScriptValue(&eng, QString("ciao")); + { + QScriptValue tmp = str.toObject(); + QCOMPARE(tmp.isObject(), true); + QCOMPARE(str.isObject(), false); + QCOMPARE(tmp.toString(), str.toString()); + } + + + QScriptValue object = eng.evaluate("new Object"); + { + QScriptValue tmp = object.toObject(); + QVERIFY(tmp.strictlyEquals(object)); + QCOMPARE(tmp.isObject(), true); + } + + + // V2 constructors: in this case, you have to use QScriptEngine::toObject() + { + QScriptValue undefined = QScriptValue(QScriptValue::UndefinedValue); + QVERIFY(!undefined.toObject().isValid()); + QVERIFY(!eng.toObject(undefined).isValid()); + QVERIFY(!undefined.engine()); + + QScriptValue null = QScriptValue(QScriptValue::NullValue); + QVERIFY(!null.toObject().isValid()); + QVERIFY(!eng.toObject(null).isValid()); + QVERIFY(!null.engine()); + + QScriptValue falskt = QScriptValue(false); + QVERIFY(!falskt.toObject().isValid()); + QCOMPARE(falskt.isObject(), false); + QVERIFY(!falskt.engine()); + { + QScriptValue tmp = eng.toObject(falskt); + QVERIFY(tmp.isObject()); + QVERIFY(tmp.toBool()); + QVERIFY(!falskt.isObject()); + } + + QScriptValue sant = QScriptValue(true); + QVERIFY(!sant.toObject().isValid()); + QCOMPARE(sant.isObject(), false); + QVERIFY(!sant.engine()); + { + QScriptValue tmp = eng.toObject(sant); + QVERIFY(tmp.isObject()); + QVERIFY(tmp.toBool()); + QVERIFY(!sant.isObject()); + } + + QScriptValue number = QScriptValue(123.0); + QVERIFY(!number.toObject().isValid()); + QVERIFY(!number.engine()); + QCOMPARE(number.isObject(), false); + { + QScriptValue tmp = eng.toObject(number); + QVERIFY(tmp.isObject()); + QCOMPARE(tmp.toInt32(), number.toInt32()); + QVERIFY(!number.isObject()); + } + + QScriptValue str = QScriptValue(QString::fromLatin1("ciao")); + QVERIFY(!str.toObject().isValid()); + QVERIFY(!str.engine()); + QCOMPARE(str.isObject(), false); + { + QScriptValue tmp = eng.toObject(str); + QVERIFY(tmp.isObject()); + QCOMPARE(tmp.toString(), QString::fromLatin1("ciao")); + QVERIFY(!str.isObject()); + } + } +} + +void tst_QScriptValue::setProperty_data() +{ + QTest::addColumn<QScriptValue>("property"); + QTest::addColumn<int>("flag"); + + QTest::newRow("int + keepExistingFlags") << QScriptValue(123456) << static_cast<int>(QScriptValue::KeepExistingFlags); + QTest::newRow("int + undeletable") << QScriptValue(123456) << static_cast<int>(QScriptValue::Undeletable); + QTest::newRow("int + readOnly") << QScriptValue(123456) << static_cast<int>(QScriptValue::ReadOnly); + QTest::newRow("int + readOnly|undeletable") << QScriptValue(123456) << static_cast<int>(QScriptValue::ReadOnly | QScriptValue::Undeletable); + QTest::newRow("int + skipInEnumeration") << QScriptValue(123456) << static_cast<int>(QScriptValue::SkipInEnumeration); + QTest::newRow("int + skipInEnumeration|readOnly") << QScriptValue(123456) << static_cast<int>(QScriptValue::SkipInEnumeration | QScriptValue::ReadOnly); + QTest::newRow("int + skipInEnumeration|undeletable") << QScriptValue(123456) << static_cast<int>(QScriptValue::SkipInEnumeration | QScriptValue::Undeletable); + QTest::newRow("int + skipInEnumeration|readOnly|undeletable") << QScriptValue(123456) << static_cast<int>(QScriptValue::SkipInEnumeration | QScriptValue::ReadOnly | QScriptValue::Undeletable); +} + +void tst_QScriptValue::setProperty() +{ + QFETCH(QScriptValue, property); + QFETCH(int, flag); + QScriptValue::PropertyFlags flags = static_cast<QScriptValue::PropertyFlag>(flag); + + QScriptEngine engine; + QScriptValue object = engine.evaluate("o = new Object; o"); + QScriptValue proto = engine.evaluate("p = new Object; o.__proto__ = p; p"); + engine.evaluate("o.defined1 = 1"); + engine.evaluate("o.defined2 = 1"); + engine.evaluate("o[5] = 1"); + engine.evaluate("p.overloaded1 = 1"); + engine.evaluate("o.overloaded1 = 2"); + engine.evaluate("p[6] = 1"); + engine.evaluate("o[6] = 2"); + engine.evaluate("p.overloaded2 = 1"); + engine.evaluate("o.overloaded2 = 2"); + engine.evaluate("p.overloaded3 = 1"); + engine.evaluate("o.overloaded3 = 2"); + engine.evaluate("p[7] = 1"); + engine.evaluate("o[7] = 2"); + engine.evaluate("p.overloaded4 = 1"); + engine.evaluate("o.overloaded4 = 2"); + + // tries to set undefined property directly on object. + object.setProperty(QString::fromAscii("undefined1"), property, flags); + QVERIFY(engine.evaluate("o.undefined1").strictlyEquals(property)); + object.setProperty(engine.toStringHandle("undefined2"), property, flags); + QVERIFY(object.property("undefined2").strictlyEquals(property)); + object.setProperty(4, property, flags); + QVERIFY(object.property(4).strictlyEquals(property)); + + // tries to set defined property directly on object + object.setProperty("defined1", property, flags); + QVERIFY(engine.evaluate("o.defined1").strictlyEquals(property)); + object.setProperty(engine.toStringHandle("defined2"), property, flags); + QVERIFY(object.property("defined2").strictlyEquals(property)); + object.setProperty(5, property, flags); + QVERIFY(object.property(5).strictlyEquals(property)); + + // tries to set overloaded property directly on object + object.setProperty("overloaded1", property, flags); + QVERIFY(engine.evaluate("o.overloaded1").strictlyEquals(property)); + object.setProperty(engine.toStringHandle("overloaded2"), property, flags); + QVERIFY(object.property("overloaded2").strictlyEquals(property)); + object.setProperty(6, property, flags); + QVERIFY(object.property(6).strictlyEquals(property)); + + // tries to set overloaded property directly on prototype + proto.setProperty("overloaded3", property, flags); + QVERIFY(!engine.evaluate("o.overloaded3").strictlyEquals(property)); + proto.setProperty(engine.toStringHandle("overloaded4"), property, flags); + QVERIFY(!object.property("overloaded4").strictlyEquals(property)); + proto.setProperty(7, property, flags); + QVERIFY(!object.property(7).strictlyEquals(property)); + + // tries to set undefined property directly on prototype + proto.setProperty("undefined3", property, flags); + QVERIFY(engine.evaluate("o.undefined3").strictlyEquals(property)); + proto.setProperty(engine.toStringHandle("undefined4"), property, flags); + QVERIFY(object.property("undefined4").strictlyEquals(property)); + proto.setProperty(8, property, flags); + QVERIFY(object.property(8).strictlyEquals(property)); + + bool readOnly = flags & QScriptValue::ReadOnly; + bool skipInEnumeration = flags & QScriptValue::SkipInEnumeration; + bool undeletable = flags & QScriptValue::Undeletable; + + QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(o, '4').writable").toBool()); + QEXPECT_FAIL("int + readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(o, '5').writable").toBool()); + QEXPECT_FAIL("int + readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(o, '6').writable").toBool()); + QEXPECT_FAIL("int + readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(p, '7').writable").toBool()); + QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(p, '8').writable").toBool()); + QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'undefined1').writable").toBool()); + QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'undefined2').writable").toBool()); + QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(p, 'undefined3').writable").toBool()); + QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(p, 'undefined4').writable").toBool()); + QEXPECT_FAIL("int + readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'defined1').writable").toBool()); + QEXPECT_FAIL("int + readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'defined2').writable").toBool()); + QVERIFY(engine.evaluate("!Object.getOwnPropertyDescriptor(p, 'undefined1').writable").toBool()); + QVERIFY(engine.evaluate("!Object.getOwnPropertyDescriptor(p, 'undefined1').writable").toBool()); + QEXPECT_FAIL("int + readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(p, 'overloaded3').writable").toBool()); + QEXPECT_FAIL("int + readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(p, 'overloaded4').writable").toBool()); + QEXPECT_FAIL("int + readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'overloaded1').writable").toBool()); + QEXPECT_FAIL("int + readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QVERIFY(readOnly == engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'overloaded2').writable").toBool()); + QVERIFY(!engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'overloaded3').writable").toBool()); + QVERIFY(!engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'overloaded4').writable").toBool()); + + QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(o, '4').configurable").toBool()); + QEXPECT_FAIL("int + undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(o, '5').configurable").toBool()); + QEXPECT_FAIL("int + undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(o, '6').configurable").toBool()); + QEXPECT_FAIL("int + undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(p, '7').configurable").toBool()); + QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(p, '8').configurable").toBool()); + QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'undefined1').configurable").toBool()); + QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'undefined2').configurable").toBool()); + QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(p, 'undefined3').configurable").toBool()); + QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(p, 'undefined4').configurable").toBool()); + QEXPECT_FAIL("int + undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'defined1').configurable").toBool()); + QEXPECT_FAIL("int + undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'defined2').configurable").toBool()); + QEXPECT_FAIL("int + undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'overloaded1').configurable").toBool()); + QEXPECT_FAIL("int + undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(o, 'overloaded2').configurable").toBool()); + QVERIFY(engine.evaluate("Object.getOwnPropertyDescriptor(p, 'overloaded1').configurable").toBool()); + QVERIFY(engine.evaluate("Object.getOwnPropertyDescriptor(p, 'overloaded2').configurable").toBool()); + QVERIFY(engine.evaluate("Object.getOwnPropertyDescriptor(o, 'overloaded3').configurable").toBool()); + QVERIFY(engine.evaluate("Object.getOwnPropertyDescriptor(o, 'overloaded4').configurable").toBool()); + QEXPECT_FAIL("int + undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(p, 'overloaded3').configurable").toBool()); + QEXPECT_FAIL("int + undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QVERIFY(undeletable == engine.evaluate("!Object.getOwnPropertyDescriptor(p, 'overloaded4').configurable").toBool()); + + QVERIFY(skipInEnumeration != engine.evaluate("Object.getOwnPropertyDescriptor(o, '4').enumerable").toBool()); + QEXPECT_FAIL("int + skipInEnumeration", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QVERIFY(skipInEnumeration != engine.evaluate("Object.getOwnPropertyDescriptor(o, '5').enumerable").toBool()); + QEXPECT_FAIL("int + skipInEnumeration", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QVERIFY(skipInEnumeration != engine.evaluate("Object.getOwnPropertyDescriptor(o, '6').enumerable").toBool()); + QEXPECT_FAIL("int + skipInEnumeration", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QVERIFY(skipInEnumeration != engine.evaluate("Object.getOwnPropertyDescriptor(p, '7').enumerable").toBool()); + QVERIFY(skipInEnumeration != engine.evaluate("Object.getOwnPropertyDescriptor(p, '8').enumerable").toBool()); + QVERIFY(skipInEnumeration != engine.evaluate("Object.getOwnPropertyDescriptor(o, 'undefined1').enumerable").toBool()); + QVERIFY(skipInEnumeration != engine.evaluate("Object.getOwnPropertyDescriptor(o, 'undefined2').enumerable").toBool()); + QVERIFY(skipInEnumeration != engine.evaluate("Object.getOwnPropertyDescriptor(p, 'undefined3').enumerable").toBool()); + QVERIFY(skipInEnumeration != engine.evaluate("Object.getOwnPropertyDescriptor(p, 'undefined4').enumerable").toBool()); + QEXPECT_FAIL("int + skipInEnumeration", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QVERIFY(skipInEnumeration != engine.evaluate("Object.getOwnPropertyDescriptor(o, 'overloaded1').enumerable").toBool()); + QEXPECT_FAIL("int + skipInEnumeration", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QVERIFY(skipInEnumeration != engine.evaluate("Object.getOwnPropertyDescriptor(o, 'overloaded2').enumerable").toBool()); + QVERIFY(engine.evaluate("p.propertyIsEnumerable('overloaded1')").toBool()); + QVERIFY(engine.evaluate("p.propertyIsEnumerable('overloaded2')").toBool()); + QVERIFY(engine.evaluate("o.propertyIsEnumerable('overloaded3')").toBool()); + QVERIFY(engine.evaluate("o.propertyIsEnumerable('overloaded4')").toBool()); + QEXPECT_FAIL("int + skipInEnumeration", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QVERIFY(skipInEnumeration != engine.evaluate("p.propertyIsEnumerable('overloaded3')").toBool()); + QEXPECT_FAIL("int + skipInEnumeration", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QVERIFY(skipInEnumeration != engine.evaluate("p.propertyIsEnumerable('overloaded4')").toBool()); + QEXPECT_FAIL("int + skipInEnumeration", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QVERIFY(skipInEnumeration != engine.evaluate("o.propertyIsEnumerable('defined1')").toBool()); + QEXPECT_FAIL("int + skipInEnumeration", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|readOnly", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QEXPECT_FAIL("int + skipInEnumeration|readOnly|undeletable", "WebKit bug: 40613 (The JSObjectSetProperty doesn't overwrite property flags)", Continue); + QVERIFY(skipInEnumeration != engine.evaluate("o.propertyIsEnumerable('defined2')").toBool()); +} + +void tst_QScriptValue::propertyFlag_data() +{ + QTest::addColumn<QString>("name"); + QTest::addColumn<int>("flag"); + + QTest::newRow("?Cr@jzi!%$") << "?Cr@jzi!%$" << static_cast<int>(0); + QTest::newRow("ReadOnly") << "ReadOnly" << static_cast<int>(QScriptValue::ReadOnly); + QTest::newRow("Undeletable") << "Undeletable" << static_cast<int>(QScriptValue::Undeletable); + QTest::newRow("SkipInEnumeration") << "SkipInEnumeration" << static_cast<int>(QScriptValue::SkipInEnumeration); + QTest::newRow("ReadOnly | Undeletable") << "ReadOnly_Undeletable" << static_cast<int>(QScriptValue::ReadOnly | QScriptValue::Undeletable); + QTest::newRow("ReadOnly | SkipInEnumeration") << "ReadOnly_SkipInEnumeration" << static_cast<int>(QScriptValue::ReadOnly | QScriptValue::SkipInEnumeration); + QTest::newRow("Undeletable | SkipInEnumeration") << "Undeletable_SkipInEnumeration" << static_cast<int>(QScriptValue::Undeletable | QScriptValue::SkipInEnumeration); + QTest::newRow("ReadOnly | Undeletable | SkipInEnumeration") << "ReadOnly_Undeletable_SkipInEnumeration" << static_cast<int>(QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration); +} + +void tst_QScriptValue::propertyFlag() +{ + QScriptEngine engine; + QFETCH(QString, name); + QFETCH(int, flag); + const QScriptString nameHandle = engine.toStringHandle(name); + const QString protoName = "proto" + name; + const QScriptString protoNameHandle = engine.toStringHandle(protoName); + + QScriptValue proto = engine.newObject(); + QScriptValue object = engine.newObject(); + object.setPrototype(proto); + + proto.setProperty(protoName, QScriptValue(124816), QScriptValue::PropertyFlag(flag)); + object.setProperty(name, QScriptValue(124816), QScriptValue::PropertyFlag(flag)); + + // Check using QString name + QCOMPARE(object.propertyFlags(name), QScriptValue::PropertyFlag(flag)); + QCOMPARE(object.propertyFlags(protoName, QScriptValue::ResolvePrototype), QScriptValue::PropertyFlag(flag)); + QVERIFY(!object.propertyFlags(protoName, QScriptValue::ResolveLocal)); + + // Check using QScriptString name + QCOMPARE(object.propertyFlags(nameHandle), QScriptValue::PropertyFlag(flag)); + QCOMPARE(object.propertyFlags(protoNameHandle, QScriptValue::ResolvePrototype), QScriptValue::PropertyFlag(flag)); + QVERIFY(!object.propertyFlags(protoNameHandle, QScriptValue::ResolveLocal)); +} + +void tst_QScriptValue::globalObjectChanges() +{ + // API functionality shouldn't depend on Global Object. + QScriptEngine engine; + QScriptValue array = engine.newArray(); + QScriptValue error = engine.evaluate("new Error"); + QScriptValue object = engine.newObject(); + + object.setProperty("foo", 512); + + // Remove properties form global object. + engine.evaluate("delete Object; delete Error; delete Array;"); + + QVERIFY(array.isArray()); + QVERIFY(error.isError()); + QVERIFY(object.isObject()); + + QVERIFY(object.property("foo").isValid()); + QVERIFY(object.property("foo", QScriptValue::ResolveLocal).isValid()); + object.setProperty("foo", QScriptValue()); + QVERIFY(!object.property("foo").isValid()); + QVERIFY(!object.property("foo", QScriptValue::ResolveLocal).isValid()); +} + +void tst_QScriptValue::assignAndCopyConstruct_data() +{ + QTest::addColumn<QScriptValue>("value"); + if (m_engine) + delete m_engine; + m_engine = new QScriptEngine; + // Copy & assign code is the same for all types, so it is enough to check only a few value. + for (unsigned i = 0; i < 10; ++i) { + QPair<QString, QScriptValue> testcase = initScriptValues(i); + QTest::newRow(testcase.first.toAscii().constData()) << testcase.second; + } +} + +void tst_QScriptValue::assignAndCopyConstruct() +{ + QFETCH(QScriptValue, value); + QScriptValue copy(value); + QEXPECT_FAIL("QScriptValue(QScriptValue::NullValue)", "FIXME: WebKit bug 43038", Abort); + QEXPECT_FAIL("QScriptValue(QScriptValue::UndefinedValue)", "FIXME: WebKit bug 43038", Abort); + QCOMPARE(copy.strictlyEquals(value), !value.isNumber() || !qIsNaN(value.toNumber())); + QCOMPARE(copy.engine(), value.engine()); + + QScriptValue assigned = copy; + QCOMPARE(assigned.strictlyEquals(value), !copy.isNumber() || !qIsNaN(copy.toNumber())); + QCOMPARE(assigned.engine(), assigned.engine()); + + QScriptValue other(!value.toBool()); + assigned = other; + QVERIFY(!assigned.strictlyEquals(copy)); + QVERIFY(assigned.strictlyEquals(other)); + QCOMPARE(assigned.engine(), other.engine()); +} + +QTEST_MAIN(tst_QScriptValue) diff --git a/Source/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.h b/Source/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.h new file mode 100644 index 0000000..7b7d9bc --- /dev/null +++ b/Source/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.h @@ -0,0 +1,143 @@ +/* + Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef tst_qscriptvalue_h +#define tst_qscriptvalue_h + +#include "qscriptengine.h" +#include "qscriptvalue.h" +#include <QtCore/qnumeric.h> +#include <QtTest/qtest.h> + +#define DEFINE_TEST_VALUE(expr) m_values.insert(QString::fromLatin1(#expr), expr) + +Q_DECLARE_METATYPE(QScriptValue*); +Q_DECLARE_METATYPE(QScriptValue); +typedef QPair<QString, QScriptValue> QPairQStringAndQScriptValue; +Q_DECLARE_METATYPE(QPairQStringAndQScriptValue); + +class tst_QScriptValue : public QObject { + Q_OBJECT + +public: + tst_QScriptValue(); + virtual ~tst_QScriptValue(); + +private slots: + void toStringSimple_data(); + void toStringSimple(); + void copyConstructor_data(); + void copyConstructor(); + void assignOperator_data(); + void assignOperator(); + void dataSharing(); + void constructors_data(); + void constructors(); + void getSetPrototype(); + void call(); + void ctor(); + void toObjectSimple(); + void getPropertySimple_data(); + void getPropertySimple(); + void setPropertySimple(); + void setProperty_data(); + void setProperty(); + void getSetProperty(); + void getPropertyResolveFlag(); + void propertyFlag_data(); + void propertyFlag(); + void globalObjectChanges(); + void assignAndCopyConstruct_data(); + void assignAndCopyConstruct(); + + // Generated test functions. + void isArray_data(); + void isArray(); + + void isBool_data(); + void isBool(); + + void isBoolean_data(); + void isBoolean(); + + void isError_data(); + void isError(); + + void isNumber_data(); + void isNumber(); + + void isFunction_data(); + void isFunction(); + + void isNull_data(); + void isNull(); + + void isObject_data(); + void isObject(); + + void isString_data(); + void isString(); + + void isUndefined_data(); + void isUndefined(); + + void isValid_data(); + void isValid(); + + void toString_data(); + void toString(); + + void toNumber_data(); + void toNumber(); + + void toBool_data(); + void toBool(); + + void toBoolean_data(); + void toBoolean(); + + void toInteger_data(); + void toInteger(); + + void toInt32_data(); + void toInt32(); + + void toUInt32_data(); + void toUInt32(); + + void toUInt16_data(); + void toUInt16(); + + void equals_data(); + void equals(); + + void strictlyEquals_data(); + void strictlyEquals(); + + void instanceOf_data(); + void instanceOf(); + +private: + // Generated function + QPair<QString, QScriptValue> initScriptValues(uint idx); + + QScriptEngine* m_engine; +}; + +#endif // tst_qscriptvalue_h diff --git a/Source/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue_generated_comparison.cpp b/Source/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue_generated_comparison.cpp new file mode 100644 index 0000000..3209530 --- /dev/null +++ b/Source/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue_generated_comparison.cpp @@ -0,0 +1,1799 @@ +/* + Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +/**************************************************************************** +*************** This file has been generated. DO NOT MODIFY! **************** +****************************************************************************/ + +#include "tst_qscriptvalue.h" + +static const QString equals_array[] = { + "QScriptValue() <=> QScriptValue()", + "QScriptValue(QScriptValue::UndefinedValue) <=> QScriptValue(QScriptValue::UndefinedValue)", + "QScriptValue(QScriptValue::UndefinedValue) <=> QScriptValue(QScriptValue::NullValue)", + "QScriptValue(QScriptValue::UndefinedValue) <=> QScriptValue(0, QScriptValue::UndefinedValue)", + "QScriptValue(QScriptValue::UndefinedValue) <=> QScriptValue(0, QScriptValue::NullValue)", + "QScriptValue(QScriptValue::UndefinedValue) <=> QScriptValue(engine, QScriptValue::UndefinedValue)", + "QScriptValue(QScriptValue::UndefinedValue) <=> QScriptValue(engine, QScriptValue::NullValue)", + "QScriptValue(QScriptValue::UndefinedValue) <=> engine->evaluate(\"{}\")", + "QScriptValue(QScriptValue::UndefinedValue) <=> engine->evaluate(\"undefined\")", + "QScriptValue(QScriptValue::UndefinedValue) <=> engine->evaluate(\"null\")", + "QScriptValue(QScriptValue::UndefinedValue) <=> engine->nullValue()", + "QScriptValue(QScriptValue::UndefinedValue) <=> engine->undefinedValue()", + "QScriptValue(QScriptValue::NullValue) <=> QScriptValue(QScriptValue::UndefinedValue)", + "QScriptValue(QScriptValue::NullValue) <=> QScriptValue(QScriptValue::NullValue)", + "QScriptValue(QScriptValue::NullValue) <=> QScriptValue(0, QScriptValue::UndefinedValue)", + "QScriptValue(QScriptValue::NullValue) <=> QScriptValue(0, QScriptValue::NullValue)", + "QScriptValue(QScriptValue::NullValue) <=> QScriptValue(engine, QScriptValue::UndefinedValue)", + "QScriptValue(QScriptValue::NullValue) <=> QScriptValue(engine, QScriptValue::NullValue)", + "QScriptValue(QScriptValue::NullValue) <=> engine->evaluate(\"{}\")", + "QScriptValue(QScriptValue::NullValue) <=> engine->evaluate(\"undefined\")", + "QScriptValue(QScriptValue::NullValue) <=> engine->evaluate(\"null\")", + "QScriptValue(QScriptValue::NullValue) <=> engine->nullValue()", + "QScriptValue(QScriptValue::NullValue) <=> engine->undefinedValue()", + "QScriptValue(true) <=> QScriptValue(true)", + "QScriptValue(true) <=> QScriptValue(0, true)", + "QScriptValue(true) <=> QScriptValue(engine, true)", + "QScriptValue(true) <=> engine->evaluate(\"true\")", + "QScriptValue(false) <=> QScriptValue(false)", + "QScriptValue(false) <=> QScriptValue(0)", + "QScriptValue(false) <=> QScriptValue(0.0)", + "QScriptValue(false) <=> QScriptValue(QString(\"\"))", + "QScriptValue(false) <=> QScriptValue(QString())", + "QScriptValue(false) <=> QScriptValue(QString(\"0\"))", + "QScriptValue(false) <=> QScriptValue(0, false)", + "QScriptValue(false) <=> QScriptValue(0, 0)", + "QScriptValue(false) <=> QScriptValue(0, 0.0)", + "QScriptValue(false) <=> QScriptValue(0, QString(\"\"))", + "QScriptValue(false) <=> QScriptValue(0, QString())", + "QScriptValue(false) <=> QScriptValue(0, QString(\"0\"))", + "QScriptValue(false) <=> QScriptValue(engine, false)", + "QScriptValue(false) <=> QScriptValue(engine, 0)", + "QScriptValue(false) <=> QScriptValue(engine, 0.0)", + "QScriptValue(false) <=> QScriptValue(engine, QString(\"\"))", + "QScriptValue(false) <=> QScriptValue(engine, QString())", + "QScriptValue(false) <=> QScriptValue(engine, QString(\"0\"))", + "QScriptValue(false) <=> engine->evaluate(\"[]\")", + "QScriptValue(false) <=> engine->evaluate(\"Array.prototype\")", + "QScriptValue(false) <=> engine->evaluate(\"new Array()\")", + "QScriptValue(false) <=> engine->evaluate(\"false\")", + "QScriptValue(false) <=> engine->evaluate(\"0\")", + "QScriptValue(false) <=> engine->evaluate(\"0.0\")", + "QScriptValue(false) <=> engine->evaluate(\"''\")", + "QScriptValue(false) <=> engine->evaluate(\"'0'\")", + "QScriptValue(false) <=> engine->newArray()", + "QScriptValue(int(122)) <=> QScriptValue(int(122))", + "QScriptValue(int(122)) <=> QScriptValue(0, int(122))", + "QScriptValue(int(122)) <=> QScriptValue(engine, int(122))", + "QScriptValue(int(122)) <=> engine->evaluate(\"122\")", + "QScriptValue(uint(124)) <=> QScriptValue(uint(124))", + "QScriptValue(uint(124)) <=> QScriptValue(0, uint(124))", + "QScriptValue(uint(124)) <=> QScriptValue(engine, uint(124))", + "QScriptValue(uint(124)) <=> engine->evaluate(\"124\")", + "QScriptValue(0) <=> QScriptValue(false)", + "QScriptValue(0) <=> QScriptValue(0)", + "QScriptValue(0) <=> QScriptValue(0.0)", + "QScriptValue(0) <=> QScriptValue(QString(\"\"))", + "QScriptValue(0) <=> QScriptValue(QString())", + "QScriptValue(0) <=> QScriptValue(QString(\"0\"))", + "QScriptValue(0) <=> QScriptValue(0, false)", + "QScriptValue(0) <=> QScriptValue(0, 0)", + "QScriptValue(0) <=> QScriptValue(0, 0.0)", + "QScriptValue(0) <=> QScriptValue(0, QString(\"\"))", + "QScriptValue(0) <=> QScriptValue(0, QString())", + "QScriptValue(0) <=> QScriptValue(0, QString(\"0\"))", + "QScriptValue(0) <=> QScriptValue(engine, false)", + "QScriptValue(0) <=> QScriptValue(engine, 0)", + "QScriptValue(0) <=> QScriptValue(engine, 0.0)", + "QScriptValue(0) <=> QScriptValue(engine, QString(\"\"))", + "QScriptValue(0) <=> QScriptValue(engine, QString())", + "QScriptValue(0) <=> QScriptValue(engine, QString(\"0\"))", + "QScriptValue(0) <=> engine->evaluate(\"[]\")", + "QScriptValue(0) <=> engine->evaluate(\"Array.prototype\")", + "QScriptValue(0) <=> engine->evaluate(\"new Array()\")", + "QScriptValue(0) <=> engine->evaluate(\"false\")", + "QScriptValue(0) <=> engine->evaluate(\"0\")", + "QScriptValue(0) <=> engine->evaluate(\"0.0\")", + "QScriptValue(0) <=> engine->evaluate(\"''\")", + "QScriptValue(0) <=> engine->evaluate(\"'0'\")", + "QScriptValue(0) <=> engine->newArray()", + "QScriptValue(0.0) <=> QScriptValue(false)", + "QScriptValue(0.0) <=> QScriptValue(0)", + "QScriptValue(0.0) <=> QScriptValue(0.0)", + "QScriptValue(0.0) <=> QScriptValue(QString(\"\"))", + "QScriptValue(0.0) <=> QScriptValue(QString())", + "QScriptValue(0.0) <=> QScriptValue(QString(\"0\"))", + "QScriptValue(0.0) <=> QScriptValue(0, false)", + "QScriptValue(0.0) <=> QScriptValue(0, 0)", + "QScriptValue(0.0) <=> QScriptValue(0, 0.0)", + "QScriptValue(0.0) <=> QScriptValue(0, QString(\"\"))", + "QScriptValue(0.0) <=> QScriptValue(0, QString())", + "QScriptValue(0.0) <=> QScriptValue(0, QString(\"0\"))", + "QScriptValue(0.0) <=> QScriptValue(engine, false)", + "QScriptValue(0.0) <=> QScriptValue(engine, 0)", + "QScriptValue(0.0) <=> QScriptValue(engine, 0.0)", + "QScriptValue(0.0) <=> QScriptValue(engine, QString(\"\"))", + "QScriptValue(0.0) <=> QScriptValue(engine, QString())", + "QScriptValue(0.0) <=> QScriptValue(engine, QString(\"0\"))", + "QScriptValue(0.0) <=> engine->evaluate(\"[]\")", + "QScriptValue(0.0) <=> engine->evaluate(\"Array.prototype\")", + "QScriptValue(0.0) <=> engine->evaluate(\"new Array()\")", + "QScriptValue(0.0) <=> engine->evaluate(\"false\")", + "QScriptValue(0.0) <=> engine->evaluate(\"0\")", + "QScriptValue(0.0) <=> engine->evaluate(\"0.0\")", + "QScriptValue(0.0) <=> engine->evaluate(\"''\")", + "QScriptValue(0.0) <=> engine->evaluate(\"'0'\")", + "QScriptValue(0.0) <=> engine->newArray()", + "QScriptValue(123.0) <=> QScriptValue(123.0)", + "QScriptValue(123.0) <=> QScriptValue(QString(\"123\"))", + "QScriptValue(123.0) <=> QScriptValue(0, 123.0)", + "QScriptValue(123.0) <=> QScriptValue(0, QString(\"123\"))", + "QScriptValue(123.0) <=> QScriptValue(engine, 123.0)", + "QScriptValue(123.0) <=> QScriptValue(engine, QString(\"123\"))", + "QScriptValue(123.0) <=> engine->evaluate(\"123.0\")", + "QScriptValue(123.0) <=> engine->evaluate(\"'123'\")", + "QScriptValue(6.37e-8) <=> QScriptValue(6.37e-8)", + "QScriptValue(6.37e-8) <=> QScriptValue(0, 6.37e-8)", + "QScriptValue(6.37e-8) <=> QScriptValue(engine, 6.37e-8)", + "QScriptValue(6.37e-8) <=> engine->evaluate(\"6.37e-8\")", + "QScriptValue(-6.37e-8) <=> QScriptValue(-6.37e-8)", + "QScriptValue(-6.37e-8) <=> QScriptValue(0, -6.37e-8)", + "QScriptValue(-6.37e-8) <=> QScriptValue(engine, -6.37e-8)", + "QScriptValue(-6.37e-8) <=> engine->evaluate(\"-6.37e-8\")", + "QScriptValue(0x43211234) <=> QScriptValue(0x43211234)", + "QScriptValue(0x43211234) <=> QScriptValue(0, 0x43211234)", + "QScriptValue(0x43211234) <=> QScriptValue(engine, 0x43211234)", + "QScriptValue(0x43211234) <=> engine->evaluate(\"0x43211234\")", + "QScriptValue(0x10000) <=> QScriptValue(0x10000)", + "QScriptValue(0x10000) <=> QScriptValue(0, 0x10000)", + "QScriptValue(0x10000) <=> QScriptValue(engine, 0x10000)", + "QScriptValue(0x10000) <=> engine->evaluate(\"0x10000\")", + "QScriptValue(0x10001) <=> QScriptValue(0x10001)", + "QScriptValue(0x10001) <=> QScriptValue(0, 0x10001)", + "QScriptValue(0x10001) <=> QScriptValue(engine, 0x10001)", + "QScriptValue(0x10001) <=> engine->evaluate(\"0x10001\")", + "QScriptValue(qInf()) <=> QScriptValue(qInf())", + "QScriptValue(qInf()) <=> QScriptValue(\"Infinity\")", + "QScriptValue(qInf()) <=> QScriptValue(0, qInf())", + "QScriptValue(qInf()) <=> QScriptValue(0, \"Infinity\")", + "QScriptValue(qInf()) <=> QScriptValue(engine, qInf())", + "QScriptValue(qInf()) <=> QScriptValue(engine, \"Infinity\")", + "QScriptValue(qInf()) <=> engine->evaluate(\"Infinity\")", + "QScriptValue(-qInf()) <=> QScriptValue(-qInf())", + "QScriptValue(-qInf()) <=> QScriptValue(\"-Infinity\")", + "QScriptValue(-qInf()) <=> QScriptValue(0, -qInf())", + "QScriptValue(-qInf()) <=> QScriptValue(0, \"-Infinity\")", + "QScriptValue(-qInf()) <=> QScriptValue(engine, -qInf())", + "QScriptValue(-qInf()) <=> QScriptValue(engine, \"-Infinity\")", + "QScriptValue(-qInf()) <=> engine->evaluate(\"-Infinity\")", + "QScriptValue(\"NaN\") <=> QScriptValue(\"NaN\")", + "QScriptValue(\"NaN\") <=> QScriptValue(0, \"NaN\")", + "QScriptValue(\"NaN\") <=> QScriptValue(engine, \"NaN\")", + "QScriptValue(\"Infinity\") <=> QScriptValue(qInf())", + "QScriptValue(\"Infinity\") <=> QScriptValue(\"Infinity\")", + "QScriptValue(\"Infinity\") <=> QScriptValue(0, qInf())", + "QScriptValue(\"Infinity\") <=> QScriptValue(0, \"Infinity\")", + "QScriptValue(\"Infinity\") <=> QScriptValue(engine, qInf())", + "QScriptValue(\"Infinity\") <=> QScriptValue(engine, \"Infinity\")", + "QScriptValue(\"Infinity\") <=> engine->evaluate(\"Infinity\")", + "QScriptValue(\"-Infinity\") <=> QScriptValue(-qInf())", + "QScriptValue(\"-Infinity\") <=> QScriptValue(\"-Infinity\")", + "QScriptValue(\"-Infinity\") <=> QScriptValue(0, -qInf())", + "QScriptValue(\"-Infinity\") <=> QScriptValue(0, \"-Infinity\")", + "QScriptValue(\"-Infinity\") <=> QScriptValue(engine, -qInf())", + "QScriptValue(\"-Infinity\") <=> QScriptValue(engine, \"-Infinity\")", + "QScriptValue(\"-Infinity\") <=> engine->evaluate(\"-Infinity\")", + "QScriptValue(\"ciao\") <=> QScriptValue(\"ciao\")", + "QScriptValue(\"ciao\") <=> QScriptValue(QString::fromLatin1(\"ciao\"))", + "QScriptValue(\"ciao\") <=> QScriptValue(0, \"ciao\")", + "QScriptValue(\"ciao\") <=> QScriptValue(0, QString::fromLatin1(\"ciao\"))", + "QScriptValue(\"ciao\") <=> QScriptValue(engine, \"ciao\")", + "QScriptValue(\"ciao\") <=> QScriptValue(engine, QString::fromLatin1(\"ciao\"))", + "QScriptValue(\"ciao\") <=> engine->evaluate(\"'ciao'\")", + "QScriptValue(QString::fromLatin1(\"ciao\")) <=> QScriptValue(\"ciao\")", + "QScriptValue(QString::fromLatin1(\"ciao\")) <=> QScriptValue(QString::fromLatin1(\"ciao\"))", + "QScriptValue(QString::fromLatin1(\"ciao\")) <=> QScriptValue(0, \"ciao\")", + "QScriptValue(QString::fromLatin1(\"ciao\")) <=> QScriptValue(0, QString::fromLatin1(\"ciao\"))", + "QScriptValue(QString::fromLatin1(\"ciao\")) <=> QScriptValue(engine, \"ciao\")", + "QScriptValue(QString::fromLatin1(\"ciao\")) <=> QScriptValue(engine, QString::fromLatin1(\"ciao\"))", + "QScriptValue(QString::fromLatin1(\"ciao\")) <=> engine->evaluate(\"'ciao'\")", + "QScriptValue(QString(\"\")) <=> QScriptValue(false)", + "QScriptValue(QString(\"\")) <=> QScriptValue(0)", + "QScriptValue(QString(\"\")) <=> QScriptValue(0.0)", + "QScriptValue(QString(\"\")) <=> QScriptValue(QString(\"\"))", + "QScriptValue(QString(\"\")) <=> QScriptValue(QString())", + "QScriptValue(QString(\"\")) <=> QScriptValue(0, false)", + "QScriptValue(QString(\"\")) <=> QScriptValue(0, 0)", + "QScriptValue(QString(\"\")) <=> QScriptValue(0, 0.0)", + "QScriptValue(QString(\"\")) <=> QScriptValue(0, QString(\"\"))", + "QScriptValue(QString(\"\")) <=> QScriptValue(0, QString())", + "QScriptValue(QString(\"\")) <=> QScriptValue(engine, false)", + "QScriptValue(QString(\"\")) <=> QScriptValue(engine, 0)", + "QScriptValue(QString(\"\")) <=> QScriptValue(engine, 0.0)", + "QScriptValue(QString(\"\")) <=> QScriptValue(engine, QString(\"\"))", + "QScriptValue(QString(\"\")) <=> QScriptValue(engine, QString())", + "QScriptValue(QString(\"\")) <=> engine->evaluate(\"[]\")", + "QScriptValue(QString(\"\")) <=> engine->evaluate(\"Array.prototype\")", + "QScriptValue(QString(\"\")) <=> engine->evaluate(\"new Array()\")", + "QScriptValue(QString(\"\")) <=> engine->evaluate(\"false\")", + "QScriptValue(QString(\"\")) <=> engine->evaluate(\"0\")", + "QScriptValue(QString(\"\")) <=> engine->evaluate(\"0.0\")", + "QScriptValue(QString(\"\")) <=> engine->evaluate(\"''\")", + "QScriptValue(QString(\"\")) <=> engine->newArray()", + "QScriptValue(QString()) <=> QScriptValue(false)", + "QScriptValue(QString()) <=> QScriptValue(0)", + "QScriptValue(QString()) <=> QScriptValue(0.0)", + "QScriptValue(QString()) <=> QScriptValue(QString(\"\"))", + "QScriptValue(QString()) <=> QScriptValue(QString())", + "QScriptValue(QString()) <=> QScriptValue(0, false)", + "QScriptValue(QString()) <=> QScriptValue(0, 0)", + "QScriptValue(QString()) <=> QScriptValue(0, 0.0)", + "QScriptValue(QString()) <=> QScriptValue(0, QString(\"\"))", + "QScriptValue(QString()) <=> QScriptValue(0, QString())", + "QScriptValue(QString()) <=> QScriptValue(engine, false)", + "QScriptValue(QString()) <=> QScriptValue(engine, 0)", + "QScriptValue(QString()) <=> QScriptValue(engine, 0.0)", + "QScriptValue(QString()) <=> QScriptValue(engine, QString(\"\"))", + "QScriptValue(QString()) <=> QScriptValue(engine, QString())", + "QScriptValue(QString()) <=> engine->evaluate(\"[]\")", + "QScriptValue(QString()) <=> engine->evaluate(\"Array.prototype\")", + "QScriptValue(QString()) <=> engine->evaluate(\"new Array()\")", + "QScriptValue(QString()) <=> engine->evaluate(\"false\")", + "QScriptValue(QString()) <=> engine->evaluate(\"0\")", + "QScriptValue(QString()) <=> engine->evaluate(\"0.0\")", + "QScriptValue(QString()) <=> engine->evaluate(\"''\")", + "QScriptValue(QString()) <=> engine->newArray()", + "QScriptValue(QString(\"0\")) <=> QScriptValue(false)", + "QScriptValue(QString(\"0\")) <=> QScriptValue(0)", + "QScriptValue(QString(\"0\")) <=> QScriptValue(0.0)", + "QScriptValue(QString(\"0\")) <=> QScriptValue(QString(\"0\"))", + "QScriptValue(QString(\"0\")) <=> QScriptValue(0, false)", + "QScriptValue(QString(\"0\")) <=> QScriptValue(0, 0)", + "QScriptValue(QString(\"0\")) <=> QScriptValue(0, 0.0)", + "QScriptValue(QString(\"0\")) <=> QScriptValue(0, QString(\"0\"))", + "QScriptValue(QString(\"0\")) <=> QScriptValue(engine, false)", + "QScriptValue(QString(\"0\")) <=> QScriptValue(engine, 0)", + "QScriptValue(QString(\"0\")) <=> QScriptValue(engine, 0.0)", + "QScriptValue(QString(\"0\")) <=> QScriptValue(engine, QString(\"0\"))", + "QScriptValue(QString(\"0\")) <=> engine->evaluate(\"false\")", + "QScriptValue(QString(\"0\")) <=> engine->evaluate(\"0\")", + "QScriptValue(QString(\"0\")) <=> engine->evaluate(\"0.0\")", + "QScriptValue(QString(\"0\")) <=> engine->evaluate(\"'0'\")", + "QScriptValue(QString(\"123\")) <=> QScriptValue(123.0)", + "QScriptValue(QString(\"123\")) <=> QScriptValue(QString(\"123\"))", + "QScriptValue(QString(\"123\")) <=> QScriptValue(0, 123.0)", + "QScriptValue(QString(\"123\")) <=> QScriptValue(0, QString(\"123\"))", + "QScriptValue(QString(\"123\")) <=> QScriptValue(engine, 123.0)", + "QScriptValue(QString(\"123\")) <=> QScriptValue(engine, QString(\"123\"))", + "QScriptValue(QString(\"123\")) <=> engine->evaluate(\"123.0\")", + "QScriptValue(QString(\"123\")) <=> engine->evaluate(\"'123'\")", + "QScriptValue(QString(\"12.4\")) <=> QScriptValue(QString(\"12.4\"))", + "QScriptValue(QString(\"12.4\")) <=> engine->evaluate(\"'12.4'\")", + "QScriptValue(0, QScriptValue::UndefinedValue) <=> QScriptValue(QScriptValue::UndefinedValue)", + "QScriptValue(0, QScriptValue::UndefinedValue) <=> QScriptValue(QScriptValue::NullValue)", + "QScriptValue(0, QScriptValue::UndefinedValue) <=> QScriptValue(0, QScriptValue::UndefinedValue)", + "QScriptValue(0, QScriptValue::UndefinedValue) <=> QScriptValue(0, QScriptValue::NullValue)", + "QScriptValue(0, QScriptValue::UndefinedValue) <=> QScriptValue(engine, QScriptValue::UndefinedValue)", + "QScriptValue(0, QScriptValue::UndefinedValue) <=> QScriptValue(engine, QScriptValue::NullValue)", + "QScriptValue(0, QScriptValue::UndefinedValue) <=> engine->evaluate(\"{}\")", + "QScriptValue(0, QScriptValue::UndefinedValue) <=> engine->evaluate(\"undefined\")", + "QScriptValue(0, QScriptValue::UndefinedValue) <=> engine->evaluate(\"null\")", + "QScriptValue(0, QScriptValue::UndefinedValue) <=> engine->nullValue()", + "QScriptValue(0, QScriptValue::UndefinedValue) <=> engine->undefinedValue()", + "QScriptValue(0, QScriptValue::NullValue) <=> QScriptValue(QScriptValue::UndefinedValue)", + "QScriptValue(0, QScriptValue::NullValue) <=> QScriptValue(QScriptValue::NullValue)", + "QScriptValue(0, QScriptValue::NullValue) <=> QScriptValue(0, QScriptValue::UndefinedValue)", + "QScriptValue(0, QScriptValue::NullValue) <=> QScriptValue(0, QScriptValue::NullValue)", + "QScriptValue(0, QScriptValue::NullValue) <=> QScriptValue(engine, QScriptValue::UndefinedValue)", + "QScriptValue(0, QScriptValue::NullValue) <=> QScriptValue(engine, QScriptValue::NullValue)", + "QScriptValue(0, QScriptValue::NullValue) <=> engine->evaluate(\"{}\")", + "QScriptValue(0, QScriptValue::NullValue) <=> engine->evaluate(\"undefined\")", + "QScriptValue(0, QScriptValue::NullValue) <=> engine->evaluate(\"null\")", + "QScriptValue(0, QScriptValue::NullValue) <=> engine->nullValue()", + "QScriptValue(0, QScriptValue::NullValue) <=> engine->undefinedValue()", + "QScriptValue(0, true) <=> QScriptValue(true)", + "QScriptValue(0, true) <=> QScriptValue(0, true)", + "QScriptValue(0, true) <=> QScriptValue(engine, true)", + "QScriptValue(0, true) <=> engine->evaluate(\"true\")", + "QScriptValue(0, false) <=> QScriptValue(false)", + "QScriptValue(0, false) <=> QScriptValue(0)", + "QScriptValue(0, false) <=> QScriptValue(0.0)", + "QScriptValue(0, false) <=> QScriptValue(QString(\"\"))", + "QScriptValue(0, false) <=> QScriptValue(QString())", + "QScriptValue(0, false) <=> QScriptValue(QString(\"0\"))", + "QScriptValue(0, false) <=> QScriptValue(0, false)", + "QScriptValue(0, false) <=> QScriptValue(0, 0)", + "QScriptValue(0, false) <=> QScriptValue(0, 0.0)", + "QScriptValue(0, false) <=> QScriptValue(0, QString(\"\"))", + "QScriptValue(0, false) <=> QScriptValue(0, QString())", + "QScriptValue(0, false) <=> QScriptValue(0, QString(\"0\"))", + "QScriptValue(0, false) <=> QScriptValue(engine, false)", + "QScriptValue(0, false) <=> QScriptValue(engine, 0)", + "QScriptValue(0, false) <=> QScriptValue(engine, 0.0)", + "QScriptValue(0, false) <=> QScriptValue(engine, QString(\"\"))", + "QScriptValue(0, false) <=> QScriptValue(engine, QString())", + "QScriptValue(0, false) <=> QScriptValue(engine, QString(\"0\"))", + "QScriptValue(0, false) <=> engine->evaluate(\"[]\")", + "QScriptValue(0, false) <=> engine->evaluate(\"Array.prototype\")", + "QScriptValue(0, false) <=> engine->evaluate(\"new Array()\")", + "QScriptValue(0, false) <=> engine->evaluate(\"false\")", + "QScriptValue(0, false) <=> engine->evaluate(\"0\")", + "QScriptValue(0, false) <=> engine->evaluate(\"0.0\")", + "QScriptValue(0, false) <=> engine->evaluate(\"''\")", + "QScriptValue(0, false) <=> engine->evaluate(\"'0'\")", + "QScriptValue(0, false) <=> engine->newArray()", + "QScriptValue(0, int(122)) <=> QScriptValue(int(122))", + "QScriptValue(0, int(122)) <=> QScriptValue(0, int(122))", + "QScriptValue(0, int(122)) <=> QScriptValue(engine, int(122))", + "QScriptValue(0, int(122)) <=> engine->evaluate(\"122\")", + "QScriptValue(0, uint(124)) <=> QScriptValue(uint(124))", + "QScriptValue(0, uint(124)) <=> QScriptValue(0, uint(124))", + "QScriptValue(0, uint(124)) <=> QScriptValue(engine, uint(124))", + "QScriptValue(0, uint(124)) <=> engine->evaluate(\"124\")", + "QScriptValue(0, 0) <=> QScriptValue(false)", + "QScriptValue(0, 0) <=> QScriptValue(0)", + "QScriptValue(0, 0) <=> QScriptValue(0.0)", + "QScriptValue(0, 0) <=> QScriptValue(QString(\"\"))", + "QScriptValue(0, 0) <=> QScriptValue(QString())", + "QScriptValue(0, 0) <=> QScriptValue(QString(\"0\"))", + "QScriptValue(0, 0) <=> QScriptValue(0, false)", + "QScriptValue(0, 0) <=> QScriptValue(0, 0)", + "QScriptValue(0, 0) <=> QScriptValue(0, 0.0)", + "QScriptValue(0, 0) <=> QScriptValue(0, QString(\"\"))", + "QScriptValue(0, 0) <=> QScriptValue(0, QString())", + "QScriptValue(0, 0) <=> QScriptValue(0, QString(\"0\"))", + "QScriptValue(0, 0) <=> QScriptValue(engine, false)", + "QScriptValue(0, 0) <=> QScriptValue(engine, 0)", + "QScriptValue(0, 0) <=> QScriptValue(engine, 0.0)", + "QScriptValue(0, 0) <=> QScriptValue(engine, QString(\"\"))", + "QScriptValue(0, 0) <=> QScriptValue(engine, QString())", + "QScriptValue(0, 0) <=> QScriptValue(engine, QString(\"0\"))", + "QScriptValue(0, 0) <=> engine->evaluate(\"[]\")", + "QScriptValue(0, 0) <=> engine->evaluate(\"Array.prototype\")", + "QScriptValue(0, 0) <=> engine->evaluate(\"new Array()\")", + "QScriptValue(0, 0) <=> engine->evaluate(\"false\")", + "QScriptValue(0, 0) <=> engine->evaluate(\"0\")", + "QScriptValue(0, 0) <=> engine->evaluate(\"0.0\")", + "QScriptValue(0, 0) <=> engine->evaluate(\"''\")", + "QScriptValue(0, 0) <=> engine->evaluate(\"'0'\")", + "QScriptValue(0, 0) <=> engine->newArray()", + "QScriptValue(0, 0.0) <=> QScriptValue(false)", + "QScriptValue(0, 0.0) <=> QScriptValue(0)", + "QScriptValue(0, 0.0) <=> QScriptValue(0.0)", + "QScriptValue(0, 0.0) <=> QScriptValue(QString(\"\"))", + "QScriptValue(0, 0.0) <=> QScriptValue(QString())", + "QScriptValue(0, 0.0) <=> QScriptValue(QString(\"0\"))", + "QScriptValue(0, 0.0) <=> QScriptValue(0, false)", + "QScriptValue(0, 0.0) <=> QScriptValue(0, 0)", + "QScriptValue(0, 0.0) <=> QScriptValue(0, 0.0)", + "QScriptValue(0, 0.0) <=> QScriptValue(0, QString(\"\"))", + "QScriptValue(0, 0.0) <=> QScriptValue(0, QString())", + "QScriptValue(0, 0.0) <=> QScriptValue(0, QString(\"0\"))", + "QScriptValue(0, 0.0) <=> QScriptValue(engine, false)", + "QScriptValue(0, 0.0) <=> QScriptValue(engine, 0)", + "QScriptValue(0, 0.0) <=> QScriptValue(engine, 0.0)", + "QScriptValue(0, 0.0) <=> QScriptValue(engine, QString(\"\"))", + "QScriptValue(0, 0.0) <=> QScriptValue(engine, QString())", + "QScriptValue(0, 0.0) <=> QScriptValue(engine, QString(\"0\"))", + "QScriptValue(0, 0.0) <=> engine->evaluate(\"[]\")", + "QScriptValue(0, 0.0) <=> engine->evaluate(\"Array.prototype\")", + "QScriptValue(0, 0.0) <=> engine->evaluate(\"new Array()\")", + "QScriptValue(0, 0.0) <=> engine->evaluate(\"false\")", + "QScriptValue(0, 0.0) <=> engine->evaluate(\"0\")", + "QScriptValue(0, 0.0) <=> engine->evaluate(\"0.0\")", + "QScriptValue(0, 0.0) <=> engine->evaluate(\"''\")", + "QScriptValue(0, 0.0) <=> engine->evaluate(\"'0'\")", + "QScriptValue(0, 0.0) <=> engine->newArray()", + "QScriptValue(0, 123.0) <=> QScriptValue(123.0)", + "QScriptValue(0, 123.0) <=> QScriptValue(QString(\"123\"))", + "QScriptValue(0, 123.0) <=> QScriptValue(0, 123.0)", + "QScriptValue(0, 123.0) <=> QScriptValue(0, QString(\"123\"))", + "QScriptValue(0, 123.0) <=> QScriptValue(engine, 123.0)", + "QScriptValue(0, 123.0) <=> QScriptValue(engine, QString(\"123\"))", + "QScriptValue(0, 123.0) <=> engine->evaluate(\"123.0\")", + "QScriptValue(0, 123.0) <=> engine->evaluate(\"'123'\")", + "QScriptValue(0, 6.37e-8) <=> QScriptValue(6.37e-8)", + "QScriptValue(0, 6.37e-8) <=> QScriptValue(0, 6.37e-8)", + "QScriptValue(0, 6.37e-8) <=> QScriptValue(engine, 6.37e-8)", + "QScriptValue(0, 6.37e-8) <=> engine->evaluate(\"6.37e-8\")", + "QScriptValue(0, -6.37e-8) <=> QScriptValue(-6.37e-8)", + "QScriptValue(0, -6.37e-8) <=> QScriptValue(0, -6.37e-8)", + "QScriptValue(0, -6.37e-8) <=> QScriptValue(engine, -6.37e-8)", + "QScriptValue(0, -6.37e-8) <=> engine->evaluate(\"-6.37e-8\")", + "QScriptValue(0, 0x43211234) <=> QScriptValue(0x43211234)", + "QScriptValue(0, 0x43211234) <=> QScriptValue(0, 0x43211234)", + "QScriptValue(0, 0x43211234) <=> QScriptValue(engine, 0x43211234)", + "QScriptValue(0, 0x43211234) <=> engine->evaluate(\"0x43211234\")", + "QScriptValue(0, 0x10000) <=> QScriptValue(0x10000)", + "QScriptValue(0, 0x10000) <=> QScriptValue(0, 0x10000)", + "QScriptValue(0, 0x10000) <=> QScriptValue(engine, 0x10000)", + "QScriptValue(0, 0x10000) <=> engine->evaluate(\"0x10000\")", + "QScriptValue(0, 0x10001) <=> QScriptValue(0x10001)", + "QScriptValue(0, 0x10001) <=> QScriptValue(0, 0x10001)", + "QScriptValue(0, 0x10001) <=> QScriptValue(engine, 0x10001)", + "QScriptValue(0, 0x10001) <=> engine->evaluate(\"0x10001\")", + "QScriptValue(0, qInf()) <=> QScriptValue(qInf())", + "QScriptValue(0, qInf()) <=> QScriptValue(\"Infinity\")", + "QScriptValue(0, qInf()) <=> QScriptValue(0, qInf())", + "QScriptValue(0, qInf()) <=> QScriptValue(0, \"Infinity\")", + "QScriptValue(0, qInf()) <=> QScriptValue(engine, qInf())", + "QScriptValue(0, qInf()) <=> QScriptValue(engine, \"Infinity\")", + "QScriptValue(0, qInf()) <=> engine->evaluate(\"Infinity\")", + "QScriptValue(0, -qInf()) <=> QScriptValue(-qInf())", + "QScriptValue(0, -qInf()) <=> QScriptValue(\"-Infinity\")", + "QScriptValue(0, -qInf()) <=> QScriptValue(0, -qInf())", + "QScriptValue(0, -qInf()) <=> QScriptValue(0, \"-Infinity\")", + "QScriptValue(0, -qInf()) <=> QScriptValue(engine, -qInf())", + "QScriptValue(0, -qInf()) <=> QScriptValue(engine, \"-Infinity\")", + "QScriptValue(0, -qInf()) <=> engine->evaluate(\"-Infinity\")", + "QScriptValue(0, \"NaN\") <=> QScriptValue(\"NaN\")", + "QScriptValue(0, \"NaN\") <=> QScriptValue(0, \"NaN\")", + "QScriptValue(0, \"NaN\") <=> QScriptValue(engine, \"NaN\")", + "QScriptValue(0, \"Infinity\") <=> QScriptValue(qInf())", + "QScriptValue(0, \"Infinity\") <=> QScriptValue(\"Infinity\")", + "QScriptValue(0, \"Infinity\") <=> QScriptValue(0, qInf())", + "QScriptValue(0, \"Infinity\") <=> QScriptValue(0, \"Infinity\")", + "QScriptValue(0, \"Infinity\") <=> QScriptValue(engine, qInf())", + "QScriptValue(0, \"Infinity\") <=> QScriptValue(engine, \"Infinity\")", + "QScriptValue(0, \"Infinity\") <=> engine->evaluate(\"Infinity\")", + "QScriptValue(0, \"-Infinity\") <=> QScriptValue(-qInf())", + "QScriptValue(0, \"-Infinity\") <=> QScriptValue(\"-Infinity\")", + "QScriptValue(0, \"-Infinity\") <=> QScriptValue(0, -qInf())", + "QScriptValue(0, \"-Infinity\") <=> QScriptValue(0, \"-Infinity\")", + "QScriptValue(0, \"-Infinity\") <=> QScriptValue(engine, -qInf())", + "QScriptValue(0, \"-Infinity\") <=> QScriptValue(engine, \"-Infinity\")", + "QScriptValue(0, \"-Infinity\") <=> engine->evaluate(\"-Infinity\")", + "QScriptValue(0, \"ciao\") <=> QScriptValue(\"ciao\")", + "QScriptValue(0, \"ciao\") <=> QScriptValue(QString::fromLatin1(\"ciao\"))", + "QScriptValue(0, \"ciao\") <=> QScriptValue(0, \"ciao\")", + "QScriptValue(0, \"ciao\") <=> QScriptValue(0, QString::fromLatin1(\"ciao\"))", + "QScriptValue(0, \"ciao\") <=> QScriptValue(engine, \"ciao\")", + "QScriptValue(0, \"ciao\") <=> QScriptValue(engine, QString::fromLatin1(\"ciao\"))", + "QScriptValue(0, \"ciao\") <=> engine->evaluate(\"'ciao'\")", + "QScriptValue(0, QString::fromLatin1(\"ciao\")) <=> QScriptValue(\"ciao\")", + "QScriptValue(0, QString::fromLatin1(\"ciao\")) <=> QScriptValue(QString::fromLatin1(\"ciao\"))", + "QScriptValue(0, QString::fromLatin1(\"ciao\")) <=> QScriptValue(0, \"ciao\")", + "QScriptValue(0, QString::fromLatin1(\"ciao\")) <=> QScriptValue(0, QString::fromLatin1(\"ciao\"))", + "QScriptValue(0, QString::fromLatin1(\"ciao\")) <=> QScriptValue(engine, \"ciao\")", + "QScriptValue(0, QString::fromLatin1(\"ciao\")) <=> QScriptValue(engine, QString::fromLatin1(\"ciao\"))", + "QScriptValue(0, QString::fromLatin1(\"ciao\")) <=> engine->evaluate(\"'ciao'\")", + "QScriptValue(0, QString(\"\")) <=> QScriptValue(false)", + "QScriptValue(0, QString(\"\")) <=> QScriptValue(0)", + "QScriptValue(0, QString(\"\")) <=> QScriptValue(0.0)", + "QScriptValue(0, QString(\"\")) <=> QScriptValue(QString(\"\"))", + "QScriptValue(0, QString(\"\")) <=> QScriptValue(QString())", + "QScriptValue(0, QString(\"\")) <=> QScriptValue(0, false)", + "QScriptValue(0, QString(\"\")) <=> QScriptValue(0, 0)", + "QScriptValue(0, QString(\"\")) <=> QScriptValue(0, 0.0)", + "QScriptValue(0, QString(\"\")) <=> QScriptValue(0, QString(\"\"))", + "QScriptValue(0, QString(\"\")) <=> QScriptValue(0, QString())", + "QScriptValue(0, QString(\"\")) <=> QScriptValue(engine, false)", + "QScriptValue(0, QString(\"\")) <=> QScriptValue(engine, 0)", + "QScriptValue(0, QString(\"\")) <=> QScriptValue(engine, 0.0)", + "QScriptValue(0, QString(\"\")) <=> QScriptValue(engine, QString(\"\"))", + "QScriptValue(0, QString(\"\")) <=> QScriptValue(engine, QString())", + "QScriptValue(0, QString(\"\")) <=> engine->evaluate(\"[]\")", + "QScriptValue(0, QString(\"\")) <=> engine->evaluate(\"Array.prototype\")", + "QScriptValue(0, QString(\"\")) <=> engine->evaluate(\"new Array()\")", + "QScriptValue(0, QString(\"\")) <=> engine->evaluate(\"false\")", + "QScriptValue(0, QString(\"\")) <=> engine->evaluate(\"0\")", + "QScriptValue(0, QString(\"\")) <=> engine->evaluate(\"0.0\")", + "QScriptValue(0, QString(\"\")) <=> engine->evaluate(\"''\")", + "QScriptValue(0, QString(\"\")) <=> engine->newArray()", + "QScriptValue(0, QString()) <=> QScriptValue(false)", + "QScriptValue(0, QString()) <=> QScriptValue(0)", + "QScriptValue(0, QString()) <=> QScriptValue(0.0)", + "QScriptValue(0, QString()) <=> QScriptValue(QString(\"\"))", + "QScriptValue(0, QString()) <=> QScriptValue(QString())", + "QScriptValue(0, QString()) <=> QScriptValue(0, false)", + "QScriptValue(0, QString()) <=> QScriptValue(0, 0)", + "QScriptValue(0, QString()) <=> QScriptValue(0, 0.0)", + "QScriptValue(0, QString()) <=> QScriptValue(0, QString(\"\"))", + "QScriptValue(0, QString()) <=> QScriptValue(0, QString())", + "QScriptValue(0, QString()) <=> QScriptValue(engine, false)", + "QScriptValue(0, QString()) <=> QScriptValue(engine, 0)", + "QScriptValue(0, QString()) <=> QScriptValue(engine, 0.0)", + "QScriptValue(0, QString()) <=> QScriptValue(engine, QString(\"\"))", + "QScriptValue(0, QString()) <=> QScriptValue(engine, QString())", + "QScriptValue(0, QString()) <=> engine->evaluate(\"[]\")", + "QScriptValue(0, QString()) <=> engine->evaluate(\"Array.prototype\")", + "QScriptValue(0, QString()) <=> engine->evaluate(\"new Array()\")", + "QScriptValue(0, QString()) <=> engine->evaluate(\"false\")", + "QScriptValue(0, QString()) <=> engine->evaluate(\"0\")", + "QScriptValue(0, QString()) <=> engine->evaluate(\"0.0\")", + "QScriptValue(0, QString()) <=> engine->evaluate(\"''\")", + "QScriptValue(0, QString()) <=> engine->newArray()", + "QScriptValue(0, QString(\"0\")) <=> QScriptValue(false)", + "QScriptValue(0, QString(\"0\")) <=> QScriptValue(0)", + "QScriptValue(0, QString(\"0\")) <=> QScriptValue(0.0)", + "QScriptValue(0, QString(\"0\")) <=> QScriptValue(QString(\"0\"))", + "QScriptValue(0, QString(\"0\")) <=> QScriptValue(0, false)", + "QScriptValue(0, QString(\"0\")) <=> QScriptValue(0, 0)", + "QScriptValue(0, QString(\"0\")) <=> QScriptValue(0, 0.0)", + "QScriptValue(0, QString(\"0\")) <=> QScriptValue(0, QString(\"0\"))", + "QScriptValue(0, QString(\"0\")) <=> QScriptValue(engine, false)", + "QScriptValue(0, QString(\"0\")) <=> QScriptValue(engine, 0)", + "QScriptValue(0, QString(\"0\")) <=> QScriptValue(engine, 0.0)", + "QScriptValue(0, QString(\"0\")) <=> QScriptValue(engine, QString(\"0\"))", + "QScriptValue(0, QString(\"0\")) <=> engine->evaluate(\"false\")", + "QScriptValue(0, QString(\"0\")) <=> engine->evaluate(\"0\")", + "QScriptValue(0, QString(\"0\")) <=> engine->evaluate(\"0.0\")", + "QScriptValue(0, QString(\"0\")) <=> engine->evaluate(\"'0'\")", + "QScriptValue(0, QString(\"123\")) <=> QScriptValue(123.0)", + "QScriptValue(0, QString(\"123\")) <=> QScriptValue(QString(\"123\"))", + "QScriptValue(0, QString(\"123\")) <=> QScriptValue(0, 123.0)", + "QScriptValue(0, QString(\"123\")) <=> QScriptValue(0, QString(\"123\"))", + "QScriptValue(0, QString(\"123\")) <=> QScriptValue(engine, 123.0)", + "QScriptValue(0, QString(\"123\")) <=> QScriptValue(engine, QString(\"123\"))", + "QScriptValue(0, QString(\"123\")) <=> engine->evaluate(\"123.0\")", + "QScriptValue(0, QString(\"123\")) <=> engine->evaluate(\"'123'\")", + "QScriptValue(0, QString(\"12.3\")) <=> QScriptValue(0, QString(\"12.3\"))", + "QScriptValue(engine, QScriptValue::UndefinedValue) <=> QScriptValue(QScriptValue::UndefinedValue)", + "QScriptValue(engine, QScriptValue::UndefinedValue) <=> QScriptValue(QScriptValue::NullValue)", + "QScriptValue(engine, QScriptValue::UndefinedValue) <=> QScriptValue(0, QScriptValue::UndefinedValue)", + "QScriptValue(engine, QScriptValue::UndefinedValue) <=> QScriptValue(0, QScriptValue::NullValue)", + "QScriptValue(engine, QScriptValue::UndefinedValue) <=> QScriptValue(engine, QScriptValue::UndefinedValue)", + "QScriptValue(engine, QScriptValue::UndefinedValue) <=> QScriptValue(engine, QScriptValue::NullValue)", + "QScriptValue(engine, QScriptValue::UndefinedValue) <=> engine->evaluate(\"{}\")", + "QScriptValue(engine, QScriptValue::UndefinedValue) <=> engine->evaluate(\"undefined\")", + "QScriptValue(engine, QScriptValue::UndefinedValue) <=> engine->evaluate(\"null\")", + "QScriptValue(engine, QScriptValue::UndefinedValue) <=> engine->nullValue()", + "QScriptValue(engine, QScriptValue::UndefinedValue) <=> engine->undefinedValue()", + "QScriptValue(engine, QScriptValue::NullValue) <=> QScriptValue(QScriptValue::UndefinedValue)", + "QScriptValue(engine, QScriptValue::NullValue) <=> QScriptValue(QScriptValue::NullValue)", + "QScriptValue(engine, QScriptValue::NullValue) <=> QScriptValue(0, QScriptValue::UndefinedValue)", + "QScriptValue(engine, QScriptValue::NullValue) <=> QScriptValue(0, QScriptValue::NullValue)", + "QScriptValue(engine, QScriptValue::NullValue) <=> QScriptValue(engine, QScriptValue::UndefinedValue)", + "QScriptValue(engine, QScriptValue::NullValue) <=> QScriptValue(engine, QScriptValue::NullValue)", + "QScriptValue(engine, QScriptValue::NullValue) <=> engine->evaluate(\"{}\")", + "QScriptValue(engine, QScriptValue::NullValue) <=> engine->evaluate(\"undefined\")", + "QScriptValue(engine, QScriptValue::NullValue) <=> engine->evaluate(\"null\")", + "QScriptValue(engine, QScriptValue::NullValue) <=> engine->nullValue()", + "QScriptValue(engine, QScriptValue::NullValue) <=> engine->undefinedValue()", + "QScriptValue(engine, true) <=> QScriptValue(true)", + "QScriptValue(engine, true) <=> QScriptValue(0, true)", + "QScriptValue(engine, true) <=> QScriptValue(engine, true)", + "QScriptValue(engine, true) <=> engine->evaluate(\"true\")", + "QScriptValue(engine, false) <=> QScriptValue(false)", + "QScriptValue(engine, false) <=> QScriptValue(0)", + "QScriptValue(engine, false) <=> QScriptValue(0.0)", + "QScriptValue(engine, false) <=> QScriptValue(QString(\"\"))", + "QScriptValue(engine, false) <=> QScriptValue(QString())", + "QScriptValue(engine, false) <=> QScriptValue(QString(\"0\"))", + "QScriptValue(engine, false) <=> QScriptValue(0, false)", + "QScriptValue(engine, false) <=> QScriptValue(0, 0)", + "QScriptValue(engine, false) <=> QScriptValue(0, 0.0)", + "QScriptValue(engine, false) <=> QScriptValue(0, QString(\"\"))", + "QScriptValue(engine, false) <=> QScriptValue(0, QString())", + "QScriptValue(engine, false) <=> QScriptValue(0, QString(\"0\"))", + "QScriptValue(engine, false) <=> QScriptValue(engine, false)", + "QScriptValue(engine, false) <=> QScriptValue(engine, 0)", + "QScriptValue(engine, false) <=> QScriptValue(engine, 0.0)", + "QScriptValue(engine, false) <=> QScriptValue(engine, QString(\"\"))", + "QScriptValue(engine, false) <=> QScriptValue(engine, QString())", + "QScriptValue(engine, false) <=> QScriptValue(engine, QString(\"0\"))", + "QScriptValue(engine, false) <=> engine->evaluate(\"[]\")", + "QScriptValue(engine, false) <=> engine->evaluate(\"Array.prototype\")", + "QScriptValue(engine, false) <=> engine->evaluate(\"new Array()\")", + "QScriptValue(engine, false) <=> engine->evaluate(\"false\")", + "QScriptValue(engine, false) <=> engine->evaluate(\"0\")", + "QScriptValue(engine, false) <=> engine->evaluate(\"0.0\")", + "QScriptValue(engine, false) <=> engine->evaluate(\"''\")", + "QScriptValue(engine, false) <=> engine->evaluate(\"'0'\")", + "QScriptValue(engine, false) <=> engine->newArray()", + "QScriptValue(engine, int(122)) <=> QScriptValue(int(122))", + "QScriptValue(engine, int(122)) <=> QScriptValue(0, int(122))", + "QScriptValue(engine, int(122)) <=> QScriptValue(engine, int(122))", + "QScriptValue(engine, int(122)) <=> engine->evaluate(\"122\")", + "QScriptValue(engine, uint(124)) <=> QScriptValue(uint(124))", + "QScriptValue(engine, uint(124)) <=> QScriptValue(0, uint(124))", + "QScriptValue(engine, uint(124)) <=> QScriptValue(engine, uint(124))", + "QScriptValue(engine, uint(124)) <=> engine->evaluate(\"124\")", + "QScriptValue(engine, 0) <=> QScriptValue(false)", + "QScriptValue(engine, 0) <=> QScriptValue(0)", + "QScriptValue(engine, 0) <=> QScriptValue(0.0)", + "QScriptValue(engine, 0) <=> QScriptValue(QString(\"\"))", + "QScriptValue(engine, 0) <=> QScriptValue(QString())", + "QScriptValue(engine, 0) <=> QScriptValue(QString(\"0\"))", + "QScriptValue(engine, 0) <=> QScriptValue(0, false)", + "QScriptValue(engine, 0) <=> QScriptValue(0, 0)", + "QScriptValue(engine, 0) <=> QScriptValue(0, 0.0)", + "QScriptValue(engine, 0) <=> QScriptValue(0, QString(\"\"))", + "QScriptValue(engine, 0) <=> QScriptValue(0, QString())", + "QScriptValue(engine, 0) <=> QScriptValue(0, QString(\"0\"))", + "QScriptValue(engine, 0) <=> QScriptValue(engine, false)", + "QScriptValue(engine, 0) <=> QScriptValue(engine, 0)", + "QScriptValue(engine, 0) <=> QScriptValue(engine, 0.0)", + "QScriptValue(engine, 0) <=> QScriptValue(engine, QString(\"\"))", + "QScriptValue(engine, 0) <=> QScriptValue(engine, QString())", + "QScriptValue(engine, 0) <=> QScriptValue(engine, QString(\"0\"))", + "QScriptValue(engine, 0) <=> engine->evaluate(\"[]\")", + "QScriptValue(engine, 0) <=> engine->evaluate(\"Array.prototype\")", + "QScriptValue(engine, 0) <=> engine->evaluate(\"new Array()\")", + "QScriptValue(engine, 0) <=> engine->evaluate(\"false\")", + "QScriptValue(engine, 0) <=> engine->evaluate(\"0\")", + "QScriptValue(engine, 0) <=> engine->evaluate(\"0.0\")", + "QScriptValue(engine, 0) <=> engine->evaluate(\"''\")", + "QScriptValue(engine, 0) <=> engine->evaluate(\"'0'\")", + "QScriptValue(engine, 0) <=> engine->newArray()", + "QScriptValue(engine, 0.0) <=> QScriptValue(false)", + "QScriptValue(engine, 0.0) <=> QScriptValue(0)", + "QScriptValue(engine, 0.0) <=> QScriptValue(0.0)", + "QScriptValue(engine, 0.0) <=> QScriptValue(QString(\"\"))", + "QScriptValue(engine, 0.0) <=> QScriptValue(QString())", + "QScriptValue(engine, 0.0) <=> QScriptValue(QString(\"0\"))", + "QScriptValue(engine, 0.0) <=> QScriptValue(0, false)", + "QScriptValue(engine, 0.0) <=> QScriptValue(0, 0)", + "QScriptValue(engine, 0.0) <=> QScriptValue(0, 0.0)", + "QScriptValue(engine, 0.0) <=> QScriptValue(0, QString(\"\"))", + "QScriptValue(engine, 0.0) <=> QScriptValue(0, QString())", + "QScriptValue(engine, 0.0) <=> QScriptValue(0, QString(\"0\"))", + "QScriptValue(engine, 0.0) <=> QScriptValue(engine, false)", + "QScriptValue(engine, 0.0) <=> QScriptValue(engine, 0)", + "QScriptValue(engine, 0.0) <=> QScriptValue(engine, 0.0)", + "QScriptValue(engine, 0.0) <=> QScriptValue(engine, QString(\"\"))", + "QScriptValue(engine, 0.0) <=> QScriptValue(engine, QString())", + "QScriptValue(engine, 0.0) <=> QScriptValue(engine, QString(\"0\"))", + "QScriptValue(engine, 0.0) <=> engine->evaluate(\"[]\")", + "QScriptValue(engine, 0.0) <=> engine->evaluate(\"Array.prototype\")", + "QScriptValue(engine, 0.0) <=> engine->evaluate(\"new Array()\")", + "QScriptValue(engine, 0.0) <=> engine->evaluate(\"false\")", + "QScriptValue(engine, 0.0) <=> engine->evaluate(\"0\")", + "QScriptValue(engine, 0.0) <=> engine->evaluate(\"0.0\")", + "QScriptValue(engine, 0.0) <=> engine->evaluate(\"''\")", + "QScriptValue(engine, 0.0) <=> engine->evaluate(\"'0'\")", + "QScriptValue(engine, 0.0) <=> engine->newArray()", + "QScriptValue(engine, 123.0) <=> QScriptValue(123.0)", + "QScriptValue(engine, 123.0) <=> QScriptValue(QString(\"123\"))", + "QScriptValue(engine, 123.0) <=> QScriptValue(0, 123.0)", + "QScriptValue(engine, 123.0) <=> QScriptValue(0, QString(\"123\"))", + "QScriptValue(engine, 123.0) <=> QScriptValue(engine, 123.0)", + "QScriptValue(engine, 123.0) <=> QScriptValue(engine, QString(\"123\"))", + "QScriptValue(engine, 123.0) <=> engine->evaluate(\"123.0\")", + "QScriptValue(engine, 123.0) <=> engine->evaluate(\"'123'\")", + "QScriptValue(engine, 6.37e-8) <=> QScriptValue(6.37e-8)", + "QScriptValue(engine, 6.37e-8) <=> QScriptValue(0, 6.37e-8)", + "QScriptValue(engine, 6.37e-8) <=> QScriptValue(engine, 6.37e-8)", + "QScriptValue(engine, 6.37e-8) <=> engine->evaluate(\"6.37e-8\")", + "QScriptValue(engine, -6.37e-8) <=> QScriptValue(-6.37e-8)", + "QScriptValue(engine, -6.37e-8) <=> QScriptValue(0, -6.37e-8)", + "QScriptValue(engine, -6.37e-8) <=> QScriptValue(engine, -6.37e-8)", + "QScriptValue(engine, -6.37e-8) <=> engine->evaluate(\"-6.37e-8\")", + "QScriptValue(engine, 0x43211234) <=> QScriptValue(0x43211234)", + "QScriptValue(engine, 0x43211234) <=> QScriptValue(0, 0x43211234)", + "QScriptValue(engine, 0x43211234) <=> QScriptValue(engine, 0x43211234)", + "QScriptValue(engine, 0x43211234) <=> engine->evaluate(\"0x43211234\")", + "QScriptValue(engine, 0x10000) <=> QScriptValue(0x10000)", + "QScriptValue(engine, 0x10000) <=> QScriptValue(0, 0x10000)", + "QScriptValue(engine, 0x10000) <=> QScriptValue(engine, 0x10000)", + "QScriptValue(engine, 0x10000) <=> engine->evaluate(\"0x10000\")", + "QScriptValue(engine, 0x10001) <=> QScriptValue(0x10001)", + "QScriptValue(engine, 0x10001) <=> QScriptValue(0, 0x10001)", + "QScriptValue(engine, 0x10001) <=> QScriptValue(engine, 0x10001)", + "QScriptValue(engine, 0x10001) <=> engine->evaluate(\"0x10001\")", + "QScriptValue(engine, qInf()) <=> QScriptValue(qInf())", + "QScriptValue(engine, qInf()) <=> QScriptValue(\"Infinity\")", + "QScriptValue(engine, qInf()) <=> QScriptValue(0, qInf())", + "QScriptValue(engine, qInf()) <=> QScriptValue(0, \"Infinity\")", + "QScriptValue(engine, qInf()) <=> QScriptValue(engine, qInf())", + "QScriptValue(engine, qInf()) <=> QScriptValue(engine, \"Infinity\")", + "QScriptValue(engine, qInf()) <=> engine->evaluate(\"Infinity\")", + "QScriptValue(engine, -qInf()) <=> QScriptValue(-qInf())", + "QScriptValue(engine, -qInf()) <=> QScriptValue(\"-Infinity\")", + "QScriptValue(engine, -qInf()) <=> QScriptValue(0, -qInf())", + "QScriptValue(engine, -qInf()) <=> QScriptValue(0, \"-Infinity\")", + "QScriptValue(engine, -qInf()) <=> QScriptValue(engine, -qInf())", + "QScriptValue(engine, -qInf()) <=> QScriptValue(engine, \"-Infinity\")", + "QScriptValue(engine, -qInf()) <=> engine->evaluate(\"-Infinity\")", + "QScriptValue(engine, \"NaN\") <=> QScriptValue(\"NaN\")", + "QScriptValue(engine, \"NaN\") <=> QScriptValue(0, \"NaN\")", + "QScriptValue(engine, \"NaN\") <=> QScriptValue(engine, \"NaN\")", + "QScriptValue(engine, \"Infinity\") <=> QScriptValue(qInf())", + "QScriptValue(engine, \"Infinity\") <=> QScriptValue(\"Infinity\")", + "QScriptValue(engine, \"Infinity\") <=> QScriptValue(0, qInf())", + "QScriptValue(engine, \"Infinity\") <=> QScriptValue(0, \"Infinity\")", + "QScriptValue(engine, \"Infinity\") <=> QScriptValue(engine, qInf())", + "QScriptValue(engine, \"Infinity\") <=> QScriptValue(engine, \"Infinity\")", + "QScriptValue(engine, \"Infinity\") <=> engine->evaluate(\"Infinity\")", + "QScriptValue(engine, \"-Infinity\") <=> QScriptValue(-qInf())", + "QScriptValue(engine, \"-Infinity\") <=> QScriptValue(\"-Infinity\")", + "QScriptValue(engine, \"-Infinity\") <=> QScriptValue(0, -qInf())", + "QScriptValue(engine, \"-Infinity\") <=> QScriptValue(0, \"-Infinity\")", + "QScriptValue(engine, \"-Infinity\") <=> QScriptValue(engine, -qInf())", + "QScriptValue(engine, \"-Infinity\") <=> QScriptValue(engine, \"-Infinity\")", + "QScriptValue(engine, \"-Infinity\") <=> engine->evaluate(\"-Infinity\")", + "QScriptValue(engine, \"ciao\") <=> QScriptValue(\"ciao\")", + "QScriptValue(engine, \"ciao\") <=> QScriptValue(QString::fromLatin1(\"ciao\"))", + "QScriptValue(engine, \"ciao\") <=> QScriptValue(0, \"ciao\")", + "QScriptValue(engine, \"ciao\") <=> QScriptValue(0, QString::fromLatin1(\"ciao\"))", + "QScriptValue(engine, \"ciao\") <=> QScriptValue(engine, \"ciao\")", + "QScriptValue(engine, \"ciao\") <=> QScriptValue(engine, QString::fromLatin1(\"ciao\"))", + "QScriptValue(engine, \"ciao\") <=> engine->evaluate(\"'ciao'\")", + "QScriptValue(engine, QString::fromLatin1(\"ciao\")) <=> QScriptValue(\"ciao\")", + "QScriptValue(engine, QString::fromLatin1(\"ciao\")) <=> QScriptValue(QString::fromLatin1(\"ciao\"))", + "QScriptValue(engine, QString::fromLatin1(\"ciao\")) <=> QScriptValue(0, \"ciao\")", + "QScriptValue(engine, QString::fromLatin1(\"ciao\")) <=> QScriptValue(0, QString::fromLatin1(\"ciao\"))", + "QScriptValue(engine, QString::fromLatin1(\"ciao\")) <=> QScriptValue(engine, \"ciao\")", + "QScriptValue(engine, QString::fromLatin1(\"ciao\")) <=> QScriptValue(engine, QString::fromLatin1(\"ciao\"))", + "QScriptValue(engine, QString::fromLatin1(\"ciao\")) <=> engine->evaluate(\"'ciao'\")", + "QScriptValue(engine, QString(\"\")) <=> QScriptValue(false)", + "QScriptValue(engine, QString(\"\")) <=> QScriptValue(0)", + "QScriptValue(engine, QString(\"\")) <=> QScriptValue(0.0)", + "QScriptValue(engine, QString(\"\")) <=> QScriptValue(QString(\"\"))", + "QScriptValue(engine, QString(\"\")) <=> QScriptValue(QString())", + "QScriptValue(engine, QString(\"\")) <=> QScriptValue(0, false)", + "QScriptValue(engine, QString(\"\")) <=> QScriptValue(0, 0)", + "QScriptValue(engine, QString(\"\")) <=> QScriptValue(0, 0.0)", + "QScriptValue(engine, QString(\"\")) <=> QScriptValue(0, QString(\"\"))", + "QScriptValue(engine, QString(\"\")) <=> QScriptValue(0, QString())", + "QScriptValue(engine, QString(\"\")) <=> QScriptValue(engine, false)", + "QScriptValue(engine, QString(\"\")) <=> QScriptValue(engine, 0)", + "QScriptValue(engine, QString(\"\")) <=> QScriptValue(engine, 0.0)", + "QScriptValue(engine, QString(\"\")) <=> QScriptValue(engine, QString(\"\"))", + "QScriptValue(engine, QString(\"\")) <=> QScriptValue(engine, QString())", + "QScriptValue(engine, QString(\"\")) <=> engine->evaluate(\"[]\")", + "QScriptValue(engine, QString(\"\")) <=> engine->evaluate(\"Array.prototype\")", + "QScriptValue(engine, QString(\"\")) <=> engine->evaluate(\"new Array()\")", + "QScriptValue(engine, QString(\"\")) <=> engine->evaluate(\"false\")", + "QScriptValue(engine, QString(\"\")) <=> engine->evaluate(\"0\")", + "QScriptValue(engine, QString(\"\")) <=> engine->evaluate(\"0.0\")", + "QScriptValue(engine, QString(\"\")) <=> engine->evaluate(\"''\")", + "QScriptValue(engine, QString(\"\")) <=> engine->newArray()", + "QScriptValue(engine, QString()) <=> QScriptValue(false)", + "QScriptValue(engine, QString()) <=> QScriptValue(0)", + "QScriptValue(engine, QString()) <=> QScriptValue(0.0)", + "QScriptValue(engine, QString()) <=> QScriptValue(QString(\"\"))", + "QScriptValue(engine, QString()) <=> QScriptValue(QString())", + "QScriptValue(engine, QString()) <=> QScriptValue(0, false)", + "QScriptValue(engine, QString()) <=> QScriptValue(0, 0)", + "QScriptValue(engine, QString()) <=> QScriptValue(0, 0.0)", + "QScriptValue(engine, QString()) <=> QScriptValue(0, QString(\"\"))", + "QScriptValue(engine, QString()) <=> QScriptValue(0, QString())", + "QScriptValue(engine, QString()) <=> QScriptValue(engine, false)", + "QScriptValue(engine, QString()) <=> QScriptValue(engine, 0)", + "QScriptValue(engine, QString()) <=> QScriptValue(engine, 0.0)", + "QScriptValue(engine, QString()) <=> QScriptValue(engine, QString(\"\"))", + "QScriptValue(engine, QString()) <=> QScriptValue(engine, QString())", + "QScriptValue(engine, QString()) <=> engine->evaluate(\"[]\")", + "QScriptValue(engine, QString()) <=> engine->evaluate(\"Array.prototype\")", + "QScriptValue(engine, QString()) <=> engine->evaluate(\"new Array()\")", + "QScriptValue(engine, QString()) <=> engine->evaluate(\"false\")", + "QScriptValue(engine, QString()) <=> engine->evaluate(\"0\")", + "QScriptValue(engine, QString()) <=> engine->evaluate(\"0.0\")", + "QScriptValue(engine, QString()) <=> engine->evaluate(\"''\")", + "QScriptValue(engine, QString()) <=> engine->newArray()", + "QScriptValue(engine, QString(\"0\")) <=> QScriptValue(false)", + "QScriptValue(engine, QString(\"0\")) <=> QScriptValue(0)", + "QScriptValue(engine, QString(\"0\")) <=> QScriptValue(0.0)", + "QScriptValue(engine, QString(\"0\")) <=> QScriptValue(QString(\"0\"))", + "QScriptValue(engine, QString(\"0\")) <=> QScriptValue(0, false)", + "QScriptValue(engine, QString(\"0\")) <=> QScriptValue(0, 0)", + "QScriptValue(engine, QString(\"0\")) <=> QScriptValue(0, 0.0)", + "QScriptValue(engine, QString(\"0\")) <=> QScriptValue(0, QString(\"0\"))", + "QScriptValue(engine, QString(\"0\")) <=> QScriptValue(engine, false)", + "QScriptValue(engine, QString(\"0\")) <=> QScriptValue(engine, 0)", + "QScriptValue(engine, QString(\"0\")) <=> QScriptValue(engine, 0.0)", + "QScriptValue(engine, QString(\"0\")) <=> QScriptValue(engine, QString(\"0\"))", + "QScriptValue(engine, QString(\"0\")) <=> engine->evaluate(\"false\")", + "QScriptValue(engine, QString(\"0\")) <=> engine->evaluate(\"0\")", + "QScriptValue(engine, QString(\"0\")) <=> engine->evaluate(\"0.0\")", + "QScriptValue(engine, QString(\"0\")) <=> engine->evaluate(\"'0'\")", + "QScriptValue(engine, QString(\"123\")) <=> QScriptValue(123.0)", + "QScriptValue(engine, QString(\"123\")) <=> QScriptValue(QString(\"123\"))", + "QScriptValue(engine, QString(\"123\")) <=> QScriptValue(0, 123.0)", + "QScriptValue(engine, QString(\"123\")) <=> QScriptValue(0, QString(\"123\"))", + "QScriptValue(engine, QString(\"123\")) <=> QScriptValue(engine, 123.0)", + "QScriptValue(engine, QString(\"123\")) <=> QScriptValue(engine, QString(\"123\"))", + "QScriptValue(engine, QString(\"123\")) <=> engine->evaluate(\"123.0\")", + "QScriptValue(engine, QString(\"123\")) <=> engine->evaluate(\"'123'\")", + "QScriptValue(engine, QString(\"1.23\")) <=> QScriptValue(engine, QString(\"1.23\"))", + "engine->evaluate(\"[]\") <=> QScriptValue(false)", + "engine->evaluate(\"[]\") <=> QScriptValue(0)", + "engine->evaluate(\"[]\") <=> QScriptValue(0.0)", + "engine->evaluate(\"[]\") <=> QScriptValue(QString(\"\"))", + "engine->evaluate(\"[]\") <=> QScriptValue(QString())", + "engine->evaluate(\"[]\") <=> QScriptValue(0, false)", + "engine->evaluate(\"[]\") <=> QScriptValue(0, 0)", + "engine->evaluate(\"[]\") <=> QScriptValue(0, 0.0)", + "engine->evaluate(\"[]\") <=> QScriptValue(0, QString(\"\"))", + "engine->evaluate(\"[]\") <=> QScriptValue(0, QString())", + "engine->evaluate(\"[]\") <=> QScriptValue(engine, false)", + "engine->evaluate(\"[]\") <=> QScriptValue(engine, 0)", + "engine->evaluate(\"[]\") <=> QScriptValue(engine, 0.0)", + "engine->evaluate(\"[]\") <=> QScriptValue(engine, QString(\"\"))", + "engine->evaluate(\"[]\") <=> QScriptValue(engine, QString())", + "engine->evaluate(\"[]\") <=> engine->evaluate(\"false\")", + "engine->evaluate(\"[]\") <=> engine->evaluate(\"0\")", + "engine->evaluate(\"[]\") <=> engine->evaluate(\"0.0\")", + "engine->evaluate(\"[]\") <=> engine->evaluate(\"''\")", + "engine->evaluate(\"{}\") <=> QScriptValue(QScriptValue::UndefinedValue)", + "engine->evaluate(\"{}\") <=> QScriptValue(QScriptValue::NullValue)", + "engine->evaluate(\"{}\") <=> QScriptValue(0, QScriptValue::UndefinedValue)", + "engine->evaluate(\"{}\") <=> QScriptValue(0, QScriptValue::NullValue)", + "engine->evaluate(\"{}\") <=> QScriptValue(engine, QScriptValue::UndefinedValue)", + "engine->evaluate(\"{}\") <=> QScriptValue(engine, QScriptValue::NullValue)", + "engine->evaluate(\"{}\") <=> engine->evaluate(\"{}\")", + "engine->evaluate(\"{}\") <=> engine->evaluate(\"undefined\")", + "engine->evaluate(\"{}\") <=> engine->evaluate(\"null\")", + "engine->evaluate(\"{}\") <=> engine->nullValue()", + "engine->evaluate(\"{}\") <=> engine->undefinedValue()", + "engine->evaluate(\"Object.prototype\") <=> engine->evaluate(\"Object.prototype\")", + "engine->evaluate(\"Date.prototype\") <=> engine->evaluate(\"Date.prototype\")", + "engine->evaluate(\"Array.prototype\") <=> QScriptValue(false)", + "engine->evaluate(\"Array.prototype\") <=> QScriptValue(0)", + "engine->evaluate(\"Array.prototype\") <=> QScriptValue(0.0)", + "engine->evaluate(\"Array.prototype\") <=> QScriptValue(QString(\"\"))", + "engine->evaluate(\"Array.prototype\") <=> QScriptValue(QString())", + "engine->evaluate(\"Array.prototype\") <=> QScriptValue(0, false)", + "engine->evaluate(\"Array.prototype\") <=> QScriptValue(0, 0)", + "engine->evaluate(\"Array.prototype\") <=> QScriptValue(0, 0.0)", + "engine->evaluate(\"Array.prototype\") <=> QScriptValue(0, QString(\"\"))", + "engine->evaluate(\"Array.prototype\") <=> QScriptValue(0, QString())", + "engine->evaluate(\"Array.prototype\") <=> QScriptValue(engine, false)", + "engine->evaluate(\"Array.prototype\") <=> QScriptValue(engine, 0)", + "engine->evaluate(\"Array.prototype\") <=> QScriptValue(engine, 0.0)", + "engine->evaluate(\"Array.prototype\") <=> QScriptValue(engine, QString(\"\"))", + "engine->evaluate(\"Array.prototype\") <=> QScriptValue(engine, QString())", + "engine->evaluate(\"Array.prototype\") <=> engine->evaluate(\"Array.prototype\")", + "engine->evaluate(\"Array.prototype\") <=> engine->evaluate(\"false\")", + "engine->evaluate(\"Array.prototype\") <=> engine->evaluate(\"0\")", + "engine->evaluate(\"Array.prototype\") <=> engine->evaluate(\"0.0\")", + "engine->evaluate(\"Array.prototype\") <=> engine->evaluate(\"''\")", + "engine->evaluate(\"Function.prototype\") <=> engine->evaluate(\"Function.prototype\")", + "engine->evaluate(\"Error.prototype\") <=> engine->evaluate(\"Error.prototype\")", + "engine->evaluate(\"Object\") <=> engine->evaluate(\"Object\")", + "engine->evaluate(\"Array\") <=> engine->evaluate(\"Array\")", + "engine->evaluate(\"Number\") <=> engine->evaluate(\"Number\")", + "engine->evaluate(\"Function\") <=> engine->evaluate(\"Function\")", + "engine->evaluate(\"new Array()\") <=> QScriptValue(false)", + "engine->evaluate(\"new Array()\") <=> QScriptValue(0)", + "engine->evaluate(\"new Array()\") <=> QScriptValue(0.0)", + "engine->evaluate(\"new Array()\") <=> QScriptValue(QString(\"\"))", + "engine->evaluate(\"new Array()\") <=> QScriptValue(QString())", + "engine->evaluate(\"new Array()\") <=> QScriptValue(0, false)", + "engine->evaluate(\"new Array()\") <=> QScriptValue(0, 0)", + "engine->evaluate(\"new Array()\") <=> QScriptValue(0, 0.0)", + "engine->evaluate(\"new Array()\") <=> QScriptValue(0, QString(\"\"))", + "engine->evaluate(\"new Array()\") <=> QScriptValue(0, QString())", + "engine->evaluate(\"new Array()\") <=> QScriptValue(engine, false)", + "engine->evaluate(\"new Array()\") <=> QScriptValue(engine, 0)", + "engine->evaluate(\"new Array()\") <=> QScriptValue(engine, 0.0)", + "engine->evaluate(\"new Array()\") <=> QScriptValue(engine, QString(\"\"))", + "engine->evaluate(\"new Array()\") <=> QScriptValue(engine, QString())", + "engine->evaluate(\"new Array()\") <=> engine->evaluate(\"false\")", + "engine->evaluate(\"new Array()\") <=> engine->evaluate(\"0\")", + "engine->evaluate(\"new Array()\") <=> engine->evaluate(\"0.0\")", + "engine->evaluate(\"new Array()\") <=> engine->evaluate(\"''\")", + "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\") <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", + "engine->evaluate(\"undefined\") <=> QScriptValue(QScriptValue::UndefinedValue)", + "engine->evaluate(\"undefined\") <=> QScriptValue(QScriptValue::NullValue)", + "engine->evaluate(\"undefined\") <=> QScriptValue(0, QScriptValue::UndefinedValue)", + "engine->evaluate(\"undefined\") <=> QScriptValue(0, QScriptValue::NullValue)", + "engine->evaluate(\"undefined\") <=> QScriptValue(engine, QScriptValue::UndefinedValue)", + "engine->evaluate(\"undefined\") <=> QScriptValue(engine, QScriptValue::NullValue)", + "engine->evaluate(\"undefined\") <=> engine->evaluate(\"{}\")", + "engine->evaluate(\"undefined\") <=> engine->evaluate(\"undefined\")", + "engine->evaluate(\"undefined\") <=> engine->evaluate(\"null\")", + "engine->evaluate(\"undefined\") <=> engine->nullValue()", + "engine->evaluate(\"undefined\") <=> engine->undefinedValue()", + "engine->evaluate(\"null\") <=> QScriptValue(QScriptValue::UndefinedValue)", + "engine->evaluate(\"null\") <=> QScriptValue(QScriptValue::NullValue)", + "engine->evaluate(\"null\") <=> QScriptValue(0, QScriptValue::UndefinedValue)", + "engine->evaluate(\"null\") <=> QScriptValue(0, QScriptValue::NullValue)", + "engine->evaluate(\"null\") <=> QScriptValue(engine, QScriptValue::UndefinedValue)", + "engine->evaluate(\"null\") <=> QScriptValue(engine, QScriptValue::NullValue)", + "engine->evaluate(\"null\") <=> engine->evaluate(\"{}\")", + "engine->evaluate(\"null\") <=> engine->evaluate(\"undefined\")", + "engine->evaluate(\"null\") <=> engine->evaluate(\"null\")", + "engine->evaluate(\"null\") <=> engine->nullValue()", + "engine->evaluate(\"null\") <=> engine->undefinedValue()", + "engine->evaluate(\"true\") <=> QScriptValue(true)", + "engine->evaluate(\"true\") <=> QScriptValue(0, true)", + "engine->evaluate(\"true\") <=> QScriptValue(engine, true)", + "engine->evaluate(\"true\") <=> engine->evaluate(\"true\")", + "engine->evaluate(\"false\") <=> QScriptValue(false)", + "engine->evaluate(\"false\") <=> QScriptValue(0)", + "engine->evaluate(\"false\") <=> QScriptValue(0.0)", + "engine->evaluate(\"false\") <=> QScriptValue(QString(\"\"))", + "engine->evaluate(\"false\") <=> QScriptValue(QString())", + "engine->evaluate(\"false\") <=> QScriptValue(QString(\"0\"))", + "engine->evaluate(\"false\") <=> QScriptValue(0, false)", + "engine->evaluate(\"false\") <=> QScriptValue(0, 0)", + "engine->evaluate(\"false\") <=> QScriptValue(0, 0.0)", + "engine->evaluate(\"false\") <=> QScriptValue(0, QString(\"\"))", + "engine->evaluate(\"false\") <=> QScriptValue(0, QString())", + "engine->evaluate(\"false\") <=> QScriptValue(0, QString(\"0\"))", + "engine->evaluate(\"false\") <=> QScriptValue(engine, false)", + "engine->evaluate(\"false\") <=> QScriptValue(engine, 0)", + "engine->evaluate(\"false\") <=> QScriptValue(engine, 0.0)", + "engine->evaluate(\"false\") <=> QScriptValue(engine, QString(\"\"))", + "engine->evaluate(\"false\") <=> QScriptValue(engine, QString())", + "engine->evaluate(\"false\") <=> QScriptValue(engine, QString(\"0\"))", + "engine->evaluate(\"false\") <=> engine->evaluate(\"[]\")", + "engine->evaluate(\"false\") <=> engine->evaluate(\"Array.prototype\")", + "engine->evaluate(\"false\") <=> engine->evaluate(\"new Array()\")", + "engine->evaluate(\"false\") <=> engine->evaluate(\"false\")", + "engine->evaluate(\"false\") <=> engine->evaluate(\"0\")", + "engine->evaluate(\"false\") <=> engine->evaluate(\"0.0\")", + "engine->evaluate(\"false\") <=> engine->evaluate(\"''\")", + "engine->evaluate(\"false\") <=> engine->evaluate(\"'0'\")", + "engine->evaluate(\"false\") <=> engine->newArray()", + "engine->evaluate(\"122\") <=> QScriptValue(int(122))", + "engine->evaluate(\"122\") <=> QScriptValue(0, int(122))", + "engine->evaluate(\"122\") <=> QScriptValue(engine, int(122))", + "engine->evaluate(\"122\") <=> engine->evaluate(\"122\")", + "engine->evaluate(\"124\") <=> QScriptValue(uint(124))", + "engine->evaluate(\"124\") <=> QScriptValue(0, uint(124))", + "engine->evaluate(\"124\") <=> QScriptValue(engine, uint(124))", + "engine->evaluate(\"124\") <=> engine->evaluate(\"124\")", + "engine->evaluate(\"0\") <=> QScriptValue(false)", + "engine->evaluate(\"0\") <=> QScriptValue(0)", + "engine->evaluate(\"0\") <=> QScriptValue(0.0)", + "engine->evaluate(\"0\") <=> QScriptValue(QString(\"\"))", + "engine->evaluate(\"0\") <=> QScriptValue(QString())", + "engine->evaluate(\"0\") <=> QScriptValue(QString(\"0\"))", + "engine->evaluate(\"0\") <=> QScriptValue(0, false)", + "engine->evaluate(\"0\") <=> QScriptValue(0, 0)", + "engine->evaluate(\"0\") <=> QScriptValue(0, 0.0)", + "engine->evaluate(\"0\") <=> QScriptValue(0, QString(\"\"))", + "engine->evaluate(\"0\") <=> QScriptValue(0, QString())", + "engine->evaluate(\"0\") <=> QScriptValue(0, QString(\"0\"))", + "engine->evaluate(\"0\") <=> QScriptValue(engine, false)", + "engine->evaluate(\"0\") <=> QScriptValue(engine, 0)", + "engine->evaluate(\"0\") <=> QScriptValue(engine, 0.0)", + "engine->evaluate(\"0\") <=> QScriptValue(engine, QString(\"\"))", + "engine->evaluate(\"0\") <=> QScriptValue(engine, QString())", + "engine->evaluate(\"0\") <=> QScriptValue(engine, QString(\"0\"))", + "engine->evaluate(\"0\") <=> engine->evaluate(\"[]\")", + "engine->evaluate(\"0\") <=> engine->evaluate(\"Array.prototype\")", + "engine->evaluate(\"0\") <=> engine->evaluate(\"new Array()\")", + "engine->evaluate(\"0\") <=> engine->evaluate(\"false\")", + "engine->evaluate(\"0\") <=> engine->evaluate(\"0\")", + "engine->evaluate(\"0\") <=> engine->evaluate(\"0.0\")", + "engine->evaluate(\"0\") <=> engine->evaluate(\"''\")", + "engine->evaluate(\"0\") <=> engine->evaluate(\"'0'\")", + "engine->evaluate(\"0\") <=> engine->newArray()", + "engine->evaluate(\"0.0\") <=> QScriptValue(false)", + "engine->evaluate(\"0.0\") <=> QScriptValue(0)", + "engine->evaluate(\"0.0\") <=> QScriptValue(0.0)", + "engine->evaluate(\"0.0\") <=> QScriptValue(QString(\"\"))", + "engine->evaluate(\"0.0\") <=> QScriptValue(QString())", + "engine->evaluate(\"0.0\") <=> QScriptValue(QString(\"0\"))", + "engine->evaluate(\"0.0\") <=> QScriptValue(0, false)", + "engine->evaluate(\"0.0\") <=> QScriptValue(0, 0)", + "engine->evaluate(\"0.0\") <=> QScriptValue(0, 0.0)", + "engine->evaluate(\"0.0\") <=> QScriptValue(0, QString(\"\"))", + "engine->evaluate(\"0.0\") <=> QScriptValue(0, QString())", + "engine->evaluate(\"0.0\") <=> QScriptValue(0, QString(\"0\"))", + "engine->evaluate(\"0.0\") <=> QScriptValue(engine, false)", + "engine->evaluate(\"0.0\") <=> QScriptValue(engine, 0)", + "engine->evaluate(\"0.0\") <=> QScriptValue(engine, 0.0)", + "engine->evaluate(\"0.0\") <=> QScriptValue(engine, QString(\"\"))", + "engine->evaluate(\"0.0\") <=> QScriptValue(engine, QString())", + "engine->evaluate(\"0.0\") <=> QScriptValue(engine, QString(\"0\"))", + "engine->evaluate(\"0.0\") <=> engine->evaluate(\"[]\")", + "engine->evaluate(\"0.0\") <=> engine->evaluate(\"Array.prototype\")", + "engine->evaluate(\"0.0\") <=> engine->evaluate(\"new Array()\")", + "engine->evaluate(\"0.0\") <=> engine->evaluate(\"false\")", + "engine->evaluate(\"0.0\") <=> engine->evaluate(\"0\")", + "engine->evaluate(\"0.0\") <=> engine->evaluate(\"0.0\")", + "engine->evaluate(\"0.0\") <=> engine->evaluate(\"''\")", + "engine->evaluate(\"0.0\") <=> engine->evaluate(\"'0'\")", + "engine->evaluate(\"0.0\") <=> engine->newArray()", + "engine->evaluate(\"123.0\") <=> QScriptValue(123.0)", + "engine->evaluate(\"123.0\") <=> QScriptValue(QString(\"123\"))", + "engine->evaluate(\"123.0\") <=> QScriptValue(0, 123.0)", + "engine->evaluate(\"123.0\") <=> QScriptValue(0, QString(\"123\"))", + "engine->evaluate(\"123.0\") <=> QScriptValue(engine, 123.0)", + "engine->evaluate(\"123.0\") <=> QScriptValue(engine, QString(\"123\"))", + "engine->evaluate(\"123.0\") <=> engine->evaluate(\"123.0\")", + "engine->evaluate(\"123.0\") <=> engine->evaluate(\"'123'\")", + "engine->evaluate(\"6.37e-8\") <=> QScriptValue(6.37e-8)", + "engine->evaluate(\"6.37e-8\") <=> QScriptValue(0, 6.37e-8)", + "engine->evaluate(\"6.37e-8\") <=> QScriptValue(engine, 6.37e-8)", + "engine->evaluate(\"6.37e-8\") <=> engine->evaluate(\"6.37e-8\")", + "engine->evaluate(\"-6.37e-8\") <=> QScriptValue(-6.37e-8)", + "engine->evaluate(\"-6.37e-8\") <=> QScriptValue(0, -6.37e-8)", + "engine->evaluate(\"-6.37e-8\") <=> QScriptValue(engine, -6.37e-8)", + "engine->evaluate(\"-6.37e-8\") <=> engine->evaluate(\"-6.37e-8\")", + "engine->evaluate(\"0x43211234\") <=> QScriptValue(0x43211234)", + "engine->evaluate(\"0x43211234\") <=> QScriptValue(0, 0x43211234)", + "engine->evaluate(\"0x43211234\") <=> QScriptValue(engine, 0x43211234)", + "engine->evaluate(\"0x43211234\") <=> engine->evaluate(\"0x43211234\")", + "engine->evaluate(\"0x10000\") <=> QScriptValue(0x10000)", + "engine->evaluate(\"0x10000\") <=> QScriptValue(0, 0x10000)", + "engine->evaluate(\"0x10000\") <=> QScriptValue(engine, 0x10000)", + "engine->evaluate(\"0x10000\") <=> engine->evaluate(\"0x10000\")", + "engine->evaluate(\"0x10001\") <=> QScriptValue(0x10001)", + "engine->evaluate(\"0x10001\") <=> QScriptValue(0, 0x10001)", + "engine->evaluate(\"0x10001\") <=> QScriptValue(engine, 0x10001)", + "engine->evaluate(\"0x10001\") <=> engine->evaluate(\"0x10001\")", + "engine->evaluate(\"Infinity\") <=> QScriptValue(qInf())", + "engine->evaluate(\"Infinity\") <=> QScriptValue(\"Infinity\")", + "engine->evaluate(\"Infinity\") <=> QScriptValue(0, qInf())", + "engine->evaluate(\"Infinity\") <=> QScriptValue(0, \"Infinity\")", + "engine->evaluate(\"Infinity\") <=> QScriptValue(engine, qInf())", + "engine->evaluate(\"Infinity\") <=> QScriptValue(engine, \"Infinity\")", + "engine->evaluate(\"Infinity\") <=> engine->evaluate(\"Infinity\")", + "engine->evaluate(\"-Infinity\") <=> QScriptValue(-qInf())", + "engine->evaluate(\"-Infinity\") <=> QScriptValue(\"-Infinity\")", + "engine->evaluate(\"-Infinity\") <=> QScriptValue(0, -qInf())", + "engine->evaluate(\"-Infinity\") <=> QScriptValue(0, \"-Infinity\")", + "engine->evaluate(\"-Infinity\") <=> QScriptValue(engine, -qInf())", + "engine->evaluate(\"-Infinity\") <=> QScriptValue(engine, \"-Infinity\")", + "engine->evaluate(\"-Infinity\") <=> engine->evaluate(\"-Infinity\")", + "engine->evaluate(\"'ciao'\") <=> QScriptValue(\"ciao\")", + "engine->evaluate(\"'ciao'\") <=> QScriptValue(QString::fromLatin1(\"ciao\"))", + "engine->evaluate(\"'ciao'\") <=> QScriptValue(0, \"ciao\")", + "engine->evaluate(\"'ciao'\") <=> QScriptValue(0, QString::fromLatin1(\"ciao\"))", + "engine->evaluate(\"'ciao'\") <=> QScriptValue(engine, \"ciao\")", + "engine->evaluate(\"'ciao'\") <=> QScriptValue(engine, QString::fromLatin1(\"ciao\"))", + "engine->evaluate(\"'ciao'\") <=> engine->evaluate(\"'ciao'\")", + "engine->evaluate(\"''\") <=> QScriptValue(false)", + "engine->evaluate(\"''\") <=> QScriptValue(0)", + "engine->evaluate(\"''\") <=> QScriptValue(0.0)", + "engine->evaluate(\"''\") <=> QScriptValue(QString(\"\"))", + "engine->evaluate(\"''\") <=> QScriptValue(QString())", + "engine->evaluate(\"''\") <=> QScriptValue(0, false)", + "engine->evaluate(\"''\") <=> QScriptValue(0, 0)", + "engine->evaluate(\"''\") <=> QScriptValue(0, 0.0)", + "engine->evaluate(\"''\") <=> QScriptValue(0, QString(\"\"))", + "engine->evaluate(\"''\") <=> QScriptValue(0, QString())", + "engine->evaluate(\"''\") <=> QScriptValue(engine, false)", + "engine->evaluate(\"''\") <=> QScriptValue(engine, 0)", + "engine->evaluate(\"''\") <=> QScriptValue(engine, 0.0)", + "engine->evaluate(\"''\") <=> QScriptValue(engine, QString(\"\"))", + "engine->evaluate(\"''\") <=> QScriptValue(engine, QString())", + "engine->evaluate(\"''\") <=> engine->evaluate(\"[]\")", + "engine->evaluate(\"''\") <=> engine->evaluate(\"Array.prototype\")", + "engine->evaluate(\"''\") <=> engine->evaluate(\"new Array()\")", + "engine->evaluate(\"''\") <=> engine->evaluate(\"false\")", + "engine->evaluate(\"''\") <=> engine->evaluate(\"0\")", + "engine->evaluate(\"''\") <=> engine->evaluate(\"0.0\")", + "engine->evaluate(\"''\") <=> engine->evaluate(\"''\")", + "engine->evaluate(\"''\") <=> engine->newArray()", + "engine->evaluate(\"'0'\") <=> QScriptValue(false)", + "engine->evaluate(\"'0'\") <=> QScriptValue(0)", + "engine->evaluate(\"'0'\") <=> QScriptValue(0.0)", + "engine->evaluate(\"'0'\") <=> QScriptValue(QString(\"0\"))", + "engine->evaluate(\"'0'\") <=> QScriptValue(0, false)", + "engine->evaluate(\"'0'\") <=> QScriptValue(0, 0)", + "engine->evaluate(\"'0'\") <=> QScriptValue(0, 0.0)", + "engine->evaluate(\"'0'\") <=> QScriptValue(0, QString(\"0\"))", + "engine->evaluate(\"'0'\") <=> QScriptValue(engine, false)", + "engine->evaluate(\"'0'\") <=> QScriptValue(engine, 0)", + "engine->evaluate(\"'0'\") <=> QScriptValue(engine, 0.0)", + "engine->evaluate(\"'0'\") <=> QScriptValue(engine, QString(\"0\"))", + "engine->evaluate(\"'0'\") <=> engine->evaluate(\"false\")", + "engine->evaluate(\"'0'\") <=> engine->evaluate(\"0\")", + "engine->evaluate(\"'0'\") <=> engine->evaluate(\"0.0\")", + "engine->evaluate(\"'0'\") <=> engine->evaluate(\"'0'\")", + "engine->evaluate(\"'123'\") <=> QScriptValue(123.0)", + "engine->evaluate(\"'123'\") <=> QScriptValue(QString(\"123\"))", + "engine->evaluate(\"'123'\") <=> QScriptValue(0, 123.0)", + "engine->evaluate(\"'123'\") <=> QScriptValue(0, QString(\"123\"))", + "engine->evaluate(\"'123'\") <=> QScriptValue(engine, 123.0)", + "engine->evaluate(\"'123'\") <=> QScriptValue(engine, QString(\"123\"))", + "engine->evaluate(\"'123'\") <=> engine->evaluate(\"123.0\")", + "engine->evaluate(\"'123'\") <=> engine->evaluate(\"'123'\")", + "engine->evaluate(\"'12.4'\") <=> QScriptValue(QString(\"12.4\"))", + "engine->evaluate(\"'12.4'\") <=> engine->evaluate(\"'12.4'\")", + "engine->nullValue() <=> QScriptValue(QScriptValue::UndefinedValue)", + "engine->nullValue() <=> QScriptValue(QScriptValue::NullValue)", + "engine->nullValue() <=> QScriptValue(0, QScriptValue::UndefinedValue)", + "engine->nullValue() <=> QScriptValue(0, QScriptValue::NullValue)", + "engine->nullValue() <=> QScriptValue(engine, QScriptValue::UndefinedValue)", + "engine->nullValue() <=> QScriptValue(engine, QScriptValue::NullValue)", + "engine->nullValue() <=> engine->evaluate(\"{}\")", + "engine->nullValue() <=> engine->evaluate(\"undefined\")", + "engine->nullValue() <=> engine->evaluate(\"null\")", + "engine->nullValue() <=> engine->nullValue()", + "engine->nullValue() <=> engine->undefinedValue()", + "engine->undefinedValue() <=> QScriptValue(QScriptValue::UndefinedValue)", + "engine->undefinedValue() <=> QScriptValue(QScriptValue::NullValue)", + "engine->undefinedValue() <=> QScriptValue(0, QScriptValue::UndefinedValue)", + "engine->undefinedValue() <=> QScriptValue(0, QScriptValue::NullValue)", + "engine->undefinedValue() <=> QScriptValue(engine, QScriptValue::UndefinedValue)", + "engine->undefinedValue() <=> QScriptValue(engine, QScriptValue::NullValue)", + "engine->undefinedValue() <=> engine->evaluate(\"{}\")", + "engine->undefinedValue() <=> engine->evaluate(\"undefined\")", + "engine->undefinedValue() <=> engine->evaluate(\"null\")", + "engine->undefinedValue() <=> engine->nullValue()", + "engine->undefinedValue() <=> engine->undefinedValue()", + "engine->newArray() <=> QScriptValue(false)", + "engine->newArray() <=> QScriptValue(0)", + "engine->newArray() <=> QScriptValue(0.0)", + "engine->newArray() <=> QScriptValue(QString(\"\"))", + "engine->newArray() <=> QScriptValue(QString())", + "engine->newArray() <=> QScriptValue(0, false)", + "engine->newArray() <=> QScriptValue(0, 0)", + "engine->newArray() <=> QScriptValue(0, 0.0)", + "engine->newArray() <=> QScriptValue(0, QString(\"\"))", + "engine->newArray() <=> QScriptValue(0, QString())", + "engine->newArray() <=> QScriptValue(engine, false)", + "engine->newArray() <=> QScriptValue(engine, 0)", + "engine->newArray() <=> QScriptValue(engine, 0.0)", + "engine->newArray() <=> QScriptValue(engine, QString(\"\"))", + "engine->newArray() <=> QScriptValue(engine, QString())", + "engine->newArray() <=> engine->evaluate(\"false\")", + "engine->newArray() <=> engine->evaluate(\"0\")", + "engine->newArray() <=> engine->evaluate(\"0.0\")", + "engine->newArray() <=> engine->evaluate(\"''\")"}; + +void tst_QScriptValue::equals_data() +{ + QTest::addColumn<QScriptValue>("value"); + QTest::addColumn<QScriptValue>("other"); + QTest::addColumn<bool>("expected"); + if (m_engine) + delete m_engine; + m_engine = new QScriptEngine(); + QSet<QString> equals; + equals.reserve(1111); + for (unsigned i = 0; i < 1111; ++i) + equals.insert(equals_array[i]); + for (unsigned i = 0; i < 135; ++i) { + QPair<QString, QScriptValue> value1 = initScriptValues(i); + for (unsigned j = 0; j < 135; ++j) { + QPair<QString, QScriptValue> value2 = initScriptValues(j); + QString tag = QString::fromLatin1("%20 <=> %21").arg(value1.first, value2.first); + QTest::newRow(tag.toAscii().constData()) << value1.second << value2.second << equals.contains(tag); } + } +} + +void tst_QScriptValue::equals() +{ + QFETCH(QScriptValue, value); + QFETCH(QScriptValue, other); + QFETCH(bool, expected); + QEXPECT_FAIL("QScriptValue(qInf()) <=> QScriptValue(\"-Infinity\")", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(qInf()) <=> QScriptValue(0, \"-Infinity\")", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(-qInf()) <=> QScriptValue(\"-Infinity\")", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(-qInf()) <=> QScriptValue(0, \"-Infinity\")", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(\"-Infinity\") <=> QScriptValue(qInf())", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(\"-Infinity\") <=> QScriptValue(-qInf())", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(\"-Infinity\") <=> QScriptValue(0, qInf())", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(\"-Infinity\") <=> QScriptValue(0, -qInf())", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(0, qInf()) <=> QScriptValue(\"-Infinity\")", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(0, qInf()) <=> QScriptValue(0, \"-Infinity\")", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(0, -qInf()) <=> QScriptValue(\"-Infinity\")", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(0, -qInf()) <=> QScriptValue(0, \"-Infinity\")", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(0, \"-Infinity\") <=> QScriptValue(qInf())", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(0, \"-Infinity\") <=> QScriptValue(-qInf())", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(0, \"-Infinity\") <=> QScriptValue(0, qInf())", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(0, \"-Infinity\") <=> QScriptValue(0, -qInf())", "FIXME: WebKit bug 43038", Continue); + QCOMPARE(value.equals(other), expected); +} + +static const QString strictlyEquals_array[] = { + "QScriptValue() <=> QScriptValue()", + "QScriptValue(QScriptValue::UndefinedValue) <=> QScriptValue(QScriptValue::UndefinedValue)", + "QScriptValue(QScriptValue::UndefinedValue) <=> QScriptValue(0, QScriptValue::UndefinedValue)", + "QScriptValue(QScriptValue::UndefinedValue) <=> QScriptValue(engine, QScriptValue::UndefinedValue)", + "QScriptValue(QScriptValue::UndefinedValue) <=> engine->evaluate(\"{}\")", + "QScriptValue(QScriptValue::UndefinedValue) <=> engine->evaluate(\"undefined\")", + "QScriptValue(QScriptValue::UndefinedValue) <=> engine->undefinedValue()", + "QScriptValue(QScriptValue::NullValue) <=> QScriptValue(QScriptValue::NullValue)", + "QScriptValue(QScriptValue::NullValue) <=> QScriptValue(0, QScriptValue::NullValue)", + "QScriptValue(QScriptValue::NullValue) <=> QScriptValue(engine, QScriptValue::NullValue)", + "QScriptValue(QScriptValue::NullValue) <=> engine->evaluate(\"null\")", + "QScriptValue(QScriptValue::NullValue) <=> engine->nullValue()", + "QScriptValue(true) <=> QScriptValue(true)", + "QScriptValue(true) <=> QScriptValue(0, true)", + "QScriptValue(true) <=> QScriptValue(engine, true)", + "QScriptValue(true) <=> engine->evaluate(\"true\")", + "QScriptValue(false) <=> QScriptValue(false)", + "QScriptValue(false) <=> QScriptValue(0, false)", + "QScriptValue(false) <=> QScriptValue(engine, false)", + "QScriptValue(false) <=> engine->evaluate(\"false\")", + "QScriptValue(int(122)) <=> QScriptValue(int(122))", + "QScriptValue(int(122)) <=> QScriptValue(0, int(122))", + "QScriptValue(int(122)) <=> QScriptValue(engine, int(122))", + "QScriptValue(int(122)) <=> engine->evaluate(\"122\")", + "QScriptValue(uint(124)) <=> QScriptValue(uint(124))", + "QScriptValue(uint(124)) <=> QScriptValue(0, uint(124))", + "QScriptValue(uint(124)) <=> QScriptValue(engine, uint(124))", + "QScriptValue(uint(124)) <=> engine->evaluate(\"124\")", + "QScriptValue(0) <=> QScriptValue(0)", + "QScriptValue(0) <=> QScriptValue(0.0)", + "QScriptValue(0) <=> QScriptValue(0, 0)", + "QScriptValue(0) <=> QScriptValue(0, 0.0)", + "QScriptValue(0) <=> QScriptValue(engine, 0)", + "QScriptValue(0) <=> QScriptValue(engine, 0.0)", + "QScriptValue(0) <=> engine->evaluate(\"0\")", + "QScriptValue(0) <=> engine->evaluate(\"0.0\")", + "QScriptValue(0.0) <=> QScriptValue(0)", + "QScriptValue(0.0) <=> QScriptValue(0.0)", + "QScriptValue(0.0) <=> QScriptValue(0, 0)", + "QScriptValue(0.0) <=> QScriptValue(0, 0.0)", + "QScriptValue(0.0) <=> QScriptValue(engine, 0)", + "QScriptValue(0.0) <=> QScriptValue(engine, 0.0)", + "QScriptValue(0.0) <=> engine->evaluate(\"0\")", + "QScriptValue(0.0) <=> engine->evaluate(\"0.0\")", + "QScriptValue(123.0) <=> QScriptValue(123.0)", + "QScriptValue(123.0) <=> QScriptValue(0, 123.0)", + "QScriptValue(123.0) <=> QScriptValue(engine, 123.0)", + "QScriptValue(123.0) <=> engine->evaluate(\"123.0\")", + "QScriptValue(6.37e-8) <=> QScriptValue(6.37e-8)", + "QScriptValue(6.37e-8) <=> QScriptValue(0, 6.37e-8)", + "QScriptValue(6.37e-8) <=> QScriptValue(engine, 6.37e-8)", + "QScriptValue(6.37e-8) <=> engine->evaluate(\"6.37e-8\")", + "QScriptValue(-6.37e-8) <=> QScriptValue(-6.37e-8)", + "QScriptValue(-6.37e-8) <=> QScriptValue(0, -6.37e-8)", + "QScriptValue(-6.37e-8) <=> QScriptValue(engine, -6.37e-8)", + "QScriptValue(-6.37e-8) <=> engine->evaluate(\"-6.37e-8\")", + "QScriptValue(0x43211234) <=> QScriptValue(0x43211234)", + "QScriptValue(0x43211234) <=> QScriptValue(0, 0x43211234)", + "QScriptValue(0x43211234) <=> QScriptValue(engine, 0x43211234)", + "QScriptValue(0x43211234) <=> engine->evaluate(\"0x43211234\")", + "QScriptValue(0x10000) <=> QScriptValue(0x10000)", + "QScriptValue(0x10000) <=> QScriptValue(0, 0x10000)", + "QScriptValue(0x10000) <=> QScriptValue(engine, 0x10000)", + "QScriptValue(0x10000) <=> engine->evaluate(\"0x10000\")", + "QScriptValue(0x10001) <=> QScriptValue(0x10001)", + "QScriptValue(0x10001) <=> QScriptValue(0, 0x10001)", + "QScriptValue(0x10001) <=> QScriptValue(engine, 0x10001)", + "QScriptValue(0x10001) <=> engine->evaluate(\"0x10001\")", + "QScriptValue(qInf()) <=> QScriptValue(qInf())", + "QScriptValue(qInf()) <=> QScriptValue(0, qInf())", + "QScriptValue(qInf()) <=> QScriptValue(engine, qInf())", + "QScriptValue(qInf()) <=> engine->evaluate(\"Infinity\")", + "QScriptValue(-qInf()) <=> QScriptValue(-qInf())", + "QScriptValue(-qInf()) <=> QScriptValue(0, -qInf())", + "QScriptValue(-qInf()) <=> QScriptValue(engine, -qInf())", + "QScriptValue(-qInf()) <=> engine->evaluate(\"-Infinity\")", + "QScriptValue(\"NaN\") <=> QScriptValue(\"NaN\")", + "QScriptValue(\"NaN\") <=> QScriptValue(0, \"NaN\")", + "QScriptValue(\"NaN\") <=> QScriptValue(engine, \"NaN\")", + "QScriptValue(\"Infinity\") <=> QScriptValue(\"Infinity\")", + "QScriptValue(\"Infinity\") <=> QScriptValue(0, \"Infinity\")", + "QScriptValue(\"Infinity\") <=> QScriptValue(engine, \"Infinity\")", + "QScriptValue(\"-Infinity\") <=> QScriptValue(\"-Infinity\")", + "QScriptValue(\"-Infinity\") <=> QScriptValue(0, \"-Infinity\")", + "QScriptValue(\"-Infinity\") <=> QScriptValue(engine, \"-Infinity\")", + "QScriptValue(\"ciao\") <=> QScriptValue(\"ciao\")", + "QScriptValue(\"ciao\") <=> QScriptValue(QString::fromLatin1(\"ciao\"))", + "QScriptValue(\"ciao\") <=> QScriptValue(0, \"ciao\")", + "QScriptValue(\"ciao\") <=> QScriptValue(0, QString::fromLatin1(\"ciao\"))", + "QScriptValue(\"ciao\") <=> QScriptValue(engine, \"ciao\")", + "QScriptValue(\"ciao\") <=> QScriptValue(engine, QString::fromLatin1(\"ciao\"))", + "QScriptValue(\"ciao\") <=> engine->evaluate(\"'ciao'\")", + "QScriptValue(QString::fromLatin1(\"ciao\")) <=> QScriptValue(\"ciao\")", + "QScriptValue(QString::fromLatin1(\"ciao\")) <=> QScriptValue(QString::fromLatin1(\"ciao\"))", + "QScriptValue(QString::fromLatin1(\"ciao\")) <=> QScriptValue(0, \"ciao\")", + "QScriptValue(QString::fromLatin1(\"ciao\")) <=> QScriptValue(0, QString::fromLatin1(\"ciao\"))", + "QScriptValue(QString::fromLatin1(\"ciao\")) <=> QScriptValue(engine, \"ciao\")", + "QScriptValue(QString::fromLatin1(\"ciao\")) <=> QScriptValue(engine, QString::fromLatin1(\"ciao\"))", + "QScriptValue(QString::fromLatin1(\"ciao\")) <=> engine->evaluate(\"'ciao'\")", + "QScriptValue(QString(\"\")) <=> QScriptValue(QString(\"\"))", + "QScriptValue(QString(\"\")) <=> QScriptValue(QString())", + "QScriptValue(QString(\"\")) <=> QScriptValue(0, QString(\"\"))", + "QScriptValue(QString(\"\")) <=> QScriptValue(0, QString())", + "QScriptValue(QString(\"\")) <=> QScriptValue(engine, QString(\"\"))", + "QScriptValue(QString(\"\")) <=> QScriptValue(engine, QString())", + "QScriptValue(QString(\"\")) <=> engine->evaluate(\"''\")", + "QScriptValue(QString()) <=> QScriptValue(QString(\"\"))", + "QScriptValue(QString()) <=> QScriptValue(QString())", + "QScriptValue(QString()) <=> QScriptValue(0, QString(\"\"))", + "QScriptValue(QString()) <=> QScriptValue(0, QString())", + "QScriptValue(QString()) <=> QScriptValue(engine, QString(\"\"))", + "QScriptValue(QString()) <=> QScriptValue(engine, QString())", + "QScriptValue(QString()) <=> engine->evaluate(\"''\")", + "QScriptValue(QString(\"0\")) <=> QScriptValue(QString(\"0\"))", + "QScriptValue(QString(\"0\")) <=> QScriptValue(0, QString(\"0\"))", + "QScriptValue(QString(\"0\")) <=> QScriptValue(engine, QString(\"0\"))", + "QScriptValue(QString(\"0\")) <=> engine->evaluate(\"'0'\")", + "QScriptValue(QString(\"123\")) <=> QScriptValue(QString(\"123\"))", + "QScriptValue(QString(\"123\")) <=> QScriptValue(0, QString(\"123\"))", + "QScriptValue(QString(\"123\")) <=> QScriptValue(engine, QString(\"123\"))", + "QScriptValue(QString(\"123\")) <=> engine->evaluate(\"'123'\")", + "QScriptValue(QString(\"12.4\")) <=> QScriptValue(QString(\"12.4\"))", + "QScriptValue(QString(\"12.4\")) <=> engine->evaluate(\"'12.4'\")", + "QScriptValue(0, QScriptValue::UndefinedValue) <=> QScriptValue(QScriptValue::UndefinedValue)", + "QScriptValue(0, QScriptValue::UndefinedValue) <=> QScriptValue(0, QScriptValue::UndefinedValue)", + "QScriptValue(0, QScriptValue::UndefinedValue) <=> QScriptValue(engine, QScriptValue::UndefinedValue)", + "QScriptValue(0, QScriptValue::UndefinedValue) <=> engine->evaluate(\"{}\")", + "QScriptValue(0, QScriptValue::UndefinedValue) <=> engine->evaluate(\"undefined\")", + "QScriptValue(0, QScriptValue::UndefinedValue) <=> engine->undefinedValue()", + "QScriptValue(0, QScriptValue::NullValue) <=> QScriptValue(QScriptValue::NullValue)", + "QScriptValue(0, QScriptValue::NullValue) <=> QScriptValue(0, QScriptValue::NullValue)", + "QScriptValue(0, QScriptValue::NullValue) <=> QScriptValue(engine, QScriptValue::NullValue)", + "QScriptValue(0, QScriptValue::NullValue) <=> engine->evaluate(\"null\")", + "QScriptValue(0, QScriptValue::NullValue) <=> engine->nullValue()", + "QScriptValue(0, true) <=> QScriptValue(true)", + "QScriptValue(0, true) <=> QScriptValue(0, true)", + "QScriptValue(0, true) <=> QScriptValue(engine, true)", + "QScriptValue(0, true) <=> engine->evaluate(\"true\")", + "QScriptValue(0, false) <=> QScriptValue(false)", + "QScriptValue(0, false) <=> QScriptValue(0, false)", + "QScriptValue(0, false) <=> QScriptValue(engine, false)", + "QScriptValue(0, false) <=> engine->evaluate(\"false\")", + "QScriptValue(0, int(122)) <=> QScriptValue(int(122))", + "QScriptValue(0, int(122)) <=> QScriptValue(0, int(122))", + "QScriptValue(0, int(122)) <=> QScriptValue(engine, int(122))", + "QScriptValue(0, int(122)) <=> engine->evaluate(\"122\")", + "QScriptValue(0, uint(124)) <=> QScriptValue(uint(124))", + "QScriptValue(0, uint(124)) <=> QScriptValue(0, uint(124))", + "QScriptValue(0, uint(124)) <=> QScriptValue(engine, uint(124))", + "QScriptValue(0, uint(124)) <=> engine->evaluate(\"124\")", + "QScriptValue(0, 0) <=> QScriptValue(0)", + "QScriptValue(0, 0) <=> QScriptValue(0.0)", + "QScriptValue(0, 0) <=> QScriptValue(0, 0)", + "QScriptValue(0, 0) <=> QScriptValue(0, 0.0)", + "QScriptValue(0, 0) <=> QScriptValue(engine, 0)", + "QScriptValue(0, 0) <=> QScriptValue(engine, 0.0)", + "QScriptValue(0, 0) <=> engine->evaluate(\"0\")", + "QScriptValue(0, 0) <=> engine->evaluate(\"0.0\")", + "QScriptValue(0, 0.0) <=> QScriptValue(0)", + "QScriptValue(0, 0.0) <=> QScriptValue(0.0)", + "QScriptValue(0, 0.0) <=> QScriptValue(0, 0)", + "QScriptValue(0, 0.0) <=> QScriptValue(0, 0.0)", + "QScriptValue(0, 0.0) <=> QScriptValue(engine, 0)", + "QScriptValue(0, 0.0) <=> QScriptValue(engine, 0.0)", + "QScriptValue(0, 0.0) <=> engine->evaluate(\"0\")", + "QScriptValue(0, 0.0) <=> engine->evaluate(\"0.0\")", + "QScriptValue(0, 123.0) <=> QScriptValue(123.0)", + "QScriptValue(0, 123.0) <=> QScriptValue(0, 123.0)", + "QScriptValue(0, 123.0) <=> QScriptValue(engine, 123.0)", + "QScriptValue(0, 123.0) <=> engine->evaluate(\"123.0\")", + "QScriptValue(0, 6.37e-8) <=> QScriptValue(6.37e-8)", + "QScriptValue(0, 6.37e-8) <=> QScriptValue(0, 6.37e-8)", + "QScriptValue(0, 6.37e-8) <=> QScriptValue(engine, 6.37e-8)", + "QScriptValue(0, 6.37e-8) <=> engine->evaluate(\"6.37e-8\")", + "QScriptValue(0, -6.37e-8) <=> QScriptValue(-6.37e-8)", + "QScriptValue(0, -6.37e-8) <=> QScriptValue(0, -6.37e-8)", + "QScriptValue(0, -6.37e-8) <=> QScriptValue(engine, -6.37e-8)", + "QScriptValue(0, -6.37e-8) <=> engine->evaluate(\"-6.37e-8\")", + "QScriptValue(0, 0x43211234) <=> QScriptValue(0x43211234)", + "QScriptValue(0, 0x43211234) <=> QScriptValue(0, 0x43211234)", + "QScriptValue(0, 0x43211234) <=> QScriptValue(engine, 0x43211234)", + "QScriptValue(0, 0x43211234) <=> engine->evaluate(\"0x43211234\")", + "QScriptValue(0, 0x10000) <=> QScriptValue(0x10000)", + "QScriptValue(0, 0x10000) <=> QScriptValue(0, 0x10000)", + "QScriptValue(0, 0x10000) <=> QScriptValue(engine, 0x10000)", + "QScriptValue(0, 0x10000) <=> engine->evaluate(\"0x10000\")", + "QScriptValue(0, 0x10001) <=> QScriptValue(0x10001)", + "QScriptValue(0, 0x10001) <=> QScriptValue(0, 0x10001)", + "QScriptValue(0, 0x10001) <=> QScriptValue(engine, 0x10001)", + "QScriptValue(0, 0x10001) <=> engine->evaluate(\"0x10001\")", + "QScriptValue(0, qInf()) <=> QScriptValue(qInf())", + "QScriptValue(0, qInf()) <=> QScriptValue(0, qInf())", + "QScriptValue(0, qInf()) <=> QScriptValue(engine, qInf())", + "QScriptValue(0, qInf()) <=> engine->evaluate(\"Infinity\")", + "QScriptValue(0, -qInf()) <=> QScriptValue(-qInf())", + "QScriptValue(0, -qInf()) <=> QScriptValue(0, -qInf())", + "QScriptValue(0, -qInf()) <=> QScriptValue(engine, -qInf())", + "QScriptValue(0, -qInf()) <=> engine->evaluate(\"-Infinity\")", + "QScriptValue(0, \"NaN\") <=> QScriptValue(\"NaN\")", + "QScriptValue(0, \"NaN\") <=> QScriptValue(0, \"NaN\")", + "QScriptValue(0, \"NaN\") <=> QScriptValue(engine, \"NaN\")", + "QScriptValue(0, \"Infinity\") <=> QScriptValue(\"Infinity\")", + "QScriptValue(0, \"Infinity\") <=> QScriptValue(0, \"Infinity\")", + "QScriptValue(0, \"Infinity\") <=> QScriptValue(engine, \"Infinity\")", + "QScriptValue(0, \"-Infinity\") <=> QScriptValue(\"-Infinity\")", + "QScriptValue(0, \"-Infinity\") <=> QScriptValue(0, \"-Infinity\")", + "QScriptValue(0, \"-Infinity\") <=> QScriptValue(engine, \"-Infinity\")", + "QScriptValue(0, \"ciao\") <=> QScriptValue(\"ciao\")", + "QScriptValue(0, \"ciao\") <=> QScriptValue(QString::fromLatin1(\"ciao\"))", + "QScriptValue(0, \"ciao\") <=> QScriptValue(0, \"ciao\")", + "QScriptValue(0, \"ciao\") <=> QScriptValue(0, QString::fromLatin1(\"ciao\"))", + "QScriptValue(0, \"ciao\") <=> QScriptValue(engine, \"ciao\")", + "QScriptValue(0, \"ciao\") <=> QScriptValue(engine, QString::fromLatin1(\"ciao\"))", + "QScriptValue(0, \"ciao\") <=> engine->evaluate(\"'ciao'\")", + "QScriptValue(0, QString::fromLatin1(\"ciao\")) <=> QScriptValue(\"ciao\")", + "QScriptValue(0, QString::fromLatin1(\"ciao\")) <=> QScriptValue(QString::fromLatin1(\"ciao\"))", + "QScriptValue(0, QString::fromLatin1(\"ciao\")) <=> QScriptValue(0, \"ciao\")", + "QScriptValue(0, QString::fromLatin1(\"ciao\")) <=> QScriptValue(0, QString::fromLatin1(\"ciao\"))", + "QScriptValue(0, QString::fromLatin1(\"ciao\")) <=> QScriptValue(engine, \"ciao\")", + "QScriptValue(0, QString::fromLatin1(\"ciao\")) <=> QScriptValue(engine, QString::fromLatin1(\"ciao\"))", + "QScriptValue(0, QString::fromLatin1(\"ciao\")) <=> engine->evaluate(\"'ciao'\")", + "QScriptValue(0, QString(\"\")) <=> QScriptValue(QString(\"\"))", + "QScriptValue(0, QString(\"\")) <=> QScriptValue(QString())", + "QScriptValue(0, QString(\"\")) <=> QScriptValue(0, QString(\"\"))", + "QScriptValue(0, QString(\"\")) <=> QScriptValue(0, QString())", + "QScriptValue(0, QString(\"\")) <=> QScriptValue(engine, QString(\"\"))", + "QScriptValue(0, QString(\"\")) <=> QScriptValue(engine, QString())", + "QScriptValue(0, QString(\"\")) <=> engine->evaluate(\"''\")", + "QScriptValue(0, QString()) <=> QScriptValue(QString(\"\"))", + "QScriptValue(0, QString()) <=> QScriptValue(QString())", + "QScriptValue(0, QString()) <=> QScriptValue(0, QString(\"\"))", + "QScriptValue(0, QString()) <=> QScriptValue(0, QString())", + "QScriptValue(0, QString()) <=> QScriptValue(engine, QString(\"\"))", + "QScriptValue(0, QString()) <=> QScriptValue(engine, QString())", + "QScriptValue(0, QString()) <=> engine->evaluate(\"''\")", + "QScriptValue(0, QString(\"0\")) <=> QScriptValue(QString(\"0\"))", + "QScriptValue(0, QString(\"0\")) <=> QScriptValue(0, QString(\"0\"))", + "QScriptValue(0, QString(\"0\")) <=> QScriptValue(engine, QString(\"0\"))", + "QScriptValue(0, QString(\"0\")) <=> engine->evaluate(\"'0'\")", + "QScriptValue(0, QString(\"123\")) <=> QScriptValue(QString(\"123\"))", + "QScriptValue(0, QString(\"123\")) <=> QScriptValue(0, QString(\"123\"))", + "QScriptValue(0, QString(\"123\")) <=> QScriptValue(engine, QString(\"123\"))", + "QScriptValue(0, QString(\"123\")) <=> engine->evaluate(\"'123'\")", + "QScriptValue(0, QString(\"12.3\")) <=> QScriptValue(0, QString(\"12.3\"))", + "QScriptValue(engine, QScriptValue::UndefinedValue) <=> QScriptValue(QScriptValue::UndefinedValue)", + "QScriptValue(engine, QScriptValue::UndefinedValue) <=> QScriptValue(0, QScriptValue::UndefinedValue)", + "QScriptValue(engine, QScriptValue::UndefinedValue) <=> QScriptValue(engine, QScriptValue::UndefinedValue)", + "QScriptValue(engine, QScriptValue::UndefinedValue) <=> engine->evaluate(\"{}\")", + "QScriptValue(engine, QScriptValue::UndefinedValue) <=> engine->evaluate(\"undefined\")", + "QScriptValue(engine, QScriptValue::UndefinedValue) <=> engine->undefinedValue()", + "QScriptValue(engine, QScriptValue::NullValue) <=> QScriptValue(QScriptValue::NullValue)", + "QScriptValue(engine, QScriptValue::NullValue) <=> QScriptValue(0, QScriptValue::NullValue)", + "QScriptValue(engine, QScriptValue::NullValue) <=> QScriptValue(engine, QScriptValue::NullValue)", + "QScriptValue(engine, QScriptValue::NullValue) <=> engine->evaluate(\"null\")", + "QScriptValue(engine, QScriptValue::NullValue) <=> engine->nullValue()", + "QScriptValue(engine, true) <=> QScriptValue(true)", + "QScriptValue(engine, true) <=> QScriptValue(0, true)", + "QScriptValue(engine, true) <=> QScriptValue(engine, true)", + "QScriptValue(engine, true) <=> engine->evaluate(\"true\")", + "QScriptValue(engine, false) <=> QScriptValue(false)", + "QScriptValue(engine, false) <=> QScriptValue(0, false)", + "QScriptValue(engine, false) <=> QScriptValue(engine, false)", + "QScriptValue(engine, false) <=> engine->evaluate(\"false\")", + "QScriptValue(engine, int(122)) <=> QScriptValue(int(122))", + "QScriptValue(engine, int(122)) <=> QScriptValue(0, int(122))", + "QScriptValue(engine, int(122)) <=> QScriptValue(engine, int(122))", + "QScriptValue(engine, int(122)) <=> engine->evaluate(\"122\")", + "QScriptValue(engine, uint(124)) <=> QScriptValue(uint(124))", + "QScriptValue(engine, uint(124)) <=> QScriptValue(0, uint(124))", + "QScriptValue(engine, uint(124)) <=> QScriptValue(engine, uint(124))", + "QScriptValue(engine, uint(124)) <=> engine->evaluate(\"124\")", + "QScriptValue(engine, 0) <=> QScriptValue(0)", + "QScriptValue(engine, 0) <=> QScriptValue(0.0)", + "QScriptValue(engine, 0) <=> QScriptValue(0, 0)", + "QScriptValue(engine, 0) <=> QScriptValue(0, 0.0)", + "QScriptValue(engine, 0) <=> QScriptValue(engine, 0)", + "QScriptValue(engine, 0) <=> QScriptValue(engine, 0.0)", + "QScriptValue(engine, 0) <=> engine->evaluate(\"0\")", + "QScriptValue(engine, 0) <=> engine->evaluate(\"0.0\")", + "QScriptValue(engine, 0.0) <=> QScriptValue(0)", + "QScriptValue(engine, 0.0) <=> QScriptValue(0.0)", + "QScriptValue(engine, 0.0) <=> QScriptValue(0, 0)", + "QScriptValue(engine, 0.0) <=> QScriptValue(0, 0.0)", + "QScriptValue(engine, 0.0) <=> QScriptValue(engine, 0)", + "QScriptValue(engine, 0.0) <=> QScriptValue(engine, 0.0)", + "QScriptValue(engine, 0.0) <=> engine->evaluate(\"0\")", + "QScriptValue(engine, 0.0) <=> engine->evaluate(\"0.0\")", + "QScriptValue(engine, 123.0) <=> QScriptValue(123.0)", + "QScriptValue(engine, 123.0) <=> QScriptValue(0, 123.0)", + "QScriptValue(engine, 123.0) <=> QScriptValue(engine, 123.0)", + "QScriptValue(engine, 123.0) <=> engine->evaluate(\"123.0\")", + "QScriptValue(engine, 6.37e-8) <=> QScriptValue(6.37e-8)", + "QScriptValue(engine, 6.37e-8) <=> QScriptValue(0, 6.37e-8)", + "QScriptValue(engine, 6.37e-8) <=> QScriptValue(engine, 6.37e-8)", + "QScriptValue(engine, 6.37e-8) <=> engine->evaluate(\"6.37e-8\")", + "QScriptValue(engine, -6.37e-8) <=> QScriptValue(-6.37e-8)", + "QScriptValue(engine, -6.37e-8) <=> QScriptValue(0, -6.37e-8)", + "QScriptValue(engine, -6.37e-8) <=> QScriptValue(engine, -6.37e-8)", + "QScriptValue(engine, -6.37e-8) <=> engine->evaluate(\"-6.37e-8\")", + "QScriptValue(engine, 0x43211234) <=> QScriptValue(0x43211234)", + "QScriptValue(engine, 0x43211234) <=> QScriptValue(0, 0x43211234)", + "QScriptValue(engine, 0x43211234) <=> QScriptValue(engine, 0x43211234)", + "QScriptValue(engine, 0x43211234) <=> engine->evaluate(\"0x43211234\")", + "QScriptValue(engine, 0x10000) <=> QScriptValue(0x10000)", + "QScriptValue(engine, 0x10000) <=> QScriptValue(0, 0x10000)", + "QScriptValue(engine, 0x10000) <=> QScriptValue(engine, 0x10000)", + "QScriptValue(engine, 0x10000) <=> engine->evaluate(\"0x10000\")", + "QScriptValue(engine, 0x10001) <=> QScriptValue(0x10001)", + "QScriptValue(engine, 0x10001) <=> QScriptValue(0, 0x10001)", + "QScriptValue(engine, 0x10001) <=> QScriptValue(engine, 0x10001)", + "QScriptValue(engine, 0x10001) <=> engine->evaluate(\"0x10001\")", + "QScriptValue(engine, qInf()) <=> QScriptValue(qInf())", + "QScriptValue(engine, qInf()) <=> QScriptValue(0, qInf())", + "QScriptValue(engine, qInf()) <=> QScriptValue(engine, qInf())", + "QScriptValue(engine, qInf()) <=> engine->evaluate(\"Infinity\")", + "QScriptValue(engine, -qInf()) <=> QScriptValue(-qInf())", + "QScriptValue(engine, -qInf()) <=> QScriptValue(0, -qInf())", + "QScriptValue(engine, -qInf()) <=> QScriptValue(engine, -qInf())", + "QScriptValue(engine, -qInf()) <=> engine->evaluate(\"-Infinity\")", + "QScriptValue(engine, \"NaN\") <=> QScriptValue(\"NaN\")", + "QScriptValue(engine, \"NaN\") <=> QScriptValue(0, \"NaN\")", + "QScriptValue(engine, \"NaN\") <=> QScriptValue(engine, \"NaN\")", + "QScriptValue(engine, \"Infinity\") <=> QScriptValue(\"Infinity\")", + "QScriptValue(engine, \"Infinity\") <=> QScriptValue(0, \"Infinity\")", + "QScriptValue(engine, \"Infinity\") <=> QScriptValue(engine, \"Infinity\")", + "QScriptValue(engine, \"-Infinity\") <=> QScriptValue(\"-Infinity\")", + "QScriptValue(engine, \"-Infinity\") <=> QScriptValue(0, \"-Infinity\")", + "QScriptValue(engine, \"-Infinity\") <=> QScriptValue(engine, \"-Infinity\")", + "QScriptValue(engine, \"ciao\") <=> QScriptValue(\"ciao\")", + "QScriptValue(engine, \"ciao\") <=> QScriptValue(QString::fromLatin1(\"ciao\"))", + "QScriptValue(engine, \"ciao\") <=> QScriptValue(0, \"ciao\")", + "QScriptValue(engine, \"ciao\") <=> QScriptValue(0, QString::fromLatin1(\"ciao\"))", + "QScriptValue(engine, \"ciao\") <=> QScriptValue(engine, \"ciao\")", + "QScriptValue(engine, \"ciao\") <=> QScriptValue(engine, QString::fromLatin1(\"ciao\"))", + "QScriptValue(engine, \"ciao\") <=> engine->evaluate(\"'ciao'\")", + "QScriptValue(engine, QString::fromLatin1(\"ciao\")) <=> QScriptValue(\"ciao\")", + "QScriptValue(engine, QString::fromLatin1(\"ciao\")) <=> QScriptValue(QString::fromLatin1(\"ciao\"))", + "QScriptValue(engine, QString::fromLatin1(\"ciao\")) <=> QScriptValue(0, \"ciao\")", + "QScriptValue(engine, QString::fromLatin1(\"ciao\")) <=> QScriptValue(0, QString::fromLatin1(\"ciao\"))", + "QScriptValue(engine, QString::fromLatin1(\"ciao\")) <=> QScriptValue(engine, \"ciao\")", + "QScriptValue(engine, QString::fromLatin1(\"ciao\")) <=> QScriptValue(engine, QString::fromLatin1(\"ciao\"))", + "QScriptValue(engine, QString::fromLatin1(\"ciao\")) <=> engine->evaluate(\"'ciao'\")", + "QScriptValue(engine, QString(\"\")) <=> QScriptValue(QString(\"\"))", + "QScriptValue(engine, QString(\"\")) <=> QScriptValue(QString())", + "QScriptValue(engine, QString(\"\")) <=> QScriptValue(0, QString(\"\"))", + "QScriptValue(engine, QString(\"\")) <=> QScriptValue(0, QString())", + "QScriptValue(engine, QString(\"\")) <=> QScriptValue(engine, QString(\"\"))", + "QScriptValue(engine, QString(\"\")) <=> QScriptValue(engine, QString())", + "QScriptValue(engine, QString(\"\")) <=> engine->evaluate(\"''\")", + "QScriptValue(engine, QString()) <=> QScriptValue(QString(\"\"))", + "QScriptValue(engine, QString()) <=> QScriptValue(QString())", + "QScriptValue(engine, QString()) <=> QScriptValue(0, QString(\"\"))", + "QScriptValue(engine, QString()) <=> QScriptValue(0, QString())", + "QScriptValue(engine, QString()) <=> QScriptValue(engine, QString(\"\"))", + "QScriptValue(engine, QString()) <=> QScriptValue(engine, QString())", + "QScriptValue(engine, QString()) <=> engine->evaluate(\"''\")", + "QScriptValue(engine, QString(\"0\")) <=> QScriptValue(QString(\"0\"))", + "QScriptValue(engine, QString(\"0\")) <=> QScriptValue(0, QString(\"0\"))", + "QScriptValue(engine, QString(\"0\")) <=> QScriptValue(engine, QString(\"0\"))", + "QScriptValue(engine, QString(\"0\")) <=> engine->evaluate(\"'0'\")", + "QScriptValue(engine, QString(\"123\")) <=> QScriptValue(QString(\"123\"))", + "QScriptValue(engine, QString(\"123\")) <=> QScriptValue(0, QString(\"123\"))", + "QScriptValue(engine, QString(\"123\")) <=> QScriptValue(engine, QString(\"123\"))", + "QScriptValue(engine, QString(\"123\")) <=> engine->evaluate(\"'123'\")", + "QScriptValue(engine, QString(\"1.23\")) <=> QScriptValue(engine, QString(\"1.23\"))", + "engine->evaluate(\"{}\") <=> QScriptValue(QScriptValue::UndefinedValue)", + "engine->evaluate(\"{}\") <=> QScriptValue(0, QScriptValue::UndefinedValue)", + "engine->evaluate(\"{}\") <=> QScriptValue(engine, QScriptValue::UndefinedValue)", + "engine->evaluate(\"{}\") <=> engine->evaluate(\"{}\")", + "engine->evaluate(\"{}\") <=> engine->evaluate(\"undefined\")", + "engine->evaluate(\"{}\") <=> engine->undefinedValue()", + "engine->evaluate(\"Object.prototype\") <=> engine->evaluate(\"Object.prototype\")", + "engine->evaluate(\"Date.prototype\") <=> engine->evaluate(\"Date.prototype\")", + "engine->evaluate(\"Array.prototype\") <=> engine->evaluate(\"Array.prototype\")", + "engine->evaluate(\"Function.prototype\") <=> engine->evaluate(\"Function.prototype\")", + "engine->evaluate(\"Error.prototype\") <=> engine->evaluate(\"Error.prototype\")", + "engine->evaluate(\"Object\") <=> engine->evaluate(\"Object\")", + "engine->evaluate(\"Array\") <=> engine->evaluate(\"Array\")", + "engine->evaluate(\"Number\") <=> engine->evaluate(\"Number\")", + "engine->evaluate(\"Function\") <=> engine->evaluate(\"Function\")", + "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\") <=> engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", + "engine->evaluate(\"undefined\") <=> QScriptValue(QScriptValue::UndefinedValue)", + "engine->evaluate(\"undefined\") <=> QScriptValue(0, QScriptValue::UndefinedValue)", + "engine->evaluate(\"undefined\") <=> QScriptValue(engine, QScriptValue::UndefinedValue)", + "engine->evaluate(\"undefined\") <=> engine->evaluate(\"{}\")", + "engine->evaluate(\"undefined\") <=> engine->evaluate(\"undefined\")", + "engine->evaluate(\"undefined\") <=> engine->undefinedValue()", + "engine->evaluate(\"null\") <=> QScriptValue(QScriptValue::NullValue)", + "engine->evaluate(\"null\") <=> QScriptValue(0, QScriptValue::NullValue)", + "engine->evaluate(\"null\") <=> QScriptValue(engine, QScriptValue::NullValue)", + "engine->evaluate(\"null\") <=> engine->evaluate(\"null\")", + "engine->evaluate(\"null\") <=> engine->nullValue()", + "engine->evaluate(\"true\") <=> QScriptValue(true)", + "engine->evaluate(\"true\") <=> QScriptValue(0, true)", + "engine->evaluate(\"true\") <=> QScriptValue(engine, true)", + "engine->evaluate(\"true\") <=> engine->evaluate(\"true\")", + "engine->evaluate(\"false\") <=> QScriptValue(false)", + "engine->evaluate(\"false\") <=> QScriptValue(0, false)", + "engine->evaluate(\"false\") <=> QScriptValue(engine, false)", + "engine->evaluate(\"false\") <=> engine->evaluate(\"false\")", + "engine->evaluate(\"122\") <=> QScriptValue(int(122))", + "engine->evaluate(\"122\") <=> QScriptValue(0, int(122))", + "engine->evaluate(\"122\") <=> QScriptValue(engine, int(122))", + "engine->evaluate(\"122\") <=> engine->evaluate(\"122\")", + "engine->evaluate(\"124\") <=> QScriptValue(uint(124))", + "engine->evaluate(\"124\") <=> QScriptValue(0, uint(124))", + "engine->evaluate(\"124\") <=> QScriptValue(engine, uint(124))", + "engine->evaluate(\"124\") <=> engine->evaluate(\"124\")", + "engine->evaluate(\"0\") <=> QScriptValue(0)", + "engine->evaluate(\"0\") <=> QScriptValue(0.0)", + "engine->evaluate(\"0\") <=> QScriptValue(0, 0)", + "engine->evaluate(\"0\") <=> QScriptValue(0, 0.0)", + "engine->evaluate(\"0\") <=> QScriptValue(engine, 0)", + "engine->evaluate(\"0\") <=> QScriptValue(engine, 0.0)", + "engine->evaluate(\"0\") <=> engine->evaluate(\"0\")", + "engine->evaluate(\"0\") <=> engine->evaluate(\"0.0\")", + "engine->evaluate(\"0.0\") <=> QScriptValue(0)", + "engine->evaluate(\"0.0\") <=> QScriptValue(0.0)", + "engine->evaluate(\"0.0\") <=> QScriptValue(0, 0)", + "engine->evaluate(\"0.0\") <=> QScriptValue(0, 0.0)", + "engine->evaluate(\"0.0\") <=> QScriptValue(engine, 0)", + "engine->evaluate(\"0.0\") <=> QScriptValue(engine, 0.0)", + "engine->evaluate(\"0.0\") <=> engine->evaluate(\"0\")", + "engine->evaluate(\"0.0\") <=> engine->evaluate(\"0.0\")", + "engine->evaluate(\"123.0\") <=> QScriptValue(123.0)", + "engine->evaluate(\"123.0\") <=> QScriptValue(0, 123.0)", + "engine->evaluate(\"123.0\") <=> QScriptValue(engine, 123.0)", + "engine->evaluate(\"123.0\") <=> engine->evaluate(\"123.0\")", + "engine->evaluate(\"6.37e-8\") <=> QScriptValue(6.37e-8)", + "engine->evaluate(\"6.37e-8\") <=> QScriptValue(0, 6.37e-8)", + "engine->evaluate(\"6.37e-8\") <=> QScriptValue(engine, 6.37e-8)", + "engine->evaluate(\"6.37e-8\") <=> engine->evaluate(\"6.37e-8\")", + "engine->evaluate(\"-6.37e-8\") <=> QScriptValue(-6.37e-8)", + "engine->evaluate(\"-6.37e-8\") <=> QScriptValue(0, -6.37e-8)", + "engine->evaluate(\"-6.37e-8\") <=> QScriptValue(engine, -6.37e-8)", + "engine->evaluate(\"-6.37e-8\") <=> engine->evaluate(\"-6.37e-8\")", + "engine->evaluate(\"0x43211234\") <=> QScriptValue(0x43211234)", + "engine->evaluate(\"0x43211234\") <=> QScriptValue(0, 0x43211234)", + "engine->evaluate(\"0x43211234\") <=> QScriptValue(engine, 0x43211234)", + "engine->evaluate(\"0x43211234\") <=> engine->evaluate(\"0x43211234\")", + "engine->evaluate(\"0x10000\") <=> QScriptValue(0x10000)", + "engine->evaluate(\"0x10000\") <=> QScriptValue(0, 0x10000)", + "engine->evaluate(\"0x10000\") <=> QScriptValue(engine, 0x10000)", + "engine->evaluate(\"0x10000\") <=> engine->evaluate(\"0x10000\")", + "engine->evaluate(\"0x10001\") <=> QScriptValue(0x10001)", + "engine->evaluate(\"0x10001\") <=> QScriptValue(0, 0x10001)", + "engine->evaluate(\"0x10001\") <=> QScriptValue(engine, 0x10001)", + "engine->evaluate(\"0x10001\") <=> engine->evaluate(\"0x10001\")", + "engine->evaluate(\"Infinity\") <=> QScriptValue(qInf())", + "engine->evaluate(\"Infinity\") <=> QScriptValue(0, qInf())", + "engine->evaluate(\"Infinity\") <=> QScriptValue(engine, qInf())", + "engine->evaluate(\"Infinity\") <=> engine->evaluate(\"Infinity\")", + "engine->evaluate(\"-Infinity\") <=> QScriptValue(-qInf())", + "engine->evaluate(\"-Infinity\") <=> QScriptValue(0, -qInf())", + "engine->evaluate(\"-Infinity\") <=> QScriptValue(engine, -qInf())", + "engine->evaluate(\"-Infinity\") <=> engine->evaluate(\"-Infinity\")", + "engine->evaluate(\"'ciao'\") <=> QScriptValue(\"ciao\")", + "engine->evaluate(\"'ciao'\") <=> QScriptValue(QString::fromLatin1(\"ciao\"))", + "engine->evaluate(\"'ciao'\") <=> QScriptValue(0, \"ciao\")", + "engine->evaluate(\"'ciao'\") <=> QScriptValue(0, QString::fromLatin1(\"ciao\"))", + "engine->evaluate(\"'ciao'\") <=> QScriptValue(engine, \"ciao\")", + "engine->evaluate(\"'ciao'\") <=> QScriptValue(engine, QString::fromLatin1(\"ciao\"))", + "engine->evaluate(\"'ciao'\") <=> engine->evaluate(\"'ciao'\")", + "engine->evaluate(\"''\") <=> QScriptValue(QString(\"\"))", + "engine->evaluate(\"''\") <=> QScriptValue(QString())", + "engine->evaluate(\"''\") <=> QScriptValue(0, QString(\"\"))", + "engine->evaluate(\"''\") <=> QScriptValue(0, QString())", + "engine->evaluate(\"''\") <=> QScriptValue(engine, QString(\"\"))", + "engine->evaluate(\"''\") <=> QScriptValue(engine, QString())", + "engine->evaluate(\"''\") <=> engine->evaluate(\"''\")", + "engine->evaluate(\"'0'\") <=> QScriptValue(QString(\"0\"))", + "engine->evaluate(\"'0'\") <=> QScriptValue(0, QString(\"0\"))", + "engine->evaluate(\"'0'\") <=> QScriptValue(engine, QString(\"0\"))", + "engine->evaluate(\"'0'\") <=> engine->evaluate(\"'0'\")", + "engine->evaluate(\"'123'\") <=> QScriptValue(QString(\"123\"))", + "engine->evaluate(\"'123'\") <=> QScriptValue(0, QString(\"123\"))", + "engine->evaluate(\"'123'\") <=> QScriptValue(engine, QString(\"123\"))", + "engine->evaluate(\"'123'\") <=> engine->evaluate(\"'123'\")", + "engine->evaluate(\"'12.4'\") <=> QScriptValue(QString(\"12.4\"))", + "engine->evaluate(\"'12.4'\") <=> engine->evaluate(\"'12.4'\")", + "engine->nullValue() <=> QScriptValue(QScriptValue::NullValue)", + "engine->nullValue() <=> QScriptValue(0, QScriptValue::NullValue)", + "engine->nullValue() <=> QScriptValue(engine, QScriptValue::NullValue)", + "engine->nullValue() <=> engine->evaluate(\"null\")", + "engine->nullValue() <=> engine->nullValue()", + "engine->undefinedValue() <=> QScriptValue(QScriptValue::UndefinedValue)", + "engine->undefinedValue() <=> QScriptValue(0, QScriptValue::UndefinedValue)", + "engine->undefinedValue() <=> QScriptValue(engine, QScriptValue::UndefinedValue)", + "engine->undefinedValue() <=> engine->evaluate(\"{}\")", + "engine->undefinedValue() <=> engine->evaluate(\"undefined\")", + "engine->undefinedValue() <=> engine->undefinedValue()"}; + +void tst_QScriptValue::strictlyEquals_data() +{ + QTest::addColumn<QScriptValue>("value"); + QTest::addColumn<QScriptValue>("other"); + QTest::addColumn<bool>("expected"); + if (m_engine) + delete m_engine; + m_engine = new QScriptEngine(); + QSet<QString> equals; + equals.reserve(491); + for (unsigned i = 0; i < 491; ++i) + equals.insert(strictlyEquals_array[i]); + for (unsigned i = 0; i < 135; ++i) { + QPair<QString, QScriptValue> value1 = initScriptValues(i); + for (unsigned j = 0; j < 135; ++j) { + QPair<QString, QScriptValue> value2 = initScriptValues(j); + QString tag = QString::fromLatin1("%20 <=> %21").arg(value1.first, value2.first); + QTest::newRow(tag.toAscii().constData()) << value1.second << value2.second << equals.contains(tag); } + } +} + +void tst_QScriptValue::strictlyEquals() +{ + QFETCH(QScriptValue, value); + QFETCH(QScriptValue, other); + QFETCH(bool, expected); + QEXPECT_FAIL("QScriptValue(QScriptValue::UndefinedValue) <=> QScriptValue(QScriptValue::UndefinedValue)", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(QScriptValue::UndefinedValue) <=> QScriptValue(0, QScriptValue::UndefinedValue)", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(QScriptValue::UndefinedValue) <=> QScriptValue(engine, QScriptValue::UndefinedValue)", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(QScriptValue::UndefinedValue) <=> engine->evaluate(\"{}\")", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(QScriptValue::UndefinedValue) <=> engine->evaluate(\"undefined\")", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(QScriptValue::UndefinedValue) <=> engine->undefinedValue()", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(QScriptValue::NullValue) <=> QScriptValue(QScriptValue::NullValue)", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(QScriptValue::NullValue) <=> QScriptValue(0, QScriptValue::NullValue)", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(QScriptValue::NullValue) <=> QScriptValue(engine, QScriptValue::NullValue)", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(QScriptValue::NullValue) <=> engine->evaluate(\"null\")", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(QScriptValue::NullValue) <=> engine->nullValue()", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(true) <=> QScriptValue(true)", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(true) <=> QScriptValue(0, true)", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(false) <=> QScriptValue(false)", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(false) <=> QScriptValue(0, false)", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(0, QScriptValue::UndefinedValue) <=> QScriptValue(QScriptValue::UndefinedValue)", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(0, QScriptValue::UndefinedValue) <=> QScriptValue(0, QScriptValue::UndefinedValue)", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(0, QScriptValue::UndefinedValue) <=> QScriptValue(engine, QScriptValue::UndefinedValue)", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(0, QScriptValue::UndefinedValue) <=> engine->evaluate(\"{}\")", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(0, QScriptValue::UndefinedValue) <=> engine->evaluate(\"undefined\")", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(0, QScriptValue::UndefinedValue) <=> engine->undefinedValue()", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(0, QScriptValue::NullValue) <=> QScriptValue(QScriptValue::NullValue)", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(0, QScriptValue::NullValue) <=> QScriptValue(0, QScriptValue::NullValue)", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(0, QScriptValue::NullValue) <=> QScriptValue(engine, QScriptValue::NullValue)", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(0, QScriptValue::NullValue) <=> engine->evaluate(\"null\")", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(0, QScriptValue::NullValue) <=> engine->nullValue()", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(0, true) <=> QScriptValue(true)", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(0, true) <=> QScriptValue(0, true)", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(0, false) <=> QScriptValue(false)", "FIXME: WebKit bug 43038", Continue); + QEXPECT_FAIL("QScriptValue(0, false) <=> QScriptValue(0, false)", "FIXME: WebKit bug 43038", Continue); + QCOMPARE(value.strictlyEquals(other), expected); +} + +static const QString instanceOf_array[] = { + "engine->evaluate(\"[]\") <=> engine->evaluate(\"Object\")", + "engine->evaluate(\"[]\") <=> engine->evaluate(\"Array\")", + "engine->evaluate(\"Date.prototype\") <=> engine->evaluate(\"Object\")", + "engine->evaluate(\"Array.prototype\") <=> engine->evaluate(\"Object\")", + "engine->evaluate(\"Function.prototype\") <=> engine->evaluate(\"Object\")", + "engine->evaluate(\"Error.prototype\") <=> engine->evaluate(\"Object\")", + "engine->evaluate(\"Object\") <=> engine->evaluate(\"Object\")", + "engine->evaluate(\"Object\") <=> engine->evaluate(\"Function\")", + "engine->evaluate(\"Array\") <=> engine->evaluate(\"Object\")", + "engine->evaluate(\"Array\") <=> engine->evaluate(\"Function\")", + "engine->evaluate(\"Number\") <=> engine->evaluate(\"Object\")", + "engine->evaluate(\"Number\") <=> engine->evaluate(\"Function\")", + "engine->evaluate(\"Function\") <=> engine->evaluate(\"Object\")", + "engine->evaluate(\"Function\") <=> engine->evaluate(\"Function\")", + "engine->evaluate(\"(function() { return 1; })\") <=> engine->evaluate(\"Object\")", + "engine->evaluate(\"(function() { return 1; })\") <=> engine->evaluate(\"Function\")", + "engine->evaluate(\"(function() { return 'ciao'; })\") <=> engine->evaluate(\"Object\")", + "engine->evaluate(\"(function() { return 'ciao'; })\") <=> engine->evaluate(\"Function\")", + "engine->evaluate(\"(function() { throw new Error('foo'); })\") <=> engine->evaluate(\"Object\")", + "engine->evaluate(\"(function() { throw new Error('foo'); })\") <=> engine->evaluate(\"Function\")", + "engine->evaluate(\"/foo/\") <=> engine->evaluate(\"Object\")", + "engine->evaluate(\"new Object()\") <=> engine->evaluate(\"Object\")", + "engine->evaluate(\"new Array()\") <=> engine->evaluate(\"Object\")", + "engine->evaluate(\"new Array()\") <=> engine->evaluate(\"Array\")", + "engine->evaluate(\"new Error()\") <=> engine->evaluate(\"Object\")", + "engine->evaluate(\"Undefined\") <=> engine->evaluate(\"Object\")", + "engine->evaluate(\"Null\") <=> engine->evaluate(\"Object\")", + "engine->evaluate(\"True\") <=> engine->evaluate(\"Object\")", + "engine->evaluate(\"False\") <=> engine->evaluate(\"Object\")", + "engine->newObject() <=> engine->evaluate(\"Object\")", + "engine->newArray() <=> engine->evaluate(\"Object\")", + "engine->newArray() <=> engine->evaluate(\"Array\")", + "engine->newArray(10) <=> engine->evaluate(\"Object\")", + "engine->newArray(10) <=> engine->evaluate(\"Array\")"}; + +void tst_QScriptValue::instanceOf_data() +{ + QTest::addColumn<QScriptValue>("value"); + QTest::addColumn<QScriptValue>("other"); + QTest::addColumn<bool>("expected"); + if (m_engine) + delete m_engine; + m_engine = new QScriptEngine(); + QSet<QString> equals; + equals.reserve(34); + for (unsigned i = 0; i < 34; ++i) + equals.insert(instanceOf_array[i]); + for (unsigned i = 0; i < 135; ++i) { + QPair<QString, QScriptValue> value1 = initScriptValues(i); + for (unsigned j = 0; j < 135; ++j) { + QPair<QString, QScriptValue> value2 = initScriptValues(j); + QString tag = QString::fromLatin1("%20 <=> %21").arg(value1.first, value2.first); + QTest::newRow(tag.toAscii().constData()) << value1.second << value2.second << equals.contains(tag); } + } +} + +void tst_QScriptValue::instanceOf() +{ + QFETCH(QScriptValue, value); + QFETCH(QScriptValue, other); + QFETCH(bool, expected); + QCOMPARE(value.instanceOf(other), expected); +} diff --git a/Source/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue_generated_init.cpp b/Source/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue_generated_init.cpp new file mode 100644 index 0000000..4c97dd4 --- /dev/null +++ b/Source/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue_generated_init.cpp @@ -0,0 +1,169 @@ +/* + Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +/**************************************************************************** +*************** This file has been generated. DO NOT MODIFY! **************** +****************************************************************************/ + +#include "tst_qscriptvalue.h" + + +QPair<QString, QScriptValue> tst_QScriptValue::initScriptValues(uint idx) +{ + QScriptEngine* engine = m_engine; + switch (idx) { + case 0: return QPair<QString, QScriptValue>("QScriptValue()", QScriptValue()); + case 1: return QPair<QString, QScriptValue>("QScriptValue(QScriptValue::UndefinedValue)", QScriptValue(QScriptValue::UndefinedValue)); + case 2: return QPair<QString, QScriptValue>("QScriptValue(QScriptValue::NullValue)", QScriptValue(QScriptValue::NullValue)); + case 3: return QPair<QString, QScriptValue>("QScriptValue(true)", QScriptValue(true)); + case 4: return QPair<QString, QScriptValue>("QScriptValue(false)", QScriptValue(false)); + case 5: return QPair<QString, QScriptValue>("QScriptValue(int(122))", QScriptValue(int(122))); + case 6: return QPair<QString, QScriptValue>("QScriptValue(uint(124))", QScriptValue(uint(124))); + case 7: return QPair<QString, QScriptValue>("QScriptValue(0)", QScriptValue(0)); + case 8: return QPair<QString, QScriptValue>("QScriptValue(0.0)", QScriptValue(0.0)); + case 9: return QPair<QString, QScriptValue>("QScriptValue(123.0)", QScriptValue(123.0)); + case 10: return QPair<QString, QScriptValue>("QScriptValue(6.37e-8)", QScriptValue(6.37e-8)); + case 11: return QPair<QString, QScriptValue>("QScriptValue(-6.37e-8)", QScriptValue(-6.37e-8)); + case 12: return QPair<QString, QScriptValue>("QScriptValue(0x43211234)", QScriptValue(0x43211234)); + case 13: return QPair<QString, QScriptValue>("QScriptValue(0x10000)", QScriptValue(0x10000)); + case 14: return QPair<QString, QScriptValue>("QScriptValue(0x10001)", QScriptValue(0x10001)); + case 15: return QPair<QString, QScriptValue>("QScriptValue(qSNaN())", QScriptValue(qSNaN())); + case 16: return QPair<QString, QScriptValue>("QScriptValue(qQNaN())", QScriptValue(qQNaN())); + case 17: return QPair<QString, QScriptValue>("QScriptValue(qInf())", QScriptValue(qInf())); + case 18: return QPair<QString, QScriptValue>("QScriptValue(-qInf())", QScriptValue(-qInf())); + case 19: return QPair<QString, QScriptValue>("QScriptValue(\"NaN\")", QScriptValue("NaN")); + case 20: return QPair<QString, QScriptValue>("QScriptValue(\"Infinity\")", QScriptValue("Infinity")); + case 21: return QPair<QString, QScriptValue>("QScriptValue(\"-Infinity\")", QScriptValue("-Infinity")); + case 22: return QPair<QString, QScriptValue>("QScriptValue(\"ciao\")", QScriptValue("ciao")); + case 23: return QPair<QString, QScriptValue>("QScriptValue(QString::fromLatin1(\"ciao\"))", QScriptValue(QString::fromLatin1("ciao"))); + case 24: return QPair<QString, QScriptValue>("QScriptValue(QString(\"\"))", QScriptValue(QString(""))); + case 25: return QPair<QString, QScriptValue>("QScriptValue(QString())", QScriptValue(QString())); + case 26: return QPair<QString, QScriptValue>("QScriptValue(QString(\"0\"))", QScriptValue(QString("0"))); + case 27: return QPair<QString, QScriptValue>("QScriptValue(QString(\"123\"))", QScriptValue(QString("123"))); + case 28: return QPair<QString, QScriptValue>("QScriptValue(QString(\"12.4\"))", QScriptValue(QString("12.4"))); + case 29: return QPair<QString, QScriptValue>("QScriptValue(0, QScriptValue::UndefinedValue)", QScriptValue(0, QScriptValue::UndefinedValue)); + case 30: return QPair<QString, QScriptValue>("QScriptValue(0, QScriptValue::NullValue)", QScriptValue(0, QScriptValue::NullValue)); + case 31: return QPair<QString, QScriptValue>("QScriptValue(0, true)", QScriptValue(0, true)); + case 32: return QPair<QString, QScriptValue>("QScriptValue(0, false)", QScriptValue(0, false)); + case 33: return QPair<QString, QScriptValue>("QScriptValue(0, int(122))", QScriptValue(0, int(122))); + case 34: return QPair<QString, QScriptValue>("QScriptValue(0, uint(124))", QScriptValue(0, uint(124))); + case 35: return QPair<QString, QScriptValue>("QScriptValue(0, 0)", QScriptValue(0, 0)); + case 36: return QPair<QString, QScriptValue>("QScriptValue(0, 0.0)", QScriptValue(0, 0.0)); + case 37: return QPair<QString, QScriptValue>("QScriptValue(0, 123.0)", QScriptValue(0, 123.0)); + case 38: return QPair<QString, QScriptValue>("QScriptValue(0, 6.37e-8)", QScriptValue(0, 6.37e-8)); + case 39: return QPair<QString, QScriptValue>("QScriptValue(0, -6.37e-8)", QScriptValue(0, -6.37e-8)); + case 40: return QPair<QString, QScriptValue>("QScriptValue(0, 0x43211234)", QScriptValue(0, 0x43211234)); + case 41: return QPair<QString, QScriptValue>("QScriptValue(0, 0x10000)", QScriptValue(0, 0x10000)); + case 42: return QPair<QString, QScriptValue>("QScriptValue(0, 0x10001)", QScriptValue(0, 0x10001)); + case 43: return QPair<QString, QScriptValue>("QScriptValue(0, qSNaN())", QScriptValue(0, qSNaN())); + case 44: return QPair<QString, QScriptValue>("QScriptValue(0, qQNaN())", QScriptValue(0, qQNaN())); + case 45: return QPair<QString, QScriptValue>("QScriptValue(0, qInf())", QScriptValue(0, qInf())); + case 46: return QPair<QString, QScriptValue>("QScriptValue(0, -qInf())", QScriptValue(0, -qInf())); + case 47: return QPair<QString, QScriptValue>("QScriptValue(0, \"NaN\")", QScriptValue(0, "NaN")); + case 48: return QPair<QString, QScriptValue>("QScriptValue(0, \"Infinity\")", QScriptValue(0, "Infinity")); + case 49: return QPair<QString, QScriptValue>("QScriptValue(0, \"-Infinity\")", QScriptValue(0, "-Infinity")); + case 50: return QPair<QString, QScriptValue>("QScriptValue(0, \"ciao\")", QScriptValue(0, "ciao")); + case 51: return QPair<QString, QScriptValue>("QScriptValue(0, QString::fromLatin1(\"ciao\"))", QScriptValue(0, QString::fromLatin1("ciao"))); + case 52: return QPair<QString, QScriptValue>("QScriptValue(0, QString(\"\"))", QScriptValue(0, QString(""))); + case 53: return QPair<QString, QScriptValue>("QScriptValue(0, QString())", QScriptValue(0, QString())); + case 54: return QPair<QString, QScriptValue>("QScriptValue(0, QString(\"0\"))", QScriptValue(0, QString("0"))); + case 55: return QPair<QString, QScriptValue>("QScriptValue(0, QString(\"123\"))", QScriptValue(0, QString("123"))); + case 56: return QPair<QString, QScriptValue>("QScriptValue(0, QString(\"12.3\"))", QScriptValue(0, QString("12.3"))); + case 57: return QPair<QString, QScriptValue>("QScriptValue(engine, QScriptValue::UndefinedValue)", QScriptValue(engine, QScriptValue::UndefinedValue)); + case 58: return QPair<QString, QScriptValue>("QScriptValue(engine, QScriptValue::NullValue)", QScriptValue(engine, QScriptValue::NullValue)); + case 59: return QPair<QString, QScriptValue>("QScriptValue(engine, true)", QScriptValue(engine, true)); + case 60: return QPair<QString, QScriptValue>("QScriptValue(engine, false)", QScriptValue(engine, false)); + case 61: return QPair<QString, QScriptValue>("QScriptValue(engine, int(122))", QScriptValue(engine, int(122))); + case 62: return QPair<QString, QScriptValue>("QScriptValue(engine, uint(124))", QScriptValue(engine, uint(124))); + case 63: return QPair<QString, QScriptValue>("QScriptValue(engine, 0)", QScriptValue(engine, 0)); + case 64: return QPair<QString, QScriptValue>("QScriptValue(engine, 0.0)", QScriptValue(engine, 0.0)); + case 65: return QPair<QString, QScriptValue>("QScriptValue(engine, 123.0)", QScriptValue(engine, 123.0)); + case 66: return QPair<QString, QScriptValue>("QScriptValue(engine, 6.37e-8)", QScriptValue(engine, 6.37e-8)); + case 67: return QPair<QString, QScriptValue>("QScriptValue(engine, -6.37e-8)", QScriptValue(engine, -6.37e-8)); + case 68: return QPair<QString, QScriptValue>("QScriptValue(engine, 0x43211234)", QScriptValue(engine, 0x43211234)); + case 69: return QPair<QString, QScriptValue>("QScriptValue(engine, 0x10000)", QScriptValue(engine, 0x10000)); + case 70: return QPair<QString, QScriptValue>("QScriptValue(engine, 0x10001)", QScriptValue(engine, 0x10001)); + case 71: return QPair<QString, QScriptValue>("QScriptValue(engine, qSNaN())", QScriptValue(engine, qSNaN())); + case 72: return QPair<QString, QScriptValue>("QScriptValue(engine, qQNaN())", QScriptValue(engine, qQNaN())); + case 73: return QPair<QString, QScriptValue>("QScriptValue(engine, qInf())", QScriptValue(engine, qInf())); + case 74: return QPair<QString, QScriptValue>("QScriptValue(engine, -qInf())", QScriptValue(engine, -qInf())); + case 75: return QPair<QString, QScriptValue>("QScriptValue(engine, \"NaN\")", QScriptValue(engine, "NaN")); + case 76: return QPair<QString, QScriptValue>("QScriptValue(engine, \"Infinity\")", QScriptValue(engine, "Infinity")); + case 77: return QPair<QString, QScriptValue>("QScriptValue(engine, \"-Infinity\")", QScriptValue(engine, "-Infinity")); + case 78: return QPair<QString, QScriptValue>("QScriptValue(engine, \"ciao\")", QScriptValue(engine, "ciao")); + case 79: return QPair<QString, QScriptValue>("QScriptValue(engine, QString::fromLatin1(\"ciao\"))", QScriptValue(engine, QString::fromLatin1("ciao"))); + case 80: return QPair<QString, QScriptValue>("QScriptValue(engine, QString(\"\"))", QScriptValue(engine, QString(""))); + case 81: return QPair<QString, QScriptValue>("QScriptValue(engine, QString())", QScriptValue(engine, QString())); + case 82: return QPair<QString, QScriptValue>("QScriptValue(engine, QString(\"0\"))", QScriptValue(engine, QString("0"))); + case 83: return QPair<QString, QScriptValue>("QScriptValue(engine, QString(\"123\"))", QScriptValue(engine, QString("123"))); + case 84: return QPair<QString, QScriptValue>("QScriptValue(engine, QString(\"1.23\"))", QScriptValue(engine, QString("1.23"))); + case 85: return QPair<QString, QScriptValue>("engine->evaluate(\"[]\")", engine->evaluate("[]")); + case 86: return QPair<QString, QScriptValue>("engine->evaluate(\"{}\")", engine->evaluate("{}")); + case 87: return QPair<QString, QScriptValue>("engine->evaluate(\"Object.prototype\")", engine->evaluate("Object.prototype")); + case 88: return QPair<QString, QScriptValue>("engine->evaluate(\"Date.prototype\")", engine->evaluate("Date.prototype")); + case 89: return QPair<QString, QScriptValue>("engine->evaluate(\"Array.prototype\")", engine->evaluate("Array.prototype")); + case 90: return QPair<QString, QScriptValue>("engine->evaluate(\"Function.prototype\")", engine->evaluate("Function.prototype")); + case 91: return QPair<QString, QScriptValue>("engine->evaluate(\"Error.prototype\")", engine->evaluate("Error.prototype")); + case 92: return QPair<QString, QScriptValue>("engine->evaluate(\"Object\")", engine->evaluate("Object")); + case 93: return QPair<QString, QScriptValue>("engine->evaluate(\"Array\")", engine->evaluate("Array")); + case 94: return QPair<QString, QScriptValue>("engine->evaluate(\"Number\")", engine->evaluate("Number")); + case 95: return QPair<QString, QScriptValue>("engine->evaluate(\"Function\")", engine->evaluate("Function")); + case 96: return QPair<QString, QScriptValue>("engine->evaluate(\"(function() { return 1; })\")", engine->evaluate("(function() { return 1; })")); + case 97: return QPair<QString, QScriptValue>("engine->evaluate(\"(function() { return 'ciao'; })\")", engine->evaluate("(function() { return 'ciao'; })")); + case 98: return QPair<QString, QScriptValue>("engine->evaluate(\"(function() { throw new Error('foo'); })\")", engine->evaluate("(function() { throw new Error('foo'); })")); + case 99: return QPair<QString, QScriptValue>("engine->evaluate(\"/foo/\")", engine->evaluate("/foo/")); + case 100: return QPair<QString, QScriptValue>("engine->evaluate(\"new Object()\")", engine->evaluate("new Object()")); + case 101: return QPair<QString, QScriptValue>("engine->evaluate(\"new Array()\")", engine->evaluate("new Array()")); + case 102: return QPair<QString, QScriptValue>("engine->evaluate(\"new Error()\")", engine->evaluate("new Error()")); + case 103: return QPair<QString, QScriptValue>("engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", engine->evaluate("a = new Object(); a.foo = 22; a.foo")); + case 104: return QPair<QString, QScriptValue>("engine->evaluate(\"Undefined\")", engine->evaluate("Undefined")); + case 105: return QPair<QString, QScriptValue>("engine->evaluate(\"Null\")", engine->evaluate("Null")); + case 106: return QPair<QString, QScriptValue>("engine->evaluate(\"True\")", engine->evaluate("True")); + case 107: return QPair<QString, QScriptValue>("engine->evaluate(\"False\")", engine->evaluate("False")); + case 108: return QPair<QString, QScriptValue>("engine->evaluate(\"undefined\")", engine->evaluate("undefined")); + case 109: return QPair<QString, QScriptValue>("engine->evaluate(\"null\")", engine->evaluate("null")); + case 110: return QPair<QString, QScriptValue>("engine->evaluate(\"true\")", engine->evaluate("true")); + case 111: return QPair<QString, QScriptValue>("engine->evaluate(\"false\")", engine->evaluate("false")); + case 112: return QPair<QString, QScriptValue>("engine->evaluate(\"122\")", engine->evaluate("122")); + case 113: return QPair<QString, QScriptValue>("engine->evaluate(\"124\")", engine->evaluate("124")); + case 114: return QPair<QString, QScriptValue>("engine->evaluate(\"0\")", engine->evaluate("0")); + case 115: return QPair<QString, QScriptValue>("engine->evaluate(\"0.0\")", engine->evaluate("0.0")); + case 116: return QPair<QString, QScriptValue>("engine->evaluate(\"123.0\")", engine->evaluate("123.0")); + case 117: return QPair<QString, QScriptValue>("engine->evaluate(\"6.37e-8\")", engine->evaluate("6.37e-8")); + case 118: return QPair<QString, QScriptValue>("engine->evaluate(\"-6.37e-8\")", engine->evaluate("-6.37e-8")); + case 119: return QPair<QString, QScriptValue>("engine->evaluate(\"0x43211234\")", engine->evaluate("0x43211234")); + case 120: return QPair<QString, QScriptValue>("engine->evaluate(\"0x10000\")", engine->evaluate("0x10000")); + case 121: return QPair<QString, QScriptValue>("engine->evaluate(\"0x10001\")", engine->evaluate("0x10001")); + case 122: return QPair<QString, QScriptValue>("engine->evaluate(\"NaN\")", engine->evaluate("NaN")); + case 123: return QPair<QString, QScriptValue>("engine->evaluate(\"Infinity\")", engine->evaluate("Infinity")); + case 124: return QPair<QString, QScriptValue>("engine->evaluate(\"-Infinity\")", engine->evaluate("-Infinity")); + case 125: return QPair<QString, QScriptValue>("engine->evaluate(\"'ciao'\")", engine->evaluate("'ciao'")); + case 126: return QPair<QString, QScriptValue>("engine->evaluate(\"''\")", engine->evaluate("''")); + case 127: return QPair<QString, QScriptValue>("engine->evaluate(\"'0'\")", engine->evaluate("'0'")); + case 128: return QPair<QString, QScriptValue>("engine->evaluate(\"'123'\")", engine->evaluate("'123'")); + case 129: return QPair<QString, QScriptValue>("engine->evaluate(\"'12.4'\")", engine->evaluate("'12.4'")); + case 130: return QPair<QString, QScriptValue>("engine->nullValue()", engine->nullValue()); + case 131: return QPair<QString, QScriptValue>("engine->undefinedValue()", engine->undefinedValue()); + case 132: return QPair<QString, QScriptValue>("engine->newObject()", engine->newObject()); + case 133: return QPair<QString, QScriptValue>("engine->newArray()", engine->newArray()); + case 134: return QPair<QString, QScriptValue>("engine->newArray(10)", engine->newArray(10)); + } + Q_ASSERT(false); + return qMakePair(QString(), QScriptValue()); +} diff --git a/Source/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue_generated_istype.cpp b/Source/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue_generated_istype.cpp new file mode 100644 index 0000000..433597f --- /dev/null +++ b/Source/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue_generated_istype.cpp @@ -0,0 +1,622 @@ +/* + Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + + +/**************************************************************************** +*************** This file has been generated. DO NOT MODIFY! **************** +****************************************************************************/ + +#include "tst_qscriptvalue.h" + + +static const QString isValid_array[] = { + "QScriptValue(QScriptValue::UndefinedValue)", + "QScriptValue(QScriptValue::NullValue)", + "QScriptValue(true)", + "QScriptValue(false)", + "QScriptValue(int(122))", + "QScriptValue(uint(124))", + "QScriptValue(0)", + "QScriptValue(0.0)", + "QScriptValue(123.0)", + "QScriptValue(6.37e-8)", + "QScriptValue(-6.37e-8)", + "QScriptValue(0x43211234)", + "QScriptValue(0x10000)", + "QScriptValue(0x10001)", + "QScriptValue(qSNaN())", + "QScriptValue(qQNaN())", + "QScriptValue(qInf())", + "QScriptValue(-qInf())", + "QScriptValue(\"NaN\")", + "QScriptValue(\"Infinity\")", + "QScriptValue(\"-Infinity\")", + "QScriptValue(\"ciao\")", + "QScriptValue(QString::fromLatin1(\"ciao\"))", + "QScriptValue(QString(\"\"))", + "QScriptValue(QString())", + "QScriptValue(QString(\"0\"))", + "QScriptValue(QString(\"123\"))", + "QScriptValue(QString(\"12.4\"))", + "QScriptValue(0, QScriptValue::UndefinedValue)", + "QScriptValue(0, QScriptValue::NullValue)", + "QScriptValue(0, true)", + "QScriptValue(0, false)", + "QScriptValue(0, int(122))", + "QScriptValue(0, uint(124))", + "QScriptValue(0, 0)", + "QScriptValue(0, 0.0)", + "QScriptValue(0, 123.0)", + "QScriptValue(0, 6.37e-8)", + "QScriptValue(0, -6.37e-8)", + "QScriptValue(0, 0x43211234)", + "QScriptValue(0, 0x10000)", + "QScriptValue(0, 0x10001)", + "QScriptValue(0, qSNaN())", + "QScriptValue(0, qQNaN())", + "QScriptValue(0, qInf())", + "QScriptValue(0, -qInf())", + "QScriptValue(0, \"NaN\")", + "QScriptValue(0, \"Infinity\")", + "QScriptValue(0, \"-Infinity\")", + "QScriptValue(0, \"ciao\")", + "QScriptValue(0, QString::fromLatin1(\"ciao\"))", + "QScriptValue(0, QString(\"\"))", + "QScriptValue(0, QString())", + "QScriptValue(0, QString(\"0\"))", + "QScriptValue(0, QString(\"123\"))", + "QScriptValue(0, QString(\"12.3\"))", + "QScriptValue(engine, QScriptValue::UndefinedValue)", + "QScriptValue(engine, QScriptValue::NullValue)", + "QScriptValue(engine, true)", + "QScriptValue(engine, false)", + "QScriptValue(engine, int(122))", + "QScriptValue(engine, uint(124))", + "QScriptValue(engine, 0)", + "QScriptValue(engine, 0.0)", + "QScriptValue(engine, 123.0)", + "QScriptValue(engine, 6.37e-8)", + "QScriptValue(engine, -6.37e-8)", + "QScriptValue(engine, 0x43211234)", + "QScriptValue(engine, 0x10000)", + "QScriptValue(engine, 0x10001)", + "QScriptValue(engine, qSNaN())", + "QScriptValue(engine, qQNaN())", + "QScriptValue(engine, qInf())", + "QScriptValue(engine, -qInf())", + "QScriptValue(engine, \"NaN\")", + "QScriptValue(engine, \"Infinity\")", + "QScriptValue(engine, \"-Infinity\")", + "QScriptValue(engine, \"ciao\")", + "QScriptValue(engine, QString::fromLatin1(\"ciao\"))", + "QScriptValue(engine, QString(\"\"))", + "QScriptValue(engine, QString())", + "QScriptValue(engine, QString(\"0\"))", + "QScriptValue(engine, QString(\"123\"))", + "QScriptValue(engine, QString(\"1.23\"))", + "engine->evaluate(\"[]\")", + "engine->evaluate(\"{}\")", + "engine->evaluate(\"Object.prototype\")", + "engine->evaluate(\"Date.prototype\")", + "engine->evaluate(\"Array.prototype\")", + "engine->evaluate(\"Function.prototype\")", + "engine->evaluate(\"Error.prototype\")", + "engine->evaluate(\"Object\")", + "engine->evaluate(\"Array\")", + "engine->evaluate(\"Number\")", + "engine->evaluate(\"Function\")", + "engine->evaluate(\"(function() { return 1; })\")", + "engine->evaluate(\"(function() { return 'ciao'; })\")", + "engine->evaluate(\"(function() { throw new Error('foo'); })\")", + "engine->evaluate(\"/foo/\")", + "engine->evaluate(\"new Object()\")", + "engine->evaluate(\"new Array()\")", + "engine->evaluate(\"new Error()\")", + "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", + "engine->evaluate(\"Undefined\")", + "engine->evaluate(\"Null\")", + "engine->evaluate(\"True\")", + "engine->evaluate(\"False\")", + "engine->evaluate(\"undefined\")", + "engine->evaluate(\"null\")", + "engine->evaluate(\"true\")", + "engine->evaluate(\"false\")", + "engine->evaluate(\"122\")", + "engine->evaluate(\"124\")", + "engine->evaluate(\"0\")", + "engine->evaluate(\"0.0\")", + "engine->evaluate(\"123.0\")", + "engine->evaluate(\"6.37e-8\")", + "engine->evaluate(\"-6.37e-8\")", + "engine->evaluate(\"0x43211234\")", + "engine->evaluate(\"0x10000\")", + "engine->evaluate(\"0x10001\")", + "engine->evaluate(\"NaN\")", + "engine->evaluate(\"Infinity\")", + "engine->evaluate(\"-Infinity\")", + "engine->evaluate(\"'ciao'\")", + "engine->evaluate(\"''\")", + "engine->evaluate(\"'0'\")", + "engine->evaluate(\"'123'\")", + "engine->evaluate(\"'12.4'\")", + "engine->nullValue()", + "engine->undefinedValue()", + "engine->newObject()", + "engine->newArray()", + "engine->newArray(10)"}; + +void tst_QScriptValue::isValid_data() +{ + QTest::addColumn<QScriptValue>("value"); + QTest::addColumn<bool>("expected"); + if (m_engine) + delete m_engine; + m_engine = new QScriptEngine(); + QSet<QString> expectedValue; + expectedValue.reserve(134); + for (uint i = 0; i < 134; ++i) + expectedValue.insert(isValid_array[i]); + for (uint i = 0; i < 135; ++i) { + QPair<QString, QScriptValue> testcase = initScriptValues(i); + QTest::newRow(testcase.first.toAscii().constData()) << testcase.second << expectedValue.contains(testcase.first); + } +} + +void tst_QScriptValue::isValid() +{ + QFETCH(QScriptValue, value); + QFETCH(bool, expected); + QCOMPARE(value.isValid(), expected); + QCOMPARE(value.isValid(), expected); +} + +static const QString isBool_array[] = { + "QScriptValue(true)", + "QScriptValue(false)", + "QScriptValue(0, true)", + "QScriptValue(0, false)", + "QScriptValue(engine, true)", + "QScriptValue(engine, false)", + "engine->evaluate(\"true\")", + "engine->evaluate(\"false\")"}; + +void tst_QScriptValue::isBool_data() +{ + QTest::addColumn<QScriptValue>("value"); + QTest::addColumn<bool>("expected"); + if (m_engine) + delete m_engine; + m_engine = new QScriptEngine(); + QSet<QString> expectedValue; + expectedValue.reserve(8); + for (uint i = 0; i < 8; ++i) + expectedValue.insert(isBool_array[i]); + for (uint i = 0; i < 135; ++i) { + QPair<QString, QScriptValue> testcase = initScriptValues(i); + QTest::newRow(testcase.first.toAscii().constData()) << testcase.second << expectedValue.contains(testcase.first); + } +} + +void tst_QScriptValue::isBool() +{ + QFETCH(QScriptValue, value); + QFETCH(bool, expected); + QCOMPARE(value.isBool(), expected); + QCOMPARE(value.isBool(), expected); +} + +static const QString isBoolean_array[] = { + "QScriptValue(true)", + "QScriptValue(false)", + "QScriptValue(0, true)", + "QScriptValue(0, false)", + "QScriptValue(engine, true)", + "QScriptValue(engine, false)", + "engine->evaluate(\"true\")", + "engine->evaluate(\"false\")"}; + +void tst_QScriptValue::isBoolean_data() +{ + QTest::addColumn<QScriptValue>("value"); + QTest::addColumn<bool>("expected"); + if (m_engine) + delete m_engine; + m_engine = new QScriptEngine(); + QSet<QString> expectedValue; + expectedValue.reserve(8); + for (uint i = 0; i < 8; ++i) + expectedValue.insert(isBoolean_array[i]); + for (uint i = 0; i < 135; ++i) { + QPair<QString, QScriptValue> testcase = initScriptValues(i); + QTest::newRow(testcase.first.toAscii().constData()) << testcase.second << expectedValue.contains(testcase.first); + } +} + +void tst_QScriptValue::isBoolean() +{ + QFETCH(QScriptValue, value); + QFETCH(bool, expected); + QCOMPARE(value.isBoolean(), expected); + QCOMPARE(value.isBoolean(), expected); +} + +static const QString isNumber_array[] = { + "QScriptValue(int(122))", + "QScriptValue(uint(124))", + "QScriptValue(0)", + "QScriptValue(0.0)", + "QScriptValue(123.0)", + "QScriptValue(6.37e-8)", + "QScriptValue(-6.37e-8)", + "QScriptValue(0x43211234)", + "QScriptValue(0x10000)", + "QScriptValue(0x10001)", + "QScriptValue(qSNaN())", + "QScriptValue(qQNaN())", + "QScriptValue(qInf())", + "QScriptValue(-qInf())", + "QScriptValue(0, int(122))", + "QScriptValue(0, uint(124))", + "QScriptValue(0, 0)", + "QScriptValue(0, 0.0)", + "QScriptValue(0, 123.0)", + "QScriptValue(0, 6.37e-8)", + "QScriptValue(0, -6.37e-8)", + "QScriptValue(0, 0x43211234)", + "QScriptValue(0, 0x10000)", + "QScriptValue(0, 0x10001)", + "QScriptValue(0, qSNaN())", + "QScriptValue(0, qQNaN())", + "QScriptValue(0, qInf())", + "QScriptValue(0, -qInf())", + "QScriptValue(engine, int(122))", + "QScriptValue(engine, uint(124))", + "QScriptValue(engine, 0)", + "QScriptValue(engine, 0.0)", + "QScriptValue(engine, 123.0)", + "QScriptValue(engine, 6.37e-8)", + "QScriptValue(engine, -6.37e-8)", + "QScriptValue(engine, 0x43211234)", + "QScriptValue(engine, 0x10000)", + "QScriptValue(engine, 0x10001)", + "QScriptValue(engine, qSNaN())", + "QScriptValue(engine, qQNaN())", + "QScriptValue(engine, qInf())", + "QScriptValue(engine, -qInf())", + "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", + "engine->evaluate(\"122\")", + "engine->evaluate(\"124\")", + "engine->evaluate(\"0\")", + "engine->evaluate(\"0.0\")", + "engine->evaluate(\"123.0\")", + "engine->evaluate(\"6.37e-8\")", + "engine->evaluate(\"-6.37e-8\")", + "engine->evaluate(\"0x43211234\")", + "engine->evaluate(\"0x10000\")", + "engine->evaluate(\"0x10001\")", + "engine->evaluate(\"NaN\")", + "engine->evaluate(\"Infinity\")", + "engine->evaluate(\"-Infinity\")"}; + +void tst_QScriptValue::isNumber_data() +{ + QTest::addColumn<QScriptValue>("value"); + QTest::addColumn<bool>("expected"); + if (m_engine) + delete m_engine; + m_engine = new QScriptEngine(); + QSet<QString> expectedValue; + expectedValue.reserve(56); + for (uint i = 0; i < 56; ++i) + expectedValue.insert(isNumber_array[i]); + for (uint i = 0; i < 135; ++i) { + QPair<QString, QScriptValue> testcase = initScriptValues(i); + QTest::newRow(testcase.first.toAscii().constData()) << testcase.second << expectedValue.contains(testcase.first); + } +} + +void tst_QScriptValue::isNumber() +{ + QFETCH(QScriptValue, value); + QFETCH(bool, expected); + QCOMPARE(value.isNumber(), expected); + QCOMPARE(value.isNumber(), expected); +} + +static const QString isFunction_array[] = { + "engine->evaluate(\"Function.prototype\")", + "engine->evaluate(\"Object\")", + "engine->evaluate(\"Array\")", + "engine->evaluate(\"Number\")", + "engine->evaluate(\"Function\")", + "engine->evaluate(\"(function() { return 1; })\")", + "engine->evaluate(\"(function() { return 'ciao'; })\")", + "engine->evaluate(\"(function() { throw new Error('foo'); })\")", + "engine->evaluate(\"/foo/\")"}; + +void tst_QScriptValue::isFunction_data() +{ + QTest::addColumn<QScriptValue>("value"); + QTest::addColumn<bool>("expected"); + if (m_engine) + delete m_engine; + m_engine = new QScriptEngine(); + QSet<QString> expectedValue; + expectedValue.reserve(9); + for (uint i = 0; i < 9; ++i) + expectedValue.insert(isFunction_array[i]); + for (uint i = 0; i < 135; ++i) { + QPair<QString, QScriptValue> testcase = initScriptValues(i); + QTest::newRow(testcase.first.toAscii().constData()) << testcase.second << expectedValue.contains(testcase.first); + } +} + +void tst_QScriptValue::isFunction() +{ + QFETCH(QScriptValue, value); + QFETCH(bool, expected); + QCOMPARE(value.isFunction(), expected); + QCOMPARE(value.isFunction(), expected); +} + +static const QString isNull_array[] = { + "QScriptValue(QScriptValue::NullValue)", + "QScriptValue(0, QScriptValue::NullValue)", + "QScriptValue(engine, QScriptValue::NullValue)", + "engine->evaluate(\"null\")", + "engine->nullValue()"}; + +void tst_QScriptValue::isNull_data() +{ + QTest::addColumn<QScriptValue>("value"); + QTest::addColumn<bool>("expected"); + if (m_engine) + delete m_engine; + m_engine = new QScriptEngine(); + QSet<QString> expectedValue; + expectedValue.reserve(5); + for (uint i = 0; i < 5; ++i) + expectedValue.insert(isNull_array[i]); + for (uint i = 0; i < 135; ++i) { + QPair<QString, QScriptValue> testcase = initScriptValues(i); + QTest::newRow(testcase.first.toAscii().constData()) << testcase.second << expectedValue.contains(testcase.first); + } +} + +void tst_QScriptValue::isNull() +{ + QFETCH(QScriptValue, value); + QFETCH(bool, expected); + QCOMPARE(value.isNull(), expected); + QCOMPARE(value.isNull(), expected); +} + +static const QString isString_array[] = { + "QScriptValue(\"NaN\")", + "QScriptValue(\"Infinity\")", + "QScriptValue(\"-Infinity\")", + "QScriptValue(\"ciao\")", + "QScriptValue(QString::fromLatin1(\"ciao\"))", + "QScriptValue(QString(\"\"))", + "QScriptValue(QString())", + "QScriptValue(QString(\"0\"))", + "QScriptValue(QString(\"123\"))", + "QScriptValue(QString(\"12.4\"))", + "QScriptValue(0, \"NaN\")", + "QScriptValue(0, \"Infinity\")", + "QScriptValue(0, \"-Infinity\")", + "QScriptValue(0, \"ciao\")", + "QScriptValue(0, QString::fromLatin1(\"ciao\"))", + "QScriptValue(0, QString(\"\"))", + "QScriptValue(0, QString())", + "QScriptValue(0, QString(\"0\"))", + "QScriptValue(0, QString(\"123\"))", + "QScriptValue(0, QString(\"12.3\"))", + "QScriptValue(engine, \"NaN\")", + "QScriptValue(engine, \"Infinity\")", + "QScriptValue(engine, \"-Infinity\")", + "QScriptValue(engine, \"ciao\")", + "QScriptValue(engine, QString::fromLatin1(\"ciao\"))", + "QScriptValue(engine, QString(\"\"))", + "QScriptValue(engine, QString())", + "QScriptValue(engine, QString(\"0\"))", + "QScriptValue(engine, QString(\"123\"))", + "QScriptValue(engine, QString(\"1.23\"))", + "engine->evaluate(\"'ciao'\")", + "engine->evaluate(\"''\")", + "engine->evaluate(\"'0'\")", + "engine->evaluate(\"'123'\")", + "engine->evaluate(\"'12.4'\")"}; + +void tst_QScriptValue::isString_data() +{ + QTest::addColumn<QScriptValue>("value"); + QTest::addColumn<bool>("expected"); + if (m_engine) + delete m_engine; + m_engine = new QScriptEngine(); + QSet<QString> expectedValue; + expectedValue.reserve(35); + for (uint i = 0; i < 35; ++i) + expectedValue.insert(isString_array[i]); + for (uint i = 0; i < 135; ++i) { + QPair<QString, QScriptValue> testcase = initScriptValues(i); + QTest::newRow(testcase.first.toAscii().constData()) << testcase.second << expectedValue.contains(testcase.first); + } +} + +void tst_QScriptValue::isString() +{ + QFETCH(QScriptValue, value); + QFETCH(bool, expected); + QCOMPARE(value.isString(), expected); + QCOMPARE(value.isString(), expected); +} + +static const QString isUndefined_array[] = { + "QScriptValue(QScriptValue::UndefinedValue)", + "QScriptValue(0, QScriptValue::UndefinedValue)", + "QScriptValue(engine, QScriptValue::UndefinedValue)", + "engine->evaluate(\"{}\")", + "engine->evaluate(\"undefined\")", + "engine->undefinedValue()"}; + +void tst_QScriptValue::isUndefined_data() +{ + QTest::addColumn<QScriptValue>("value"); + QTest::addColumn<bool>("expected"); + if (m_engine) + delete m_engine; + m_engine = new QScriptEngine(); + QSet<QString> expectedValue; + expectedValue.reserve(6); + for (uint i = 0; i < 6; ++i) + expectedValue.insert(isUndefined_array[i]); + for (uint i = 0; i < 135; ++i) { + QPair<QString, QScriptValue> testcase = initScriptValues(i); + QTest::newRow(testcase.first.toAscii().constData()) << testcase.second << expectedValue.contains(testcase.first); + } +} + +void tst_QScriptValue::isUndefined() +{ + QFETCH(QScriptValue, value); + QFETCH(bool, expected); + QCOMPARE(value.isUndefined(), expected); + QCOMPARE(value.isUndefined(), expected); +} + + + + +static const QString isObject_array[] = { + "engine->evaluate(\"[]\")", + "engine->evaluate(\"Object.prototype\")", + "engine->evaluate(\"Date.prototype\")", + "engine->evaluate(\"Array.prototype\")", + "engine->evaluate(\"Function.prototype\")", + "engine->evaluate(\"Error.prototype\")", + "engine->evaluate(\"Object\")", + "engine->evaluate(\"Array\")", + "engine->evaluate(\"Number\")", + "engine->evaluate(\"Function\")", + "engine->evaluate(\"(function() { return 1; })\")", + "engine->evaluate(\"(function() { return 'ciao'; })\")", + "engine->evaluate(\"(function() { throw new Error('foo'); })\")", + "engine->evaluate(\"/foo/\")", + "engine->evaluate(\"new Object()\")", + "engine->evaluate(\"new Array()\")", + "engine->evaluate(\"new Error()\")", + "engine->evaluate(\"Undefined\")", + "engine->evaluate(\"Null\")", + "engine->evaluate(\"True\")", + "engine->evaluate(\"False\")", + "engine->newObject()", + "engine->newArray()", + "engine->newArray(10)"}; + +void tst_QScriptValue::isObject_data() +{ + QTest::addColumn<QScriptValue>("value"); + QTest::addColumn<bool>("expected"); + if (m_engine) + delete m_engine; + m_engine = new QScriptEngine(); + QSet<QString> expectedValue; + expectedValue.reserve(24); + for (uint i = 0; i < 24; ++i) + expectedValue.insert(isObject_array[i]); + for (uint i = 0; i < 135; ++i) { + QPair<QString, QScriptValue> testcase = initScriptValues(i); + QTest::newRow(testcase.first.toAscii().constData()) << testcase.second << expectedValue.contains(testcase.first); + } +} + +void tst_QScriptValue::isObject() +{ + QFETCH(QScriptValue, value); + QFETCH(bool, expected); + QCOMPARE(value.isObject(), expected); + QCOMPARE(value.isObject(), expected); +} + +static const QString isArray_array[] = { + "engine->evaluate(\"[]\")", + "engine->evaluate(\"Array.prototype\")", + "engine->evaluate(\"new Array()\")", + "engine->newArray()", + "engine->newArray(10)"}; + +void tst_QScriptValue::isArray_data() +{ + QTest::addColumn<QScriptValue>("value"); + QTest::addColumn<bool>("expected"); + if (m_engine) + delete m_engine; + m_engine = new QScriptEngine(); + QSet<QString> expectedValue; + expectedValue.reserve(5); + for (uint i = 0; i < 5; ++i) + expectedValue.insert(isArray_array[i]); + for (uint i = 0; i < 135; ++i) { + QPair<QString, QScriptValue> testcase = initScriptValues(i); + QTest::newRow(testcase.first.toAscii().constData()) << testcase.second << expectedValue.contains(testcase.first); + } +} + +void tst_QScriptValue::isArray() +{ + QFETCH(QScriptValue, value); + QFETCH(bool, expected); + QCOMPARE(value.isArray(), expected); + QCOMPARE(value.isArray(), expected); +} + +static const QString isError_array[] = { + "engine->evaluate(\"Error.prototype\")", + "engine->evaluate(\"new Error()\")", + "engine->evaluate(\"Undefined\")", + "engine->evaluate(\"Null\")", + "engine->evaluate(\"True\")", + "engine->evaluate(\"False\")"}; + +void tst_QScriptValue::isError_data() +{ + QTest::addColumn<QScriptValue>("value"); + QTest::addColumn<bool>("expected"); + if (m_engine) + delete m_engine; + m_engine = new QScriptEngine(); + QSet<QString> expectedValue; + expectedValue.reserve(6); + for (uint i = 0; i < 6; ++i) + expectedValue.insert(isError_array[i]); + for (uint i = 0; i < 135; ++i) { + QPair<QString, QScriptValue> testcase = initScriptValues(i); + QTest::newRow(testcase.first.toAscii().constData()) << testcase.second << expectedValue.contains(testcase.first); + } +} + +void tst_QScriptValue::isError() +{ + QFETCH(QScriptValue, value); + QFETCH(bool, expected); + QCOMPARE(value.isError(), expected); + QCOMPARE(value.isError(), expected); +} diff --git a/Source/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue_generated_totype.cpp b/Source/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue_generated_totype.cpp new file mode 100644 index 0000000..eaa5d14 --- /dev/null +++ b/Source/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue_generated_totype.cpp @@ -0,0 +1,1786 @@ +/* + Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +/**************************************************************************** +*************** This file has been generated. DO NOT MODIFY! **************** +****************************************************************************/ + +#include "tst_qscriptvalue.h" + +static const QString toString_tagArray[] = { + "QScriptValue()", + "QScriptValue(QScriptValue::UndefinedValue)", + "QScriptValue(QScriptValue::NullValue)", + "QScriptValue(true)", + "QScriptValue(false)", + "QScriptValue(int(122))", + "QScriptValue(uint(124))", + "QScriptValue(0)", + "QScriptValue(0.0)", + "QScriptValue(123.0)", + "QScriptValue(6.37e-8)", + "QScriptValue(-6.37e-8)", + "QScriptValue(0x43211234)", + "QScriptValue(0x10000)", + "QScriptValue(0x10001)", + "QScriptValue(qSNaN())", + "QScriptValue(qQNaN())", + "QScriptValue(qInf())", + "QScriptValue(-qInf())", + "QScriptValue(\"NaN\")", + "QScriptValue(\"Infinity\")", + "QScriptValue(\"-Infinity\")", + "QScriptValue(\"ciao\")", + "QScriptValue(QString::fromLatin1(\"ciao\"))", + "QScriptValue(QString(\"\"))", + "QScriptValue(QString())", + "QScriptValue(QString(\"0\"))", + "QScriptValue(QString(\"123\"))", + "QScriptValue(QString(\"12.4\"))", + "QScriptValue(0, QScriptValue::UndefinedValue)", + "QScriptValue(0, QScriptValue::NullValue)", + "QScriptValue(0, true)", + "QScriptValue(0, false)", + "QScriptValue(0, int(122))", + "QScriptValue(0, uint(124))", + "QScriptValue(0, 0)", + "QScriptValue(0, 0.0)", + "QScriptValue(0, 123.0)", + "QScriptValue(0, 6.37e-8)", + "QScriptValue(0, -6.37e-8)", + "QScriptValue(0, 0x43211234)", + "QScriptValue(0, 0x10000)", + "QScriptValue(0, 0x10001)", + "QScriptValue(0, qSNaN())", + "QScriptValue(0, qQNaN())", + "QScriptValue(0, qInf())", + "QScriptValue(0, -qInf())", + "QScriptValue(0, \"NaN\")", + "QScriptValue(0, \"Infinity\")", + "QScriptValue(0, \"-Infinity\")", + "QScriptValue(0, \"ciao\")", + "QScriptValue(0, QString::fromLatin1(\"ciao\"))", + "QScriptValue(0, QString(\"\"))", + "QScriptValue(0, QString())", + "QScriptValue(0, QString(\"0\"))", + "QScriptValue(0, QString(\"123\"))", + "QScriptValue(0, QString(\"12.3\"))", + "QScriptValue(engine, QScriptValue::UndefinedValue)", + "QScriptValue(engine, QScriptValue::NullValue)", + "QScriptValue(engine, true)", + "QScriptValue(engine, false)", + "QScriptValue(engine, int(122))", + "QScriptValue(engine, uint(124))", + "QScriptValue(engine, 0)", + "QScriptValue(engine, 0.0)", + "QScriptValue(engine, 123.0)", + "QScriptValue(engine, 6.37e-8)", + "QScriptValue(engine, -6.37e-8)", + "QScriptValue(engine, 0x43211234)", + "QScriptValue(engine, 0x10000)", + "QScriptValue(engine, 0x10001)", + "QScriptValue(engine, qSNaN())", + "QScriptValue(engine, qQNaN())", + "QScriptValue(engine, qInf())", + "QScriptValue(engine, -qInf())", + "QScriptValue(engine, \"NaN\")", + "QScriptValue(engine, \"Infinity\")", + "QScriptValue(engine, \"-Infinity\")", + "QScriptValue(engine, \"ciao\")", + "QScriptValue(engine, QString::fromLatin1(\"ciao\"))", + "QScriptValue(engine, QString(\"\"))", + "QScriptValue(engine, QString())", + "QScriptValue(engine, QString(\"0\"))", + "QScriptValue(engine, QString(\"123\"))", + "QScriptValue(engine, QString(\"1.23\"))", + "engine->evaluate(\"[]\")", + "engine->evaluate(\"{}\")", + "engine->evaluate(\"Object.prototype\")", + "engine->evaluate(\"Date.prototype\")", + "engine->evaluate(\"Array.prototype\")", + "engine->evaluate(\"Function.prototype\")", + "engine->evaluate(\"Error.prototype\")", + "engine->evaluate(\"Object\")", + "engine->evaluate(\"Array\")", + "engine->evaluate(\"Number\")", + "engine->evaluate(\"Function\")", + "engine->evaluate(\"(function() { return 1; })\")", + "engine->evaluate(\"(function() { return 'ciao'; })\")", + "engine->evaluate(\"(function() { throw new Error('foo'); })\")", + "engine->evaluate(\"/foo/\")", + "engine->evaluate(\"new Object()\")", + "engine->evaluate(\"new Array()\")", + "engine->evaluate(\"new Error()\")", + "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", + "engine->evaluate(\"Undefined\")", + "engine->evaluate(\"Null\")", + "engine->evaluate(\"True\")", + "engine->evaluate(\"False\")", + "engine->evaluate(\"undefined\")", + "engine->evaluate(\"null\")", + "engine->evaluate(\"true\")", + "engine->evaluate(\"false\")", + "engine->evaluate(\"122\")", + "engine->evaluate(\"124\")", + "engine->evaluate(\"0\")", + "engine->evaluate(\"0.0\")", + "engine->evaluate(\"123.0\")", + "engine->evaluate(\"6.37e-8\")", + "engine->evaluate(\"-6.37e-8\")", + "engine->evaluate(\"0x43211234\")", + "engine->evaluate(\"0x10000\")", + "engine->evaluate(\"0x10001\")", + "engine->evaluate(\"NaN\")", + "engine->evaluate(\"Infinity\")", + "engine->evaluate(\"-Infinity\")", + "engine->evaluate(\"'ciao'\")", + "engine->evaluate(\"''\")", + "engine->evaluate(\"'0'\")", + "engine->evaluate(\"'123'\")", + "engine->evaluate(\"'12.4'\")", + "engine->nullValue()", + "engine->undefinedValue()", + "engine->newObject()", + "engine->newArray()", + "engine->newArray(10)"}; + +static const QString toString_valueArray[] = { + "", "undefined", + "null", "true", + "false", "122", + "124", "0", + "0", "123", + "6.37e-8", "-6.37e-8", + "1126240820", "65536", + "65537", "NaN", + "NaN", "Infinity", + "-Infinity", "NaN", + "Infinity", "-Infinity", + "ciao", "ciao", + "", "", + "0", "123", + "12.4", "undefined", + "null", "true", + "false", "122", + "124", "0", + "0", "123", + "6.37e-8", "-6.37e-8", + "1126240820", "65536", + "65537", "NaN", + "NaN", "Infinity", + "-Infinity", "NaN", + "Infinity", "-Infinity", + "ciao", "ciao", + "", "", + "0", "123", + "12.3", "undefined", + "null", "true", + "false", "122", + "124", "0", + "0", "123", + "6.37e-8", "-6.37e-8", + "1126240820", "65536", + "65537", "NaN", + "NaN", "Infinity", + "-Infinity", "NaN", + "Infinity", "-Infinity", + "ciao", "ciao", + "", "", + "0", "123", + "1.23", "", + "undefined", "[object Object]", + "Invalid Date", "", + "function () {\n [native code]\n}", "Error: Unknown error", + "function Object() {\n [native code]\n}", "function Array() {\n [native code]\n}", + "function Number() {\n [native code]\n}", "function Function() {\n [native code]\n}", + "function () { return 1; }", "function () { return 'ciao'; }", + "function () { throw new Error('foo'); }", "/foo/", + "[object Object]", "", + "Error: Unknown error", "22", + "ReferenceError: Can't find variable: Undefined", "ReferenceError: Can't find variable: Null", + "ReferenceError: Can't find variable: True", "ReferenceError: Can't find variable: False", + "undefined", "null", + "true", "false", + "122", "124", + "0", "0", + "123", "6.37e-8", + "-6.37e-8", "1126240820", + "65536", "65537", + "NaN", "Infinity", + "-Infinity", "ciao", + "", "0", + "123", "12.4", + "null", "undefined", + "[object Object]", "", + ",,,,,,,,,"}; + +void tst_QScriptValue::toString_data() +{ + QTest::addColumn<QScriptValue>("value"); + QTest::addColumn<QString>("expected"); + if (m_engine) + delete m_engine; + m_engine = new QScriptEngine(); + QHash<QString, QString> expectedValue; + expectedValue.reserve(135); + for (uint i = 0; i < 135; ++i) + expectedValue.insert(toString_tagArray[i], toString_valueArray[i]); + for (uint i = 0; i < 135; ++i) { + QPair<QString, QScriptValue> testcase = initScriptValues(i); + QTest::newRow(testcase.first.toAscii().constData()) << testcase.second << expectedValue[testcase.first]; + } +} + +void tst_QScriptValue::toString() +{ + QFETCH(QScriptValue, value); + QFETCH(QString, expected); + QCOMPARE(value.toString(), expected); + QCOMPARE(value.toString(), expected); +} + +static const QString toNumber_tagArray[] = { + "QScriptValue()", + "QScriptValue(QScriptValue::UndefinedValue)", + "QScriptValue(QScriptValue::NullValue)", + "QScriptValue(true)", + "QScriptValue(false)", + "QScriptValue(int(122))", + "QScriptValue(uint(124))", + "QScriptValue(0)", + "QScriptValue(0.0)", + "QScriptValue(123.0)", + "QScriptValue(6.37e-8)", + "QScriptValue(-6.37e-8)", + "QScriptValue(0x43211234)", + "QScriptValue(0x10000)", + "QScriptValue(0x10001)", + "QScriptValue(qSNaN())", + "QScriptValue(qQNaN())", + "QScriptValue(qInf())", + "QScriptValue(-qInf())", + "QScriptValue(\"NaN\")", + "QScriptValue(\"Infinity\")", + "QScriptValue(\"-Infinity\")", + "QScriptValue(\"ciao\")", + "QScriptValue(QString::fromLatin1(\"ciao\"))", + "QScriptValue(QString(\"\"))", + "QScriptValue(QString())", + "QScriptValue(QString(\"0\"))", + "QScriptValue(QString(\"123\"))", + "QScriptValue(QString(\"12.4\"))", + "QScriptValue(0, QScriptValue::UndefinedValue)", + "QScriptValue(0, QScriptValue::NullValue)", + "QScriptValue(0, true)", + "QScriptValue(0, false)", + "QScriptValue(0, int(122))", + "QScriptValue(0, uint(124))", + "QScriptValue(0, 0)", + "QScriptValue(0, 0.0)", + "QScriptValue(0, 123.0)", + "QScriptValue(0, 6.37e-8)", + "QScriptValue(0, -6.37e-8)", + "QScriptValue(0, 0x43211234)", + "QScriptValue(0, 0x10000)", + "QScriptValue(0, 0x10001)", + "QScriptValue(0, qSNaN())", + "QScriptValue(0, qQNaN())", + "QScriptValue(0, qInf())", + "QScriptValue(0, -qInf())", + "QScriptValue(0, \"NaN\")", + "QScriptValue(0, \"Infinity\")", + "QScriptValue(0, \"-Infinity\")", + "QScriptValue(0, \"ciao\")", + "QScriptValue(0, QString::fromLatin1(\"ciao\"))", + "QScriptValue(0, QString(\"\"))", + "QScriptValue(0, QString())", + "QScriptValue(0, QString(\"0\"))", + "QScriptValue(0, QString(\"123\"))", + "QScriptValue(0, QString(\"12.3\"))", + "QScriptValue(engine, QScriptValue::UndefinedValue)", + "QScriptValue(engine, QScriptValue::NullValue)", + "QScriptValue(engine, true)", + "QScriptValue(engine, false)", + "QScriptValue(engine, int(122))", + "QScriptValue(engine, uint(124))", + "QScriptValue(engine, 0)", + "QScriptValue(engine, 0.0)", + "QScriptValue(engine, 123.0)", + "QScriptValue(engine, 6.37e-8)", + "QScriptValue(engine, -6.37e-8)", + "QScriptValue(engine, 0x43211234)", + "QScriptValue(engine, 0x10000)", + "QScriptValue(engine, 0x10001)", + "QScriptValue(engine, qSNaN())", + "QScriptValue(engine, qQNaN())", + "QScriptValue(engine, qInf())", + "QScriptValue(engine, -qInf())", + "QScriptValue(engine, \"NaN\")", + "QScriptValue(engine, \"Infinity\")", + "QScriptValue(engine, \"-Infinity\")", + "QScriptValue(engine, \"ciao\")", + "QScriptValue(engine, QString::fromLatin1(\"ciao\"))", + "QScriptValue(engine, QString(\"\"))", + "QScriptValue(engine, QString())", + "QScriptValue(engine, QString(\"0\"))", + "QScriptValue(engine, QString(\"123\"))", + "QScriptValue(engine, QString(\"1.23\"))", + "engine->evaluate(\"[]\")", + "engine->evaluate(\"{}\")", + "engine->evaluate(\"Object.prototype\")", + "engine->evaluate(\"Date.prototype\")", + "engine->evaluate(\"Array.prototype\")", + "engine->evaluate(\"Function.prototype\")", + "engine->evaluate(\"Error.prototype\")", + "engine->evaluate(\"Object\")", + "engine->evaluate(\"Array\")", + "engine->evaluate(\"Number\")", + "engine->evaluate(\"Function\")", + "engine->evaluate(\"(function() { return 1; })\")", + "engine->evaluate(\"(function() { return 'ciao'; })\")", + "engine->evaluate(\"(function() { throw new Error('foo'); })\")", + "engine->evaluate(\"/foo/\")", + "engine->evaluate(\"new Object()\")", + "engine->evaluate(\"new Array()\")", + "engine->evaluate(\"new Error()\")", + "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", + "engine->evaluate(\"Undefined\")", + "engine->evaluate(\"Null\")", + "engine->evaluate(\"True\")", + "engine->evaluate(\"False\")", + "engine->evaluate(\"undefined\")", + "engine->evaluate(\"null\")", + "engine->evaluate(\"true\")", + "engine->evaluate(\"false\")", + "engine->evaluate(\"122\")", + "engine->evaluate(\"124\")", + "engine->evaluate(\"0\")", + "engine->evaluate(\"0.0\")", + "engine->evaluate(\"123.0\")", + "engine->evaluate(\"6.37e-8\")", + "engine->evaluate(\"-6.37e-8\")", + "engine->evaluate(\"0x43211234\")", + "engine->evaluate(\"0x10000\")", + "engine->evaluate(\"0x10001\")", + "engine->evaluate(\"NaN\")", + "engine->evaluate(\"Infinity\")", + "engine->evaluate(\"-Infinity\")", + "engine->evaluate(\"'ciao'\")", + "engine->evaluate(\"''\")", + "engine->evaluate(\"'0'\")", + "engine->evaluate(\"'123'\")", + "engine->evaluate(\"'12.4'\")", + "engine->nullValue()", + "engine->undefinedValue()", + "engine->newObject()", + "engine->newArray()", + "engine->newArray(10)"}; + +static const qsreal toNumber_valueArray[] = { + 0, qQNaN(), 0, 1, 0, 122, 124, 0, 0, 123, + 6.369999999999999e-08, -6.369999999999999e-08, 1126240820, 65536, 65537, qQNaN(), qQNaN(), qInf(), qInf(), qQNaN(), + qInf(), qInf(), qQNaN(), qQNaN(), 0, 0, 0, 123, 12.4, qQNaN(), + 0, 1, 0, 122, 124, 0, 0, 123, 6.369999999999999e-08, -6.369999999999999e-08, + 1126240820, 65536, 65537, qQNaN(), qQNaN(), qInf(), qInf(), qQNaN(), qInf(), qInf(), + qQNaN(), qQNaN(), 0, 0, 0, 123, 12.3, qQNaN(), 0, 1, + 0, 122, 124, 0, 0, 123, 6.369999999999999e-08, -6.369999999999999e-08, 1126240820, 65536, + 65537, qQNaN(), qQNaN(), qInf(), qInf(), qQNaN(), qInf(), qInf(), qQNaN(), qQNaN(), + 0, 0, 0, 123, 1.23, 0, qQNaN(), qQNaN(), qQNaN(), 0, + qQNaN(), qQNaN(), qQNaN(), qQNaN(), qQNaN(), qQNaN(), qQNaN(), qQNaN(), qQNaN(), qQNaN(), + qQNaN(), 0, qQNaN(), 22, qQNaN(), qQNaN(), qQNaN(), qQNaN(), qQNaN(), 0, + 1, 0, 122, 124, 0, 0, 123, 6.369999999999999e-08, -6.369999999999999e-08, 1126240820, + 65536, 65537, qQNaN(), qInf(), qInf(), qQNaN(), 0, 0, 123, 12.4, + 0, qQNaN(), qQNaN(), 0, qQNaN()}; + +void tst_QScriptValue::toNumber_data() +{ + QTest::addColumn<QScriptValue>("value"); + QTest::addColumn<qsreal>("expected"); + if (m_engine) + delete m_engine; + m_engine = new QScriptEngine(); + QHash<QString, qsreal> expectedValue; + expectedValue.reserve(135); + for (uint i = 0; i < 135; ++i) + expectedValue.insert(toNumber_tagArray[i], toNumber_valueArray[i]); + for (uint i = 0; i < 135; ++i) { + QPair<QString, QScriptValue> testcase = initScriptValues(i); + QTest::newRow(testcase.first.toAscii().constData()) << testcase.second << expectedValue[testcase.first]; + } +} + +void tst_QScriptValue::toNumber() +{ + QFETCH(QScriptValue, value); + QFETCH(qsreal, expected); + if (qIsNaN(expected)) { + QVERIFY(qIsNaN(value.toNumber())); + return; + } + if (qIsInf(expected)) { + QVERIFY(qIsInf(value.toNumber())); + QVERIFY(qIsInf(value.toNumber())); + return; + } + QCOMPARE(value.toNumber(), expected); + QCOMPARE(value.toNumber(), expected); +} + +static const QString toBool_tagArray[] = { + "QScriptValue()", + "QScriptValue(QScriptValue::UndefinedValue)", + "QScriptValue(QScriptValue::NullValue)", + "QScriptValue(true)", + "QScriptValue(false)", + "QScriptValue(int(122))", + "QScriptValue(uint(124))", + "QScriptValue(0)", + "QScriptValue(0.0)", + "QScriptValue(123.0)", + "QScriptValue(6.37e-8)", + "QScriptValue(-6.37e-8)", + "QScriptValue(0x43211234)", + "QScriptValue(0x10000)", + "QScriptValue(0x10001)", + "QScriptValue(qSNaN())", + "QScriptValue(qQNaN())", + "QScriptValue(qInf())", + "QScriptValue(-qInf())", + "QScriptValue(\"NaN\")", + "QScriptValue(\"Infinity\")", + "QScriptValue(\"-Infinity\")", + "QScriptValue(\"ciao\")", + "QScriptValue(QString::fromLatin1(\"ciao\"))", + "QScriptValue(QString(\"\"))", + "QScriptValue(QString())", + "QScriptValue(QString(\"0\"))", + "QScriptValue(QString(\"123\"))", + "QScriptValue(QString(\"12.4\"))", + "QScriptValue(0, QScriptValue::UndefinedValue)", + "QScriptValue(0, QScriptValue::NullValue)", + "QScriptValue(0, true)", + "QScriptValue(0, false)", + "QScriptValue(0, int(122))", + "QScriptValue(0, uint(124))", + "QScriptValue(0, 0)", + "QScriptValue(0, 0.0)", + "QScriptValue(0, 123.0)", + "QScriptValue(0, 6.37e-8)", + "QScriptValue(0, -6.37e-8)", + "QScriptValue(0, 0x43211234)", + "QScriptValue(0, 0x10000)", + "QScriptValue(0, 0x10001)", + "QScriptValue(0, qSNaN())", + "QScriptValue(0, qQNaN())", + "QScriptValue(0, qInf())", + "QScriptValue(0, -qInf())", + "QScriptValue(0, \"NaN\")", + "QScriptValue(0, \"Infinity\")", + "QScriptValue(0, \"-Infinity\")", + "QScriptValue(0, \"ciao\")", + "QScriptValue(0, QString::fromLatin1(\"ciao\"))", + "QScriptValue(0, QString(\"\"))", + "QScriptValue(0, QString())", + "QScriptValue(0, QString(\"0\"))", + "QScriptValue(0, QString(\"123\"))", + "QScriptValue(0, QString(\"12.3\"))", + "QScriptValue(engine, QScriptValue::UndefinedValue)", + "QScriptValue(engine, QScriptValue::NullValue)", + "QScriptValue(engine, true)", + "QScriptValue(engine, false)", + "QScriptValue(engine, int(122))", + "QScriptValue(engine, uint(124))", + "QScriptValue(engine, 0)", + "QScriptValue(engine, 0.0)", + "QScriptValue(engine, 123.0)", + "QScriptValue(engine, 6.37e-8)", + "QScriptValue(engine, -6.37e-8)", + "QScriptValue(engine, 0x43211234)", + "QScriptValue(engine, 0x10000)", + "QScriptValue(engine, 0x10001)", + "QScriptValue(engine, qSNaN())", + "QScriptValue(engine, qQNaN())", + "QScriptValue(engine, qInf())", + "QScriptValue(engine, -qInf())", + "QScriptValue(engine, \"NaN\")", + "QScriptValue(engine, \"Infinity\")", + "QScriptValue(engine, \"-Infinity\")", + "QScriptValue(engine, \"ciao\")", + "QScriptValue(engine, QString::fromLatin1(\"ciao\"))", + "QScriptValue(engine, QString(\"\"))", + "QScriptValue(engine, QString())", + "QScriptValue(engine, QString(\"0\"))", + "QScriptValue(engine, QString(\"123\"))", + "QScriptValue(engine, QString(\"1.23\"))", + "engine->evaluate(\"[]\")", + "engine->evaluate(\"{}\")", + "engine->evaluate(\"Object.prototype\")", + "engine->evaluate(\"Date.prototype\")", + "engine->evaluate(\"Array.prototype\")", + "engine->evaluate(\"Function.prototype\")", + "engine->evaluate(\"Error.prototype\")", + "engine->evaluate(\"Object\")", + "engine->evaluate(\"Array\")", + "engine->evaluate(\"Number\")", + "engine->evaluate(\"Function\")", + "engine->evaluate(\"(function() { return 1; })\")", + "engine->evaluate(\"(function() { return 'ciao'; })\")", + "engine->evaluate(\"(function() { throw new Error('foo'); })\")", + "engine->evaluate(\"/foo/\")", + "engine->evaluate(\"new Object()\")", + "engine->evaluate(\"new Array()\")", + "engine->evaluate(\"new Error()\")", + "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", + "engine->evaluate(\"Undefined\")", + "engine->evaluate(\"Null\")", + "engine->evaluate(\"True\")", + "engine->evaluate(\"False\")", + "engine->evaluate(\"undefined\")", + "engine->evaluate(\"null\")", + "engine->evaluate(\"true\")", + "engine->evaluate(\"false\")", + "engine->evaluate(\"122\")", + "engine->evaluate(\"124\")", + "engine->evaluate(\"0\")", + "engine->evaluate(\"0.0\")", + "engine->evaluate(\"123.0\")", + "engine->evaluate(\"6.37e-8\")", + "engine->evaluate(\"-6.37e-8\")", + "engine->evaluate(\"0x43211234\")", + "engine->evaluate(\"0x10000\")", + "engine->evaluate(\"0x10001\")", + "engine->evaluate(\"NaN\")", + "engine->evaluate(\"Infinity\")", + "engine->evaluate(\"-Infinity\")", + "engine->evaluate(\"'ciao'\")", + "engine->evaluate(\"''\")", + "engine->evaluate(\"'0'\")", + "engine->evaluate(\"'123'\")", + "engine->evaluate(\"'12.4'\")", + "engine->nullValue()", + "engine->undefinedValue()", + "engine->newObject()", + "engine->newArray()", + "engine->newArray(10)"}; + +static const bool toBool_valueArray[] = { + false, false, + false, true, + false, true, + true, false, + false, true, + true, true, + true, true, + true, false, + false, true, + true, true, + true, true, + true, true, + false, false, + true, true, + true, false, + false, true, + false, true, + true, false, + false, true, + true, true, + true, true, + true, false, + false, true, + true, true, + true, true, + true, true, + false, false, + true, true, + true, false, + false, true, + false, true, + true, false, + false, true, + true, true, + true, true, + true, false, + false, true, + true, true, + true, true, + true, true, + false, false, + true, true, + true, true, + false, true, + true, true, + true, true, + true, true, + true, true, + true, true, + true, true, + true, true, + true, true, + true, true, + true, true, + false, false, + true, false, + true, true, + false, false, + true, true, + true, true, + true, true, + false, true, + true, true, + false, true, + true, true, + false, false, + true, true, + true}; + +void tst_QScriptValue::toBool_data() +{ + QTest::addColumn<QScriptValue>("value"); + QTest::addColumn<bool>("expected"); + if (m_engine) + delete m_engine; + m_engine = new QScriptEngine(); + QHash<QString, bool> expectedValue; + expectedValue.reserve(135); + for (uint i = 0; i < 135; ++i) + expectedValue.insert(toBool_tagArray[i], toBool_valueArray[i]); + for (uint i = 0; i < 135; ++i) { + QPair<QString, QScriptValue> testcase = initScriptValues(i); + QTest::newRow(testcase.first.toAscii().constData()) << testcase.second << expectedValue[testcase.first]; + } +} + +void tst_QScriptValue::toBool() +{ + QFETCH(QScriptValue, value); + QFETCH(bool, expected); + QCOMPARE(value.toBool(), expected); + QCOMPARE(value.toBool(), expected); +} + +static const QString toBoolean_tagArray[] = { + "QScriptValue()", + "QScriptValue(QScriptValue::UndefinedValue)", + "QScriptValue(QScriptValue::NullValue)", + "QScriptValue(true)", + "QScriptValue(false)", + "QScriptValue(int(122))", + "QScriptValue(uint(124))", + "QScriptValue(0)", + "QScriptValue(0.0)", + "QScriptValue(123.0)", + "QScriptValue(6.37e-8)", + "QScriptValue(-6.37e-8)", + "QScriptValue(0x43211234)", + "QScriptValue(0x10000)", + "QScriptValue(0x10001)", + "QScriptValue(qSNaN())", + "QScriptValue(qQNaN())", + "QScriptValue(qInf())", + "QScriptValue(-qInf())", + "QScriptValue(\"NaN\")", + "QScriptValue(\"Infinity\")", + "QScriptValue(\"-Infinity\")", + "QScriptValue(\"ciao\")", + "QScriptValue(QString::fromLatin1(\"ciao\"))", + "QScriptValue(QString(\"\"))", + "QScriptValue(QString())", + "QScriptValue(QString(\"0\"))", + "QScriptValue(QString(\"123\"))", + "QScriptValue(QString(\"12.4\"))", + "QScriptValue(0, QScriptValue::UndefinedValue)", + "QScriptValue(0, QScriptValue::NullValue)", + "QScriptValue(0, true)", + "QScriptValue(0, false)", + "QScriptValue(0, int(122))", + "QScriptValue(0, uint(124))", + "QScriptValue(0, 0)", + "QScriptValue(0, 0.0)", + "QScriptValue(0, 123.0)", + "QScriptValue(0, 6.37e-8)", + "QScriptValue(0, -6.37e-8)", + "QScriptValue(0, 0x43211234)", + "QScriptValue(0, 0x10000)", + "QScriptValue(0, 0x10001)", + "QScriptValue(0, qSNaN())", + "QScriptValue(0, qQNaN())", + "QScriptValue(0, qInf())", + "QScriptValue(0, -qInf())", + "QScriptValue(0, \"NaN\")", + "QScriptValue(0, \"Infinity\")", + "QScriptValue(0, \"-Infinity\")", + "QScriptValue(0, \"ciao\")", + "QScriptValue(0, QString::fromLatin1(\"ciao\"))", + "QScriptValue(0, QString(\"\"))", + "QScriptValue(0, QString())", + "QScriptValue(0, QString(\"0\"))", + "QScriptValue(0, QString(\"123\"))", + "QScriptValue(0, QString(\"12.3\"))", + "QScriptValue(engine, QScriptValue::UndefinedValue)", + "QScriptValue(engine, QScriptValue::NullValue)", + "QScriptValue(engine, true)", + "QScriptValue(engine, false)", + "QScriptValue(engine, int(122))", + "QScriptValue(engine, uint(124))", + "QScriptValue(engine, 0)", + "QScriptValue(engine, 0.0)", + "QScriptValue(engine, 123.0)", + "QScriptValue(engine, 6.37e-8)", + "QScriptValue(engine, -6.37e-8)", + "QScriptValue(engine, 0x43211234)", + "QScriptValue(engine, 0x10000)", + "QScriptValue(engine, 0x10001)", + "QScriptValue(engine, qSNaN())", + "QScriptValue(engine, qQNaN())", + "QScriptValue(engine, qInf())", + "QScriptValue(engine, -qInf())", + "QScriptValue(engine, \"NaN\")", + "QScriptValue(engine, \"Infinity\")", + "QScriptValue(engine, \"-Infinity\")", + "QScriptValue(engine, \"ciao\")", + "QScriptValue(engine, QString::fromLatin1(\"ciao\"))", + "QScriptValue(engine, QString(\"\"))", + "QScriptValue(engine, QString())", + "QScriptValue(engine, QString(\"0\"))", + "QScriptValue(engine, QString(\"123\"))", + "QScriptValue(engine, QString(\"1.23\"))", + "engine->evaluate(\"[]\")", + "engine->evaluate(\"{}\")", + "engine->evaluate(\"Object.prototype\")", + "engine->evaluate(\"Date.prototype\")", + "engine->evaluate(\"Array.prototype\")", + "engine->evaluate(\"Function.prototype\")", + "engine->evaluate(\"Error.prototype\")", + "engine->evaluate(\"Object\")", + "engine->evaluate(\"Array\")", + "engine->evaluate(\"Number\")", + "engine->evaluate(\"Function\")", + "engine->evaluate(\"(function() { return 1; })\")", + "engine->evaluate(\"(function() { return 'ciao'; })\")", + "engine->evaluate(\"(function() { throw new Error('foo'); })\")", + "engine->evaluate(\"/foo/\")", + "engine->evaluate(\"new Object()\")", + "engine->evaluate(\"new Array()\")", + "engine->evaluate(\"new Error()\")", + "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", + "engine->evaluate(\"Undefined\")", + "engine->evaluate(\"Null\")", + "engine->evaluate(\"True\")", + "engine->evaluate(\"False\")", + "engine->evaluate(\"undefined\")", + "engine->evaluate(\"null\")", + "engine->evaluate(\"true\")", + "engine->evaluate(\"false\")", + "engine->evaluate(\"122\")", + "engine->evaluate(\"124\")", + "engine->evaluate(\"0\")", + "engine->evaluate(\"0.0\")", + "engine->evaluate(\"123.0\")", + "engine->evaluate(\"6.37e-8\")", + "engine->evaluate(\"-6.37e-8\")", + "engine->evaluate(\"0x43211234\")", + "engine->evaluate(\"0x10000\")", + "engine->evaluate(\"0x10001\")", + "engine->evaluate(\"NaN\")", + "engine->evaluate(\"Infinity\")", + "engine->evaluate(\"-Infinity\")", + "engine->evaluate(\"'ciao'\")", + "engine->evaluate(\"''\")", + "engine->evaluate(\"'0'\")", + "engine->evaluate(\"'123'\")", + "engine->evaluate(\"'12.4'\")", + "engine->nullValue()", + "engine->undefinedValue()", + "engine->newObject()", + "engine->newArray()", + "engine->newArray(10)"}; + +static const bool toBoolean_valueArray[] = { + false, false, + false, true, + false, true, + true, false, + false, true, + true, true, + true, true, + true, false, + false, true, + true, true, + true, true, + true, true, + false, false, + true, true, + true, false, + false, true, + false, true, + true, false, + false, true, + true, true, + true, true, + true, false, + false, true, + true, true, + true, true, + true, true, + false, false, + true, true, + true, false, + false, true, + false, true, + true, false, + false, true, + true, true, + true, true, + true, false, + false, true, + true, true, + true, true, + true, true, + false, false, + true, true, + true, true, + false, true, + true, true, + true, true, + true, true, + true, true, + true, true, + true, true, + true, true, + true, true, + true, true, + true, true, + false, false, + true, false, + true, true, + false, false, + true, true, + true, true, + true, true, + false, true, + true, true, + false, true, + true, true, + false, false, + true, true, + true}; + +void tst_QScriptValue::toBoolean_data() +{ + QTest::addColumn<QScriptValue>("value"); + QTest::addColumn<bool>("expected"); + if (m_engine) + delete m_engine; + m_engine = new QScriptEngine(); + QHash<QString, bool> expectedValue; + expectedValue.reserve(135); + for (uint i = 0; i < 135; ++i) + expectedValue.insert(toBoolean_tagArray[i], toBoolean_valueArray[i]); + for (uint i = 0; i < 135; ++i) { + QPair<QString, QScriptValue> testcase = initScriptValues(i); + QTest::newRow(testcase.first.toAscii().constData()) << testcase.second << expectedValue[testcase.first]; + } +} + +void tst_QScriptValue::toBoolean() +{ + QFETCH(QScriptValue, value); + QFETCH(bool, expected); + QCOMPARE(value.toBoolean(), expected); + QCOMPARE(value.toBoolean(), expected); +} + +static const QString toInteger_tagArray[] = { + "QScriptValue()", + "QScriptValue(QScriptValue::UndefinedValue)", + "QScriptValue(QScriptValue::NullValue)", + "QScriptValue(true)", + "QScriptValue(false)", + "QScriptValue(int(122))", + "QScriptValue(uint(124))", + "QScriptValue(0)", + "QScriptValue(0.0)", + "QScriptValue(123.0)", + "QScriptValue(6.37e-8)", + "QScriptValue(-6.37e-8)", + "QScriptValue(0x43211234)", + "QScriptValue(0x10000)", + "QScriptValue(0x10001)", + "QScriptValue(qSNaN())", + "QScriptValue(qQNaN())", + "QScriptValue(qInf())", + "QScriptValue(-qInf())", + "QScriptValue(\"NaN\")", + "QScriptValue(\"Infinity\")", + "QScriptValue(\"-Infinity\")", + "QScriptValue(\"ciao\")", + "QScriptValue(QString::fromLatin1(\"ciao\"))", + "QScriptValue(QString(\"\"))", + "QScriptValue(QString())", + "QScriptValue(QString(\"0\"))", + "QScriptValue(QString(\"123\"))", + "QScriptValue(QString(\"12.4\"))", + "QScriptValue(0, QScriptValue::UndefinedValue)", + "QScriptValue(0, QScriptValue::NullValue)", + "QScriptValue(0, true)", + "QScriptValue(0, false)", + "QScriptValue(0, int(122))", + "QScriptValue(0, uint(124))", + "QScriptValue(0, 0)", + "QScriptValue(0, 0.0)", + "QScriptValue(0, 123.0)", + "QScriptValue(0, 6.37e-8)", + "QScriptValue(0, -6.37e-8)", + "QScriptValue(0, 0x43211234)", + "QScriptValue(0, 0x10000)", + "QScriptValue(0, 0x10001)", + "QScriptValue(0, qSNaN())", + "QScriptValue(0, qQNaN())", + "QScriptValue(0, qInf())", + "QScriptValue(0, -qInf())", + "QScriptValue(0, \"NaN\")", + "QScriptValue(0, \"Infinity\")", + "QScriptValue(0, \"-Infinity\")", + "QScriptValue(0, \"ciao\")", + "QScriptValue(0, QString::fromLatin1(\"ciao\"))", + "QScriptValue(0, QString(\"\"))", + "QScriptValue(0, QString())", + "QScriptValue(0, QString(\"0\"))", + "QScriptValue(0, QString(\"123\"))", + "QScriptValue(0, QString(\"12.3\"))", + "QScriptValue(engine, QScriptValue::UndefinedValue)", + "QScriptValue(engine, QScriptValue::NullValue)", + "QScriptValue(engine, true)", + "QScriptValue(engine, false)", + "QScriptValue(engine, int(122))", + "QScriptValue(engine, uint(124))", + "QScriptValue(engine, 0)", + "QScriptValue(engine, 0.0)", + "QScriptValue(engine, 123.0)", + "QScriptValue(engine, 6.37e-8)", + "QScriptValue(engine, -6.37e-8)", + "QScriptValue(engine, 0x43211234)", + "QScriptValue(engine, 0x10000)", + "QScriptValue(engine, 0x10001)", + "QScriptValue(engine, qSNaN())", + "QScriptValue(engine, qQNaN())", + "QScriptValue(engine, qInf())", + "QScriptValue(engine, -qInf())", + "QScriptValue(engine, \"NaN\")", + "QScriptValue(engine, \"Infinity\")", + "QScriptValue(engine, \"-Infinity\")", + "QScriptValue(engine, \"ciao\")", + "QScriptValue(engine, QString::fromLatin1(\"ciao\"))", + "QScriptValue(engine, QString(\"\"))", + "QScriptValue(engine, QString())", + "QScriptValue(engine, QString(\"0\"))", + "QScriptValue(engine, QString(\"123\"))", + "QScriptValue(engine, QString(\"1.23\"))", + "engine->evaluate(\"[]\")", + "engine->evaluate(\"{}\")", + "engine->evaluate(\"Object.prototype\")", + "engine->evaluate(\"Date.prototype\")", + "engine->evaluate(\"Array.prototype\")", + "engine->evaluate(\"Function.prototype\")", + "engine->evaluate(\"Error.prototype\")", + "engine->evaluate(\"Object\")", + "engine->evaluate(\"Array\")", + "engine->evaluate(\"Number\")", + "engine->evaluate(\"Function\")", + "engine->evaluate(\"(function() { return 1; })\")", + "engine->evaluate(\"(function() { return 'ciao'; })\")", + "engine->evaluate(\"(function() { throw new Error('foo'); })\")", + "engine->evaluate(\"/foo/\")", + "engine->evaluate(\"new Object()\")", + "engine->evaluate(\"new Array()\")", + "engine->evaluate(\"new Error()\")", + "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", + "engine->evaluate(\"Undefined\")", + "engine->evaluate(\"Null\")", + "engine->evaluate(\"True\")", + "engine->evaluate(\"False\")", + "engine->evaluate(\"undefined\")", + "engine->evaluate(\"null\")", + "engine->evaluate(\"true\")", + "engine->evaluate(\"false\")", + "engine->evaluate(\"122\")", + "engine->evaluate(\"124\")", + "engine->evaluate(\"0\")", + "engine->evaluate(\"0.0\")", + "engine->evaluate(\"123.0\")", + "engine->evaluate(\"6.37e-8\")", + "engine->evaluate(\"-6.37e-8\")", + "engine->evaluate(\"0x43211234\")", + "engine->evaluate(\"0x10000\")", + "engine->evaluate(\"0x10001\")", + "engine->evaluate(\"NaN\")", + "engine->evaluate(\"Infinity\")", + "engine->evaluate(\"-Infinity\")", + "engine->evaluate(\"'ciao'\")", + "engine->evaluate(\"''\")", + "engine->evaluate(\"'0'\")", + "engine->evaluate(\"'123'\")", + "engine->evaluate(\"'12.4'\")", + "engine->nullValue()", + "engine->undefinedValue()", + "engine->newObject()", + "engine->newArray()", + "engine->newArray(10)"}; + +static const qsreal toInteger_valueArray[] = { + 0, 0, 0, 1, 0, 122, 124, 0, 0, 123, + 0, 0, 1126240820, 65536, 65537, 0, 0, qInf(), qInf(), 0, + qInf(), qInf(), 0, 0, 0, 0, 0, 123, 12, 0, + 0, 1, 0, 122, 124, 0, 0, 123, 0, 0, + 1126240820, 65536, 65537, 0, 0, qInf(), qInf(), 0, qInf(), qInf(), + 0, 0, 0, 0, 0, 123, 12, 0, 0, 1, + 0, 122, 124, 0, 0, 123, 0, 0, 1126240820, 65536, + 65537, 0, 0, qInf(), qInf(), 0, qInf(), qInf(), 0, 0, + 0, 0, 0, 123, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 22, 0, 0, 0, 0, 0, 0, + 1, 0, 122, 124, 0, 0, 123, 0, 0, 1126240820, + 65536, 65537, 0, qInf(), qInf(), 0, 0, 0, 123, 12, + 0, 0, 0, 0, 0}; + +void tst_QScriptValue::toInteger_data() +{ + QTest::addColumn<QScriptValue>("value"); + QTest::addColumn<qsreal>("expected"); + if (m_engine) + delete m_engine; + m_engine = new QScriptEngine(); + QHash<QString, qsreal> expectedValue; + expectedValue.reserve(135); + for (uint i = 0; i < 135; ++i) + expectedValue.insert(toInteger_tagArray[i], toInteger_valueArray[i]); + for (uint i = 0; i < 135; ++i) { + QPair<QString, QScriptValue> testcase = initScriptValues(i); + QTest::newRow(testcase.first.toAscii().constData()) << testcase.second << expectedValue[testcase.first]; + } +} + +void tst_QScriptValue::toInteger() +{ + QFETCH(QScriptValue, value); + QFETCH(qsreal, expected); + if (qIsInf(expected)) { + QVERIFY(qIsInf(value.toInteger())); + QVERIFY(qIsInf(value.toInteger())); + return; + } + QCOMPARE(value.toInteger(), expected); + QCOMPARE(value.toInteger(), expected); +} + +static const QString toInt32_tagArray[] = { + "QScriptValue()", + "QScriptValue(QScriptValue::UndefinedValue)", + "QScriptValue(QScriptValue::NullValue)", + "QScriptValue(true)", + "QScriptValue(false)", + "QScriptValue(int(122))", + "QScriptValue(uint(124))", + "QScriptValue(0)", + "QScriptValue(0.0)", + "QScriptValue(123.0)", + "QScriptValue(6.37e-8)", + "QScriptValue(-6.37e-8)", + "QScriptValue(0x43211234)", + "QScriptValue(0x10000)", + "QScriptValue(0x10001)", + "QScriptValue(qSNaN())", + "QScriptValue(qQNaN())", + "QScriptValue(qInf())", + "QScriptValue(-qInf())", + "QScriptValue(\"NaN\")", + "QScriptValue(\"Infinity\")", + "QScriptValue(\"-Infinity\")", + "QScriptValue(\"ciao\")", + "QScriptValue(QString::fromLatin1(\"ciao\"))", + "QScriptValue(QString(\"\"))", + "QScriptValue(QString())", + "QScriptValue(QString(\"0\"))", + "QScriptValue(QString(\"123\"))", + "QScriptValue(QString(\"12.4\"))", + "QScriptValue(0, QScriptValue::UndefinedValue)", + "QScriptValue(0, QScriptValue::NullValue)", + "QScriptValue(0, true)", + "QScriptValue(0, false)", + "QScriptValue(0, int(122))", + "QScriptValue(0, uint(124))", + "QScriptValue(0, 0)", + "QScriptValue(0, 0.0)", + "QScriptValue(0, 123.0)", + "QScriptValue(0, 6.37e-8)", + "QScriptValue(0, -6.37e-8)", + "QScriptValue(0, 0x43211234)", + "QScriptValue(0, 0x10000)", + "QScriptValue(0, 0x10001)", + "QScriptValue(0, qSNaN())", + "QScriptValue(0, qQNaN())", + "QScriptValue(0, qInf())", + "QScriptValue(0, -qInf())", + "QScriptValue(0, \"NaN\")", + "QScriptValue(0, \"Infinity\")", + "QScriptValue(0, \"-Infinity\")", + "QScriptValue(0, \"ciao\")", + "QScriptValue(0, QString::fromLatin1(\"ciao\"))", + "QScriptValue(0, QString(\"\"))", + "QScriptValue(0, QString())", + "QScriptValue(0, QString(\"0\"))", + "QScriptValue(0, QString(\"123\"))", + "QScriptValue(0, QString(\"12.3\"))", + "QScriptValue(engine, QScriptValue::UndefinedValue)", + "QScriptValue(engine, QScriptValue::NullValue)", + "QScriptValue(engine, true)", + "QScriptValue(engine, false)", + "QScriptValue(engine, int(122))", + "QScriptValue(engine, uint(124))", + "QScriptValue(engine, 0)", + "QScriptValue(engine, 0.0)", + "QScriptValue(engine, 123.0)", + "QScriptValue(engine, 6.37e-8)", + "QScriptValue(engine, -6.37e-8)", + "QScriptValue(engine, 0x43211234)", + "QScriptValue(engine, 0x10000)", + "QScriptValue(engine, 0x10001)", + "QScriptValue(engine, qSNaN())", + "QScriptValue(engine, qQNaN())", + "QScriptValue(engine, qInf())", + "QScriptValue(engine, -qInf())", + "QScriptValue(engine, \"NaN\")", + "QScriptValue(engine, \"Infinity\")", + "QScriptValue(engine, \"-Infinity\")", + "QScriptValue(engine, \"ciao\")", + "QScriptValue(engine, QString::fromLatin1(\"ciao\"))", + "QScriptValue(engine, QString(\"\"))", + "QScriptValue(engine, QString())", + "QScriptValue(engine, QString(\"0\"))", + "QScriptValue(engine, QString(\"123\"))", + "QScriptValue(engine, QString(\"1.23\"))", + "engine->evaluate(\"[]\")", + "engine->evaluate(\"{}\")", + "engine->evaluate(\"Object.prototype\")", + "engine->evaluate(\"Date.prototype\")", + "engine->evaluate(\"Array.prototype\")", + "engine->evaluate(\"Function.prototype\")", + "engine->evaluate(\"Error.prototype\")", + "engine->evaluate(\"Object\")", + "engine->evaluate(\"Array\")", + "engine->evaluate(\"Number\")", + "engine->evaluate(\"Function\")", + "engine->evaluate(\"(function() { return 1; })\")", + "engine->evaluate(\"(function() { return 'ciao'; })\")", + "engine->evaluate(\"(function() { throw new Error('foo'); })\")", + "engine->evaluate(\"/foo/\")", + "engine->evaluate(\"new Object()\")", + "engine->evaluate(\"new Array()\")", + "engine->evaluate(\"new Error()\")", + "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", + "engine->evaluate(\"Undefined\")", + "engine->evaluate(\"Null\")", + "engine->evaluate(\"True\")", + "engine->evaluate(\"False\")", + "engine->evaluate(\"undefined\")", + "engine->evaluate(\"null\")", + "engine->evaluate(\"true\")", + "engine->evaluate(\"false\")", + "engine->evaluate(\"122\")", + "engine->evaluate(\"124\")", + "engine->evaluate(\"0\")", + "engine->evaluate(\"0.0\")", + "engine->evaluate(\"123.0\")", + "engine->evaluate(\"6.37e-8\")", + "engine->evaluate(\"-6.37e-8\")", + "engine->evaluate(\"0x43211234\")", + "engine->evaluate(\"0x10000\")", + "engine->evaluate(\"0x10001\")", + "engine->evaluate(\"NaN\")", + "engine->evaluate(\"Infinity\")", + "engine->evaluate(\"-Infinity\")", + "engine->evaluate(\"'ciao'\")", + "engine->evaluate(\"''\")", + "engine->evaluate(\"'0'\")", + "engine->evaluate(\"'123'\")", + "engine->evaluate(\"'12.4'\")", + "engine->nullValue()", + "engine->undefinedValue()", + "engine->newObject()", + "engine->newArray()", + "engine->newArray(10)"}; + +static const qint32 toInt32_valueArray[] = { + 0, 0, + 0, 1, + 0, 122, + 124, 0, + 0, 123, + 0, 0, + 1126240820, 65536, + 65537, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 123, + 12, 0, + 0, 1, + 0, 122, + 124, 0, + 0, 123, + 0, 0, + 1126240820, 65536, + 65537, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 123, + 12, 0, + 0, 1, + 0, 122, + 124, 0, + 0, 123, + 0, 0, + 1126240820, 65536, + 65537, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 123, + 1, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 22, + 0, 0, + 0, 0, + 0, 0, + 1, 0, + 122, 124, + 0, 0, + 123, 0, + 0, 1126240820, + 65536, 65537, + 0, 0, + 0, 0, + 0, 0, + 123, 12, + 0, 0, + 0, 0, + 0}; + +void tst_QScriptValue::toInt32_data() +{ + QTest::addColumn<QScriptValue>("value"); + QTest::addColumn<qint32>("expected"); + if (m_engine) + delete m_engine; + m_engine = new QScriptEngine(); + QHash<QString, qint32> expectedValue; + expectedValue.reserve(135); + for (uint i = 0; i < 135; ++i) + expectedValue.insert(toInt32_tagArray[i], toInt32_valueArray[i]); + for (uint i = 0; i < 135; ++i) { + QPair<QString, QScriptValue> testcase = initScriptValues(i); + QTest::newRow(testcase.first.toAscii().constData()) << testcase.second << expectedValue[testcase.first]; + } +} + +void tst_QScriptValue::toInt32() +{ + QFETCH(QScriptValue, value); + QFETCH(qint32, expected); + QCOMPARE(value.toInt32(), expected); + QCOMPARE(value.toInt32(), expected); +} + +static const QString toUInt32_tagArray[] = { + "QScriptValue()", + "QScriptValue(QScriptValue::UndefinedValue)", + "QScriptValue(QScriptValue::NullValue)", + "QScriptValue(true)", + "QScriptValue(false)", + "QScriptValue(int(122))", + "QScriptValue(uint(124))", + "QScriptValue(0)", + "QScriptValue(0.0)", + "QScriptValue(123.0)", + "QScriptValue(6.37e-8)", + "QScriptValue(-6.37e-8)", + "QScriptValue(0x43211234)", + "QScriptValue(0x10000)", + "QScriptValue(0x10001)", + "QScriptValue(qSNaN())", + "QScriptValue(qQNaN())", + "QScriptValue(qInf())", + "QScriptValue(-qInf())", + "QScriptValue(\"NaN\")", + "QScriptValue(\"Infinity\")", + "QScriptValue(\"-Infinity\")", + "QScriptValue(\"ciao\")", + "QScriptValue(QString::fromLatin1(\"ciao\"))", + "QScriptValue(QString(\"\"))", + "QScriptValue(QString())", + "QScriptValue(QString(\"0\"))", + "QScriptValue(QString(\"123\"))", + "QScriptValue(QString(\"12.4\"))", + "QScriptValue(0, QScriptValue::UndefinedValue)", + "QScriptValue(0, QScriptValue::NullValue)", + "QScriptValue(0, true)", + "QScriptValue(0, false)", + "QScriptValue(0, int(122))", + "QScriptValue(0, uint(124))", + "QScriptValue(0, 0)", + "QScriptValue(0, 0.0)", + "QScriptValue(0, 123.0)", + "QScriptValue(0, 6.37e-8)", + "QScriptValue(0, -6.37e-8)", + "QScriptValue(0, 0x43211234)", + "QScriptValue(0, 0x10000)", + "QScriptValue(0, 0x10001)", + "QScriptValue(0, qSNaN())", + "QScriptValue(0, qQNaN())", + "QScriptValue(0, qInf())", + "QScriptValue(0, -qInf())", + "QScriptValue(0, \"NaN\")", + "QScriptValue(0, \"Infinity\")", + "QScriptValue(0, \"-Infinity\")", + "QScriptValue(0, \"ciao\")", + "QScriptValue(0, QString::fromLatin1(\"ciao\"))", + "QScriptValue(0, QString(\"\"))", + "QScriptValue(0, QString())", + "QScriptValue(0, QString(\"0\"))", + "QScriptValue(0, QString(\"123\"))", + "QScriptValue(0, QString(\"12.3\"))", + "QScriptValue(engine, QScriptValue::UndefinedValue)", + "QScriptValue(engine, QScriptValue::NullValue)", + "QScriptValue(engine, true)", + "QScriptValue(engine, false)", + "QScriptValue(engine, int(122))", + "QScriptValue(engine, uint(124))", + "QScriptValue(engine, 0)", + "QScriptValue(engine, 0.0)", + "QScriptValue(engine, 123.0)", + "QScriptValue(engine, 6.37e-8)", + "QScriptValue(engine, -6.37e-8)", + "QScriptValue(engine, 0x43211234)", + "QScriptValue(engine, 0x10000)", + "QScriptValue(engine, 0x10001)", + "QScriptValue(engine, qSNaN())", + "QScriptValue(engine, qQNaN())", + "QScriptValue(engine, qInf())", + "QScriptValue(engine, -qInf())", + "QScriptValue(engine, \"NaN\")", + "QScriptValue(engine, \"Infinity\")", + "QScriptValue(engine, \"-Infinity\")", + "QScriptValue(engine, \"ciao\")", + "QScriptValue(engine, QString::fromLatin1(\"ciao\"))", + "QScriptValue(engine, QString(\"\"))", + "QScriptValue(engine, QString())", + "QScriptValue(engine, QString(\"0\"))", + "QScriptValue(engine, QString(\"123\"))", + "QScriptValue(engine, QString(\"1.23\"))", + "engine->evaluate(\"[]\")", + "engine->evaluate(\"{}\")", + "engine->evaluate(\"Object.prototype\")", + "engine->evaluate(\"Date.prototype\")", + "engine->evaluate(\"Array.prototype\")", + "engine->evaluate(\"Function.prototype\")", + "engine->evaluate(\"Error.prototype\")", + "engine->evaluate(\"Object\")", + "engine->evaluate(\"Array\")", + "engine->evaluate(\"Number\")", + "engine->evaluate(\"Function\")", + "engine->evaluate(\"(function() { return 1; })\")", + "engine->evaluate(\"(function() { return 'ciao'; })\")", + "engine->evaluate(\"(function() { throw new Error('foo'); })\")", + "engine->evaluate(\"/foo/\")", + "engine->evaluate(\"new Object()\")", + "engine->evaluate(\"new Array()\")", + "engine->evaluate(\"new Error()\")", + "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", + "engine->evaluate(\"Undefined\")", + "engine->evaluate(\"Null\")", + "engine->evaluate(\"True\")", + "engine->evaluate(\"False\")", + "engine->evaluate(\"undefined\")", + "engine->evaluate(\"null\")", + "engine->evaluate(\"true\")", + "engine->evaluate(\"false\")", + "engine->evaluate(\"122\")", + "engine->evaluate(\"124\")", + "engine->evaluate(\"0\")", + "engine->evaluate(\"0.0\")", + "engine->evaluate(\"123.0\")", + "engine->evaluate(\"6.37e-8\")", + "engine->evaluate(\"-6.37e-8\")", + "engine->evaluate(\"0x43211234\")", + "engine->evaluate(\"0x10000\")", + "engine->evaluate(\"0x10001\")", + "engine->evaluate(\"NaN\")", + "engine->evaluate(\"Infinity\")", + "engine->evaluate(\"-Infinity\")", + "engine->evaluate(\"'ciao'\")", + "engine->evaluate(\"''\")", + "engine->evaluate(\"'0'\")", + "engine->evaluate(\"'123'\")", + "engine->evaluate(\"'12.4'\")", + "engine->nullValue()", + "engine->undefinedValue()", + "engine->newObject()", + "engine->newArray()", + "engine->newArray(10)"}; + +static const quint32 toUInt32_valueArray[] = { + 0, 0, + 0, 1, + 0, 122, + 124, 0, + 0, 123, + 0, 0, + 1126240820, 65536, + 65537, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 123, + 12, 0, + 0, 1, + 0, 122, + 124, 0, + 0, 123, + 0, 0, + 1126240820, 65536, + 65537, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 123, + 12, 0, + 0, 1, + 0, 122, + 124, 0, + 0, 123, + 0, 0, + 1126240820, 65536, + 65537, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 123, + 1, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 22, + 0, 0, + 0, 0, + 0, 0, + 1, 0, + 122, 124, + 0, 0, + 123, 0, + 0, 1126240820, + 65536, 65537, + 0, 0, + 0, 0, + 0, 0, + 123, 12, + 0, 0, + 0, 0, + 0}; + +void tst_QScriptValue::toUInt32_data() +{ + QTest::addColumn<QScriptValue>("value"); + QTest::addColumn<quint32>("expected"); + if (m_engine) + delete m_engine; + m_engine = new QScriptEngine(); + QHash<QString, quint32> expectedValue; + expectedValue.reserve(135); + for (uint i = 0; i < 135; ++i) + expectedValue.insert(toUInt32_tagArray[i], toUInt32_valueArray[i]); + for (uint i = 0; i < 135; ++i) { + QPair<QString, QScriptValue> testcase = initScriptValues(i); + QTest::newRow(testcase.first.toAscii().constData()) << testcase.second << expectedValue[testcase.first]; + } +} + +void tst_QScriptValue::toUInt32() +{ + QFETCH(QScriptValue, value); + QFETCH(quint32, expected); + QCOMPARE(value.toUInt32(), expected); + QCOMPARE(value.toUInt32(), expected); +} + +static const QString toUInt16_tagArray[] = { + "QScriptValue()", + "QScriptValue(QScriptValue::UndefinedValue)", + "QScriptValue(QScriptValue::NullValue)", + "QScriptValue(true)", + "QScriptValue(false)", + "QScriptValue(int(122))", + "QScriptValue(uint(124))", + "QScriptValue(0)", + "QScriptValue(0.0)", + "QScriptValue(123.0)", + "QScriptValue(6.37e-8)", + "QScriptValue(-6.37e-8)", + "QScriptValue(0x43211234)", + "QScriptValue(0x10000)", + "QScriptValue(0x10001)", + "QScriptValue(qSNaN())", + "QScriptValue(qQNaN())", + "QScriptValue(qInf())", + "QScriptValue(-qInf())", + "QScriptValue(\"NaN\")", + "QScriptValue(\"Infinity\")", + "QScriptValue(\"-Infinity\")", + "QScriptValue(\"ciao\")", + "QScriptValue(QString::fromLatin1(\"ciao\"))", + "QScriptValue(QString(\"\"))", + "QScriptValue(QString())", + "QScriptValue(QString(\"0\"))", + "QScriptValue(QString(\"123\"))", + "QScriptValue(QString(\"12.4\"))", + "QScriptValue(0, QScriptValue::UndefinedValue)", + "QScriptValue(0, QScriptValue::NullValue)", + "QScriptValue(0, true)", + "QScriptValue(0, false)", + "QScriptValue(0, int(122))", + "QScriptValue(0, uint(124))", + "QScriptValue(0, 0)", + "QScriptValue(0, 0.0)", + "QScriptValue(0, 123.0)", + "QScriptValue(0, 6.37e-8)", + "QScriptValue(0, -6.37e-8)", + "QScriptValue(0, 0x43211234)", + "QScriptValue(0, 0x10000)", + "QScriptValue(0, 0x10001)", + "QScriptValue(0, qSNaN())", + "QScriptValue(0, qQNaN())", + "QScriptValue(0, qInf())", + "QScriptValue(0, -qInf())", + "QScriptValue(0, \"NaN\")", + "QScriptValue(0, \"Infinity\")", + "QScriptValue(0, \"-Infinity\")", + "QScriptValue(0, \"ciao\")", + "QScriptValue(0, QString::fromLatin1(\"ciao\"))", + "QScriptValue(0, QString(\"\"))", + "QScriptValue(0, QString())", + "QScriptValue(0, QString(\"0\"))", + "QScriptValue(0, QString(\"123\"))", + "QScriptValue(0, QString(\"12.3\"))", + "QScriptValue(engine, QScriptValue::UndefinedValue)", + "QScriptValue(engine, QScriptValue::NullValue)", + "QScriptValue(engine, true)", + "QScriptValue(engine, false)", + "QScriptValue(engine, int(122))", + "QScriptValue(engine, uint(124))", + "QScriptValue(engine, 0)", + "QScriptValue(engine, 0.0)", + "QScriptValue(engine, 123.0)", + "QScriptValue(engine, 6.37e-8)", + "QScriptValue(engine, -6.37e-8)", + "QScriptValue(engine, 0x43211234)", + "QScriptValue(engine, 0x10000)", + "QScriptValue(engine, 0x10001)", + "QScriptValue(engine, qSNaN())", + "QScriptValue(engine, qQNaN())", + "QScriptValue(engine, qInf())", + "QScriptValue(engine, -qInf())", + "QScriptValue(engine, \"NaN\")", + "QScriptValue(engine, \"Infinity\")", + "QScriptValue(engine, \"-Infinity\")", + "QScriptValue(engine, \"ciao\")", + "QScriptValue(engine, QString::fromLatin1(\"ciao\"))", + "QScriptValue(engine, QString(\"\"))", + "QScriptValue(engine, QString())", + "QScriptValue(engine, QString(\"0\"))", + "QScriptValue(engine, QString(\"123\"))", + "QScriptValue(engine, QString(\"1.23\"))", + "engine->evaluate(\"[]\")", + "engine->evaluate(\"{}\")", + "engine->evaluate(\"Object.prototype\")", + "engine->evaluate(\"Date.prototype\")", + "engine->evaluate(\"Array.prototype\")", + "engine->evaluate(\"Function.prototype\")", + "engine->evaluate(\"Error.prototype\")", + "engine->evaluate(\"Object\")", + "engine->evaluate(\"Array\")", + "engine->evaluate(\"Number\")", + "engine->evaluate(\"Function\")", + "engine->evaluate(\"(function() { return 1; })\")", + "engine->evaluate(\"(function() { return 'ciao'; })\")", + "engine->evaluate(\"(function() { throw new Error('foo'); })\")", + "engine->evaluate(\"/foo/\")", + "engine->evaluate(\"new Object()\")", + "engine->evaluate(\"new Array()\")", + "engine->evaluate(\"new Error()\")", + "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", + "engine->evaluate(\"Undefined\")", + "engine->evaluate(\"Null\")", + "engine->evaluate(\"True\")", + "engine->evaluate(\"False\")", + "engine->evaluate(\"undefined\")", + "engine->evaluate(\"null\")", + "engine->evaluate(\"true\")", + "engine->evaluate(\"false\")", + "engine->evaluate(\"122\")", + "engine->evaluate(\"124\")", + "engine->evaluate(\"0\")", + "engine->evaluate(\"0.0\")", + "engine->evaluate(\"123.0\")", + "engine->evaluate(\"6.37e-8\")", + "engine->evaluate(\"-6.37e-8\")", + "engine->evaluate(\"0x43211234\")", + "engine->evaluate(\"0x10000\")", + "engine->evaluate(\"0x10001\")", + "engine->evaluate(\"NaN\")", + "engine->evaluate(\"Infinity\")", + "engine->evaluate(\"-Infinity\")", + "engine->evaluate(\"'ciao'\")", + "engine->evaluate(\"''\")", + "engine->evaluate(\"'0'\")", + "engine->evaluate(\"'123'\")", + "engine->evaluate(\"'12.4'\")", + "engine->nullValue()", + "engine->undefinedValue()", + "engine->newObject()", + "engine->newArray()", + "engine->newArray(10)"}; + +static const quint16 toUInt16_valueArray[] = { + 0, 0, + 0, 1, + 0, 122, + 124, 0, + 0, 123, + 0, 0, + 4660, 0, + 1, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 123, + 12, 0, + 0, 1, + 0, 122, + 124, 0, + 0, 123, + 0, 0, + 4660, 0, + 1, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 123, + 12, 0, + 0, 1, + 0, 122, + 124, 0, + 0, 123, + 0, 0, + 4660, 0, + 1, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 123, + 1, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 22, + 0, 0, + 0, 0, + 0, 0, + 1, 0, + 122, 124, + 0, 0, + 123, 0, + 0, 4660, + 0, 1, + 0, 0, + 0, 0, + 0, 0, + 123, 12, + 0, 0, + 0, 0, + 0}; + +void tst_QScriptValue::toUInt16_data() +{ + QTest::addColumn<QScriptValue>("value"); + QTest::addColumn<quint16>("expected"); + if (m_engine) + delete m_engine; + m_engine = new QScriptEngine(); + QHash<QString, quint16> expectedValue; + expectedValue.reserve(135); + for (uint i = 0; i < 135; ++i) + expectedValue.insert(toUInt16_tagArray[i], toUInt16_valueArray[i]); + for (uint i = 0; i < 135; ++i) { + QPair<QString, QScriptValue> testcase = initScriptValues(i); + QTest::newRow(testcase.first.toAscii().constData()) << testcase.second << expectedValue[testcase.first]; + } +} + +void tst_QScriptValue::toUInt16() +{ + QFETCH(QScriptValue, value); + QFETCH(quint16, expected); + QCOMPARE(value.toUInt16(), expected); + QCOMPARE(value.toUInt16(), expected); +} diff --git a/Source/JavaScriptCore/qt/tests/qscriptvalueiterator/qscriptvalueiterator.pro b/Source/JavaScriptCore/qt/tests/qscriptvalueiterator/qscriptvalueiterator.pro new file mode 100644 index 0000000..5314ec9 --- /dev/null +++ b/Source/JavaScriptCore/qt/tests/qscriptvalueiterator/qscriptvalueiterator.pro @@ -0,0 +1,7 @@ +TEMPLATE = app +TARGET = tst_qscriptvalueiterator +QT += testlib +include(../tests.pri) + +SOURCES += tst_qscriptvalueiterator.cpp + diff --git a/Source/JavaScriptCore/qt/tests/qscriptvalueiterator/tst_qscriptvalueiterator.cpp b/Source/JavaScriptCore/qt/tests/qscriptvalueiterator/tst_qscriptvalueiterator.cpp new file mode 100644 index 0000000..43d0042 --- /dev/null +++ b/Source/JavaScriptCore/qt/tests/qscriptvalueiterator/tst_qscriptvalueiterator.cpp @@ -0,0 +1,531 @@ +/* + Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef tst_qscriptvalueiterator_h +#define tst_qscriptvalueiterator_h + +#include "qscriptengine.h" +#include "qscriptvalue.h" +#include "qscriptvalueiterator.h" +#include <QtCore/qhash.h> +#include <QtTest/QtTest> + +class tst_QScriptValueIterator : public QObject { + Q_OBJECT + +public: + tst_QScriptValueIterator(); + virtual ~tst_QScriptValueIterator(); + +private slots: + void iterateForward_data(); + void iterateForward(); + void iterateBackward_data(); + void iterateBackward(); + void iterateArray_data(); + void iterateArray(); + void iterateBackAndForth(); + void setValue(); + void remove(); + void removeMixed(); + void removeUndeletable(); + void iterateString(); + void assignObjectToIterator(); +}; + +tst_QScriptValueIterator::tst_QScriptValueIterator() +{ +} + +tst_QScriptValueIterator::~tst_QScriptValueIterator() +{ +} + +void tst_QScriptValueIterator::iterateForward_data() +{ + QTest::addColumn<QStringList>("propertyNames"); + QTest::addColumn<QStringList>("propertyValues"); + + QTest::newRow("no properties") + << QStringList() << QStringList(); + QTest::newRow("foo=bar") + << (QStringList() << "foo") + << (QStringList() << "bar"); + QTest::newRow("foo=bar, baz=123") + << (QStringList() << "foo" << "baz") + << (QStringList() << "bar" << "123"); + QTest::newRow("foo=bar, baz=123, rab=oof") + << (QStringList() << "foo" << "baz" << "rab") + << (QStringList() << "bar" << "123" << "oof"); +} + +void tst_QScriptValueIterator::iterateForward() +{ + QFETCH(QStringList, propertyNames); + QFETCH(QStringList, propertyValues); + QMap<QString, QString> pmap; + Q_ASSERT(propertyNames.size() == propertyValues.size()); + + QScriptEngine engine; + QScriptValue object = engine.newObject(); + for (int i = 0; i < propertyNames.size(); ++i) { + QString name = propertyNames.at(i); + QString value = propertyValues.at(i); + pmap.insert(name, value); + object.setProperty(name, QScriptValue(&engine, value)); + } + QScriptValue otherObject = engine.newObject(); + otherObject.setProperty("foo", QScriptValue(&engine, 123456)); + otherObject.setProperty("protoProperty", QScriptValue(&engine, 654321)); + object.setPrototype(otherObject); // should not affect iterator + + QStringList lst; + QScriptValueIterator it(object); + while (!pmap.isEmpty()) { + QCOMPARE(it.hasNext(), true); + QCOMPARE(it.hasNext(), true); + it.next(); + QString name = it.name(); + QCOMPARE(pmap.contains(name), true); + QCOMPARE(it.name(), name); + QCOMPARE(it.flags(), object.propertyFlags(name)); + QCOMPARE(it.value().strictlyEquals(QScriptValue(&engine, pmap.value(name))), true); + QCOMPARE(it.scriptName(), engine.toStringHandle(name)); + pmap.remove(name); + lst.append(name); + } + + QCOMPARE(it.hasNext(), false); + QCOMPARE(it.hasNext(), false); + + it.toFront(); + for (int i = 0; i < lst.count(); ++i) { + QCOMPARE(it.hasNext(), true); + it.next(); + QCOMPARE(it.name(), lst.at(i)); + } + + for (int i = 0; i < lst.count(); ++i) { + QCOMPARE(it.hasPrevious(), true); + it.previous(); + QCOMPARE(it.name(), lst.at(lst.count()-1-i)); + } + QCOMPARE(it.hasPrevious(), false); +} + +void tst_QScriptValueIterator::iterateBackward_data() +{ + iterateForward_data(); +} + +void tst_QScriptValueIterator::iterateBackward() +{ + QFETCH(QStringList, propertyNames); + QFETCH(QStringList, propertyValues); + QMap<QString, QString> pmap; + Q_ASSERT(propertyNames.size() == propertyValues.size()); + + QScriptEngine engine; + QScriptValue object = engine.newObject(); + for (int i = 0; i < propertyNames.size(); ++i) { + QString name = propertyNames.at(i); + QString value = propertyValues.at(i); + pmap.insert(name, value); + object.setProperty(name, QScriptValue(&engine, value)); + } + + QStringList lst; + QScriptValueIterator it(object); + it.toBack(); + while (!pmap.isEmpty()) { + QCOMPARE(it.hasPrevious(), true); + QCOMPARE(it.hasPrevious(), true); + it.previous(); + QString name = it.name(); + QCOMPARE(pmap.contains(name), true); + QCOMPARE(it.name(), name); + QCOMPARE(it.flags(), object.propertyFlags(name)); + QCOMPARE(it.value().strictlyEquals(QScriptValue(&engine, pmap.value(name))), true); + pmap.remove(name); + lst.append(name); + } + + QCOMPARE(it.hasPrevious(), false); + QCOMPARE(it.hasPrevious(), false); + + it.toBack(); + for (int i = 0; i < lst.count(); ++i) { + QCOMPARE(it.hasPrevious(), true); + it.previous(); + QCOMPARE(it.name(), lst.at(i)); + } + + for (int i = 0; i < lst.count(); ++i) { + QCOMPARE(it.hasNext(), true); + it.next(); + QCOMPARE(it.name(), lst.at(lst.count()-1-i)); + } + QCOMPARE(it.hasNext(), false); +} + +void tst_QScriptValueIterator::iterateArray_data() +{ + QTest::addColumn<QStringList>("inputPropertyNames"); + QTest::addColumn<QStringList>("inputPropertyValues"); + QTest::addColumn<QStringList>("propertyNames"); + QTest::addColumn<QStringList>("propertyValues"); + QTest::newRow("no elements") << QStringList() << QStringList() << QStringList() << QStringList(); + + QTest::newRow("0=foo, 1=barr") + << (QStringList() << "0" << "1") + << (QStringList() << "foo" << "bar") + << (QStringList() << "0" << "1") + << (QStringList() << "foo" << "bar"); + + QTest::newRow("0=foo, 3=barr") + << (QStringList() << "0" << "1" << "2" << "3") + << (QStringList() << "foo" << "" << "" << "bar") + << (QStringList() << "0" << "1" << "2" << "3") + << (QStringList() << "foo" << "" << "" << "bar"); +} + +void tst_QScriptValueIterator::iterateArray() +{ + QFETCH(QStringList, inputPropertyNames); + QFETCH(QStringList, inputPropertyValues); + QFETCH(QStringList, propertyNames); + QFETCH(QStringList, propertyValues); + + QScriptEngine engine; + QScriptValue array = engine.newArray(); + for (int i = 0; i < inputPropertyNames.size(); ++i) + array.setProperty(inputPropertyNames.at(i), inputPropertyValues.at(i)); + + int length = array.property("length").toInt32(); + QCOMPARE(length, propertyNames.size()); + QScriptValueIterator it(array); + for (int i = 0; i < length; ++i) { + QCOMPARE(it.hasNext(), true); + it.next(); + QCOMPARE(it.name(), propertyNames.at(i)); + QCOMPARE(it.flags(), array.propertyFlags(propertyNames.at(i))); + QVERIFY(it.value().strictlyEquals(array.property(propertyNames.at(i)))); + QCOMPARE(it.value().toString(), propertyValues.at(i)); + } + QVERIFY(it.hasNext()); + it.next(); + QCOMPARE(it.name(), QString::fromLatin1("length")); + QVERIFY(it.value().isNumber()); + QCOMPARE(it.value().toInt32(), length); + QCOMPARE(it.flags(), QScriptValue::PropertyFlags(QScriptValue::SkipInEnumeration | QScriptValue::Undeletable)); + + it.previous(); + QCOMPARE(it.hasPrevious(), length > 0); + for (int i = length - 1; i >= 0; --i) { + it.previous(); + QCOMPARE(it.name(), propertyNames.at(i)); + QCOMPARE(it.flags(), array.propertyFlags(propertyNames.at(i))); + QVERIFY(it.value().strictlyEquals(array.property(propertyNames.at(i)))); + QCOMPARE(it.value().toString(), propertyValues.at(i)); + QCOMPARE(it.hasPrevious(), i > 0); + } + QCOMPARE(it.hasPrevious(), false); + + // hasNext() and hasPrevious() cache their result; verify that the result is in sync + if (length > 1) { + QVERIFY(it.hasNext()); + it.next(); + QCOMPARE(it.name(), QString::fromLatin1("0")); + QVERIFY(it.hasNext()); + it.previous(); + QCOMPARE(it.name(), QString::fromLatin1("0")); + QVERIFY(!it.hasPrevious()); + it.next(); + QCOMPARE(it.name(), QString::fromLatin1("0")); + QVERIFY(it.hasPrevious()); + it.next(); + QCOMPARE(it.name(), QString::fromLatin1("1")); + } + { + // same test as object: + QScriptValue originalArray = engine.newArray(); + for (int i = 0; i < inputPropertyNames.size(); ++i) + originalArray.setProperty(inputPropertyNames.at(i), inputPropertyValues.at(i)); + + QScriptValue array = originalArray.toObject(); + int length = array.property("length").toInt32(); + QCOMPARE(length, propertyNames.size()); + QScriptValueIterator it(array); + for (int i = 0; i < length; ++i) { + QCOMPARE(it.hasNext(), true); + it.next(); + QCOMPARE(it.name(), propertyNames.at(i)); + QCOMPARE(it.flags(), array.propertyFlags(propertyNames.at(i))); + QVERIFY(it.value().strictlyEquals(array.property(propertyNames.at(i)))); + QCOMPARE(it.value().toString(), propertyValues.at(i)); + } + QCOMPARE(it.hasNext(), true); + it.next(); + QCOMPARE(it.name(), QString::fromLatin1("length")); + } +} + +void tst_QScriptValueIterator::iterateBackAndForth() +{ + QScriptEngine engine; + { + QScriptValue object = engine.newObject(); + object.setProperty("foo", QScriptValue(&engine, "bar")); + object.setProperty("rab", QScriptValue(&engine, "oof"), + QScriptValue::SkipInEnumeration); // should not affect iterator + QScriptValueIterator it(object); + QVERIFY(it.hasNext()); + it.next(); + QCOMPARE(it.name(), QLatin1String("foo")); + QVERIFY(it.hasPrevious()); + it.previous(); + QCOMPARE(it.name(), QLatin1String("foo")); + QVERIFY(it.hasNext()); + it.next(); + QCOMPARE(it.name(), QLatin1String("foo")); + QVERIFY(it.hasPrevious()); + it.previous(); + QCOMPARE(it.name(), QLatin1String("foo")); + QVERIFY(it.hasNext()); + it.next(); + QCOMPARE(it.name(), QLatin1String("foo")); + QVERIFY(it.hasNext()); + it.next(); + QCOMPARE(it.name(), QLatin1String("rab")); + QVERIFY(it.hasPrevious()); + it.previous(); + QCOMPARE(it.name(), QLatin1String("rab")); + QVERIFY(it.hasNext()); + it.next(); + QCOMPARE(it.name(), QLatin1String("rab")); + QVERIFY(it.hasPrevious()); + it.previous(); + QCOMPARE(it.name(), QLatin1String("rab")); + } + { + // hasNext() and hasPrevious() cache their result; verify that the result is in sync + QScriptValue object = engine.newObject(); + object.setProperty("foo", QScriptValue(&engine, "bar")); + object.setProperty("rab", QScriptValue(&engine, "oof")); + QScriptValueIterator it(object); + QVERIFY(it.hasNext()); + it.next(); + QCOMPARE(it.name(), QString::fromLatin1("foo")); + QVERIFY(it.hasNext()); + it.previous(); + QCOMPARE(it.name(), QString::fromLatin1("foo")); + QVERIFY(!it.hasPrevious()); + it.next(); + QCOMPARE(it.name(), QString::fromLatin1("foo")); + QVERIFY(it.hasPrevious()); + it.next(); + QCOMPARE(it.name(), QString::fromLatin1("rab")); + } +} + +void tst_QScriptValueIterator::setValue() +{ + QScriptEngine engine; + QScriptValue object = engine.newObject(); + object.setProperty("foo", QScriptValue(&engine, "bar")); + QScriptValueIterator it(object); + it.next(); + QCOMPARE(it.name(), QLatin1String("foo")); + it.setValue(QScriptValue(&engine, "baz")); + QCOMPARE(it.value().strictlyEquals(QScriptValue(&engine, QLatin1String("baz"))), true); + QCOMPARE(object.property("foo").toString(), QLatin1String("baz")); + it.setValue(QScriptValue(&engine, "zab")); + QCOMPARE(it.value().strictlyEquals(QScriptValue(&engine, QLatin1String("zab"))), true); + QCOMPARE(object.property("foo").toString(), QLatin1String("zab")); +} + +void tst_QScriptValueIterator::remove() +{ + QScriptEngine engine; + QScriptValue object = engine.newObject(); + object.setProperty("foo", QScriptValue(&engine, "bar"), + QScriptValue::SkipInEnumeration); // should not affect iterator + object.setProperty("rab", QScriptValue(&engine, "oof")); + QScriptValueIterator it(object); + it.next(); + QCOMPARE(it.name(), QLatin1String("foo")); + it.remove(); + QCOMPARE(it.hasPrevious(), false); + QCOMPARE(object.property("foo").isValid(), false); + QCOMPARE(object.property("rab").toString(), QLatin1String("oof")); + it.next(); + QCOMPARE(it.name(), QLatin1String("rab")); + QCOMPARE(it.value().toString(), QLatin1String("oof")); + QCOMPARE(it.hasNext(), false); + it.remove(); + QCOMPARE(object.property("rab").isValid(), false); + QCOMPARE(it.hasPrevious(), false); + QCOMPARE(it.hasNext(), false); +} + +void tst_QScriptValueIterator::removeMixed() +{ + // This test checks if QScriptValueIterator behaives correctly if an object's property got deleted + // in different way. + QScriptEngine engine; + QScriptValue object = engine.evaluate("o = new Object; o"); + object.setProperty("a", QScriptValue(124), QScriptValue::SkipInEnumeration); + object.setProperty("b", QScriptValue(816)); + object.setProperty("c", QScriptValue(3264)); + QScriptValueIterator it(object); + it.next(); + it.next(); + QCOMPARE(it.name(), QLatin1String("b")); + QCOMPARE(it.hasPrevious(), true); + QCOMPARE(it.hasNext(), true); + // Remove 'a' + object.setProperty("a", QScriptValue()); + QEXPECT_FAIL("", "That would be a significant behavioral and performance change, new QtScript API should be developed (QTBUG-12087)", Abort); + QCOMPARE(it.hasPrevious(), false); + QCOMPARE(it.hasNext(), true); + // Remove 'c' + engine.evaluate("delete o.c"); + QCOMPARE(it.hasPrevious(), false); + QCOMPARE(it.hasNext(), false); + // Remove 'b' + object.setProperty("b", QScriptValue()); + QCOMPARE(it.hasPrevious(), false); + QCOMPARE(it.hasNext(), false); + QCOMPARE(it.name(), QString()); + QCOMPARE(it.value().toString(), QString()); + + // Try to remove a removed property. + it.remove(); + QCOMPARE(it.hasPrevious(), false); + QCOMPARE(it.hasNext(), false); + QCOMPARE(it.name(), QString()); + QCOMPARE(it.value().toString(), QString()); + + for (int i = 0; i < 2; ++i) { + it.next(); + QCOMPARE(it.hasPrevious(), false); + QCOMPARE(it.hasNext(), false); + QCOMPARE(it.name(), QString()); + QCOMPARE(it.value().toString(), QString()); + } + + for (int i = 0; i < 2; ++i) { + it.previous(); + QCOMPARE(it.hasPrevious(), false); + QCOMPARE(it.hasNext(), false); + QCOMPARE(it.name(), QString()); + QCOMPARE(it.value().toString(), QString()); + } +} + +void tst_QScriptValueIterator::removeUndeletable() +{ + // Undeletable property can't be deleted via iterator. + QScriptEngine engine; + QScriptValue object = engine.evaluate("o = new Object; o"); + object.setProperty("a", QScriptValue(&engine, 124)); + object.setProperty("b", QScriptValue(&engine, 816), QScriptValue::Undeletable); + QVERIFY(object.property("b").isValid()); + QScriptValueIterator it(object); + it.next(); + it.next(); + it.remove(); + it.toFront(); + QVERIFY(it.hasNext()); + QVERIFY(object.property("b").isValid()); +} + +void tst_QScriptValueIterator::iterateString() +{ + QScriptEngine engine; + QScriptValue str = QScriptValue(&engine, QString::fromLatin1("ciao")); + QVERIFY(str.isString()); + QScriptValue obj = str.toObject(); + int length = obj.property("length").toInt32(); + QCOMPARE(length, 4); + QScriptValueIterator it(obj); + for (int i = 0; i < length; ++i) { + QCOMPARE(it.hasNext(), true); + QString indexStr = QScriptValue(&engine, i).toString(); + it.next(); + QCOMPARE(it.name(), indexStr); + QCOMPARE(it.flags(), obj.propertyFlags(indexStr)); + QCOMPARE(it.value().strictlyEquals(obj.property(indexStr)), true); + } + QVERIFY(it.hasNext()); + it.next(); + QCOMPARE(it.name(), QString::fromLatin1("length")); + QVERIFY(it.value().isNumber()); + QCOMPARE(it.value().toInt32(), length); + QCOMPARE(it.flags(), QScriptValue::PropertyFlags(QScriptValue::ReadOnly | QScriptValue::SkipInEnumeration | QScriptValue::Undeletable)); + + it.previous(); + QCOMPARE(it.hasPrevious(), length > 0); + for (int i = length - 1; i >= 0; --i) { + it.previous(); + QString indexStr = QScriptValue(&engine, i).toString(); + QCOMPARE(it.name(), indexStr); + QCOMPARE(it.flags(), obj.propertyFlags(indexStr)); + QCOMPARE(it.value().strictlyEquals(obj.property(indexStr)), true); + QCOMPARE(it.hasPrevious(), i > 0); + } + QCOMPARE(it.hasPrevious(), false); +} + +void tst_QScriptValueIterator::assignObjectToIterator() +{ + QScriptEngine eng; + QScriptValue obj1 = eng.newObject(); + obj1.setProperty("foo", 123); + QScriptValue obj2 = eng.newObject(); + obj2.setProperty("bar", 456); + + QScriptValueIterator it(obj1); + QVERIFY(it.hasNext()); + it.next(); + it = obj2; + QVERIFY(it.hasNext()); + it.next(); + QCOMPARE(it.name(), QString::fromLatin1("bar")); + + it = obj1; + QVERIFY(it.hasNext()); + it.next(); + QCOMPARE(it.name(), QString::fromLatin1("foo")); + + it = obj2; + QVERIFY(it.hasNext()); + it.next(); + QCOMPARE(it.name(), QString::fromLatin1("bar")); + + it = obj2; + QVERIFY(it.hasNext()); + it.next(); + QCOMPARE(it.name(), QString::fromLatin1("bar")); +} + +QTEST_MAIN(tst_QScriptValueIterator) +#include "tst_qscriptvalueiterator.moc" + +#endif // tst_qscriptvalueiterator_h diff --git a/Source/JavaScriptCore/qt/tests/tests.pri b/Source/JavaScriptCore/qt/tests/tests.pri new file mode 100644 index 0000000..5af3383 --- /dev/null +++ b/Source/JavaScriptCore/qt/tests/tests.pri @@ -0,0 +1,19 @@ +QMAKE_RPATHDIR = $$OUTPUT_DIR/lib $$QMAKE_RPATHDIR +QMAKE_LIBDIR = $$OUTPUT_DIR/lib $$QMAKE_LIBDIR +mac:!static:contains(QT_CONFIG, qt_framework):!CONFIG(webkit_no_framework) { + LIBS += -framework QtScript + QMAKE_FRAMEWORKPATH = $$OUTPUT_DIR/lib $$QMAKE_FRAMEWORKPATH +} else { + win32-*|wince* { + LIBS += -lQtScript$${QT_MAJOR_VERSION} + } else { + LIBS += -lQtScript + } +} + +CONFIG(release, debug|release) { + DEFINES += NDEBUG +} + +INCLUDEPATH += $$PWD/../api + diff --git a/Source/JavaScriptCore/qt/tests/tests.pro b/Source/JavaScriptCore/qt/tests/tests.pro new file mode 100644 index 0000000..6d5559b --- /dev/null +++ b/Source/JavaScriptCore/qt/tests/tests.pro @@ -0,0 +1,5 @@ +TEMPLATE = subdirs +SUBDIRS = qscriptengine \ + qscriptvalue \ + qscriptvalueiterator \ + qscriptstring |