aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/qml
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
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')
-rw-r--r--tests/auto/qml/qqmlecmascript/data/registeredFlagMethod.qml1
-rw-r--r--tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp34
-rw-r--r--tests/auto/qml/qqmlqt/data/qtObjectContents.qml10
-rw-r--r--tests/auto/qml/qqmlqt/data/resolvedUrl.qml2
-rw-r--r--tests/auto/qml/qqmlqt/tst_qqmlqt.cpp310
5 files changed, 201 insertions, 156 deletions
diff --git a/tests/auto/qml/qqmlecmascript/data/registeredFlagMethod.qml b/tests/auto/qml/qqmlecmascript/data/registeredFlagMethod.qml
index b323b49662..33b94d753c 100644
--- a/tests/auto/qml/qqmlecmascript/data/registeredFlagMethod.qml
+++ b/tests/auto/qml/qqmlecmascript/data/registeredFlagMethod.qml
@@ -1,3 +1,4 @@
+import QtQml
import Qt.test 1.0
MyQmlObject {
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
diff --git a/tests/auto/qml/qqmlqt/data/qtObjectContents.qml b/tests/auto/qml/qqmlqt/data/qtObjectContents.qml
deleted file mode 100644
index c85e7986e9..0000000000
--- a/tests/auto/qml/qqmlqt/data/qtObjectContents.qml
+++ /dev/null
@@ -1,10 +0,0 @@
-import QtQuick 2.0
-
-QtObject {
- property var values: Object()
- Component.onCompleted: {
- for (var key in Qt) {
- values[key] = Qt[key]
- }
- }
-}
diff --git a/tests/auto/qml/qqmlqt/data/resolvedUrl.qml b/tests/auto/qml/qqmlqt/data/resolvedUrl.qml
index 06ef48b82b..aa57c73627 100644
--- a/tests/auto/qml/qqmlqt/data/resolvedUrl.qml
+++ b/tests/auto/qml/qqmlqt/data/resolvedUrl.qml
@@ -3,11 +3,13 @@ import QtQuick 2.0
QtObject {
property string result
property bool isString: false
+ property bool isObject: false
Component.onCompleted: {
var a = Qt.resolvedUrl("resolvedUrl.qml");
result = a;
isString = (typeof a) == "string"
+ isObject = (typeof a) == "object"
}
}
diff --git a/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp b/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp
index a6d8a52e0e..9406ba5d6a 100644
--- a/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp
+++ b/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp
@@ -180,9 +180,9 @@ void tst_qqmlqt::rgba()
{
QQmlComponent component(&engine, testFileUrl("rgba.qml"));
- QString warning1 = component.url().toString() + ":6: Error: Qt.rgba(): Invalid arguments";
- QString warning2 = component.url().toString() + ":7: Error: Qt.rgba(): Invalid arguments";
- QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
+ QString warning1 = "rgba.qml:6: Error: Unable to determine callable overload";
+ QString warning2 = component.url().toString() + ":7: Error: Too many arguments";
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression(warning1));
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2));
QScopedPointer<QObject> object(component.create());
@@ -201,9 +201,9 @@ void tst_qqmlqt::hsla()
{
QQmlComponent component(&engine, testFileUrl("hsla.qml"));
- QString warning1 = component.url().toString() + ":6: Error: Qt.hsla(): Invalid arguments";
- QString warning2 = component.url().toString() + ":7: Error: Qt.hsla(): Invalid arguments";
- QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
+ QString warning1 = "hsla.qml:6: Error: Unable to determine callable overload";
+ QString warning2 = component.url().toString() + ":7: Error: Too many arguments";
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression(warning1));
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2));
QScopedPointer<QObject> object(component.create());
@@ -221,9 +221,9 @@ void tst_qqmlqt::hsva()
{
QQmlComponent component(&engine, testFileUrl("hsva.qml"));
- QString warning1 = component.url().toString() + ":6: Error: Qt.hsva(): Invalid arguments";
- QString warning2 = component.url().toString() + ":7: Error: Qt.hsva(): Invalid arguments";
- QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
+ QString warning1 = "hsva.qml:6: Error: Unable to determine callable overload";
+ QString warning2 = component.url().toString() + ":7: Error: Too many arguments";
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression(warning1));
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2));
QScopedPointer<QObject> object(component.create());
@@ -241,8 +241,8 @@ void tst_qqmlqt::colorEqual()
{
QQmlComponent component(&engine, testFileUrl("colorEqual.qml"));
- QTest::ignoreMessage(QtWarningMsg, qPrintable(component.url().toString() + ":6: Error: Qt.colorEqual(): Invalid arguments"));
- QTest::ignoreMessage(QtWarningMsg, qPrintable(component.url().toString() + ":7: Error: Qt.colorEqual(): Invalid arguments"));
+ QTest::ignoreMessage(QtWarningMsg, qPrintable(component.url().toString() + ":6: Error: Insufficient arguments"));
+ QTest::ignoreMessage(QtWarningMsg, qPrintable(component.url().toString() + ":7: Error: Insufficient arguments"));
QTest::ignoreMessage(QtWarningMsg, qPrintable(component.url().toString() + ":9: Error: Qt.colorEqual(): Invalid color name"));
QTest::ignoreMessage(QtWarningMsg, qPrintable(component.url().toString() + ":10: Error: Qt.colorEqual(): Invalid color name"));
QTest::ignoreMessage(QtWarningMsg, qPrintable(component.url().toString() + ":12: Error: Qt.colorEqual(): Invalid arguments"));
@@ -322,8 +322,8 @@ void tst_qqmlqt::rect()
{
QQmlComponent component(&engine, testFileUrl("rect.qml"));
- QString warning1 = component.url().toString() + ":6: Error: Qt.rect(): Invalid arguments";
- QString warning2 = component.url().toString() + ":7: Error: Qt.rect(): Invalid arguments";
+ QString warning1 = component.url().toString() + ":6: Error: Insufficient arguments";
+ QString warning2 = component.url().toString() + ":7: Error: Too many arguments";
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2));
@@ -341,8 +341,8 @@ void tst_qqmlqt::point()
{
QQmlComponent component(&engine, testFileUrl("point.qml"));
- QString warning1 = component.url().toString() + ":6: Error: Qt.point(): Invalid arguments";
- QString warning2 = component.url().toString() + ":7: Error: Qt.point(): Invalid arguments";
+ QString warning1 = component.url().toString() + ":6: Error: Insufficient arguments";
+ QString warning2 = component.url().toString() + ":7: Error: Too many arguments";
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2));
@@ -359,8 +359,8 @@ void tst_qqmlqt::size()
{
QQmlComponent component(&engine, testFileUrl("size.qml"));
- QString warning1 = component.url().toString() + ":7: Error: Qt.size(): Invalid arguments";
- QString warning2 = component.url().toString() + ":8: Error: Qt.size(): Invalid arguments";
+ QString warning1 = component.url().toString() + ":7: Error: Insufficient arguments";
+ QString warning2 = component.url().toString() + ":8: Error: Too many arguments";
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2));
@@ -378,8 +378,8 @@ void tst_qqmlqt::vector2d()
{
QQmlComponent component(&engine, testFileUrl("vector2.qml"));
- QString warning1 = component.url().toString() + ":6: Error: Qt.vector2d(): Invalid arguments";
- QString warning2 = component.url().toString() + ":7: Error: Qt.vector2d(): Invalid arguments";
+ QString warning1 = component.url().toString() + ":6: Error: Insufficient arguments";
+ QString warning2 = component.url().toString() + ":7: Error: Too many arguments";
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2));
@@ -396,8 +396,8 @@ void tst_qqmlqt::vector3d()
{
QQmlComponent component(&engine, testFileUrl("vector.qml"));
- QString warning1 = component.url().toString() + ":6: Error: Qt.vector3d(): Invalid arguments";
- QString warning2 = component.url().toString() + ":7: Error: Qt.vector3d(): Invalid arguments";
+ QString warning1 = component.url().toString() + ":6: Error: Insufficient arguments";
+ QString warning2 = component.url().toString() + ":7: Error: Too many arguments";
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2));
@@ -414,8 +414,8 @@ void tst_qqmlqt::vector4d()
{
QQmlComponent component(&engine, testFileUrl("vector4.qml"));
- QString warning1 = component.url().toString() + ":6: Error: Qt.vector4d(): Invalid arguments";
- QString warning2 = component.url().toString() + ":7: Error: Qt.vector4d(): Invalid arguments";
+ QString warning1 = component.url().toString() + ":6: Error: Insufficient arguments";
+ QString warning2 = component.url().toString() + ":7: Error: Too many arguments";
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2));
@@ -432,8 +432,8 @@ void tst_qqmlqt::quaternion()
{
QQmlComponent component(&engine, testFileUrl("quaternion.qml"));
- QString warning1 = component.url().toString() + ":6: Error: Qt.quaternion(): Invalid arguments";
- QString warning2 = component.url().toString() + ":7: Error: Qt.quaternion(): Invalid arguments";
+ QString warning1 = component.url().toString() + ":6: Error: Insufficient arguments";
+ QString warning2 = component.url().toString() + ":7: Error: Too many arguments";
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2));
@@ -450,7 +450,7 @@ void tst_qqmlqt::matrix4x4()
{
QQmlComponent component(&engine, testFileUrl("matrix4x4.qml"));
- QString warning1 = component.url().toString() + ":6: Error: Qt.matrix4x4(): Invalid arguments";
+ QString warning1 = component.url().toString() + ":6: Error: Too many arguments";
QString warning2 = component.url().toString() + ":7: Error: Qt.matrix4x4(): Invalid argument: not a valid matrix4x4 values array";
QString warning3 = component.url().toString() + ":8: Error: Qt.matrix4x4(): Invalid argument: not a valid matrix4x4 values array";
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
@@ -471,7 +471,7 @@ void tst_qqmlqt::font()
{
QQmlComponent component(&engine, testFileUrl("font.qml"));
- QString warning1 = component.url().toString() + ":6: Error: Qt.font(): Invalid arguments";
+ QString warning1 = component.url().toString() + ":6: Error: Too many arguments";
QString warning2 = component.url().toString() + ":7: Error: Qt.font(): Invalid argument: no valid font subproperties specified";
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2));
@@ -495,9 +495,9 @@ void tst_qqmlqt::lighter()
{
QQmlComponent component(&engine, testFileUrl("lighter.qml"));
- QString warning1 = component.url().toString() + ":5: Error: Qt.lighter(): Invalid arguments";
- QString warning2 = component.url().toString() + ":10: Error: Qt.lighter(): Invalid arguments";
- QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
+ QString warning1 = "lighter.qml:5: Error: Unable to determine callable overload";
+ QString warning2 = component.url().toString() + ":10: Error: Too many arguments";
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression(warning1));
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2));
QScopedPointer<QObject> object(component.create());
@@ -520,9 +520,9 @@ void tst_qqmlqt::darker()
{
QQmlComponent component(&engine, testFileUrl("darker.qml"));
- QString warning1 = component.url().toString() + ":5: Error: Qt.darker(): Invalid arguments";
- QString warning2 = component.url().toString() + ":10: Error: Qt.darker(): Invalid arguments";
- QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
+ QString warning1 = "darker.qml:5: Error: Unable to determine callable overload";
+ QString warning2 = component.url().toString() + ":10: Error: Too many arguments";
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression(warning1));
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2));
QScopedPointer<QObject> object(component.create());
@@ -545,8 +545,8 @@ void tst_qqmlqt::alpha()
{
QQmlComponent component(&engine, testFileUrl("alpha.qml"));
- QString warning1 = component.url().toString() + ":5: Error: Qt.alpha(): Wrong number of arguments provided";
- QString warning2 = component.url().toString() + ":10: Error: Qt.alpha(): Wrong number of arguments provided";
+ QString warning1 = component.url().toString() + ":5: Error: Insufficient arguments";
+ QString warning2 = component.url().toString() + ":10: Error: Too many arguments";
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2));
@@ -576,8 +576,8 @@ void tst_qqmlqt::tint()
{
QQmlComponent component(&engine, testFileUrl("tint.qml"));
- QString warning1 = component.url().toString() + ":7: Error: Qt.tint(): Invalid arguments";
- QString warning2 = component.url().toString() + ":8: Error: Qt.tint(): Invalid arguments";
+ QString warning1 = component.url().toString() + ":7: Error: Too many arguments";
+ QString warning2 = component.url().toString() + ":8: Error: Insufficient arguments";
QString warning3 = component.url().toString() + ":13: Error: Insufficient arguments";
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
@@ -604,9 +604,10 @@ void tst_qqmlqt::color()
{
QQmlComponent component(&engine, testFileUrl("color.qml"));
- QStringList warnings = { ":7: Error: Qt.color(): Argument must be a string",
- ":8: Error: Qt.color(): Qt.color takes exactly one argument",
- ":9: Error: Qt.color(): Qt.color takes exactly one argument" };
+ QStringList warnings = { ":6: Error: \"taint\" is not a valid color name",
+ ":7: Error: \"0.5\" is not a valid color name",
+ ":8: Error: Insufficient arguments",
+ ":9: Error: Too many arguments" };
for (const QString &warning : warnings)
QTest::ignoreMessage(QtWarningMsg, qPrintable(component.url().toString() + warning));
@@ -682,7 +683,7 @@ void tst_qqmlqt::md5()
{
QQmlComponent component(&engine, testFileUrl("md5.qml"));
- QString warning1 = component.url().toString() + ":4: Error: Qt.md5(): Invalid arguments";
+ QString warning1 = component.url().toString() + ":4: Error: Insufficient arguments";
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
QScopedPointer<QObject> object(component.create());
@@ -696,9 +697,9 @@ void tst_qqmlqt::createComponent()
{
QQmlComponent component(&engine, testFileUrl("createComponent.qml"));
- QString warning1 = component.url().toString() + ":9: Error: Qt.createComponent(): Invalid arguments";
- QString warning2 = component.url().toString() + ":10: Error: Qt.createComponent(): Invalid arguments";
- QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
+ QString warning1 = "createComponent.qml:9: Error: Unable to determine callable overload";
+ QString warning2 = component.url().toString() + ":10: Error: Invalid compilation mode 10";
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression(warning1));
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2));
QScopedPointer<QObject> object(component.create());
@@ -733,18 +734,22 @@ void tst_qqmlqt::createQmlObject()
{
QQmlComponent component(&engine, testFileUrl("createQmlObject.qml"));
- QString warning1 = component.url().toString() + ":7: Error: Qt.createQmlObject(): Invalid arguments";
+ QString warning1 = "createQmlObject.qml:7: Error: Unable to determine callable overload";
QString warning2 = component.url().toString()+ ":10: Error: Qt.createQmlObject(): failed to create object: \n " + testFileUrl("inline").toString() + ":2:10: Blah is not a type";
QString warning3 = component.url().toString()+ ":11: Error: Qt.createQmlObject(): failed to create object: \n " + testFileUrl("main.qml").toString() + ":4:14: Duplicate property name";
- QString warning4 = component.url().toString()+ ":9: Error: Qt.createQmlObject(): Missing parent object";
- QString warning5 = component.url().toString()+ ":8: Error: Qt.createQmlObject(): Invalid arguments";
+ QString warning4 = component.url().toString()+ ":9: TypeError: Passing incompatible arguments to C++ functions from JavaScript is not allowed.";
+ QString warning5 = component.url().toString()+ ":8: Error: Too many arguments";
QString warning6 = "RunTimeError: Qt.createQmlObject(): failed to create object: \n " + testFileUrl("inline").toString() + ":3:16: Cannot assign object type QObject with no default method";
- QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
+ QString warning7 = "Could not convert argument 1 at";
+ QString warning8 = "expression for noParent@";
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression(warning1));
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2));
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning3));
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning4));
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning5));
QTest::ignoreMessage(QtDebugMsg, qPrintable(warning6));
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression(warning7));
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression(warning8));
QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
@@ -808,28 +813,41 @@ void tst_qqmlqt::dateTimeFormatting()
QQmlComponent component(&eng, testFileUrl("formatting.qml"));
QStringList warnings;
- warnings << component.url().toString() + ":37: Error: Qt.formatDate(): Bad second argument (must be either string, number or locale)"
- << component.url().toString() + ":36: Error: Qt.formatDate(): Missing argument"
- << component.url().toString() + ":40: Error: Qt.formatTime(): Bad second argument (must be either string, number or locale)"
- << component.url().toString() + ":39: Error: Qt.formatTime(): Missing argument"
- << component.url().toString() + ":43: Error: Qt.formatDateTime(): Bad second argument (must be either string, number or locale)"
- << component.url().toString() + ":42: Error: Qt.formatDateTime(): Missing argument";
+ warnings
+ << component.url().toString() + ":37: TypeError: Passing incompatible arguments to C++ functions from JavaScript is not allowed."
+ << component.url().toString() + ":40: TypeError: Passing incompatible arguments to C++ functions from JavaScript is not allowed."
+ << component.url().toString() + ":43: TypeError: Passing incompatible arguments to C++ functions from JavaScript is not allowed.";
foreach (const QString &warning, warnings)
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
- QObject *object = component.createWithInitialProperties({
+ warnings.clear();
+ warnings
+ << "formatting.qml:36: Error: Unable to determine callable overload"
+ << "formatting.qml:39: Error: Unable to determine callable overload"
+ << "formatting.qml:42: Error: Unable to determine callable overload"
+ << "Could not convert argument 1 at"
+ << "expression for err_date2@"
+ << "Could not convert argument 1 at"
+ << "expression for err_time2@"
+ << "Could not convert argument 1 at"
+ << "expression for err_dateTime2@";
+
+ foreach (const QString &warning, warnings)
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression(warning));
+
+ QScopedPointer<QObject> object(component.createWithInitialProperties({
{"qdate", date},
{"qtime", time},
{"qdatetime", dateTime}
- });
+ }));
QVERIFY2(component.errorString().isEmpty(), qPrintable(component.errorString()));
QVERIFY(object != nullptr);
QVERIFY(inputProperties.count() > 0);
QVariant result;
foreach(const QString &prop, inputProperties) {
- QVERIFY(QMetaObject::invokeMethod(object, method.toUtf8().constData(),
+ QVERIFY(QMetaObject::invokeMethod(object.data(), method.toUtf8().constData(),
Q_RETURN_ARG(QVariant, result),
Q_ARG(QVariant, prop)));
QStringList output = result.toStringList();
@@ -837,8 +855,6 @@ void tst_qqmlqt::dateTimeFormatting()
for (int i=0; i<output.count(); i++)
QCOMPARE(output[i], expectedResults[i]);
}
-
- delete object;
}
void tst_qqmlqt::dateTimeFormatting_data()
@@ -884,28 +900,63 @@ void tst_qqmlqt::dateTimeFormattingVariants()
QQmlComponent component(&eng, testFileUrl("formatting.qml"));
QStringList warnings;
- warnings << component.url().toString() + ":37: Error: Qt.formatDate(): Bad second argument (must be either string, number or locale)"
- << component.url().toString() + ":36: Error: Qt.formatDate(): Missing argument"
- << component.url().toString() + ":40: Error: Qt.formatTime(): Bad second argument (must be either string, number or locale)"
- << component.url().toString() + ":39: Error: Qt.formatTime(): Missing argument"
- << component.url().toString() + ":43: Error: Qt.formatDateTime(): Bad second argument (must be either string, number or locale)"
- << component.url().toString() + ":42: Error: Qt.formatDateTime(): Missing argument";
+ warnings << component.url().toString() + ":37: TypeError: Passing incompatible arguments to C++ functions from JavaScript is not allowed."
+ << component.url().toString() + ":40: TypeError: Passing incompatible arguments to C++ functions from JavaScript is not allowed."
+ << component.url().toString() + ":43: TypeError: Passing incompatible arguments to C++ functions from JavaScript is not allowed.";
- foreach (const QString &warning, warnings)
+ for (const QString &warning : qAsConst(warnings))
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
- QObject *object = component.createWithInitialProperties({{"qvariant", variant}});
+ warnings.clear();
+ warnings << "formatting.qml:36: Error: Unable to determine callable overload."
+ << "formatting.qml:39: Error: Unable to determine callable overload."
+ << "formatting.qml:42: Error: Unable to determine callable overload."
+ << "Could not convert argument 1 at"
+ << "expression for err_date2@"
+ << "Could not convert argument 1 at"
+ << "expression for err_time2@"
+ << "Could not convert argument 1 at"
+ << "expression for err_dateTime2@";
+
+ for (const QString &warning : qAsConst(warnings))
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression(warning));
+
+ warnings.clear();
+ if (method == QStringLiteral("formatTime") && variant.typeId() == QMetaType::QString) {
+ for (int i = 0; i < 4; ++i) {
+ QTest::ignoreMessage(QtWarningMsg,
+ "\"2011/05/31 11:16:39.755\" is a "
+ "date/time string being passed to formatTime(). You should only "
+ "pass time strings to formatTime().");
+ }
+ }
+
+ if (variant.typeId() == QMetaType::QColor || variant.typeId() == QMetaType::Int) {
+ if (method == "formatTime") {
+ // formatTime has special error handling as it parses the strings itself.
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression(
+ "formatting.qml:18: Error: Invalid argument passed to "
+ "formatTime"));
+ } else {
+ QTest::ignoreMessage(QtWarningMsg,
+ QRegularExpression("Could not convert argument 0 at"));
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression(method + "@"));
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression(
+ "TypeError: Passing incompatible arguments to "
+ "C.. functions from JavaScript is not allowed."));
+ }
+ }
+
+ QScopedPointer<QObject> object(component.createWithInitialProperties({{"qvariant", variant}}));
QVERIFY2(component.errorString().isEmpty(), qPrintable(component.errorString()));
QVERIFY(object != nullptr);
QVariant result;
- QVERIFY(QMetaObject::invokeMethod(object, method.toUtf8().constData(),
+ QVERIFY(QMetaObject::invokeMethod(object.data(), method.toUtf8().constData(),
Q_RETURN_ARG(QVariant, result),
Q_ARG(QVariant, QString(QLatin1String("qvariant")))));
QStringList output = result.toStringList();
QCOMPARE(output, expectedResults);
-
- delete object;
}
void tst_qqmlqt::dateTimeFormattingVariants_data()
@@ -997,45 +1048,25 @@ void tst_qqmlqt::dateTimeFormattingVariants_data()
temporary = QVariant::fromValue(color).toDateTime();
QTest::newRow("formatDate, qcolor")
<< "formatDate" << QVariant::fromValue(color)
- << (QStringList()
- << QLocale().toString(temporary.date(), QLocale::ShortFormat)
- << QLocale().toString(temporary.date(), QLocale::LongFormat)
- << temporary.date().toString("ddd MMMM d yy"));
+ << QStringList();
QTest::newRow("formatDateTime, qcolor")
<< "formatDateTime" << QVariant::fromValue(color)
- << (QStringList()
- << QLocale().toString(temporary, QLocale::ShortFormat)
- << QLocale().toString(temporary, QLocale::LongFormat)
- << temporary.toString("M/d/yy H:m:s a"));
+ << QStringList();
QTest::newRow("formatTime, qcolor")
<< "formatTime" << QVariant::fromValue(color)
- << (QStringList()
- << QLocale().toString(temporary.time(), QLocale::ShortFormat)
- << QLocale().toString(temporary.time(), QLocale::LongFormat)
- << temporary.time().toString("H:m:s a")
- << temporary.time().toString("hh:mm:ss.zzz"));
+ << QStringList();
int integer(4);
temporary = QVariant::fromValue(integer).toDateTime();
QTest::newRow("formatDate, int")
<< "formatDate" << QVariant::fromValue(integer)
- << (QStringList()
- << QLocale().toString(temporary.date(), QLocale::ShortFormat)
- << QLocale().toString(temporary.date(), QLocale::LongFormat)
- << temporary.date().toString("ddd MMMM d yy"));
+ << QStringList();
QTest::newRow("formatDateTime, int")
<< "formatDateTime" << QVariant::fromValue(integer)
- << (QStringList()
- << QLocale().toString(temporary, QLocale::ShortFormat)
- << QLocale().toString(temporary, QLocale::LongFormat)
- << temporary.toString("M/d/yy H:m:s a"));
+ << QStringList();
QTest::newRow("formatTime, int")
<< "formatTime" << QVariant::fromValue(integer)
- << (QStringList()
- << QLocale().toString(temporary.time(), QLocale::ShortFormat)
- << QLocale().toString(temporary.time(), QLocale::LongFormat)
- << temporary.time().toString("H:m:s a")
- << temporary.time().toString("hh:mm:ss.zzz"));
+ << QStringList();
}
void tst_qqmlqt::dateTimeFormattingWithLocale()
@@ -1054,8 +1085,13 @@ void tst_qqmlqt::dateTimeFormattingWithLocale()
auto dateString = o->property("dateString").toString();
QCOMPARE(dateString, QLocale("de_DE").toString(date, QLocale::ShortFormat));
- QString warningMsg = url.toString() + QLatin1String(":11: Error: Qt.formatTime(): Third argument must be a Locale format option");
- QTest::ignoreMessage(QtMsgType::QtWarningMsg, warningMsg.toUtf8().constData());
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression("Could not convert argument 1 at"));
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression("invalidUsage@"));
+ QTest::ignoreMessage(
+ QtWarningMsg,
+ qPrintable(url.toString() + QStringLiteral(":11: TypeError: Passing incompatible "
+ "arguments to C++ functions from "
+ "JavaScript is not allowed.")));
QMetaObject::invokeMethod(o.get(), "invalidUsage");
}
@@ -1076,7 +1112,7 @@ void tst_qqmlqt::btoa()
{
QQmlComponent component(&engine, testFileUrl("btoa.qml"));
- QString warning1 = component.url().toString() + ":4: Error: Qt.btoa(): Invalid arguments";
+ QString warning1 = component.url().toString() + ":4: Error: Insufficient arguments";
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
QScopedPointer<QObject> object(component.create());
@@ -1089,7 +1125,7 @@ void tst_qqmlqt::atob()
{
QQmlComponent component(&engine, testFileUrl("atob.qml"));
- QString warning1 = component.url().toString() + ":4: Error: Qt.atob(): Invalid arguments";
+ QString warning1 = component.url().toString() + ":4: Error: Insufficient arguments";
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
QScopedPointer<QObject> object(component.create());
@@ -1102,7 +1138,7 @@ void tst_qqmlqt::fontFamilies()
{
QQmlComponent component(&engine, testFileUrl("fontFamilies.qml"));
- QString warning1 = component.url().toString() + ":4: Error: Qt.fontFamilies(): Invalid arguments";
+ QString warning1 = component.url().toString() + ":4: Error: Too many arguments";
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
QScopedPointer<QObject> object(component.create());
@@ -1141,7 +1177,8 @@ void tst_qqmlqt::resolvedUrl()
QVERIFY(object != nullptr);
QCOMPARE(object->property("result").toString(), component.url().toString());
- QCOMPARE(object->property("isString").toBool(), true);
+ QCOMPARE(object->property("isString").toBool(), false);
+ QCOMPARE(object->property("isObject").toBool(), true);
}
void tst_qqmlqt::later_data()
@@ -1245,39 +1282,56 @@ void tst_qqmlqt::later()
void tst_qqmlqt::qtObjectContents()
{
- QQmlComponent component(&engine, testFileUrl("qtObjectContents.qml"));
+ QByteArray qml =
+ "import QtQml\n"
+ "QtObject {\n"
+ " property int vLoadingModeAsynchronous: Qt.Asynchronous\n"
+ " property int vLoadingModeSynchronous: Qt.Synchronous\n";
- QScopedPointer<QObject> object(component.create());
- QVERIFY(object != nullptr);
+ const QMetaObject *qtMetaObject = &Qt::staticMetaObject;
+ for (int ii = 0; ii < qtMetaObject->enumeratorCount(); ++ii) {
+ const QMetaEnum enumerator = qtMetaObject->enumerator(ii);
+ for (int jj = 0; jj < enumerator.keyCount(); ++jj) {
+ const QByteArray key = enumerator.key(jj);
+ QVERIFY(!key.isEmpty());
- QVERIFY(object->property("values").canConvert<QJSValue>());
- QVariantMap values = object->property("values").value<QJSValue>().toVariant().toMap();
+ // We don't want to check for Qt.green and things like that.
+ // They're nonsensical
+ if (QChar::fromLatin1(key.front()).isLower())
+ continue;
- QSet<const char *> keys;
- int uniqueKeys = 0;
- const QMetaObject *qtMetaObject = &Qt::staticMetaObject;
+ qml += QByteArray(" property int v") + enumerator.name() + key
+ + QByteArray(": Qt.") + key + '\n';
+ }
+ }
+
+ qml += "}\n";
+
+ QQmlComponent component(&engine);
+ component.setData(qml, QUrl());
+
+ QScopedPointer<QObject> object(component.create());
+ QVERIFY2(object != nullptr, qPrintable(component.errorString()));
+
+ bool ok = false;
for (int ii = 0; ii < qtMetaObject->enumeratorCount(); ++ii) {
- QMetaEnum enumerator = qtMetaObject->enumerator(ii);
+ const QMetaEnum enumerator = qtMetaObject->enumerator(ii);
for (int jj = 0; jj < enumerator.keyCount(); ++jj) {
- auto key = enumerator.key(jj);
-// qDebug() << "key:" << key;
- if (!keys.contains(key)) {
- ++uniqueKeys;
- keys.insert(key);
- }
- QVERIFY(values.contains(key));
- QVariant value = values.value(key);
- QVERIFY(value.canConvert<int>());
- QCOMPARE(value.toInt(), enumerator.value(jj));
+ const QByteArray key = enumerator.key(jj);
+
+ if (QChar::fromLatin1(key.front()).isLower())
+ continue;
+
+ QCOMPARE(object->property(QByteArray("v") + enumerator.name() + key).toInt(&ok),
+ enumerator.value(jj));
+ QVERIFY(ok);
}
}
- QVERIFY(values.contains("Asynchronous"));
- QCOMPARE(values.value("Asynchronous").toInt(), 0);
- ++uniqueKeys;
- QVERIFY(values.contains("Synchronous"));
- QCOMPARE(values.value("Synchronous").toInt(), 1);
- ++uniqueKeys;
- QCOMPARE(values.count(), uniqueKeys);
+
+ QCOMPARE(object->property("vLoadingModeAsynchronous").toInt(&ok), 0);
+ QVERIFY(ok);
+ QCOMPARE(object->property("vLoadingModeSynchronous").toInt(&ok), 1);
+ QVERIFY(ok);
}
class TimeProvider: public QObject