blob: 67c11c3d3778906b84d4074d35a3bcab8d3c3c7b [file] [log] [blame]
/****************************************************************************
**
** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <qtest.h>
#include <QtScript>
Q_DECLARE_METATYPE(QScriptValue)
class tst_QScriptValue : public QObject
{
Q_OBJECT
public:
tst_QScriptValue();
virtual ~tst_QScriptValue();
public slots:
void init();
void cleanup();
private slots:
void boolConstructor();
void floatConstructor();
void numberConstructor();
void stringConstructor();
void nullConstructor();
void undefinedConstructor();
void boolConstructorWithEngine();
void floatConstructorWithEngine();
void intConstructorWithEngine();
void stringConstructorWithEngine();
void nullConstructorWithEngine();
void undefinedConstructorWithEngine();
void copyConstructor_data();
void copyConstructor();
void call_data();
void call();
void construct_data();
void construct();
void data();
void setData();
void data_noData_data();
void data_noData();
void engine_data();
void engine();
void equalsSelf_data();
void equalsSelf();
void lessThanSelf_data();
void lessThanSelf();
void strictlyEqualsSelf_data();
void strictlyEqualsSelf();
void instanceOf();
void isArray_data();
void isArray();
void isBool_data();
void isBool();
void isDate_data();
void isDate();
void isError_data();
void isError();
void isFunction_data();
void isFunction();
void isNull_data();
void isNull();
void isNumber_data();
void isNumber();
void isObject_data();
void isObject();
void isQMetaObject_data();
void isQMetaObject();
void isQObject_data();
void isQObject();
void isRegExp_data();
void isRegExp();
void isString_data();
void isString();
void isUndefined_data();
void isUndefined();
void isValid_data();
void isValid();
void isVariant_data();
void isVariant();
void toBool_data();
void toBool();
void toDateTime_data();
void toDateTime();
void toInt32_data();
void toInt32();
void toInteger_data();
void toInteger();
void toNumber_data();
void toNumber();
void toRegExp_data();
void toRegExp();
void toString_data();
void toString();
void toUInt16_data();
void toUInt16();
void toUInt32_data();
void toUInt32();
void toQMetaObject_data();
void toQMetaObject();
void toQObject_data();
void toQObject();
void toVariant_data();
void toVariant();
void property_data();
void property();
void propertyById_data();
void propertyById();
void propertyByIndex();
void setProperty_data();
void setProperty();
void setPropertyById_data();
void setPropertyById();
void setPropertyByIndex();
void propertyFlags_data();
void propertyFlags();
void propertyFlagsById_data();
void propertyFlagsById();
void prototype_data();
void prototype();
void setPrototype();
void scriptClass_data();
void scriptClass();
void setScriptClass();
void readMetaProperty();
void writeMetaProperty();
private:
void defineStandardTestValues();
void newEngine()
{
delete m_engine;
m_engine = new QScriptEngine;
}
QScriptEngine *m_engine;
};
tst_QScriptValue::tst_QScriptValue()
: m_engine(0)
{
}
tst_QScriptValue::~tst_QScriptValue()
{
delete m_engine;
}
void tst_QScriptValue::init()
{
}
void tst_QScriptValue::cleanup()
{
}
void tst_QScriptValue::boolConstructor()
{
QBENCHMARK {
QScriptValue val(true);
}
}
void tst_QScriptValue::floatConstructor()
{
QBENCHMARK {
QScriptValue val(123.0);
}
}
void tst_QScriptValue::numberConstructor()
{
QBENCHMARK {
(void)QScriptValue(123);
}
}
void tst_QScriptValue::stringConstructor()
{
QString str = QString::fromLatin1("ciao");
QBENCHMARK {
(void)QScriptValue(str);
}
}
void tst_QScriptValue::nullConstructor()
{
QBENCHMARK {
QScriptValue val(QScriptValue::NullValue);
}
}
void tst_QScriptValue::undefinedConstructor()
{
QBENCHMARK {
QScriptValue val(QScriptValue::UndefinedValue);
}
}
void tst_QScriptValue::boolConstructorWithEngine()
{
newEngine();
QBENCHMARK {
QScriptValue val(m_engine, true);
}
}
void tst_QScriptValue::floatConstructorWithEngine()
{
newEngine();
QBENCHMARK {
QScriptValue val(m_engine, 123.0);
}
}
void tst_QScriptValue::intConstructorWithEngine()
{
newEngine();
QBENCHMARK {
(void)QScriptValue(m_engine, 123);
}
}
void tst_QScriptValue::stringConstructorWithEngine()
{
newEngine();
QString str = QString::fromLatin1("ciao");
QBENCHMARK {
(void)QScriptValue(m_engine, str);
}
}
void tst_QScriptValue::nullConstructorWithEngine()
{
newEngine();
QBENCHMARK {
QScriptValue val(m_engine, QScriptValue::NullValue);
}
}
void tst_QScriptValue::undefinedConstructorWithEngine()
{
newEngine();
QBENCHMARK {
QScriptValue val(m_engine, QScriptValue::UndefinedValue);
}
}
void tst_QScriptValue::copyConstructor_data()
{
defineStandardTestValues();
}
void tst_QScriptValue::copyConstructor()
{
QFETCH(QScriptValue, val);
QBENCHMARK {
QScriptValue copy(val);
}
}
void tst_QScriptValue::call_data()
{
newEngine();
QTest::addColumn<QString>("code");
QTest::newRow("empty function") << QString::fromLatin1("(function(){})");
QTest::newRow("function returning number") << QString::fromLatin1("(function(){ return 123; })");
QTest::newRow("closure") << QString::fromLatin1("(function(a, b){ return function() { return a + b; }; })(1, 2)");
}
void tst_QScriptValue::call()
{
QFETCH(QString, code);
QScriptValue fun = m_engine->evaluate(code);
QVERIFY(fun.isFunction());
QBENCHMARK {
(void)fun.call();
}
}
void tst_QScriptValue::construct_data()
{
newEngine();
QTest::addColumn<QString>("code");
QTest::newRow("empty function") << QString::fromLatin1("(function(){})");
QTest::newRow("simple constructor") << QString::fromLatin1("(function(){ this.x = 10; this.y = 20; })");
}
void tst_QScriptValue::construct()
{
QFETCH(QString, code);
QScriptValue fun = m_engine->evaluate(code);
QVERIFY(fun.isFunction());
QBENCHMARK {
(void)fun.construct();
}
}
void tst_QScriptValue::data()
{
newEngine();
QScriptValue obj = m_engine->newObject();
obj.setData(QScriptValue(m_engine, 123));
QBENCHMARK {
obj.data();
}
}
void tst_QScriptValue::setData()
{
newEngine();
QScriptValue obj = m_engine->newObject();
QScriptValue val(m_engine, 123);
QBENCHMARK {
obj.setData(val);
}
}
void tst_QScriptValue::data_noData_data()
{
defineStandardTestValues();
}
void tst_QScriptValue::data_noData()
{
QFETCH(QScriptValue, val);
QVERIFY(!val.data().isValid());
QBENCHMARK {
val.data();
}
}
void tst_QScriptValue::engine_data()
{
defineStandardTestValues();
}
void tst_QScriptValue::engine()
{
QFETCH(QScriptValue, val);
QBENCHMARK {
val.engine();
}
}
void tst_QScriptValue::equalsSelf_data()
{
defineStandardTestValues();
}
void tst_QScriptValue::equalsSelf()
{
QFETCH(QScriptValue, val);
QBENCHMARK {
val.equals(val);
}
}
void tst_QScriptValue::lessThanSelf_data()
{
defineStandardTestValues();
}
void tst_QScriptValue::lessThanSelf()
{
QFETCH(QScriptValue, val);
QBENCHMARK {
val.lessThan(val);
}
}
void tst_QScriptValue::strictlyEqualsSelf_data()
{
defineStandardTestValues();
}
void tst_QScriptValue::strictlyEqualsSelf()
{
QFETCH(QScriptValue, val);
QBENCHMARK {
val.strictlyEquals(val);
}
}
void tst_QScriptValue::instanceOf()
{
newEngine();
QScriptValue arrayCtor = m_engine->globalObject().property("Array");
QScriptValue array = arrayCtor.construct();
QVERIFY(array.instanceOf(arrayCtor));
QBENCHMARK {
array.instanceOf(arrayCtor);
}
}
void tst_QScriptValue::isArray_data()
{
defineStandardTestValues();
}
void tst_QScriptValue::isArray()
{
QFETCH(QScriptValue, val);
QBENCHMARK {
val.isArray();
}
}
void tst_QScriptValue::isBool_data()
{
defineStandardTestValues();
}
void tst_QScriptValue::isBool()
{
QFETCH(QScriptValue, val);
QBENCHMARK {
val.isBool();
}
}
void tst_QScriptValue::isDate_data()
{
defineStandardTestValues();
}
void tst_QScriptValue::isDate()
{
QFETCH(QScriptValue, val);
QBENCHMARK {
val.isDate();
}
}
void tst_QScriptValue::isError_data()
{
defineStandardTestValues();
}
void tst_QScriptValue::isError()
{
QFETCH(QScriptValue, val);
QBENCHMARK {
val.isError();
}
}
void tst_QScriptValue::isFunction_data()
{
defineStandardTestValues();
}
void tst_QScriptValue::isFunction()
{
QFETCH(QScriptValue, val);
QBENCHMARK {
val.isFunction();
}
}
void tst_QScriptValue::isNull_data()
{
defineStandardTestValues();
}
void tst_QScriptValue::isNull()
{
QFETCH(QScriptValue, val);
QBENCHMARK {
val.isNull();
}
}
void tst_QScriptValue::isNumber_data()
{
defineStandardTestValues();
}
void tst_QScriptValue::isNumber()
{
QFETCH(QScriptValue, val);
QBENCHMARK {
val.isNumber();
}
}
void tst_QScriptValue::isObject_data()
{
defineStandardTestValues();
}
void tst_QScriptValue::isObject()
{
QFETCH(QScriptValue, val);
QBENCHMARK {
val.isObject();
}
}
void tst_QScriptValue::isQMetaObject_data()
{
defineStandardTestValues();
}
void tst_QScriptValue::isQMetaObject()
{
QFETCH(QScriptValue, val);
QBENCHMARK {
val.isQMetaObject();
}
}
void tst_QScriptValue::isQObject_data()
{
defineStandardTestValues();
}
void tst_QScriptValue::isQObject()
{
QFETCH(QScriptValue, val);
QBENCHMARK {
val.isQObject();
}
}
void tst_QScriptValue::isRegExp_data()
{
defineStandardTestValues();
}
void tst_QScriptValue::isRegExp()
{
QFETCH(QScriptValue, val);
QBENCHMARK {
val.isRegExp();
}
}
void tst_QScriptValue::isString_data()
{
defineStandardTestValues();
}
void tst_QScriptValue::isString()
{
QFETCH(QScriptValue, val);
QBENCHMARK {
val.isString();
}
}
void tst_QScriptValue::isUndefined_data()
{
defineStandardTestValues();
}
void tst_QScriptValue::isUndefined()
{
QFETCH(QScriptValue, val);
QBENCHMARK {
val.isUndefined();
}
}
void tst_QScriptValue::isValid_data()
{
defineStandardTestValues();
}
void tst_QScriptValue::isValid()
{
QFETCH(QScriptValue, val);
QBENCHMARK {
val.isValid();
}
}
void tst_QScriptValue::isVariant_data()
{
defineStandardTestValues();
}
void tst_QScriptValue::isVariant()
{
QFETCH(QScriptValue, val);
QBENCHMARK {
val.isVariant();
}
}
void tst_QScriptValue::toBool_data()
{
defineStandardTestValues();
}
void tst_QScriptValue::toBool()
{
QFETCH(QScriptValue, val);
QBENCHMARK {
val.toBool();
}
}
void tst_QScriptValue::toDateTime_data()
{
defineStandardTestValues();
}
void tst_QScriptValue::toDateTime()
{
QFETCH(QScriptValue, val);
QBENCHMARK {
val.toDateTime();
}
}
void tst_QScriptValue::toInt32_data()
{
defineStandardTestValues();
}
void tst_QScriptValue::toInt32()
{
QFETCH(QScriptValue, val);
QBENCHMARK {
val.toInt32();
}
}
void tst_QScriptValue::toInteger_data()
{
defineStandardTestValues();
}
void tst_QScriptValue::toInteger()
{
QFETCH(QScriptValue, val);
QBENCHMARK {
val.toInteger();
}
}
void tst_QScriptValue::toNumber_data()
{
defineStandardTestValues();
}
void tst_QScriptValue::toNumber()
{
QFETCH(QScriptValue, val);
QBENCHMARK {
val.toNumber();
}
}
void tst_QScriptValue::toRegExp_data()
{
defineStandardTestValues();
}
void tst_QScriptValue::toRegExp()
{
QFETCH(QScriptValue, val);
QBENCHMARK {
val.toRegExp();
}
}
void tst_QScriptValue::toString_data()
{
defineStandardTestValues();
}
void tst_QScriptValue::toString()
{
QFETCH(QScriptValue, val);
QBENCHMARK {
(void)val.toString();
}
}
void tst_QScriptValue::toQMetaObject_data()
{
defineStandardTestValues();
}
void tst_QScriptValue::toQMetaObject()
{
QFETCH(QScriptValue, val);
QBENCHMARK {
val.toQMetaObject();
}
}
void tst_QScriptValue::toQObject_data()
{
defineStandardTestValues();
}
void tst_QScriptValue::toQObject()
{
QFETCH(QScriptValue, val);
QBENCHMARK {
(void)val.toQObject();
}
}
void tst_QScriptValue::toUInt16_data()
{
defineStandardTestValues();
}
void tst_QScriptValue::toUInt16()
{
QFETCH(QScriptValue, val);
QBENCHMARK {
val.toUInt16();
}
}
void tst_QScriptValue::toUInt32_data()
{
defineStandardTestValues();
}
void tst_QScriptValue::toUInt32()
{
QFETCH(QScriptValue, val);
QBENCHMARK {
val.toUInt32();
}
}
void tst_QScriptValue::toVariant_data()
{
defineStandardTestValues();
}
void tst_QScriptValue::toVariant()
{
QFETCH(QScriptValue, val);
QBENCHMARK {
val.toVariant();
}
}
void tst_QScriptValue::property_data()
{
QTest::addColumn<QString>("propertyName");
QTest::addColumn<bool>("create");
QTest::newRow("foo") << QString::fromLatin1("foo") << true;
QTest::newRow("hasOwnProperty") << QString::fromLatin1("hasOwnProperty") << false; // From Object.prototype.
QTest::newRow("noSuchProperty") << QString::fromLatin1("noSuchProperty") << false;
}
void tst_QScriptValue::property()
{
QFETCH(QString, propertyName);
QFETCH(bool, create);
newEngine();
QScriptValue obj = m_engine->newObject();
if (create)
obj.setProperty(propertyName, 123);
QBENCHMARK {
(void)obj.property(propertyName);
}
}
void tst_QScriptValue::propertyById_data()
{
property_data();
}
void tst_QScriptValue::propertyById()
{
QFETCH(QString, propertyName);
QFETCH(bool, create);
newEngine();
QScriptValue obj = m_engine->newObject();
QScriptString id = m_engine->toStringHandle(propertyName);
if (create)
obj.setProperty(id, 123);
QBENCHMARK {
obj.property(id);
}
}
void tst_QScriptValue::propertyByIndex()
{
newEngine();
QScriptValue obj = m_engine->newObject();
obj.setProperty(123, 456);
QBENCHMARK {
obj.property(123);
}
}
void tst_QScriptValue::setProperty_data()
{
newEngine();
QTest::addColumn<QString>("propertyName");
QTest::addColumn<QScriptValue>("val");
QTest::newRow("foo") << QString::fromLatin1("foo") << QScriptValue(123);
QTest::newRow("bar") << QString::fromLatin1("bar") << QScriptValue(m_engine, 123);
QTest::newRow("baz") << QString::fromLatin1("baz") << QScriptValue();
QTest::newRow("toString") << QString::fromLatin1("toString") << QScriptValue(m_engine, true);
}
void tst_QScriptValue::setProperty()
{
QFETCH(QString, propertyName);
QFETCH(QScriptValue, val);
QScriptValue obj = m_engine->newObject();
QBENCHMARK {
obj.setProperty(propertyName, val);
}
}
void tst_QScriptValue::setPropertyById_data()
{
setProperty_data();
}
void tst_QScriptValue::setPropertyById()
{
QFETCH(QString, propertyName);
QFETCH(QScriptValue, val);
QScriptValue obj = m_engine->newObject();
QScriptString id = m_engine->toStringHandle(propertyName);
QBENCHMARK {
obj.setProperty(id, val);
}
}
void tst_QScriptValue::setPropertyByIndex()
{
newEngine();
QScriptValue obj = m_engine->newObject();
QScriptValue val(456);
QBENCHMARK {
obj.setProperty(123, 456);
}
}
void tst_QScriptValue::propertyFlags_data()
{
property_data();
}
void tst_QScriptValue::propertyFlags()
{
QFETCH(QString, propertyName);
QFETCH(bool, create);
newEngine();
QScriptValue obj = m_engine->newObject();
if (create)
obj.setProperty(propertyName, 123, QScriptValue::SkipInEnumeration | QScriptValue::ReadOnly);
QBENCHMARK {
(void)obj.propertyFlags(propertyName);
}
}
void tst_QScriptValue::propertyFlagsById_data()
{
propertyFlags_data();
}
void tst_QScriptValue::propertyFlagsById()
{
QFETCH(QString, propertyName);
QFETCH(bool, create);
newEngine();
QScriptValue obj = m_engine->newObject();
QScriptString id = m_engine->toStringHandle(propertyName);
if (create)
obj.setProperty(id, 123, QScriptValue::SkipInEnumeration | QScriptValue::ReadOnly);
QBENCHMARK {
obj.propertyFlags(id);
}
}
void tst_QScriptValue::prototype_data()
{
defineStandardTestValues();
}
void tst_QScriptValue::prototype()
{
QFETCH(QScriptValue, val);
QBENCHMARK {
val.prototype();
}
}
void tst_QScriptValue::setPrototype()
{
newEngine();
QScriptValue obj = m_engine->newObject();
QScriptValue proto = m_engine->newObject();
QBENCHMARK {
obj.setPrototype(proto);
}
}
void tst_QScriptValue::scriptClass_data()
{
defineStandardTestValues();
}
void tst_QScriptValue::scriptClass()
{
QFETCH(QScriptValue, val);
QBENCHMARK {
val.scriptClass();
}
}
void tst_QScriptValue::setScriptClass()
{
newEngine();
QScriptValue obj = m_engine->newObject();
QScriptClass cls(m_engine);
QBENCHMARK {
obj.setScriptClass(&cls);
}
}
void tst_QScriptValue::readMetaProperty()
{
newEngine();
QScriptValue object = m_engine->newQObject(QCoreApplication::instance());
QScriptString propertyName = m_engine->toStringHandle("objectName");
QBENCHMARK {
for (int i = 0; i < 10000; ++i)
object.property(propertyName);
}
}
void tst_QScriptValue::writeMetaProperty()
{
newEngine();
QScriptValue object = m_engine->newQObject(QCoreApplication::instance());
QScriptString propertyName = m_engine->toStringHandle("objectName");
QScriptValue value(m_engine, "foo");
QBENCHMARK {
for (int i = 0; i < 10000; ++i)
object.setProperty(propertyName, value);
}
}
void tst_QScriptValue::defineStandardTestValues()
{
newEngine();
QTest::addColumn<QScriptValue>("val");
QTest::newRow("bool") << m_engine->evaluate("true");
QTest::newRow("number") << m_engine->evaluate("123");
QTest::newRow("string") << m_engine->evaluate("'ciao'");
QTest::newRow("null") << m_engine->evaluate("null");
QTest::newRow("undefined") << m_engine->evaluate("undefined");
QTest::newRow("object") << m_engine->evaluate("({foo:123})");
QTest::newRow("array") << m_engine->evaluate("[10,20,30]");
QTest::newRow("function") << m_engine->evaluate("(function foo(a, b, c) { return a + b + c; })");
QTest::newRow("date") << m_engine->evaluate("new Date");
QTest::newRow("regexp") << m_engine->evaluate("new RegExp('foo')");
QTest::newRow("error") << m_engine->evaluate("new Error");
QTest::newRow("qobject") << m_engine->newQObject(this);
QTest::newRow("qmetaobject") << m_engine->newQMetaObject(&QScriptEngine::staticMetaObject);
QTest::newRow("variant") << m_engine->newVariant(123);
QTest::newRow("qscriptclassobject") << m_engine->newObject(new QScriptClass(m_engine));
QTest::newRow("invalid") << QScriptValue();
QTest::newRow("bool-no-engine") << QScriptValue(true);
QTest::newRow("number-no-engine") << QScriptValue(123.0);
QTest::newRow("string-no-engine") << QScriptValue(QString::fromLatin1("hello"));
QTest::newRow("null-no-engine") << QScriptValue(QScriptValue::NullValue);
QTest::newRow("undefined-no-engine") << QScriptValue(QScriptValue::UndefinedValue);
}
QTEST_MAIN(tst_QScriptValue)
#include "tst_qscriptvalue.moc"