diff options
Diffstat (limited to 'tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp')
-rw-r--r-- | tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp index 068881affb..72179d243f 100644 --- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp +++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp @@ -46,6 +46,7 @@ #include <private/qv4runtime_p.h> #include <private/qv4object_p.h> #include <private/qqmlcomponentattached_p.h> +#include <private/qv4objectiterator_p.h> #ifdef Q_CC_MSVC #define NO_INLINE __declspec(noinline) @@ -260,6 +261,7 @@ private slots: void nonNotifyable(); void deleteWhileBindingRunning(); void callQtInvokables(); + void resolveClashingProperties(); void invokableObjectArg(); void invokableObjectRet(); void invokableEnumRet(); @@ -331,6 +333,9 @@ private slots: void qtbug_54589(); void qtbug_54687(); void stringify_qtbug_50592(); + void instanceof_data(); + void instanceof(); + void freeze_empty_object(); void singleBlockLoops(); private: @@ -2985,6 +2990,48 @@ void tst_qqmlecmascript::callQtInvokables() QVERIFY(callback.isCallable()); } +void tst_qqmlecmascript::resolveClashingProperties() +{ + ClashingNames *o = new ClashingNames(); + QQmlEngine qmlengine; + QQmlEnginePrivate *ep = QQmlEnginePrivate::get(&qmlengine); + + QV4::ExecutionEngine *engine = QV8Engine::getV4(ep->v8engine()); + QV4::Scope scope(engine); + + QV4::ScopedValue object(scope, QV4::QObjectWrapper::wrap(engine, o)); + QV4::ObjectIterator it(scope, object->as<QV4::Object>(), QV4::ObjectIterator::EnumerableOnly); + QV4::ScopedValue name(scope); + QV4::ScopedValue value(scope); + + bool seenProperty = false; + bool seenMethod = false; + while (true) { + QV4::Value v; + name = it.nextPropertyNameAsString(&v); + if (name->isNull()) + break; + QString key = name->toQStringNoThrow(); + if (key == QLatin1String("clashes")) { + value = v; + QV4::ScopedValue typeString(scope, QV4::Runtime::method_typeofValue(engine, value)); + QString type = typeString->toQStringNoThrow(); + if (type == QLatin1String("boolean")) { + QVERIFY(!seenProperty); + seenProperty = true; + } else if (type == QLatin1String("function")) { + QVERIFY(!seenMethod); + seenMethod = true; + } else { + QFAIL(qPrintable(QString::fromLatin1("found 'clashes' property of type %1") + .arg(type))); + } + } + } + QVERIFY(seenProperty); + QVERIFY(seenMethod); +} + // QTBUG-13047 (check that you can pass registered object types as args) void tst_qqmlecmascript::invokableObjectArg() { @@ -8120,6 +8167,80 @@ void tst_qqmlecmascript::stringify_qtbug_50592() QCOMPARE(obj->property("source").toString(), QString::fromLatin1("http://example.org/some_nonexistant_image.png")); } +void tst_qqmlecmascript::instanceof_data() +{ + QTest::addColumn<QString>("setupCode"); + QTest::addColumn<QVariant>("expectedValue"); + + // so the way this works is that the name of the test tag defines the test + // to run. the code in setupCode defines code run before the actual test + // (e.g. to create vars). + // + // the expectedValue is either a boolean true or false for whether the two + // operands are indeed an instanceof each other, or a string for the + // expected error message. + QTest::newRow("String instanceof String") + << "" + << QVariant(false); + QTest::newRow("s instanceof String") + << "var s = \"hello\"" + << QVariant(false); + QTest::newRow("objectString instanceof String") + << "var objectString = new String(\"hello\")" + << QVariant(true); + QTest::newRow("o instanceof Object") + << "var o = new Object()" + << QVariant(true); + QTest::newRow("o instanceof String") + << "var o = new Object()" + << QVariant(false); + QTest::newRow("true instanceof true") + << "" + << QVariant("TypeError: Type error"); + QTest::newRow("1 instanceof Math") + << "" + << QVariant("TypeError: Type error"); + QTest::newRow("date instanceof Date") + << "var date = new Date" + << QVariant(true); + QTest::newRow("date instanceof Object") + << "var date = new Date" + << QVariant(true); + QTest::newRow("date instanceof String") + << "var date = new Date" + << QVariant(false); +} + +void tst_qqmlecmascript::instanceof() +{ + QFETCH(QString, setupCode); + QFETCH(QVariant, expectedValue); + + QJSEngine engine; + QJSValue ret = engine.evaluate(setupCode + ";\n" + QTest::currentDataTag()); + + if (expectedValue.type() == QMetaType::Bool) { + bool returnValue = ret.toBool(); + QVERIFY2(!ret.isError(), qPrintable(ret.toString())); + QCOMPARE(returnValue, expectedValue.toBool()); + } else { + QVERIFY2(ret.isError(), qPrintable(ret.toString())); + QCOMPARE(ret.toString(), expectedValue.toString()); + } +} + +void tst_qqmlecmascript::freeze_empty_object() +{ + // this shouldn't crash + QJSEngine engine; + QJSValue v = engine.evaluate(QString::fromLatin1( + "var obj = {};\n" + "Object.freeze(obj);\n" + )); + QVERIFY(!v.isError()); + QCOMPARE(v.toBool(), true); +} + void tst_qqmlecmascript::singleBlockLoops() { QQmlComponent component(&engine, testFileUrl("qtbug_59012.qml")); |