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.cpp95
1 files changed, 95 insertions, 0 deletions
diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
index 2d38bf0524..f47c7132a2 100644
--- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
+++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
@@ -428,6 +428,9 @@ private slots:
void functionAsDefaultArgument();
void internalClassParentGc();
+ void methodTypeMismatch();
+
+ void doNotCrashOnReadOnlyBindable();
private:
// static void propertyVarWeakRefCallback(v8::Persistent<v8::Value> object, void* parameter);
@@ -3331,6 +3334,19 @@ void tst_qqmlecmascript::callQtInvokables()
QJSValue callback = qvariant_cast<QJSValue>(o->actuals().at(1));
QVERIFY(!callback.isNull());
QVERIFY(callback.isCallable());
+
+ o->reset();
+ QVERIFY(EVALUATE_VALUE("object.method_gadget(object.someFont)",
+ QV4::Primitive::undefinedValue()));
+ QCOMPARE(o->error(), false);
+ QCOMPARE(o->invoked(), 40);
+ QCOMPARE(o->actuals(), QVariantList() << QVariant(o->someFont()));
+
+ o->reset();
+ QVERIFY(EVALUATE_ERROR("object.method_gadget(123)"));
+ QCOMPARE(o->error(), false);
+ QCOMPARE(o->invoked(), -1);
+ QCOMPARE(o->actuals(), QVariantList());
}
void tst_qqmlecmascript::resolveClashingProperties()
@@ -9978,6 +9994,85 @@ void tst_qqmlecmascript::internalClassParentGc()
QCOMPARE(root->objectName(), "3");
}
+void tst_qqmlecmascript::methodTypeMismatch()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine, testFileUrl("methodTypeMismatch.qml"));
+
+ QScopedPointer<MyInvokableObject> object(new MyInvokableObject());
+
+ QScopedPointer<QObject> o(component.create());
+ QVERIFY2(o, qPrintable(component.errorString()));
+ o->setProperty("object", QVariant::fromValue(object.get()));
+
+ auto mo = o->metaObject();
+ QVERIFY(mo);
+
+ auto method = mo->method(mo->indexOfMethod("callWithFont()"));
+ QVERIFY(method.isValid());
+ QVERIFY(method.invoke(o.get()));
+ QCOMPARE(object->actuals(), QVariantList() << QVariant(object->someFont()));
+
+ QRegularExpression argumentConversionErrorMatcher("Could not convert argument 0");
+ QRegularExpression argumentConversionErrorMatcher2(".*/methodTypeMismatch.qml");
+ QRegularExpression typeErrorMatcher(
+ ".*/methodTypeMismatch\\.qml:..: TypeError: Passing incompatible arguments to C\\+\\+ "
+ "functions from JavaScript is not allowed.");
+
+ QTest::ignoreMessage(QtWarningMsg, argumentConversionErrorMatcher);
+ QTest::ignoreMessage(QtWarningMsg, argumentConversionErrorMatcher2);
+ QTest::ignoreMessage(QtWarningMsg, typeErrorMatcher);
+ object->reset();
+ method = mo->method(mo->indexOfMethod("callWithInt()"));
+ QVERIFY(method.isValid());
+ QVERIFY(method.invoke(o.get()));
+ QCOMPARE(object->actuals().size(),
+ 0); // actuals() should not contain reinterpret_cast<QFont>(123) !!!
+
+ QTest::ignoreMessage(QtWarningMsg, argumentConversionErrorMatcher);
+ QTest::ignoreMessage(QtWarningMsg, argumentConversionErrorMatcher2);
+ QTest::ignoreMessage(QtWarningMsg, typeErrorMatcher);
+ object->reset();
+ method = mo->method(mo->indexOfMethod("callWithInt2()"));
+ QVERIFY(method.isValid());
+ QVERIFY(method.invoke(o.get()));
+ QCOMPARE(object->actuals().size(),
+ 0); // actuals() should not contain reinterpret_cast<QFont>(0) !!!
+
+ QTest::ignoreMessage(QtWarningMsg, argumentConversionErrorMatcher);
+ QTest::ignoreMessage(QtWarningMsg, argumentConversionErrorMatcher2);
+ QTest::ignoreMessage(QtWarningMsg, typeErrorMatcher);
+ object->reset();
+ method = mo->method(mo->indexOfMethod("callWithNull()"));
+ QVERIFY(method.isValid());
+ QVERIFY(method.invoke(o.get()));
+ QCOMPARE(object->actuals().size(),
+ 0); // actuals() should not contain reinterpret_cast<QFont>(nullptr) !!!
+
+ // make sure that null is still accepted by functions accepting, e.g., a QObject*!
+ object->reset();
+ method = mo->method(mo->indexOfMethod("callWithAllowedNull()"));
+ QVERIFY(method.isValid());
+ QVERIFY(method.invoke(o.get()));
+ QCOMPARE(object->actuals(), QVariantList() << QVariant::fromValue((QObject *)nullptr));
+}
+
+void tst_qqmlecmascript::doNotCrashOnReadOnlyBindable()
+{
+ QQmlEngine engine;
+ QQmlComponent c(&engine, testFileUrl("readOnlyBindable.qml"));
+ QVERIFY2(c.isReady(), qPrintable(c.errorString()));
+#ifndef QT_NO_DEBUG
+ QTest::ignoreMessage(
+ QtWarningMsg,
+ "setBinding: Could not set binding via bindable interface. "
+ "The QBindable is read-only.");
+#endif
+ QScopedPointer<QObject> o(c.create());
+ QVERIFY(o);
+ QCOMPARE(o->property("x").toInt(), 7);
+}
+
QTEST_MAIN(tst_qqmlecmascript)
#include "tst_qqmlecmascript.moc"