summaryrefslogtreecommitdiffstats
path: root/tests/auto/qscriptvalue/tst_qscriptvalue.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/qscriptvalue/tst_qscriptvalue.cpp')
-rw-r--r--tests/auto/qscriptvalue/tst_qscriptvalue.cpp1929
1 files changed, 1158 insertions, 771 deletions
diff --git a/tests/auto/qscriptvalue/tst_qscriptvalue.cpp b/tests/auto/qscriptvalue/tst_qscriptvalue.cpp
index c40be40..6779d9b 100644
--- a/tests/auto/qscriptvalue/tst_qscriptvalue.cpp
+++ b/tests/auto/qscriptvalue/tst_qscriptvalue.cpp
@@ -56,64 +56,11 @@ tst_QScriptValue::tst_QScriptValue()
tst_QScriptValue::~tst_QScriptValue()
{
- delete engine;
+ if (engine)
+ delete engine;
}
-void tst_QScriptValue::dataHelper(InitDataFunction init, DefineDataFunction define)
-{
- QTest::addColumn<QString>("__expression__");
- (this->*init)();
- QHash<QString,QScriptValue>::const_iterator it;
- for (it = m_values.constBegin(); it != m_values.constEnd(); ++it) {
- m_currentExpression = it.key();
- (this->*define)(it.key().toLatin1());
- }
- m_currentExpression = QString();
-}
-
-QTestData &tst_QScriptValue::newRow(const char *tag)
-{
- return QTest::newRow(tag) << m_currentExpression;
-}
-
-void tst_QScriptValue::testHelper(TestFunction fun)
-{
- QFETCH(QString, __expression__);
- QScriptValue value = m_values.value(__expression__);
- (this->*fun)(__expression__.toLatin1(), value);
-}
-
-void tst_QScriptValue::assignAndCopyConstruct_initData()
-{
- QTest::addColumn<int>("dummy");
- initScriptValues();
-}
-
-void tst_QScriptValue::assignAndCopyConstruct_makeData(const char *expr)
-{
- newRow(expr) << 0;
-}
-
-void tst_QScriptValue::assignAndCopyConstruct_test(const char *, const QScriptValue &value)
-{
- QScriptValue copy(value);
- 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());
-}
-
-DEFINE_TEST_FUNCTION(assignAndCopyConstruct)
-
-void tst_QScriptValue::ctor()
+void tst_QScriptValue::ctor_invalid()
{
QScriptEngine eng;
{
@@ -121,6 +68,11 @@ void tst_QScriptValue::ctor()
QCOMPARE(v.isValid(), false);
QCOMPARE(v.engine(), (QScriptEngine *)0);
}
+}
+
+void tst_QScriptValue::ctor_undefinedWithEngine()
+{
+ QScriptEngine eng;
{
QScriptValue v(&eng, QScriptValue::UndefinedValue);
QCOMPARE(v.isValid(), true);
@@ -128,6 +80,11 @@ void tst_QScriptValue::ctor()
QCOMPARE(v.isObject(), false);
QCOMPARE(v.engine(), &eng);
}
+}
+
+void tst_QScriptValue::ctor_nullWithEngine()
+{
+ QScriptEngine eng;
{
QScriptValue v(&eng, QScriptValue::NullValue);
QCOMPARE(v.isValid(), true);
@@ -135,6 +92,11 @@ void tst_QScriptValue::ctor()
QCOMPARE(v.isObject(), false);
QCOMPARE(v.engine(), &eng);
}
+}
+
+void tst_QScriptValue::ctor_boolWithEngine()
+{
+ QScriptEngine eng;
{
QScriptValue v(&eng, false);
QCOMPARE(v.isValid(), true);
@@ -144,6 +106,11 @@ void tst_QScriptValue::ctor()
QCOMPARE(v.toBoolean(), false);
QCOMPARE(v.engine(), &eng);
}
+}
+
+void tst_QScriptValue::ctor_intWithEngine()
+{
+ QScriptEngine eng;
{
QScriptValue v(&eng, int(1));
QCOMPARE(v.isValid(), true);
@@ -152,132 +119,102 @@ void tst_QScriptValue::ctor()
QCOMPARE(v.toNumber(), 1.0);
QCOMPARE(v.engine(), &eng);
}
+}
+
+void tst_QScriptValue::ctor_int()
+{
{
QScriptValue v(int(0x43211234));
QVERIFY(v.isNumber());
QCOMPARE(v.toInt32(), 0x43211234);
}
{
- QScriptValue v(&eng, uint(1));
+ QScriptValue v(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(uint(0x43211234));
- QVERIFY(v.isNumber());
- QCOMPARE(v.toUInt32(), uint(0x43211234));
+ QCOMPARE(v.engine(), (QScriptEngine *)0);
}
+}
+
+void tst_QScriptValue::ctor_uintWithEngine()
+{
+ QScriptEngine eng;
{
- QScriptValue v(&eng, 1.0);
+ 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);
}
+}
+
+void tst_QScriptValue::ctor_uint()
+{
{
- QScriptValue v(12345678910.5);
+ QScriptValue v(uint(0x43211234));
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);
+ QCOMPARE(v.toUInt32(), uint(0x43211234));
}
{
- QScriptValue v(&eng, QString("ciao"));
+ QScriptValue v(uint(1));
QCOMPARE(v.isValid(), true);
- QCOMPARE(v.isString(), true);
+ QCOMPARE(v.isNumber(), 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);
}
+}
+
+void tst_QScriptValue::ctor_floatWithEngine()
+{
+ QScriptEngine eng;
{
- QScriptValue v(int(1));
+ 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(), (QScriptEngine *)0);
+ QCOMPARE(v.engine(), &eng);
}
+}
+
+void tst_QScriptValue::ctor_float()
+{
{
- QScriptValue v(uint(1));
+ QScriptValue v(12345678910.5);
+ QVERIFY(v.isNumber());
+ QCOMPARE(v.toNumber(), 12345678910.5);
+ }
+ {
+ 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);
}
+}
+
+void tst_QScriptValue::ctor_stringWithEngine()
+{
+ QScriptEngine eng;
{
- QScriptValue v(1.0);
+ QScriptValue v(&eng, "ciao");
QCOMPARE(v.isValid(), true);
- QCOMPARE(v.isNumber(), true);
+ QCOMPARE(v.isString(), true);
QCOMPARE(v.isObject(), false);
- QCOMPARE(v.toNumber(), 1.0);
- QCOMPARE(v.engine(), (QScriptEngine *)0);
+ QCOMPARE(v.toString(), QLatin1String("ciao"));
+ QCOMPARE(v.engine(), &eng);
}
+}
+
+void tst_QScriptValue::ctor_string()
+{
{
- QScriptValue v("ciao");
+ QScriptValue v(QString("ciao"));
QCOMPARE(v.isValid(), true);
QCOMPARE(v.isString(), true);
QCOMPARE(v.isObject(), false);
@@ -285,26 +222,31 @@ void tst_QScriptValue::ctor()
QCOMPARE(v.engine(), (QScriptEngine *)0);
}
{
- QScriptValue v(QString("ciao"));
+ 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);
}
+}
+
+void tst_QScriptValue::ctor_copyAndAssignWithEngine()
+{
+ QScriptEngine eng;
// copy constructor, operator=
{
- QScriptValue v(1.0);
+ QScriptValue v(&eng, 1.0);
QScriptValue v2(v);
QCOMPARE(v2.strictlyEquals(v), true);
- QCOMPARE(v2.engine(), (QScriptEngine *)0);
+ QCOMPARE(v2.engine(), &eng);
QScriptValue v3(v);
QCOMPARE(v3.strictlyEquals(v), true);
QCOMPARE(v3.strictlyEquals(v2), true);
- QCOMPARE(v3.engine(), (QScriptEngine *)0);
+ QCOMPARE(v3.engine(), &eng);
- QScriptValue v4(2.0);
+ QScriptValue v4(&eng, 2.0);
QCOMPARE(v4.strictlyEquals(v), false);
v3 = v4;
QCOMPARE(v3.strictlyEquals(v), false);
@@ -320,7 +262,68 @@ void tst_QScriptValue::ctor()
QCOMPARE(v5.strictlyEquals(v), false);
QCOMPARE(v5.toNumber(), 1.0);
}
+}
+
+void tst_QScriptValue::ctor_undefined()
+{
+ QScriptValue v(QScriptValue::UndefinedValue);
+ QCOMPARE(v.isValid(), true);
+ QCOMPARE(v.isUndefined(), true);
+ QCOMPARE(v.isObject(), false);
+ QCOMPARE(v.engine(), (QScriptEngine *)0);
+}
+
+void tst_QScriptValue::ctor_null()
+{
+ QScriptValue v(QScriptValue::NullValue);
+ QCOMPARE(v.isValid(), true);
+ QCOMPARE(v.isNull(), true);
+ QCOMPARE(v.isObject(), false);
+ QCOMPARE(v.engine(), (QScriptEngine *)0);
+}
+
+void tst_QScriptValue::ctor_bool()
+{
+ 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);
+}
+
+void tst_QScriptValue::ctor_copyAndAssign()
+{
+ 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);
+}
+void tst_QScriptValue::ctor_nullEngine()
+{
// 0 engine
QVERIFY(QScriptValue(0, QScriptValue::UndefinedValue).isUndefined());
QVERIFY(QScriptValue(0, QScriptValue::NullValue).isNull());
@@ -337,7 +340,7 @@ static QScriptValue myFunction(QScriptContext *, QScriptEngine *eng)
return eng->undefinedValue();
}
-void tst_QScriptValue::toString_old()
+void tst_QScriptValue::toString()
{
QScriptEngine eng;
@@ -451,7 +454,7 @@ void tst_QScriptValue::toString_old()
QVERIFY(variant.toString().isEmpty());
}
-void tst_QScriptValue::toNumber_old()
+void tst_QScriptValue::toNumber()
{
QScriptEngine eng;
@@ -524,7 +527,7 @@ void tst_QScriptValue::toNumber_old()
}
}
-void tst_QScriptValue::toBoolean_old() // deprecated
+void tst_QScriptValue::toBoolean() // deprecated
{
QScriptEngine eng;
@@ -621,7 +624,7 @@ void tst_QScriptValue::toBoolean_old() // deprecated
}
}
-void tst_QScriptValue::toBool_old()
+void tst_QScriptValue::toBool()
{
QScriptEngine eng;
@@ -718,7 +721,7 @@ void tst_QScriptValue::toBool_old()
}
}
-void tst_QScriptValue::toInteger_old()
+void tst_QScriptValue::toInteger()
{
QScriptEngine eng;
@@ -805,7 +808,7 @@ void tst_QScriptValue::toInteger_old()
QCOMPARE(inv.toInteger(), 0.0);
}
-void tst_QScriptValue::toInt32_old()
+void tst_QScriptValue::toInt32()
{
QScriptEngine eng;
@@ -941,7 +944,7 @@ void tst_QScriptValue::toInt32_old()
QCOMPARE(qscriptvalue_cast<qint32>(inv), 0);
}
-void tst_QScriptValue::toUInt32_old()
+void tst_QScriptValue::toUInt32()
{
QScriptEngine eng;
@@ -1073,7 +1076,7 @@ void tst_QScriptValue::toUInt32_old()
QCOMPARE(qscriptvalue_cast<quint32>(inv), quint32(0));
}
-void tst_QScriptValue::toUInt16_old()
+void tst_QScriptValue::toUInt16()
{
QScriptEngine eng;
@@ -1234,7 +1237,7 @@ void tst_QScriptValue::toUInt16_old()
Q_DECLARE_METATYPE(QVariant)
#endif
-void tst_QScriptValue::toVariant_old()
+void tst_QScriptValue::toVariant()
{
QScriptEngine eng;
@@ -1251,6 +1254,10 @@ void tst_QScriptValue::toVariant_old()
QCOMPARE(number.toVariant(), QVariant(123.0));
QCOMPARE(qscriptvalue_cast<QVariant>(number), QVariant(123.0));
+ QScriptValue intNumber = QScriptValue(&eng, (qint32)123);
+ QCOMPARE(intNumber.toVariant().type(), QVariant((qint32)123).type());
+ QCOMPARE((qscriptvalue_cast<QVariant>(number)).type(), QVariant((qint32)123).type());
+
QScriptValue falskt = QScriptValue(&eng, false);
QCOMPARE(falskt.toVariant(), QVariant(false));
QCOMPARE(qscriptvalue_cast<QVariant>(falskt), QVariant(false));
@@ -1338,52 +1345,53 @@ void tst_QScriptValue::toVariant_old()
}
}
-// unfortunately, this is necessary in order to do qscriptvalue_cast<QPushButton*>(...)
-Q_DECLARE_METATYPE(QPushButton*)
-
-void tst_QScriptValue::toQObject_old()
+void tst_QScriptValue::toQObject_nonQObject_data()
{
- QScriptEngine eng;
-
- QScriptValue undefined = eng.undefinedValue();
- QCOMPARE(undefined.toQObject(), (QObject *)0);
- QCOMPARE(qscriptvalue_cast<QObject*>(undefined), (QObject *)0);
-
- QScriptValue null = eng.nullValue();
- QCOMPARE(null.toQObject(), (QObject *)0);
- QCOMPARE(qscriptvalue_cast<QObject*>(null), (QObject *)0);
-
- {
- QScriptValue falskt = QScriptValue(&eng, false);
- QCOMPARE(falskt.toQObject(), (QObject *)0);
- QCOMPARE(qscriptvalue_cast<QObject*>(falskt), (QObject *)0);
+ newEngine();
+ QTest::addColumn<QScriptValue>("value");
+
+ QTest::newRow("invalid") << QScriptValue();
+ QTest::newRow("bool(false)") << QScriptValue(false);
+ QTest::newRow("bool(true)") << QScriptValue(true);
+ QTest::newRow("int") << QScriptValue(123);
+ QTest::newRow("string") << QScriptValue(QString::fromLatin1("ciao"));
+ QTest::newRow("undefined") << QScriptValue(QScriptValue::UndefinedValue);
+ QTest::newRow("null") << QScriptValue(QScriptValue::NullValue);
+
+ QTest::newRow("bool bound(false)") << QScriptValue(engine, false);
+ QTest::newRow("bool bound(true)") << QScriptValue(engine, true);
+ QTest::newRow("int bound") << QScriptValue(engine, 123);
+ QTest::newRow("string bound") << QScriptValue(engine, QString::fromLatin1("ciao"));
+ QTest::newRow("undefined bound") << engine->undefinedValue();
+ QTest::newRow("null bound") << engine->nullValue();
+ QTest::newRow("object") << engine->newObject();
+ QTest::newRow("array") << engine->newArray();
+ QTest::newRow("date") << engine->newDate(124);
+ QTest::newRow("variant(12345)") << engine->newVariant(12345);
+ QTest::newRow("variant((QObject*)0)") << engine->newVariant(qVariantFromValue((QObject*)0));
+ QTest::newRow("newQObject(0)") << engine->newQObject(0);
+}
- QScriptValue sant = QScriptValue(&eng, true);
- QCOMPARE(sant.toQObject(), (QObject *)0);
- QCOMPARE(qscriptvalue_cast<QObject*>(sant), (QObject *)0);
- QScriptValue number = QScriptValue(&eng, 123.0);
- QCOMPARE(number.toQObject(), (QObject *)0);
- QCOMPARE(qscriptvalue_cast<QObject*>(number), (QObject *)0);
+void tst_QScriptValue::toQObject_nonQObject()
+{
+ QFETCH(QScriptValue, value);
+ QCOMPARE(value.toQObject(), (QObject *)0);
+ QCOMPARE(qscriptvalue_cast<QObject*>(value), (QObject *)0);
+}
- QScriptValue str = QScriptValue(&eng, QString("ciao"));
- QCOMPARE(str.toQObject(), (QObject *)0);
- QCOMPARE(qscriptvalue_cast<QObject*>(str), (QObject *)0);
- }
+// unfortunately, this is necessary in order to do qscriptvalue_cast<QPushButton*>(...)
+Q_DECLARE_METATYPE(QPushButton*);
- QScriptValue object = eng.newObject();
- QCOMPARE(object.toQObject(), (QObject *)0);
- QCOMPARE(qscriptvalue_cast<QObject*>(object), (QObject *)0);
+void tst_QScriptValue::toQObject()
+{
+ QScriptEngine eng;
QScriptValue qobject = eng.newQObject(this);
QCOMPARE(qobject.toQObject(), (QObject *)this);
QCOMPARE(qscriptvalue_cast<QObject*>(qobject), (QObject *)this);
QCOMPARE(qscriptvalue_cast<QWidget*>(qobject), (QWidget *)0);
- QScriptValue qobject2 = eng.newQObject(0);
- QCOMPARE(qobject2.toQObject(), (QObject *)0);
- QCOMPARE(qscriptvalue_cast<QObject*>(qobject2), (QObject *)0);
-
QWidget widget;
QScriptValue qwidget = eng.newQObject(&widget);
QCOMPARE(qwidget.toQObject(), (QObject *)&widget);
@@ -1397,25 +1405,6 @@ void tst_QScriptValue::toQObject_old()
QCOMPARE(qscriptvalue_cast<QWidget*>(qbutton), (QWidget *)&button);
QCOMPARE(qscriptvalue_cast<QPushButton*>(qbutton), &button);
- // V2 constructors
- {
- QScriptValue falskt = QScriptValue(false);
- QCOMPARE(falskt.toQObject(), (QObject *)0);
- QCOMPARE(qscriptvalue_cast<QObject*>(falskt), (QObject *)0);
-
- QScriptValue sant = QScriptValue(true);
- QCOMPARE(sant.toQObject(), (QObject *)0);
- QCOMPARE(qscriptvalue_cast<QObject*>(sant), (QObject *)0);
-
- QScriptValue number = QScriptValue(123.0);
- QCOMPARE(number.toQObject(), (QObject *)0);
- QCOMPARE(qscriptvalue_cast<QObject*>(number), (QObject *)0);
-
- QScriptValue str = QScriptValue(QString("ciao"));
- QCOMPARE(str.toQObject(), (QObject *)0);
- QCOMPARE(qscriptvalue_cast<QObject*>(str), (QObject *)0);
- }
-
// wrapping a QObject* as variant
QScriptValue variant = eng.newVariant(qVariantFromValue((QObject*)&button));
QCOMPARE(variant.toQObject(), (QObject*)&button);
@@ -1434,10 +1423,6 @@ void tst_QScriptValue::toQObject_old()
QCOMPARE(qscriptvalue_cast<QObject*>(variant3), (QObject*)0);
QCOMPARE(qscriptvalue_cast<QWidget*>(variant3), (QWidget*)0);
QCOMPARE(qscriptvalue_cast<QPushButton*>(variant3), &button);
-
- QScriptValue inv;
- QCOMPARE(inv.toQObject(), (QObject *)0);
- QCOMPARE(qscriptvalue_cast<QObject*>(inv), (QObject *)0);
}
void tst_QScriptValue::toObject()
@@ -1548,7 +1533,7 @@ void tst_QScriptValue::toObject()
}
}
-void tst_QScriptValue::toDateTime_old()
+void tst_QScriptValue::toDateTime()
{
QScriptEngine eng;
QDateTime dt = eng.evaluate("new Date(0)").toDateTime();
@@ -1566,7 +1551,7 @@ void tst_QScriptValue::toDateTime_old()
QVERIFY(!eng.undefinedValue().toDateTime().isValid());
}
-void tst_QScriptValue::toRegExp_old()
+void tst_QScriptValue::toRegExp()
{
QScriptEngine eng;
{
@@ -1596,7 +1581,16 @@ void tst_QScriptValue::toRegExp_old()
QVERIFY(eng.undefinedValue().toRegExp().isEmpty());
}
-void tst_QScriptValue::instanceOf_old()
+void tst_QScriptValue::instanceOf_twoEngines()
+{
+ QScriptEngine eng;
+ QScriptValue obj = eng.newObject();
+ QScriptEngine otherEngine;
+ QTest::ignoreMessage(QtWarningMsg, "QScriptValue::instanceof: cannot perform operation on a value created in a different engine");
+ QCOMPARE(obj.instanceOf(otherEngine.globalObject().property("Object")), false);
+}
+
+void tst_QScriptValue::instanceOf()
{
QScriptEngine eng;
QScriptValue obj = eng.newObject();
@@ -1626,40 +1620,60 @@ void tst_QScriptValue::instanceOf_old()
QCOMPARE(arr.instanceOf(eng.evaluate("QObject")), false);
QCOMPARE(QScriptValue().instanceOf(arr), false);
+}
- QScriptEngine otherEngine;
- QTest::ignoreMessage(QtWarningMsg, "QScriptValue::instanceof: cannot perform operation on a value created in a different engine");
- QCOMPARE(obj.instanceOf(otherEngine.globalObject().property("Object")), false);
+void tst_QScriptValue::isArray_data()
+{
+ newEngine();
+
+ QTest::addColumn<QScriptValue>("value");
+ QTest::addColumn<bool>("array");
+
+ QTest::newRow("[]") << engine->evaluate("[]") << true;
+ QTest::newRow("{}") << engine->evaluate("{}") << false;
+ QTest::newRow("globalObject") << engine->globalObject() << false;
+ QTest::newRow("invalid") << QScriptValue() << false;
+ QTest::newRow("number") << QScriptValue(123) << false;
+ QTest::newRow("bool") << QScriptValue(false) << false;
+ QTest::newRow("null") << engine->nullValue() << false;
+ QTest::newRow("undefined") << engine->undefinedValue() << false;
}
-void tst_QScriptValue::isArray_old()
+void tst_QScriptValue::isArray()
{
- QScriptEngine eng;
- QVERIFY(eng.evaluate("[]").isArray());
- QVERIFY(!eng.evaluate("{}").isArray());
- QVERIFY(!eng.globalObject().isArray());
- QVERIFY(!QScriptValue().isArray());
- QVERIFY(!QScriptValue(123).isArray());
- QVERIFY(!QScriptValue(false).isArray());
- QVERIFY(!eng.nullValue().isArray());
- QVERIFY(!eng.undefinedValue().isArray());
+ QFETCH(QScriptValue, value);
+ QFETCH(bool, array);
+
+ QCOMPARE(value.isArray(), array);
}
-void tst_QScriptValue::isDate_old()
+void tst_QScriptValue::isDate_data()
{
- QScriptEngine eng;
- QVERIFY(eng.evaluate("new Date()").isDate());
- QVERIFY(!eng.evaluate("[]").isDate());
- QVERIFY(!eng.evaluate("{}").isDate());
- QVERIFY(!eng.globalObject().isDate());
- QVERIFY(!QScriptValue().isDate());
- QVERIFY(!QScriptValue(123).isDate());
- QVERIFY(!QScriptValue(false).isDate());
- QVERIFY(!eng.nullValue().isDate());
- QVERIFY(!eng.undefinedValue().isDate());
+ newEngine();
+
+ QTest::addColumn<QScriptValue>("value");
+ QTest::addColumn<bool>("date");
+
+ QTest::newRow("date") << engine->evaluate("new Date()") << true;
+ QTest::newRow("[]") << engine->evaluate("[]") << false;
+ QTest::newRow("{}") << engine->evaluate("{}") << false;
+ QTest::newRow("globalObject") << engine->globalObject() << false;
+ QTest::newRow("invalid") << QScriptValue() << false;
+ QTest::newRow("number") << QScriptValue(123) << false;
+ QTest::newRow("bool") << QScriptValue(false) << false;
+ QTest::newRow("null") << engine->nullValue() << false;
+ QTest::newRow("undefined") << engine->undefinedValue() << false;
+}
+
+void tst_QScriptValue::isDate()
+{
+ QFETCH(QScriptValue, value);
+ QFETCH(bool, date);
+
+ QCOMPARE(value.isDate(), date);
}
-void tst_QScriptValue::isError_old()
+void tst_QScriptValue::isError_propertiesOfGlobalObject()
{
QStringList errors;
errors << "Error"
@@ -1675,27 +1689,60 @@ void tst_QScriptValue::isError_old()
QVERIFY(ctor.isFunction());
QVERIFY(ctor.property("prototype").isError());
}
- QVERIFY(!eng.globalObject().isError());
- QVERIFY(!QScriptValue().isError());
- QVERIFY(!QScriptValue(123).isError());
- QVERIFY(!QScriptValue(false).isError());
- QVERIFY(!eng.nullValue().isError());
- QVERIFY(!eng.undefinedValue().isError());
- QVERIFY(!eng.evaluate("new Object()").isError());
}
-void tst_QScriptValue::isRegExp_old()
+void tst_QScriptValue::isError_data()
{
- QScriptEngine eng;
- QVERIFY(eng.evaluate("/foo/").isRegExp());
- QVERIFY(!eng.evaluate("[]").isRegExp());
- QVERIFY(!eng.evaluate("{}").isRegExp());
- QVERIFY(!eng.globalObject().isRegExp());
- QVERIFY(!QScriptValue().isRegExp());
- QVERIFY(!QScriptValue(123).isRegExp());
- QVERIFY(!QScriptValue(false).isRegExp());
- QVERIFY(!eng.nullValue().isRegExp());
- QVERIFY(!eng.undefinedValue().isRegExp());
+ newEngine();
+
+ QTest::addColumn<QScriptValue>("value");
+ QTest::addColumn<bool>("error");
+
+ QTest::newRow("syntax error") << engine->evaluate("%fsdg's") << true;
+ QTest::newRow("[]") << engine->evaluate("[]") << false;
+ QTest::newRow("{}") << engine->evaluate("{}") << false;
+ QTest::newRow("globalObject") << engine->globalObject() << false;
+ QTest::newRow("invalid") << QScriptValue() << false;
+ QTest::newRow("number") << QScriptValue(123) << false;
+ QTest::newRow("bool") << QScriptValue(false) << false;
+ QTest::newRow("null") << engine->nullValue() << false;
+ QTest::newRow("undefined") << engine->undefinedValue() << false;
+ QTest::newRow("newObject") << engine->newObject() << false;
+ QTest::newRow("new Object") << engine->evaluate("new Object()") << false;
+}
+
+void tst_QScriptValue::isError()
+{
+ QFETCH(QScriptValue, value);
+ QFETCH(bool, error);
+
+ QCOMPARE(value.isError(), error);
+}
+
+void tst_QScriptValue::isRegExp_data()
+{
+ newEngine();
+
+ QTest::addColumn<QScriptValue>("value");
+ QTest::addColumn<bool>("regexp");
+
+ QTest::newRow("/foo/") << engine->evaluate("/foo/") << true;
+ QTest::newRow("[]") << engine->evaluate("[]") << false;
+ QTest::newRow("{}") << engine->evaluate("{}") << false;
+ QTest::newRow("globalObject") << engine->globalObject() << false;
+ QTest::newRow("invalid") << QScriptValue() << false;
+ QTest::newRow("number") << QScriptValue(123) << false;
+ QTest::newRow("bool") << QScriptValue(false) << false;
+ QTest::newRow("null") << engine->nullValue() << false;
+ QTest::newRow("undefined") << engine->undefinedValue() << false;
+}
+
+void tst_QScriptValue::isRegExp()
+{
+ QFETCH(QScriptValue, value);
+ QFETCH(bool, regexp);
+
+ QCOMPARE(value.isRegExp(), regexp);
}
static QScriptValue getter(QScriptContext *ctx, QScriptEngine *)
@@ -1731,48 +1778,9 @@ static QScriptValue getSet__proto__(QScriptContext *ctx, QScriptEngine *)
return ctx->callee().property("value");
}
-void tst_QScriptValue::getSetProperty()
+void tst_QScriptValue::getSetProperty_HooliganTask162051()
{
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();
- QVERIFY(array.isArray());
- 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)));
@@ -1785,24 +1793,62 @@ void tst_QScriptValue::getSetProperty()
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)));
+}
+void tst_QScriptValue::getSetProperty_HooliganTask183072()
+{
+ QScriptEngine eng;
// 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(oof) failed: cannot set value created in a different engine");
- object.setProperty("oof", otherNum);
- QCOMPARE(object.property("oof").isValid(), false);
+void tst_QScriptValue::getSetProperty_propertyRemoval()
+{
+ // test property removal (setProperty(QScriptValue()))
+ QScriptEngine eng;
+ QScriptValue object = eng.newObject();
+ QScriptValue str = QScriptValue(&eng, "bar");
+ QScriptValue num = QScriptValue(&eng, 123.0);
+
+ object.setProperty("foo", num);
+ QCOMPARE(object.property("foo").strictlyEquals(num), true);
+ object.setProperty("bar", str);
+ QCOMPARE(object.property("bar").strictlyEquals(str), true);
+ object.setProperty("foo", QScriptValue());
+ QCOMPARE(object.property("foo").isValid(), false);
+ QCOMPARE(object.property("bar").strictlyEquals(str), true);
+ object.setProperty("foo", num);
+ QCOMPARE(object.property("foo").strictlyEquals(num), true);
+ QCOMPARE(object.property("bar").strictlyEquals(str), true);
+ object.setProperty("bar", QScriptValue());
+ QCOMPARE(object.property("bar").isValid(), false);
+ QCOMPARE(object.property("foo").strictlyEquals(num), true);
+ object.setProperty("foo", QScriptValue());
+ object.setProperty("foo", QScriptValue());
+
+ eng.globalObject().setProperty("object3", object);
+ QCOMPARE(eng.evaluate("object3.hasOwnProperty('foo')")
+ .strictlyEquals(QScriptValue(&eng, false)), true);
+ object.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);
+}
+void tst_QScriptValue::getSetProperty_resolveMode()
+{
// test ResolveMode
- QScriptValue object2 = eng.newObject();
- object.setPrototype(object2);
+ QScriptEngine eng;
+ QScriptValue object = eng.newObject();
+ QScriptValue prototype = eng.newObject();
+ object.setPrototype(prototype);
QScriptValue num2 = QScriptValue(&eng, 456.0);
- object2.setProperty("propertyInPrototype", num2);
+ prototype.setProperty("propertyInPrototype", num2);
// default is ResolvePrototype
QCOMPARE(object.property("propertyInPrototype")
.strictlyEquals(num2), true);
@@ -1814,199 +1860,279 @@ void tst_QScriptValue::getSetProperty()
.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);
+void tst_QScriptValue::getSetProperty_twoEngines()
+{
+ QScriptEngine engine;
+ QScriptValue object = engine.newObject();
- // getters and setters
- {
- QScriptValue object4 = eng.newObject();
- for (int x = 0; x < 2; ++x) {
- object4.setProperty("foo", QScriptValue());
- // getter() returns this.x
- object4.setProperty("foo", eng.newFunction(getter),
- QScriptValue::PropertyGetter | QScriptValue::UserRange);
- QCOMPARE(object4.propertyFlags("foo") & ~QScriptValue::UserRange,
- QScriptValue::PropertyGetter );
-
- QEXPECT_FAIL("", "User-range flags are not retained for getter/setter properties", Continue);
- QCOMPARE(object4.propertyFlags("foo"),
- QScriptValue::PropertyGetter | QScriptValue::UserRange);
- object4.setProperty("x", num);
- QCOMPARE(object4.property("foo").strictlyEquals(num), true);
-
- // setter() sets this.x
- object4.setProperty("foo", eng.newFunction(setter),
- QScriptValue::PropertySetter);
- QCOMPARE(object4.propertyFlags("foo") & ~QScriptValue::UserRange,
- QScriptValue::PropertySetter | QScriptValue::PropertyGetter);
-
- QCOMPARE(object4.propertyFlags("foo"),
- QScriptValue::PropertySetter | QScriptValue::PropertyGetter);
- object4.setProperty("foo", str);
- QCOMPARE(object4.property("x").strictlyEquals(str), true);
- QCOMPARE(object4.property("foo").strictlyEquals(str), true);
-
- // kill the getter
- object4.setProperty("foo", QScriptValue(), QScriptValue::PropertyGetter);
- QVERIFY(!(object4.propertyFlags("foo") & QScriptValue::PropertyGetter));
- QVERIFY(object4.propertyFlags("foo") & QScriptValue::PropertySetter);
- QCOMPARE(object4.property("foo").isUndefined(), true);
-
- // setter should still work
- object4.setProperty("foo", num);
- QCOMPARE(object4.property("x").strictlyEquals(num), true);
-
- // kill the setter too
- object4.setProperty("foo", QScriptValue(), QScriptValue::PropertySetter);
- QVERIFY(!(object4.propertyFlags("foo") & QScriptValue::PropertySetter));
- // now foo is just a regular property
- object4.setProperty("foo", str);
- QCOMPARE(object4.property("x").strictlyEquals(num), true);
- QCOMPARE(object4.property("foo").strictlyEquals(str), true);
- }
+ QScriptEngine otherEngine;
+ QScriptValue otherNum = QScriptValue(&otherEngine, 123);
+ QTest::ignoreMessage(QtWarningMsg, "QScriptValue::setProperty(oof) failed: cannot set value created in a different engine");
+ object.setProperty("oof", otherNum);
+ QCOMPARE(object.property("oof").isValid(), false);
+}
- for (int x = 0; x < 2; ++x) {
- object4.setProperty("foo", QScriptValue());
- // setter() sets this.x
- object4.setProperty("foo", eng.newFunction(setter), QScriptValue::PropertySetter);
- object4.setProperty("foo", str);
- QCOMPARE(object4.property("x").strictlyEquals(str), true);
- QCOMPARE(object4.property("foo").isUndefined(), true);
-
- // getter() returns this.x
- object4.setProperty("foo", eng.newFunction(getter), QScriptValue::PropertyGetter);
- object4.setProperty("x", num);
- QCOMPARE(object4.property("foo").strictlyEquals(num), true);
-
- // kill the setter
- object4.setProperty("foo", QScriptValue(), QScriptValue::PropertySetter);
- QTest::ignoreMessage(QtWarningMsg, "QScriptValue::setProperty() failed: property 'foo' has a getter but no setter");
- object4.setProperty("foo", str);
-
- // getter should still work
- QCOMPARE(object4.property("foo").strictlyEquals(num), true);
-
- // kill the getter too
- object4.setProperty("foo", QScriptValue(), QScriptValue::PropertyGetter);
- // now foo is just a regular property
- object4.setProperty("foo", str);
- QCOMPARE(object4.property("x").strictlyEquals(num), true);
- QCOMPARE(object4.property("foo").strictlyEquals(str), true);
- }
- // use a single function as both getter and setter
- object4.setProperty("foo", QScriptValue());
- object4.setProperty("foo", eng.newFunction(getterSetter),
- QScriptValue::PropertyGetter | QScriptValue::PropertySetter);
- QCOMPARE(object4.propertyFlags("foo"),
- QScriptValue::PropertyGetter | QScriptValue::PropertySetter);
- object4.setProperty("x", num);
- QCOMPARE(object4.property("foo").strictlyEquals(num), true);
-
- // killing the getter will preserve the setter, even though they are the same function
- object4.setProperty("foo", QScriptValue(), QScriptValue::PropertyGetter);
- QVERIFY(object4.propertyFlags("foo") & QScriptValue::PropertySetter);
- QCOMPARE(object4.property("foo").isUndefined(), true);
-
- // getter/setter that throws an error
- {
- QScriptValue object5 = eng.newObject();
- object5.setProperty("foo", eng.newFunction(getterSetterThrowingError),
- QScriptValue::PropertyGetter | QScriptValue::PropertySetter);
- QVERIFY(!eng.hasUncaughtException());
- QScriptValue ret = object5.property("foo");
- QVERIFY(ret.isError());
- QVERIFY(eng.hasUncaughtException());
- QVERIFY(ret.strictlyEquals(eng.uncaughtException()));
- eng.evaluate("Object"); // clear exception state...
- QVERIFY(!eng.hasUncaughtException());
- object5.setProperty("foo", str);
- QVERIFY(eng.hasUncaughtException());
- QCOMPARE(eng.uncaughtException().toString(), QLatin1String("Error: set foo"));
- }
+void tst_QScriptValue::getSetProperty_gettersAndSetters()
+{
+ QScriptEngine eng;
+ QScriptValue str = QScriptValue(&eng, "bar");
+ QScriptValue num = QScriptValue(&eng, 123.0);
+ QScriptValue object = eng.newObject();
+ for (int x = 0; x < 2; ++x) {
+ object.setProperty("foo", QScriptValue());
+ // getter() returns this.x
+ object.setProperty("foo", eng.newFunction(getter),
+ QScriptValue::PropertyGetter | QScriptValue::UserRange);
+ QCOMPARE(object.propertyFlags("foo") & ~QScriptValue::UserRange,
+ QScriptValue::PropertyGetter );
+
+ QEXPECT_FAIL("", "QTBUG-17615: User-range flags are not retained for getter/setter properties", Continue);
+ QCOMPARE(object.propertyFlags("foo"),
+ QScriptValue::PropertyGetter | QScriptValue::UserRange);
+ object.setProperty("x", num);
+ QCOMPARE(object.property("foo").strictlyEquals(num), true);
+
+ // setter() sets this.x
+ object.setProperty("foo", eng.newFunction(setter),
+ QScriptValue::PropertySetter);
+ QCOMPARE(object.propertyFlags("foo") & ~QScriptValue::UserRange,
+ QScriptValue::PropertySetter | QScriptValue::PropertyGetter);
+
+ QCOMPARE(object.propertyFlags("foo"),
+ QScriptValue::PropertySetter | QScriptValue::PropertyGetter);
+ object.setProperty("foo", str);
+ QCOMPARE(object.property("x").strictlyEquals(str), true);
+ QCOMPARE(object.property("foo").strictlyEquals(str), true);
+
+ // kill the getter
+ object.setProperty("foo", QScriptValue(), QScriptValue::PropertyGetter);
+ QVERIFY(!(object.propertyFlags("foo") & QScriptValue::PropertyGetter));
+ QVERIFY(object.propertyFlags("foo") & QScriptValue::PropertySetter);
+ QCOMPARE(object.property("foo").isUndefined(), true);
+
+ // setter should still work
+ object.setProperty("foo", num);
+ QCOMPARE(object.property("x").strictlyEquals(num), true);
+
+ // kill the setter too
+ object.setProperty("foo", QScriptValue(), QScriptValue::PropertySetter);
+ QVERIFY(!(object.propertyFlags("foo") & QScriptValue::PropertySetter));
+ // now foo is just a regular property
+ object.setProperty("foo", str);
+ QCOMPARE(object.property("x").strictlyEquals(num), true);
+ QCOMPARE(object.property("foo").strictlyEquals(str), true);
+ }
+
+ for (int x = 0; x < 2; ++x) {
+ object.setProperty("foo", QScriptValue());
+ // setter() sets this.x
+ object.setProperty("foo", eng.newFunction(setter), QScriptValue::PropertySetter);
+ object.setProperty("foo", str);
+ QCOMPARE(object.property("x").strictlyEquals(str), true);
+ QCOMPARE(object.property("foo").isUndefined(), true);
+
+ // getter() returns this.x
+ object.setProperty("foo", eng.newFunction(getter), QScriptValue::PropertyGetter);
+ object.setProperty("x", num);
+ QCOMPARE(object.property("foo").strictlyEquals(num), true);
+
+ // kill the setter
+ object.setProperty("foo", QScriptValue(), QScriptValue::PropertySetter);
+ QTest::ignoreMessage(QtWarningMsg, "QScriptValue::setProperty() failed: property 'foo' has a getter but no setter");
+ object.setProperty("foo", str);
+
+ // getter should still work
+ QCOMPARE(object.property("foo").strictlyEquals(num), true);
+
+ // kill the getter too
+ object.setProperty("foo", QScriptValue(), QScriptValue::PropertyGetter);
+ // now foo is just a regular property
+ object.setProperty("foo", str);
+ QCOMPARE(object.property("x").strictlyEquals(num), true);
+ QCOMPARE(object.property("foo").strictlyEquals(str), true);
+ }
+
+ // use a single function as both getter and setter
+ object.setProperty("foo", QScriptValue());
+ object.setProperty("foo", eng.newFunction(getterSetter),
+ QScriptValue::PropertyGetter | QScriptValue::PropertySetter);
+ QCOMPARE(object.propertyFlags("foo"),
+ QScriptValue::PropertyGetter | QScriptValue::PropertySetter);
+ object.setProperty("x", num);
+ QCOMPARE(object.property("foo").strictlyEquals(num), true);
+
+ // killing the getter will preserve the setter, even though they are the same function
+ object.setProperty("foo", QScriptValue(), QScriptValue::PropertyGetter);
+ QVERIFY(object.propertyFlags("foo") & QScriptValue::PropertySetter);
+ QCOMPARE(object.property("foo").isUndefined(), true);
+}
- // attempt to install getter+setter on built-in (native) property
- {
- QScriptValue object6 = eng.newObject();
- QVERIFY(object6.property("__proto__").strictlyEquals(object6.prototype()));
-
- QScriptValue fun = eng.newFunction(getSet__proto__);
- fun.setProperty("value", QScriptValue(&eng, "boo"));
- QTest::ignoreMessage(QtWarningMsg, "QScriptValue::setProperty() failed: "
- "cannot set getter or setter of native property "
- "`__proto__'");
- object6.setProperty("__proto__", fun,
- QScriptValue::PropertyGetter | QScriptValue::PropertySetter
- | QScriptValue::UserRange);
- QVERIFY(object6.property("__proto__").strictlyEquals(object6.prototype()));
-
- object6.setProperty("__proto__", QScriptValue(),
- QScriptValue::PropertyGetter | QScriptValue::PropertySetter);
- QVERIFY(object6.property("__proto__").strictlyEquals(object6.prototype()));
- }
+void tst_QScriptValue::getSetProperty_gettersAndSettersThrowErrorNative()
+{
+ // getter/setter that throws an error
+ QScriptEngine eng;
+ QScriptValue str = QScriptValue(&eng, "bar");
+ QScriptValue object = eng.newObject();
- // global property that's a getter+setter
- {
- eng.globalObject().setProperty("globalGetterSetterProperty", eng.newFunction(getterSetter),
- QScriptValue::PropertyGetter | QScriptValue::PropertySetter);
- eng.evaluate("globalGetterSetterProperty = 123");
- {
- QScriptValue ret = eng.evaluate("globalGetterSetterProperty");
- QVERIFY(ret.isNumber());
- QVERIFY(ret.strictlyEquals(QScriptValue(&eng, 123)));
- }
- QCOMPARE(eng.evaluate("typeof globalGetterSetterProperty").toString(),
- QString::fromLatin1("number"));
- {
- QScriptValue ret = eng.evaluate("this.globalGetterSetterProperty()");
- QVERIFY(ret.isError());
- QCOMPARE(ret.toString(), QString::fromLatin1("TypeError: Result of expression 'this.globalGetterSetterProperty' [123] is not a function."));
- }
- {
- QScriptValue ret = eng.evaluate("new this.globalGetterSetterProperty()");
- QVERIFY(ret.isError());
- QCOMPARE(ret.toString(), QString::fromLatin1("TypeError: Result of expression 'this.globalGetterSetterProperty' [123] is not a constructor."));
- }
- }
+ object.setProperty("foo", eng.newFunction(getterSetterThrowingError),
+ QScriptValue::PropertyGetter | QScriptValue::PropertySetter);
+ QVERIFY(!eng.hasUncaughtException());
+ QScriptValue ret = object.property("foo");
+ QVERIFY(ret.isError());
+ QVERIFY(eng.hasUncaughtException());
+ QVERIFY(ret.strictlyEquals(eng.uncaughtException()));
+ QCOMPARE(ret.toString(), QLatin1String("Error: get foo"));
+ eng.evaluate("Object"); // clear exception state...
+ QVERIFY(!eng.hasUncaughtException());
+ object.setProperty("foo", str);
+ QVERIFY(eng.hasUncaughtException());
+ QCOMPARE(eng.uncaughtException().toString(), QLatin1String("Error: set foo"));
+}
- // "upgrading" an existing property to become a getter+setter
- {
- QScriptValue object7 = eng.newObject();
- QScriptValue num(&eng, 123);
- object7.setProperty("foo", num);
- object7.setProperty("foo", eng.newFunction(getterSetter),
- QScriptValue::PropertyGetter | QScriptValue::PropertySetter);
- QVERIFY(!object7.property("x").isValid());
- object7.setProperty("foo", num);
- QVERIFY(object7.property("x").equals(num));
- }
+void tst_QScriptValue::getSetProperty_gettersAndSettersThrowErrorJS()
+{
+ // getter/setter that throws an error (from js function)
+ QScriptEngine eng;
+ QScriptValue str = QScriptValue(&eng, "bar");
+
+ eng.evaluate("o = new Object; "
+ "o.__defineGetter__('foo', function() { throw new Error('get foo') }); "
+ "o.__defineSetter__('foo', function() { throw new Error('set foo') }); ");
+ QScriptValue object = eng.evaluate("o");
+ QVERIFY(!eng.hasUncaughtException());
+ QScriptValue ret = object.property("foo");
+ QEXPECT_FAIL("", "QTBUG-17616: Exception thrown from js function are not returned by the JSC port", Continue);
+ QVERIFY(ret.isError());
+ QVERIFY(eng.hasUncaughtException());
+ QEXPECT_FAIL("", "QTBUG-17616: Exception thrown from js function are not returned by the JSC port", Continue);
+ QVERIFY(ret.strictlyEquals(eng.uncaughtException()));
+ QCOMPARE(eng.uncaughtException().toString(), QLatin1String("Error: get foo"));
+ eng.evaluate("Object"); // clear exception state...
+ QVERIFY(!eng.hasUncaughtException());
+ object.setProperty("foo", str);
+ QVERIFY(eng.hasUncaughtException());
+ QCOMPARE(eng.uncaughtException().toString(), QLatin1String("Error: set foo"));
+}
+
+void tst_QScriptValue::getSetProperty_gettersAndSettersOnNative()
+{
+ // attempt to install getter+setter on built-in (native) property
+ QScriptEngine eng;
+ QScriptValue object = eng.newObject();
+ QVERIFY(object.property("__proto__").strictlyEquals(object.prototype()));
+
+ QScriptValue fun = eng.newFunction(getSet__proto__);
+ fun.setProperty("value", QScriptValue(&eng, "boo"));
+ QTest::ignoreMessage(QtWarningMsg, "QScriptValue::setProperty() failed: "
+ "cannot set getter or setter of native property "
+ "`__proto__'");
+ object.setProperty("__proto__", fun,
+ QScriptValue::PropertyGetter | QScriptValue::PropertySetter
+ | QScriptValue::UserRange);
+ QVERIFY(object.property("__proto__").strictlyEquals(object.prototype()));
+
+ object.setProperty("__proto__", QScriptValue(),
+ QScriptValue::PropertyGetter | QScriptValue::PropertySetter);
+ QVERIFY(object.property("__proto__").strictlyEquals(object.prototype()));
+}
+
+void tst_QScriptValue::getSetProperty_gettersAndSettersOnGlobalObject()
+{
+ // global property that's a getter+setter
+ QScriptEngine eng;
+ eng.globalObject().setProperty("globalGetterSetterProperty", eng.newFunction(getterSetter),
+ QScriptValue::PropertyGetter | QScriptValue::PropertySetter);
+ eng.evaluate("globalGetterSetterProperty = 123");
+ {
+ QScriptValue ret = eng.evaluate("globalGetterSetterProperty");
+ QVERIFY(ret.isNumber());
+ QVERIFY(ret.strictlyEquals(QScriptValue(&eng, 123)));
}
+ QCOMPARE(eng.evaluate("typeof globalGetterSetterProperty").toString(),
+ QString::fromLatin1("number"));
+ {
+ QScriptValue ret = eng.evaluate("this.globalGetterSetterProperty()");
+ QVERIFY(ret.isError());
+ QCOMPARE(ret.toString(), QString::fromLatin1("TypeError: Result of expression 'this.globalGetterSetterProperty' [123] is not a function."));
+ }
+ {
+ QScriptValue ret = eng.evaluate("new this.globalGetterSetterProperty()");
+ QVERIFY(ret.isError());
+ QCOMPARE(ret.toString(), QString::fromLatin1("TypeError: Result of expression 'this.globalGetterSetterProperty' [123] is not a constructor."));
+ }
+}
+
+void tst_QScriptValue::getSetProperty_gettersAndSettersChange()
+{
+ // "upgrading" an existing property to become a getter+setter
+ QScriptEngine eng;
+ QScriptValue object = eng.newObject();
+ QScriptValue num(&eng, 123);
+ object.setProperty("foo", num);
+ object.setProperty("foo", eng.newFunction(getterSetter),
+ QScriptValue::PropertyGetter | QScriptValue::PropertySetter);
+ QVERIFY(!object.property("x").isValid());
+ object.setProperty("foo", num);
+ QVERIFY(object.property("x").equals(num));
+
+ eng.globalObject().setProperty("object", object);
+ QScriptValue res = eng.evaluate("object.x = 89; var a = object.foo; object.foo = 65; a");
+ QCOMPARE(res.toInt32(), 89);
+ QCOMPARE(object.property("x").toInt32(), 65);
+ QCOMPARE(object.property("foo").toInt32(), 65);
+}
+
+void tst_QScriptValue::getSetProperty_array()
+{
+ QScriptEngine eng;
+ QScriptValue str = QScriptValue(&eng, "bar");
+ QScriptValue num = QScriptValue(&eng, 123.0);
+ QScriptValue array = eng.newArray();
+
+ QVERIFY(array.isArray());
+ 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);
+}
+
+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);
eng.globalObject().setProperty("object", object);
@@ -2059,9 +2185,9 @@ void tst_QScriptValue::getSetProperty()
}
// 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);
+ QEXPECT_FAIL("", "QTBUG-17617: 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);
+ QEXPECT_FAIL("", "QTBUG-17617: With JSC-based back-end, undeletable properties can't be deleted from C++", Continue);
QCOMPARE(object.propertyFlags("undeletableProperty"), 0);
// SkipInEnumeration
@@ -2155,50 +2281,123 @@ void tst_QScriptValue::arrayElementGetterSetter()
QVERIFY(obj.propertyFlags("1") == 0);
}
-void tst_QScriptValue::getSetPrototype()
+void tst_QScriptValue::getSetPrototype_cyclicPrototype()
{
QScriptEngine eng;
-
+ QScriptValue prototype = eng.newObject();
QScriptValue object = eng.newObject();
+ object.setPrototype(prototype);
- QScriptValue object2 = eng.newObject();
- object2.setPrototype(object);
+ QScriptValue previousPrototype = prototype.prototype();
+ QTest::ignoreMessage(QtWarningMsg, "QScriptValue::setPrototype() failed: cyclic prototype value");
+ prototype.setPrototype(prototype);
+ QCOMPARE(prototype.prototype().strictlyEquals(previousPrototype), true);
+
+ object.setPrototype(prototype);
+ QTest::ignoreMessage(QtWarningMsg, "QScriptValue::setPrototype() failed: cyclic prototype value");
+ prototype.setPrototype(object);
+ QCOMPARE(prototype.prototype().strictlyEquals(previousPrototype), true);
+
+}
- QCOMPARE(object2.prototype().strictlyEquals(object), true);
+void tst_QScriptValue::getSetPrototype_evalCyclicPrototype()
+{
+ QScriptEngine eng;
+ QScriptValue ret = eng.evaluate("o = { }; p = { }; o.__proto__ = p; p.__proto__ = o");
+ QCOMPARE(eng.hasUncaughtException(), true);
+ QVERIFY(ret.strictlyEquals(eng.uncaughtException()));
+ QCOMPARE(ret.isError(), true);
+ QCOMPARE(ret.toString(), QLatin1String("Error: cyclic __proto__ value"));
+}
+void tst_QScriptValue::getSetPrototype_eval()
+{
+ QScriptEngine eng;
+ QScriptValue ret = eng.evaluate("p = { }; p.__proto__ = { }");
+ QCOMPARE(eng.hasUncaughtException(), false);
+ QCOMPARE(ret.isError(), false);
+}
+
+void tst_QScriptValue::getSetPrototype_invalidPrototype()
+{
+ QScriptEngine eng;
QScriptValue inv;
+ QScriptValue object = eng.newObject();
+ QScriptValue proto = object.prototype();
+ QVERIFY(object.prototype().strictlyEquals(proto));
inv.setPrototype(object);
QCOMPARE(inv.prototype().isValid(), false);
+ object.setPrototype(inv);
+ QVERIFY(object.prototype().strictlyEquals(proto));
+}
+void tst_QScriptValue::getSetPrototype_twoEngines()
+{
+ QScriptEngine eng;
+ QScriptValue prototype = eng.newObject();
+ QScriptValue object = eng.newObject();
+ object.setPrototype(prototype);
QScriptEngine otherEngine;
- QScriptValue object3 = otherEngine.newObject();
+ QScriptValue newPrototype = otherEngine.newObject();
QTest::ignoreMessage(QtWarningMsg, "QScriptValue::setPrototype() failed: cannot set a prototype created in a different engine");
- object2.setPrototype(object3);
- QCOMPARE(object2.prototype().strictlyEquals(object), true);
+ object.setPrototype(newPrototype);
+ QCOMPARE(object.prototype().strictlyEquals(prototype), true);
- // cyclic prototypes
- 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::getSetPrototype_null()
+{
+ QScriptEngine eng;
+ QScriptValue object = eng.newObject();
+ object.setPrototype(QScriptValue(QScriptValue::NullValue));
+ QVERIFY(object.prototype().isNull());
- {
- QScriptValue ret = eng.evaluate("o = { }; p = { }; o.__proto__ = p; p.__proto__ = o");
- QCOMPARE(eng.hasUncaughtException(), true);
- QVERIFY(ret.strictlyEquals(eng.uncaughtException()));
- QCOMPARE(ret.isError(), true);
- QCOMPARE(ret.toString(), QLatin1String("Error: cyclic __proto__ value"));
- }
- {
- QScriptValue ret = eng.evaluate("p.__proto__ = { }");
- QCOMPARE(eng.hasUncaughtException(), false);
- QCOMPARE(ret.isError(), false);
- }
+ QScriptValue newProto = eng.newObject();
+ object.setPrototype(newProto);
+ QVERIFY(object.prototype().equals(newProto));
+
+ object.setPrototype(QScriptValue(&eng, QScriptValue::NullValue));
+ QVERIFY(object.prototype().isNull());
+}
+
+void tst_QScriptValue::getSetPrototype_notObjectOrNull()
+{
+ QScriptEngine eng;
+ QScriptValue object = eng.newObject();
+ QScriptValue originalProto = object.prototype();
+
+ // bool
+ object.setPrototype(true);
+ QVERIFY(object.prototype().equals(originalProto));
+ object.setPrototype(QScriptValue(&eng, true));
+ QVERIFY(object.prototype().equals(originalProto));
+
+ // number
+ object.setPrototype(123);
+ QVERIFY(object.prototype().equals(originalProto));
+ object.setPrototype(QScriptValue(&eng, 123));
+ QVERIFY(object.prototype().equals(originalProto));
+
+ // string
+ object.setPrototype("foo");
+ QVERIFY(object.prototype().equals(originalProto));
+ object.setPrototype(QScriptValue(&eng, "foo"));
+ QVERIFY(object.prototype().equals(originalProto));
+
+ // undefined
+ object.setPrototype(QScriptValue(QScriptValue::UndefinedValue));
+ QVERIFY(object.prototype().equals(originalProto));
+ object.setPrototype(QScriptValue(&eng, QScriptValue::UndefinedValue));
+ QVERIFY(object.prototype().equals(originalProto));
+}
+
+void tst_QScriptValue::getSetPrototype()
+{
+ QScriptEngine eng;
+ QScriptValue prototype = eng.newObject();
+ QScriptValue object = eng.newObject();
+ object.setPrototype(prototype);
+ QCOMPARE(object.prototype().strictlyEquals(prototype), true);
}
void tst_QScriptValue::getSetScope()
@@ -2235,10 +2434,24 @@ void tst_QScriptValue::getSetScope()
QVERIFY(!object2.scope().isValid());
}
-void tst_QScriptValue::getSetData()
+void tst_QScriptValue::getSetData_objects_data()
{
- QScriptEngine eng;
- QScriptValue object = eng.newObject();
+ newEngine();
+
+ QTest::addColumn<QScriptValue>("object");
+
+ QTest::newRow("object from evaluate") << engine->evaluate("new Object()");
+ QTest::newRow("object from engine") << engine->newObject();
+ QTest::newRow("Array") << engine->newArray();
+ QTest::newRow("Date") << engine->newDate(12324);
+ QTest::newRow("QObject") << engine->newQObject(this);
+ QTest::newRow("RegExp") << engine->newRegExp(QRegExp());
+}
+
+void tst_QScriptValue::getSetData_objects()
+{
+ QFETCH(QScriptValue, object);
+
QVERIFY(!object.data().isValid());
QScriptValue v1(true);
object.setData(v1);
@@ -2246,13 +2459,48 @@ void tst_QScriptValue::getSetData()
QScriptValue v2(123);
object.setData(v2);
QVERIFY(object.data().strictlyEquals(v2));
- QScriptValue v3 = eng.newObject();
+ QScriptValue v3 = engine->newObject();
object.setData(v3);
QVERIFY(object.data().strictlyEquals(v3));
object.setData(QScriptValue());
QVERIFY(!object.data().isValid());
}
+void tst_QScriptValue::getSetData_nonObjects_data()
+{
+ newEngine();
+
+ QTest::addColumn<QScriptValue>("value");
+
+ QTest::newRow("undefined (bound)") << engine->undefinedValue();
+ QTest::newRow("null (bound)") << engine->nullValue();
+ QTest::newRow("string (bound)") << QScriptValue(engine, "Pong");
+ QTest::newRow("bool (bound)") << QScriptValue(engine, false);
+
+ QTest::newRow("undefined") << QScriptValue(QScriptValue::UndefinedValue);
+ QTest::newRow("null") << QScriptValue(QScriptValue::NullValue);
+ QTest::newRow("string") << QScriptValue("Pong");
+ QTest::newRow("bool") << QScriptValue(true);
+}
+
+void tst_QScriptValue::getSetData_nonObjects()
+{
+ QFETCH(QScriptValue, value);
+
+ QVERIFY(!value.data().isValid());
+ QScriptValue v1(true);
+ value.setData(v1);
+ QVERIFY(!value.data().isValid());
+ QScriptValue v2(123);
+ value.setData(v2);
+ QVERIFY(!value.data().isValid());
+ QScriptValue v3 = engine->newObject();
+ value.setData(v3);
+ QVERIFY(!value.data().isValid());
+ value.setData(QScriptValue());
+ QVERIFY(!value.data().isValid());
+}
+
void tst_QScriptValue::setData_QTBUG15144()
{
QScriptEngine eng;
@@ -2266,30 +2514,59 @@ void tst_QScriptValue::setData_QTBUG15144()
obj.setData("foodfight");
}
}
+
class TestScriptClass : public QScriptClass
{
public:
TestScriptClass(QScriptEngine *engine) : QScriptClass(engine) {}
};
-void tst_QScriptValue::getSetScriptClass()
+void tst_QScriptValue::getSetScriptClass_emptyClass_data()
{
- QScriptEngine eng;
- QScriptValue inv;
- QCOMPARE(inv.scriptClass(), (QScriptClass*)0);
- QScriptValue num(123);
- QCOMPARE(num.scriptClass(), (QScriptClass*)0);
+ newEngine();
+ QTest::addColumn<QScriptValue>("value");
+
+ QTest::newRow("invalid") << QScriptValue();
+ QTest::newRow("number") << QScriptValue(123);
+ QTest::newRow("string") << QScriptValue("pong");
+ QTest::newRow("bool") << QScriptValue(false);
+ QTest::newRow("null") << QScriptValue(QScriptValue::NullValue);
+ QTest::newRow("undefined") << QScriptValue(QScriptValue::UndefinedValue);
+
+ QTest::newRow("number") << QScriptValue(engine, 123);
+ QTest::newRow("string") << QScriptValue(engine, "pong");
+ QTest::newRow("bool") << QScriptValue(engine, true);
+ QTest::newRow("null") << QScriptValue(engine->nullValue());
+ QTest::newRow("undefined") << QScriptValue(engine->undefinedValue());
+ QTest::newRow("object") << QScriptValue(engine->newObject());
+ QTest::newRow("date") << QScriptValue(engine->evaluate("new Date()"));
+ QTest::newRow("qobject") << QScriptValue(engine->newQObject(this));
+}
+
+void tst_QScriptValue::getSetScriptClass_emptyClass()
+{
+ QFETCH(QScriptValue, value);
+ QCOMPARE(value.scriptClass(), (QScriptClass*)0);
+}
+void tst_QScriptValue::getSetScriptClass_JSObjectFromCpp()
+{
+ QScriptEngine eng;
TestScriptClass testClass(&eng);
// object created in C++ (newObject())
{
QScriptValue obj = eng.newObject();
- QCOMPARE(obj.scriptClass(), (QScriptClass*)0);
obj.setScriptClass(&testClass);
QCOMPARE(obj.scriptClass(), (QScriptClass*)&testClass);
obj.setScriptClass(0);
QCOMPARE(obj.scriptClass(), (QScriptClass*)0);
}
+}
+
+void tst_QScriptValue::getSetScriptClass_JSObjectFromJS()
+{
+ QScriptEngine eng;
+ TestScriptClass testClass(&eng);
// object created in JS
{
QScriptValue obj = eng.evaluate("new Object");
@@ -2304,6 +2581,12 @@ void tst_QScriptValue::getSetScriptClass()
obj.setScriptClass(0);
QCOMPARE(obj.scriptClass(), (QScriptClass*)0);
}
+}
+
+void tst_QScriptValue::getSetScriptClass_QVariant()
+{
+ QScriptEngine eng;
+ TestScriptClass testClass(&eng);
// object that already has a(n internal) class
{
QScriptValue obj = eng.newVariant(QUrl("http://example.com"));
@@ -2315,10 +2598,15 @@ void tst_QScriptValue::getSetScriptClass()
QVERIFY(!obj.isVariant());
QCOMPARE(obj.toVariant(), QVariant(QVariantMap()));
}
+}
+
+void tst_QScriptValue::getSetScriptClass_QObject()
+{
+ QScriptEngine eng;
+ TestScriptClass testClass(&eng);
{
QScriptValue obj = eng.newQObject(this);
QVERIFY(obj.isQObject());
- QCOMPARE(obj.scriptClass(), (QScriptClass*)0);
obj.setScriptClass(&testClass);
QCOMPARE(obj.scriptClass(), (QScriptClass*)&testClass);
QVERIFY(obj.isObject());
@@ -2347,83 +2635,89 @@ static QScriptValue returnInvalidValue(QScriptContext *, QScriptEngine *)
return QScriptValue();
}
-void tst_QScriptValue::call()
+void tst_QScriptValue::call_function()
{
QScriptEngine eng;
+ QScriptValue fun = eng.evaluate("(function() { return 1; })");
+ QVERIFY(fun.isFunction());
+ QScriptValue result = fun.call();
+ QVERIFY(result.isNumber());
+ QCOMPARE(result.toInt32(), 1);
+}
- {
- QScriptValue fun = eng.evaluate("(function() { return 1; })");
- QVERIFY(fun.isFunction());
- QScriptValue result = fun.call();
- QVERIFY(result.isNumber());
- QCOMPARE(result.toInt32(), 1);
- }
-
+void tst_QScriptValue::call_object()
+{
+ QScriptEngine eng;
QScriptValue Object = eng.evaluate("Object");
QCOMPARE(Object.isFunction(), true);
- {
- QScriptValue result = Object.call(Object);
- QCOMPARE(result.isObject(), true);
- }
+ QScriptValue result = Object.call(Object);
+ QCOMPARE(result.isObject(), true);
+}
+void tst_QScriptValue::call_newObjects()
+{
+ QScriptEngine eng;
// test that call() doesn't construct new objects
QScriptValue Number = eng.evaluate("Number");
+ QScriptValue Object = eng.evaluate("Object");
QCOMPARE(Object.isFunction(), true);
- {
- QScriptValueList args;
- args << QScriptValue(&eng, 123);
- QScriptValue result = Number.call(Object, args);
- QCOMPARE(result.strictlyEquals(args.at(0)), true);
- }
+ QScriptValueList args;
+ args << QScriptValue(&eng, 123);
+ QScriptValue result = Number.call(Object, args);
+ QCOMPARE(result.strictlyEquals(args.at(0)), true);
+}
+void tst_QScriptValue::call_this()
+{
+ QScriptEngine eng;
// test that correct "this" object is used
- {
- QScriptValue fun = eng.evaluate("(function() { return this; })");
- QCOMPARE(fun.isFunction(), true);
+ QScriptValue fun = eng.evaluate("(function() { return this; })");
+ QCOMPARE(fun.isFunction(), true);
- {
- QScriptValue numberObject = QScriptValue(&eng, 123.0).toObject();
- QScriptValue result = fun.call(numberObject);
- QCOMPARE(result.isObject(), true);
- QCOMPARE(result.toNumber(), 123.0);
- }
- }
+ QScriptValue numberObject = QScriptValue(&eng, 123.0).toObject();
+ QScriptValue result = fun.call(numberObject);
+ QCOMPARE(result.isObject(), true);
+ QCOMPARE(result.toNumber(), 123.0);
+}
+void tst_QScriptValue::call_arguments()
+{
+ QScriptEngine eng;
// test that correct arguments are passed
- {
- QScriptValue fun = eng.evaluate("(function() { return arguments[0]; })");
- QCOMPARE(fun.isFunction(), true);
-
- {
- QScriptValue result = fun.call(eng.undefinedValue());
- QCOMPARE(result.isUndefined(), true);
- }
-
- {
- QScriptValueList args;
- args << QScriptValue(&eng, 123.0);
- QScriptValue result = fun.call(eng.undefinedValue(), args);
- QCOMPARE(result.isNumber(), true);
- QCOMPARE(result.toNumber(), 123.0);
- }
- // V2 constructors
- {
- QScriptValueList args;
- args << QScriptValue(123.0);
- QScriptValue result = fun.call(eng.undefinedValue(), args);
- QCOMPARE(result.isNumber(), true);
- QCOMPARE(result.toNumber(), 123.0);
- }
- {
- QScriptValue args = eng.newArray();
- args.setProperty(0, 123);
- QScriptValue result = fun.call(eng.undefinedValue(), args);
- QVERIFY(result.isNumber());
- QCOMPARE(result.toNumber(), 123.0);
- }
+ QScriptValue fun = eng.evaluate("(function() { return arguments[0]; })");
+ QCOMPARE(fun.isFunction(), true);
+ {
+ QScriptValue result = fun.call(eng.undefinedValue());
+ QCOMPARE(result.isUndefined(), true);
}
+ {
+ QScriptValueList args;
+ args << QScriptValue(&eng, 123.0);
+ QScriptValue result = fun.call(eng.undefinedValue(), args);
+ QCOMPARE(result.isNumber(), true);
+ QCOMPARE(result.toNumber(), 123.0);
+ }
+ // V2 constructors
+ {
+ QScriptValueList args;
+ args << QScriptValue(123.0);
+ QScriptValue result = fun.call(eng.undefinedValue(), args);
+ QCOMPARE(result.isNumber(), true);
+ QCOMPARE(result.toNumber(), 123.0);
+ }
+ {
+ QScriptValue args = eng.newArray();
+ args.setProperty(0, 123);
+ QScriptValue result = fun.call(eng.undefinedValue(), args);
+ QVERIFY(result.isNumber());
+ QCOMPARE(result.toNumber(), 123.0);
+ }
+}
+void tst_QScriptValue::call()
+{
+ QScriptEngine eng;
{
QScriptValue fun = eng.evaluate("(function() { return arguments[1]; })");
QCOMPARE(fun.isFunction(), true);
@@ -2444,7 +2738,6 @@ void tst_QScriptValue::call()
QCOMPARE(result.toNumber(), 456.0);
}
}
-
{
QScriptValue fun = eng.evaluate("(function() { throw new Error('foo'); })");
QCOMPARE(fun.isFunction(), true);
@@ -2457,7 +2750,6 @@ void tst_QScriptValue::call()
QVERIFY(result.strictlyEquals(eng.uncaughtException()));
}
}
-
{
eng.clearExceptions();
QScriptValue fun = eng.newFunction(getArg);
@@ -2485,7 +2777,6 @@ void tst_QScriptValue::call()
QCOMPARE(result.toNumber(), 123.0);
}
}
-
{
QScriptValue fun = eng.newFunction(evaluateArg);
{
@@ -2497,11 +2788,12 @@ void tst_QScriptValue::call()
QCOMPARE(result.toNumber(), 123.0);
}
}
+}
- QScriptValue inv;
- QCOMPARE(inv.call().isValid(), false);
-
+void tst_QScriptValue::call_invalidArguments()
+{
// test that invalid arguments are handled gracefully
+ QScriptEngine eng;
{
QScriptValue fun = eng.newFunction(getArg);
{
@@ -2534,6 +2826,35 @@ void tst_QScriptValue::call()
QCOMPARE(qIsNaN(ret.toNumber()), true);
}
}
+}
+
+void tst_QScriptValue::call_invalidReturn()
+{
+ // test that invalid return value is handled gracefully
+ QScriptEngine eng;
+ QScriptValue fun = eng.newFunction(returnInvalidValue);
+ eng.globalObject().setProperty("returnInvalidValue", fun);
+ QScriptValue ret = eng.evaluate("returnInvalidValue() + returnInvalidValue()");
+ QCOMPARE(ret.isValid(), true);
+ QCOMPARE(ret.isNumber(), true);
+ QCOMPARE(qIsNaN(ret.toNumber()), true);
+}
+
+void tst_QScriptValue::call_twoEngines()
+{
+ QScriptEngine eng;
+ QScriptValue object = eng.evaluate("Object");
+ QScriptEngine otherEngine;
+ QScriptValue fun = otherEngine.evaluate("(function() { return 1; })");
+ QVERIFY(fun.isFunction());
+ QTest::ignoreMessage(QtWarningMsg, "QScriptValue::call() failed: "
+ "cannot call function with thisObject created in "
+ "a different engine");
+ QCOMPARE(fun.call(object).isValid(), false);
+ QTest::ignoreMessage(QtWarningMsg, "QScriptValue::call() failed: "
+ "cannot call function with argument created in "
+ "a different engine");
+ QCOMPARE(fun.call(QScriptValue(), QScriptValueList() << QScriptValue(&eng, 123)).isValid(), false);
{
QScriptValue fun = eng.evaluate("Object");
QVERIFY(fun.isFunction());
@@ -2544,76 +2865,74 @@ void tst_QScriptValue::call()
QTest::ignoreMessage(QtWarningMsg, "QScriptValue::call() failed: cannot call function with argument created in a different engine");
fun.call(QScriptValue(), args);
}
+}
- // test that invalid return value is handled gracefully
- {
- QScriptValue fun = eng.newFunction(returnInvalidValue);
- eng.globalObject().setProperty("returnInvalidValue", fun);
- QScriptValue ret = eng.evaluate("returnInvalidValue() + returnInvalidValue()");
- QCOMPARE(ret.isValid(), true);
- QCOMPARE(ret.isNumber(), true);
- QCOMPARE(qIsNaN(ret.toNumber()), true);
- }
+void tst_QScriptValue::call_array()
+{
+ QScriptEngine eng;
+ QScriptValue fun = eng.evaluate("(function() { return arguments; })");
+ QVERIFY(fun.isFunction());
+ QScriptValue array = eng.newArray(3);
+ array.setProperty(0, QScriptValue(&eng, 123.0));
+ array.setProperty(1, QScriptValue(&eng, 456.0));
+ array.setProperty(2, QScriptValue(&eng, 789.0));
+ // call with single array object as arguments
+ QScriptValue ret = fun.call(QScriptValue(), array);
+ QVERIFY(!eng.hasUncaughtException());
+ QCOMPARE(ret.isError(), false);
+ QCOMPARE(ret.property(0).strictlyEquals(array.property(0)), true);
+ QCOMPARE(ret.property(1).strictlyEquals(array.property(1)), true);
+ QCOMPARE(ret.property(2).strictlyEquals(array.property(2)), true);
+ // call with arguments object as arguments
+ QScriptValue ret2 = fun.call(QScriptValue(), ret);
+ QCOMPARE(ret2.isError(), false);
+ QCOMPARE(ret2.property(0).strictlyEquals(ret.property(0)), true);
+ QCOMPARE(ret2.property(1).strictlyEquals(ret.property(1)), true);
+ QCOMPARE(ret2.property(2).strictlyEquals(ret.property(2)), true);
+ // call with null as arguments
+ QScriptValue ret3 = fun.call(QScriptValue(), eng.nullValue());
+ QCOMPARE(ret3.isError(), false);
+ QCOMPARE(ret3.property("length").isNumber(), true);
+ QCOMPARE(ret3.property("length").toNumber(), 0.0);
+ // call with undefined as arguments
+ QScriptValue ret4 = fun.call(QScriptValue(), eng.undefinedValue());
+ QCOMPARE(ret4.isError(), false);
+ QCOMPARE(ret4.property("length").isNumber(), true);
+ QCOMPARE(ret4.property("length").toNumber(), 0.0);
+ // call with something else as arguments
+ QScriptValue ret5 = fun.call(QScriptValue(), QScriptValue(&eng, 123.0));
+ QCOMPARE(ret5.isError(), true);
+ // call with a non-array object as arguments
+ QScriptValue ret6 = fun.call(QScriptValue(), eng.globalObject());
+ QVERIFY(ret6.isError());
+ QCOMPARE(ret6.toString(), QString::fromLatin1("TypeError: Arguments must be an array"));
+}
- {
- QScriptEngine otherEngine;
- QScriptValue fun = otherEngine.evaluate("(function() { return 1; })");
- QVERIFY(fun.isFunction());
- QTest::ignoreMessage(QtWarningMsg, "QScriptValue::call() failed: "
- "cannot call function with thisObject created in "
- "a different engine");
- QCOMPARE(fun.call(Object).isValid(), false);
- QTest::ignoreMessage(QtWarningMsg, "QScriptValue::call() failed: "
- "cannot call function with argument created in "
- "a different engine");
- QCOMPARE(fun.call(QScriptValue(), QScriptValueList() << QScriptValue(&eng, 123)).isValid(), false);
- }
- {
- QScriptValue fun = eng.evaluate("(function() { return arguments; })");
- QVERIFY(fun.isFunction());
- QScriptValue array = eng.newArray(3);
- array.setProperty(0, QScriptValue(&eng, 123.0));
- array.setProperty(1, QScriptValue(&eng, 456.0));
- array.setProperty(2, QScriptValue(&eng, 789.0));
- // call with single array object as arguments
- QScriptValue ret = fun.call(QScriptValue(), array);
- QVERIFY(!eng.hasUncaughtException());
- QCOMPARE(ret.isError(), false);
- QCOMPARE(ret.property(0).strictlyEquals(array.property(0)), true);
- QCOMPARE(ret.property(1).strictlyEquals(array.property(1)), true);
- QCOMPARE(ret.property(2).strictlyEquals(array.property(2)), true);
- // call with arguments object as arguments
- QScriptValue ret2 = fun.call(QScriptValue(), ret);
- QCOMPARE(ret2.isError(), false);
- QCOMPARE(ret2.property(0).strictlyEquals(ret.property(0)), true);
- QCOMPARE(ret2.property(1).strictlyEquals(ret.property(1)), true);
- QCOMPARE(ret2.property(2).strictlyEquals(ret.property(2)), true);
- // call with null as arguments
- QScriptValue ret3 = fun.call(QScriptValue(), eng.nullValue());
- QCOMPARE(ret3.isError(), false);
- QCOMPARE(ret3.property("length").isNumber(), true);
- QCOMPARE(ret3.property("length").toNumber(), 0.0);
- // call with undefined as arguments
- QScriptValue ret4 = fun.call(QScriptValue(), eng.undefinedValue());
- QCOMPARE(ret4.isError(), false);
- QCOMPARE(ret4.property("length").isNumber(), true);
- QCOMPARE(ret4.property("length").toNumber(), 0.0);
- // call with something else as arguments
- QScriptValue ret5 = fun.call(QScriptValue(), QScriptValue(&eng, 123.0));
- QCOMPARE(ret5.isError(), true);
- // call with a non-array object as arguments
- QScriptValue ret6 = fun.call(QScriptValue(), eng.globalObject());
- QVERIFY(ret6.isError());
- QCOMPARE(ret6.toString(), QString::fromLatin1("TypeError: Arguments must be an array"));
- }
+void tst_QScriptValue::call_nonFunction_data()
+{
+ newEngine();
+ QTest::addColumn<QScriptValue>("value");
+
+ QTest::newRow("invalid") << QScriptValue();
+ QTest::newRow("bool") << QScriptValue(false);
+ QTest::newRow("int") << QScriptValue(123);
+ QTest::newRow("string") << QScriptValue(QString::fromLatin1("ciao"));
+ QTest::newRow("undefined") << QScriptValue(QScriptValue::UndefinedValue);
+ QTest::newRow("null") << QScriptValue(QScriptValue::NullValue);
+
+ QTest::newRow("bool bound") << QScriptValue(engine, false);
+ QTest::newRow("int bound") << QScriptValue(engine, 123);
+ QTest::newRow("string bound") << QScriptValue(engine, QString::fromLatin1("ciao"));
+ QTest::newRow("undefined bound") << engine->undefinedValue();
+ QTest::newRow("null bound") << engine->nullValue();
+}
+void tst_QScriptValue::call_nonFunction()
+{
// calling things that are not functions
- QVERIFY(!QScriptValue(false).call().isValid());
- QVERIFY(!QScriptValue(123).call().isValid());
- QVERIFY(!QScriptValue(QString::fromLatin1("ciao")).call().isValid());
- QVERIFY(!QScriptValue(QScriptValue::UndefinedValue).call().isValid());
- QVERIFY(!QScriptValue(QScriptValue::NullValue).call().isValid());
+ QFETCH(QScriptValue, value);
+ QVERIFY(!value.call().isValid());
}
static QScriptValue ctorReturningUndefined(QScriptContext *ctx, QScriptEngine *)
@@ -2629,127 +2948,169 @@ static QScriptValue ctorReturningNewObject(QScriptContext *, QScriptEngine *eng)
return result;
}
-void tst_QScriptValue::construct()
+void tst_QScriptValue::construct_nonFunction_data()
+{
+ newEngine();
+ QTest::addColumn<QScriptValue>("value");
+
+ QTest::newRow("invalid") << QScriptValue();
+ QTest::newRow("bool") << QScriptValue(false);
+ QTest::newRow("int") << QScriptValue(123);
+ QTest::newRow("string") << QScriptValue(QString::fromLatin1("ciao"));
+ QTest::newRow("undefined") << QScriptValue(QScriptValue::UndefinedValue);
+ QTest::newRow("null") << QScriptValue(QScriptValue::NullValue);
+
+ QTest::newRow("bool bound") << QScriptValue(engine, false);
+ QTest::newRow("int bound") << QScriptValue(engine, 123);
+ QTest::newRow("string bound") << QScriptValue(engine, QString::fromLatin1("ciao"));
+ QTest::newRow("undefined bound") << engine->undefinedValue();
+ QTest::newRow("null bound") << engine->nullValue();
+}
+
+void tst_QScriptValue::construct_nonFunction()
+{
+ QFETCH(QScriptValue, value);
+ QVERIFY(!value.construct().isValid());
+}
+
+void tst_QScriptValue::construct_simple()
{
QScriptEngine eng;
+ QScriptValue fun = eng.evaluate("(function () { this.foo = 123; })");
+ QVERIFY(fun.isFunction());
+ QScriptValue ret = fun.construct();
+ QVERIFY(ret.isObject());
+ QVERIFY(ret.instanceOf(fun));
+ QCOMPARE(ret.property("foo").toInt32(), 123);
+}
- {
- QScriptValue fun = eng.evaluate("(function () { this.foo = 123; })");
- QVERIFY(fun.isFunction());
- QScriptValue ret = fun.construct();
- QVERIFY(ret.isObject());
- QVERIFY(ret.instanceOf(fun));
- QCOMPARE(ret.property("foo").toInt32(), 123);
- }
+void tst_QScriptValue::construct_newObjectJS()
+{
+ QScriptEngine eng;
// returning a different object overrides the default-constructed one
- {
- QScriptValue fun = eng.evaluate("(function () { return { bar: 456 }; })");
- QVERIFY(fun.isFunction());
- QScriptValue ret = fun.construct();
- QVERIFY(ret.isObject());
- QVERIFY(!ret.instanceOf(fun));
- QCOMPARE(ret.property("bar").toInt32(), 456);
- }
+ QScriptValue fun = eng.evaluate("(function () { return { bar: 456 }; })");
+ QVERIFY(fun.isFunction());
+ QScriptValue ret = fun.construct();
+ QVERIFY(ret.isObject());
+ QVERIFY(!ret.instanceOf(fun));
+ QCOMPARE(ret.property("bar").toInt32(), 456);
+}
- {
- QScriptValue fun = eng.newFunction(ctorReturningUndefined);
- QScriptValue ret = fun.construct();
- QVERIFY(ret.isObject());
- QVERIFY(ret.instanceOf(fun));
- QCOMPARE(ret.property("foo").toInt32(), 123);
- }
- {
- QScriptValue fun = eng.newFunction(ctorReturningNewObject);
- QScriptValue ret = fun.construct();
- QVERIFY(ret.isObject());
- QVERIFY(!ret.instanceOf(fun));
- QCOMPARE(ret.property("bar").toInt32(), 456);
- }
+void tst_QScriptValue::construct_undefined()
+{
+ QScriptEngine eng;
+ QScriptValue fun = eng.newFunction(ctorReturningUndefined);
+ QScriptValue ret = fun.construct();
+ QVERIFY(ret.isObject());
+ QVERIFY(ret.instanceOf(fun));
+ QCOMPARE(ret.property("foo").toInt32(), 123);
+}
+void tst_QScriptValue::construct_newObjectCpp()
+{
+ QScriptEngine eng;
+ QScriptValue fun = eng.newFunction(ctorReturningNewObject);
+ QScriptValue ret = fun.construct();
+ QVERIFY(ret.isObject());
+ QVERIFY(!ret.instanceOf(fun));
+ QCOMPARE(ret.property("bar").toInt32(), 456);
+}
+
+void tst_QScriptValue::construct_arg()
+{
+ QScriptEngine eng;
QScriptValue Number = eng.evaluate("Number");
QCOMPARE(Number.isFunction(), true);
- {
- QScriptValueList args;
- args << QScriptValue(&eng, 123);
- QScriptValue ret = Number.construct(args);
- QCOMPARE(ret.isObject(), true);
- QCOMPARE(ret.toNumber(), args.at(0).toNumber());
- }
+ QScriptValueList args;
+ args << QScriptValue(&eng, 123);
+ QScriptValue ret = Number.construct(args);
+ QCOMPARE(ret.isObject(), true);
+ QCOMPARE(ret.toNumber(), args.at(0).toNumber());
+}
+void tst_QScriptValue::construct_proto()
+{
+ QScriptEngine eng;
// test that internal prototype is set correctly
- {
- QScriptValue fun = eng.evaluate("(function() { return this.__proto__; })");
- QCOMPARE(fun.isFunction(), true);
- QCOMPARE(fun.property("prototype").isObject(), true);
- QScriptValue ret = fun.construct();
- QCOMPARE(fun.property("prototype").strictlyEquals(ret), true);
- }
+ QScriptValue fun = eng.evaluate("(function() { return this.__proto__; })");
+ QCOMPARE(fun.isFunction(), true);
+ QCOMPARE(fun.property("prototype").isObject(), true);
+ QScriptValue ret = fun.construct();
+ QCOMPARE(fun.property("prototype").strictlyEquals(ret), true);
+}
+void tst_QScriptValue::construct_returnInt()
+{
+ QScriptEngine eng;
// test that we return the new object even if a non-object value is returned from the function
- {
- QScriptValue fun = eng.evaluate("(function() { return 123; })");
- QCOMPARE(fun.isFunction(), true);
- QScriptValue ret = fun.construct();
- QCOMPARE(ret.isObject(), true);
- }
+ QScriptValue fun = eng.evaluate("(function() { return 123; })");
+ QCOMPARE(fun.isFunction(), true);
+ QScriptValue ret = fun.construct();
+ QCOMPARE(ret.isObject(), true);
+}
- {
- QScriptValue fun = eng.evaluate("(function() { throw new Error('foo'); })");
- QCOMPARE(fun.isFunction(), true);
- QScriptValue ret = fun.construct();
- QCOMPARE(ret.isError(), true);
- QCOMPARE(eng.hasUncaughtException(), true);
- QVERIFY(ret.strictlyEquals(eng.uncaughtException()));
- }
+void tst_QScriptValue::construct_throw()
+{
+ QScriptEngine eng;
+ QScriptValue fun = eng.evaluate("(function() { throw new Error('foo'); })");
+ QCOMPARE(fun.isFunction(), true);
+ QScriptValue ret = fun.construct();
+ QCOMPARE(ret.isError(), true);
+ QCOMPARE(eng.hasUncaughtException(), true);
+ QVERIFY(ret.strictlyEquals(eng.uncaughtException()));
+}
- QScriptValue inv;
- QCOMPARE(inv.construct().isValid(), false);
+void tst_QScriptValue::construct()
+{
+ QScriptEngine eng;
+ QScriptValue fun = eng.evaluate("(function() { return arguments; })");
+ QVERIFY(fun.isFunction());
+ QScriptValue array = eng.newArray(3);
+ array.setProperty(0, QScriptValue(&eng, 123.0));
+ array.setProperty(1, QScriptValue(&eng, 456.0));
+ array.setProperty(2, QScriptValue(&eng, 789.0));
+ // construct with single array object as arguments
+ QScriptValue ret = fun.construct(array);
+ QVERIFY(!eng.hasUncaughtException());
+ QVERIFY(ret.isValid());
+ QVERIFY(ret.isObject());
+ QCOMPARE(ret.property(0).strictlyEquals(array.property(0)), true);
+ QCOMPARE(ret.property(1).strictlyEquals(array.property(1)), true);
+ QCOMPARE(ret.property(2).strictlyEquals(array.property(2)), true);
+ // construct with arguments object as arguments
+ QScriptValue ret2 = fun.construct(ret);
+ QCOMPARE(ret2.property(0).strictlyEquals(ret.property(0)), true);
+ QCOMPARE(ret2.property(1).strictlyEquals(ret.property(1)), true);
+ QCOMPARE(ret2.property(2).strictlyEquals(ret.property(2)), true);
+ // construct with null as arguments
+ QScriptValue ret3 = fun.construct(eng.nullValue());
+ QCOMPARE(ret3.isError(), false);
+ QCOMPARE(ret3.property("length").isNumber(), true);
+ QCOMPARE(ret3.property("length").toNumber(), 0.0);
+ // construct with undefined as arguments
+ QScriptValue ret4 = fun.construct(eng.undefinedValue());
+ QCOMPARE(ret4.isError(), false);
+ QCOMPARE(ret4.property("length").isNumber(), true);
+ QCOMPARE(ret4.property("length").toNumber(), 0.0);
+ // construct with something else as arguments
+ QScriptValue ret5 = fun.construct(QScriptValue(&eng, 123.0));
+ QCOMPARE(ret5.isError(), true);
+ // construct with a non-array object as arguments
+ QScriptValue ret6 = fun.construct(eng.globalObject());
+ QVERIFY(ret6.isError());
+ QCOMPARE(ret6.toString(), QString::fromLatin1("TypeError: Arguments must be an array"));
+}
- {
- QScriptValue fun = eng.evaluate("(function() { return arguments; })");
- QVERIFY(fun.isFunction());
- QScriptValue array = eng.newArray(3);
- array.setProperty(0, QScriptValue(&eng, 123.0));
- array.setProperty(1, QScriptValue(&eng, 456.0));
- array.setProperty(2, QScriptValue(&eng, 789.0));
- // construct with single array object as arguments
- QScriptValue ret = fun.construct(array);
- QVERIFY(!eng.hasUncaughtException());
- QVERIFY(ret.isValid());
- QVERIFY(ret.isObject());
- QCOMPARE(ret.property(0).strictlyEquals(array.property(0)), true);
- QCOMPARE(ret.property(1).strictlyEquals(array.property(1)), true);
- QCOMPARE(ret.property(2).strictlyEquals(array.property(2)), true);
- // construct with arguments object as arguments
- QScriptValue ret2 = fun.construct(ret);
- QCOMPARE(ret2.property(0).strictlyEquals(ret.property(0)), true);
- QCOMPARE(ret2.property(1).strictlyEquals(ret.property(1)), true);
- QCOMPARE(ret2.property(2).strictlyEquals(ret.property(2)), true);
- // construct with null as arguments
- QScriptValue ret3 = fun.construct(eng.nullValue());
- QCOMPARE(ret3.isError(), false);
- QCOMPARE(ret3.property("length").isNumber(), true);
- QCOMPARE(ret3.property("length").toNumber(), 0.0);
- // construct with undefined as arguments
- QScriptValue ret4 = fun.construct(eng.undefinedValue());
- QCOMPARE(ret4.isError(), false);
- QCOMPARE(ret4.property("length").isNumber(), true);
- QCOMPARE(ret4.property("length").toNumber(), 0.0);
- // construct with something else as arguments
- QScriptValue ret5 = fun.construct(QScriptValue(&eng, 123.0));
- QCOMPARE(ret5.isError(), true);
- // construct with a non-array object as arguments
- QScriptValue ret6 = fun.construct(eng.globalObject());
- QVERIFY(ret6.isError());
- QCOMPARE(ret6.toString(), QString::fromLatin1("TypeError: Arguments must be an array"));
- }
-
- // construct on things that are not functions
- QVERIFY(!QScriptValue(false).construct().isValid());
- QVERIFY(!QScriptValue(123).construct().isValid());
- QVERIFY(!QScriptValue(QString::fromLatin1("ciao")).construct().isValid());
- QVERIFY(!QScriptValue(QScriptValue::UndefinedValue).construct().isValid());
- QVERIFY(!QScriptValue(QScriptValue::NullValue).construct().isValid());
+void tst_QScriptValue::construct_twoEngines()
+{
+ QScriptEngine engine;
+ QScriptEngine otherEngine;
+ QScriptValue ctor = engine.evaluate("(function (a, b) { this.foo = 123; })");
+ QScriptValue arg(&otherEngine, 124567);
+ QTest::ignoreMessage(QtWarningMsg, "QScriptValue::construct() failed: cannot construct function with argument created in a different engine");
+ QVERIFY(!ctor.construct(arg).isValid());
+ QTest::ignoreMessage(QtWarningMsg, "QScriptValue::construct() failed: cannot construct function with argument created in a different engine");
+ QVERIFY(!ctor.construct(QScriptValueList() << arg << otherEngine.newObject()).isValid());
}
void tst_QScriptValue::construct_constructorThrowsPrimitive()
@@ -2777,7 +3138,7 @@ void tst_QScriptValue::construct_constructorThrowsPrimitive()
}
}
-void tst_QScriptValue::lessThan_old()
+void tst_QScriptValue::lessThan()
{
QScriptEngine eng;
@@ -2871,7 +3232,7 @@ void tst_QScriptValue::lessThan_old()
QCOMPARE(date1.lessThan(QScriptValue(&otherEngine, 123)), false);
}
-void tst_QScriptValue::equals_old()
+void tst_QScriptValue::equals()
{
QScriptEngine eng;
@@ -3064,7 +3425,7 @@ void tst_QScriptValue::equals_old()
QCOMPARE(date1.equals(QScriptValue(&otherEngine, 123)), false);
}
-void tst_QScriptValue::strictlyEquals_old()
+void tst_QScriptValue::strictlyEquals()
{
QScriptEngine eng;
@@ -3599,4 +3960,30 @@ void tst_QScriptValue::nestedObjectToVariant()
QCOMPARE(o.toVariant(), expected);
}
+void tst_QScriptValue::propertyFlags_data()
+{
+ QTest::addColumn<QString>("program");
+ QTest::addColumn<uint>("expected");
+
+ QTest::newRow("nothing") << "" << 0u;
+ QTest::newRow("getter") << "o.__defineGetter__('prop', function() { return 'blah' } );\n" << uint(QScriptValue::PropertyGetter);
+ QTest::newRow("setter") << "o.__defineSetter__('prop', function(a) { this.setted_prop2 = a; } );\n" << uint(QScriptValue::PropertySetter);
+ QTest::newRow("getterSetter") << "o.__defineGetter__('prop', function() { return 'ploup' } );\n"
+ "o.__defineSetter__('prop', function(a) { this.setted_prop3 = a; } );\n" << uint(QScriptValue::PropertySetter|QScriptValue::PropertyGetter);
+ QTest::newRow("nothing2") << "o.prop = 'nothing'" << 0u;
+}
+
+void tst_QScriptValue::propertyFlags()
+{
+ QFETCH(QString, program);
+ QFETCH(uint, expected);
+ QScriptEngine eng;
+ eng.evaluate("o = new Object;");
+ eng.evaluate(program);
+ QScriptValue o = eng.evaluate("o");
+
+ QCOMPARE(uint(o.propertyFlags("prop")), expected);
+}
+
+
QTEST_MAIN(tst_QScriptValue)