aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2020-10-29 19:34:24 +0100
committerUlf Hermann <ulf.hermann@qt.io>2020-11-09 18:10:38 +0100
commitcbe1869fbe7048f34513b201a1d9111a0a64257a (patch)
tree5c36cdf60a064f661551c8cf6a11a9716db4aa3f /tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
parentd7008c79d4ec023527ebfc118ad47f40075f244d (diff)
QML: Rewrite Qt object in actual C++
Quite obviously, the Qt object is a singleton, extended with a namespace, backed by a member of the JavaScript global object. Defining all the methods as JavaScript functions is unnecessary and duplicates the general type transformation code. Also, it makes it hard to use those same methods from a C++ context as we cannot properly set up the arguments outside the JS engine. Rewriting the Qt object reveals some deficiencies in the old implementation that we need to fix now: 1. The enums of the Qt type were listed as properties of the Qt object, which means you could iterate them with a for..in loop in in JavaScript. This is just wrong. Enums are not properties. This functionality is deleted and the test adapted to check for each enum value separately. The commit message for the change that introduced the iterability already mentioned that the author had failed to find any occurrence of this in the real world. 2. Parsing time objects from strings was done by parsing the string as a date/time and then picking the time from that. We still support that for now, but output a (categorized) warning. Parsing the time directly is preferred where possible. 3. Previously you could create (invalid) dates and times from various kinds of QML types, like int and color. This does not work anymore as we now validate the types before calling the functions. 4. Passing more arguments to a function than the function accepted was unconditionally ignored before. Now, a Q_CLASSINFO on the surrounding class can specify that the arguments should be checked, in which case a JavaScript error is thrown if too many arguments are passed. In order for this to work correctly we also have to ignore JS undefined values as trailing arguments for overload resolution. This way, if a method matching the defined arguments exists, it will be preferred over a method that matches the full argument count, but possibly cannot accept undefined as parameter. Consequently a number of error messages change, which is reflected in the qqmlqt test. [ChangeLog][QtQMl][Important Behavior Changes] You can not iterate the enumerations of the Qt object in JavaScript anymore. This does not work with any other enumeration type either. You can of course still access them by name, for example as Qt.LeftButton or similar. [ChangeLog][QtQMl][Important Behavior Changes] The time formatting functions of the Qt object in QML now allow you to pass an actual time string, rather than a date/time string as argument. Passing a date/time string results in a warning now. [ChangeLog][QtQml][Important Behavior Changes] Functions in the Qt object for formatting date and time will now throw a JavaScript error when presented with a value of an incompatible type, such as int or color. [ChangeLog][QtQml][Important Behavior Changes] The Qt.resolvedUrl() function now returns a URL rather than a string. This follows the documentation. [ChangeLog][QtQml][Important Behavior Changes] The GlobalColor enum of the Qt namespace is not exposed to QML anymore. It did not make any sense before as the enum values could not be used as colors. Change-Id: I7fc2f24377eb2fde8f63a1ffac5548d652de7b12 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp')
-rw-r--r--tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp34
1 files changed, 16 insertions, 18 deletions
diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
index 985b8c7a98..03fc8e5ad4 100644
--- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
+++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
@@ -1782,15 +1782,15 @@ void tst_qqmlecmascript::componentCreation_data()
<< "null";
QTest::newRow("invalidSecondArg")
<< "invalidSecondArg"
- << ":40: Error: Qt.createComponent(): Invalid arguments"
+ << "" // We cannot catch this case as coercing a string to a number is valid in JavaScript
<< "";
QTest::newRow("invalidThirdArg")
<< "invalidThirdArg"
- << ":45: Error: Qt.createComponent(): Invalid parent object"
+ << ":45: TypeError: Passing incompatible arguments to C++ functions from JavaScript is not allowed."
<< "";
QTest::newRow("invalidMode")
<< "invalidMode"
- << ":50: Error: Qt.createComponent(): Invalid arguments"
+ << ":50: Error: Invalid compilation mode -666"
<< "";
}
@@ -3448,6 +3448,9 @@ void tst_qqmlecmascript::scriptConnect()
QVERIFY(object != nullptr);
QCOMPARE(object->methodCalled(), false);
+
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression("When matching arguments for MyQmlObject_QML_[0-9]+::methodNoArgs\\(\\):"));
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression("Too many arguments, ignoring 5"));
emit object->argumentSignal(19, "Hello world!", 10.25, MyQmlObject::EnumValue4, Qt::RightButton);
QCOMPARE(object->methodCalled(), true);
@@ -3461,6 +3464,8 @@ void tst_qqmlecmascript::scriptConnect()
QVERIFY(object != nullptr);
QCOMPARE(object->methodCalled(), false);
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression("When matching arguments for MyQmlObject_QML_[0-9]+::methodNoArgs\\(\\):"));
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression("Too many arguments, ignoring 5"));
emit object->argumentSignal(19, "Hello world!", 10.25, MyQmlObject::EnumValue4, Qt::RightButton);
QCOMPARE(object->methodCalled(), true);
@@ -6365,7 +6370,7 @@ void tst_qqmlecmascript::include()
// Non-library relative include
{
QQmlComponent component(&engine, testFileUrl("include.qml"));
- QObject *o = component.create();
+ QScopedPointer<QObject> o(component.create());
QVERIFY(o != nullptr);
QCOMPARE(o->property("test0").toInt(), 99);
@@ -6375,13 +6380,12 @@ void tst_qqmlecmascript::include()
QCOMPARE(o->property("test3").toBool(), true);
QCOMPARE(o->property("test3_1").toBool(), true);
- delete o;
}
// Library relative include
{
QQmlComponent component(&engine, testFileUrl("include_shared.qml"));
- QObject *o = component.create();
+ QScopedPointer<QObject> o(component.create());
QVERIFY(o != nullptr);
QCOMPARE(o->property("test0").toInt(), 99);
@@ -6391,13 +6395,12 @@ void tst_qqmlecmascript::include()
QCOMPARE(o->property("test3").toBool(), true);
QCOMPARE(o->property("test3_1").toBool(), true);
- delete o;
}
// Callback
{
QQmlComponent component(&engine, testFileUrl("include_callback.qml"));
- QObject *o = component.create();
+ QScopedPointer<QObject> o(component.create());
QVERIFY(o != nullptr);
QCOMPARE(o->property("test1").toBool(), true);
@@ -6407,17 +6410,15 @@ void tst_qqmlecmascript::include()
QCOMPARE(o->property("test5").toBool(), true);
QCOMPARE(o->property("test6").toBool(), true);
- delete o;
}
// Including file with ".pragma library"
{
QQmlComponent component(&engine, testFileUrl("include_pragma.qml"));
- QObject *o = component.create();
+ QScopedPointer<QObject> o(component.create());
QVERIFY(o != nullptr);
QCOMPARE(o->property("test1").toInt(), 100);
- delete o;
}
// Including file with ".pragma library", shadowing a global var
@@ -6435,7 +6436,7 @@ void tst_qqmlecmascript::include()
server.serveDirectory(dataDirectory());
QQmlComponent component(&engine, testFileUrl("include_remote_missing.qml"));
- QObject *o = component.beginCreate(engine.rootContext());
+ QScopedPointer<QObject> o(component.beginCreate(engine.rootContext()));
QVERIFY(o != nullptr);
o->setProperty("serverBaseUrl", server.baseUrl().toString());
component.completeCreate();
@@ -6446,13 +6447,12 @@ void tst_qqmlecmascript::include()
QCOMPARE(o->property("test2").toBool(), true);
QCOMPARE(o->property("test3").toBool(), true);
- delete o;
}
// include from resources
{
QQmlComponent component(&engine, QUrl("qrc:///data/include.qml"));
- QObject *o = component.create();
+ QScopedPointer<QObject> o(component.create());
QVERIFY(o != nullptr);
QCOMPARE(o->property("test0").toInt(), 99);
@@ -6462,7 +6462,6 @@ void tst_qqmlecmascript::include()
QCOMPARE(o->property("test3").toBool(), true);
QCOMPARE(o->property("test3_1").toBool(), true);
- delete o;
}
}
@@ -7495,14 +7494,13 @@ void tst_qqmlecmascript::registeredFlagMethod()
{
QQmlEngine engine;
QQmlComponent component(&engine, testFileUrl("registeredFlagMethod.qml"));
- MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
+ QScopedPointer<QObject> o(component.create());
+ MyQmlObject *object = qobject_cast<MyQmlObject *>(o.data());
QVERIFY(object != nullptr);
QCOMPARE(object->buttons(), 0);
emit object->basicSignal();
QCOMPARE(object->buttons(), Qt::RightButton);
-
- delete object;
}
// QTBUG-23138