aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp')
-rw-r--r--tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp121
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"));