diff options
Diffstat (limited to 'tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp')
-rw-r--r-- | tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp | 95 |
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" |