aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/qml
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2020-11-06 15:13:27 +0100
committerUlf Hermann <ulf.hermann@qt.io>2020-11-11 11:37:49 +0100
commitf0908255c9921371d886eff0b8ce245929b50d88 (patch)
treeb246bca2fcdae9ee906acc6e2b54a874b36734ea /tests/auto/qml
parent40c0cbda771e9888999d8b78179e9600de4e7795 (diff)
QtQml: Integrate sequences with registration macros
You get to write QML_SEQUENTIAL_CONTAINER(value_type) now, and qmltyperegistrar will generate a sensible registration call from that. A registration might look like this: struct MyStringListForeign { Q_GADGET QML_ANONYMOUS QML_SEQUENTIAL_CONTAINER(QString) QML_FOREIGN(MyStringList) QML_ADDED_IN_VERSION(3, 1) }; It's unfortunate that we need to use a metaobject to transfer all of this information, but there is no other sensible way. Transform the containers defined in qv4sequenceobject.cpp to use the new style, and move them out of the builtins, into QtQml. Recognize that only one of them was ever tested, and add tests for the rest. Task-number: QTBUG-82443 Change-Id: I3a30f9e27266bb575eea26c5daf5dad1ec461cc5 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'tests/auto/qml')
-rw-r--r--tests/auto/qml/qjsengine/tst_qjsengine.cpp70
-rw-r--r--tests/auto/qml/qjsvalue/tst_qjsvalue.cpp22
-rw-r--r--tests/auto/qml/qqmlitemmodels/data/itemselection.qml1
3 files changed, 85 insertions, 8 deletions
diff --git a/tests/auto/qml/qjsengine/tst_qjsengine.cpp b/tests/auto/qml/qjsengine/tst_qjsengine.cpp
index d98a5ec51a..4f2e6f1866 100644
--- a/tests/auto/qml/qjsengine/tst_qjsengine.cpp
+++ b/tests/auto/qml/qjsengine/tst_qjsengine.cpp
@@ -41,6 +41,8 @@
#include <private/qv4alloca_p.h>
#include <private/qjsvalue_p.h>
#include <QScopeGuard>
+#include <QUrl>
+#include <QModelIndex>
#ifdef Q_CC_MSVC
#define NO_INLINE __declspec(noinline)
@@ -66,8 +68,10 @@ private slots:
void newArray();
void newArray_HooliganTask218092();
void newArray_HooliganTask233836();
- void toScriptValue_data();
- void toScriptValue();
+ void toScriptValueBuiltin_data();
+ void toScriptValueBuiltin();
+ void toScriptValueQtQml_data();
+ void toScriptValueQtQml();
void toScriptValuenotroundtripped_data();
void toScriptValuenotroundtripped();
void newVariant();
@@ -512,7 +516,7 @@ void tst_QJSEngine::newArray_HooliganTask233836()
}
}
-void tst_QJSEngine::toScriptValue_data()
+void tst_QJSEngine::toScriptValueBuiltin_data()
{
QTest::addColumn<QVariant>("input");
@@ -544,8 +548,6 @@ void tst_QJSEngine::toScriptValue_data()
vm.clear(); vm.insert("point1", QPointF(42.24, 24.42)); vm.insert("point2", QPointF(42.24, 24.42));
QTest::newRow("qvariantmap_point") << QVariant(vm);
QTest::newRow("qvariant") << QVariant(QVariant(42));
- QTest::newRow("QList<int>") << QVariant::fromValue(QList<int>() << 1 << 2 << 3 << 4);
- QTest::newRow("QVector<int>") << QVariant::fromValue(QVector<int>() << 1 << 2 << 3 << 4);
QTest::newRow("QList<QString>") << QVariant::fromValue(QVector<QString>() << "1" << "2" << "3" << "4");
QTest::newRow("QStringList") << QVariant::fromValue(QStringList() << "1" << "2" << "3" << "4");
QTest::newRow("QMap<QString, QString>") << QVariant::fromValue(QMap<QString, QString>{{ "1", "2" }, { "3", "4" }});
@@ -554,7 +556,7 @@ void tst_QJSEngine::toScriptValue_data()
QTest::newRow("QHash<QString, QPointF>") << QVariant::fromValue(QHash<QString, QPointF>{{ "1", { 42.24, 24.42 } }, { "3", { 24.42, 42.24 } }});
}
-void tst_QJSEngine::toScriptValue()
+void tst_QJSEngine::toScriptValueBuiltin()
{
QFETCH(QVariant, input);
@@ -570,6 +572,62 @@ void tst_QJSEngine::toScriptValue()
QCOMPARE(input, output);
}
+void tst_QJSEngine::toScriptValueQtQml_data()
+{
+ QTest::addColumn<QVariant>("input");
+
+ QTest::newRow("std::vector<qreal>") << QVariant::fromValue(std::vector<qreal>{.1, .2, .3, .4});
+ QTest::newRow("QList<qreal>") << QVariant::fromValue(QList<qreal>{.1, .2, .3, .4});
+
+ QTest::newRow("std::vector<int>") << QVariant::fromValue(std::vector<int>{1, 2, 3, 4});
+ QTest::newRow("std::vector<bool>") << QVariant::fromValue(std::vector<bool>{true, false, true, false});
+ QTest::newRow("std::vector<QString>") << QVariant::fromValue(std::vector<QString>{"a", "b", "c", "d"});
+ QTest::newRow("std::vector<QUrl>") << QVariant::fromValue(std::vector<QUrl>{QUrl("htt://a.com"), QUrl("file:///tmp/b/"), QUrl("c.foo"), QUrl("/some/d")});
+
+ QTest::newRow("QList<int>") << QVariant::fromValue(QList<int>{1, 2, 3, 4});
+ QTest::newRow("QList<bool>") << QVariant::fromValue(QList<bool>{true, false, true, false});
+ QTest::newRow("QStringList") << QVariant::fromValue(QStringList{"a", "b", "c", "d"});
+ QTest::newRow("QList<QUrl>") << QVariant::fromValue(QList<QUrl>{QUrl("htt://a.com"), QUrl("file:///tmp/b/"), QUrl("c.foo"), QUrl("/some/d")});
+
+ static const QStandardItemModel model(4, 4);
+ QTest::newRow("QModelIndexList") << QVariant::fromValue(QModelIndexList{ model.index(1, 2), model.index(2, 3), model.index(3, 1), model.index(3, 2)});
+ QTest::newRow("std::vector<QModelIndex>") << QVariant::fromValue(std::vector<QModelIndex>{ model.index(1, 2), model.index(2, 3), model.index(3, 1), model.index(3, 2)});
+
+ // QVariant wants to implicitly convert this to a QList<QItemSelectionRange>. Prevent that by
+ // keeping the instance on the stack, and explicitly instantiating the template below.
+ QItemSelection selection;
+
+ // It doesn't have an initializer list ctor ...
+ selection << QItemSelectionRange(model.index(1, 2), model.index(2, 3))
+ << QItemSelectionRange(model.index(3, 1), model.index(3, 2))
+ << QItemSelectionRange(model.index(2, 2), model.index(3, 3))
+ << QItemSelectionRange(model.index(1, 1), model.index(2, 2));
+
+ QTest::newRow("QItemSelection") << QVariant::fromValue<QItemSelection>(selection);
+}
+
+void tst_QJSEngine::toScriptValueQtQml()
+{
+ QFETCH(QVariant, input);
+
+ // Import QtQml, to enable the sequential containers defined there.
+ QQmlEngine engine;
+ QQmlComponent c(&engine);
+ c.setData("import QtQml\nQtObject{}", QUrl());
+ QScopedPointer<QObject> obj(c.create());
+ QVERIFY(!obj.isNull());
+
+ QJSValue outputJS = engine.toScriptValue(input);
+ QVariant output = engine.fromScriptValue<QVariant>(outputJS);
+
+ if (input.metaType().id() == QMetaType::QChar) {
+ if (!input.convert(QMetaType(QMetaType::QString)))
+ QFAIL("cannot convert to the original value");
+ } else if (!output.convert(input.metaType()) && input.isValid())
+ QFAIL("cannot convert to the original value");
+ QCOMPARE(input, output);
+}
+
void tst_QJSEngine::toScriptValuenotroundtripped_data()
{
QTest::addColumn<QVariant>("input");
diff --git a/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp b/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp
index cdf04ceb00..1771d8ccde 100644
--- a/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp
+++ b/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp
@@ -33,6 +33,8 @@
#include <QtWidgets/QPushButton>
#include <QtCore/qthread.h>
+#include <QtQml/qqmlengine.h>
+#include <QtQml/qqmlcomponent.h>
#include <memory>
@@ -2250,8 +2252,8 @@ void tst_QJSValue::strictlyEquals()
{
QJSValue var1 = eng.toScriptValue(QVariant(QStringList() << "a"));
QJSValue var2 = eng.toScriptValue(QVariant(QStringList() << "a"));
- QVERIFY(!var1.isArray());
- QVERIFY(!var2.isArray());
+ QVERIFY(var1.isArray());
+ QVERIFY(var2.isArray());
QVERIFY(!var1.strictlyEquals(var2));
}
{
@@ -2269,6 +2271,22 @@ void tst_QJSValue::strictlyEquals()
QJSValue var2 = eng.toScriptValue(QVariant(QPoint(3, 4)));
QVERIFY(!var1.strictlyEquals(var2));
}
+
+ {
+ // Import QtQml to trigger the registration of QStringList, which makes it a sequence
+ // type, rather than a generic JS array.
+ QQmlEngine qmlEngine;
+ QQmlComponent c(&qmlEngine);
+ c.setData("import QtQml\nQtObject {}", QUrl());
+ QScopedPointer<QObject> obj(c.create());
+ QVERIFY(!obj.isNull());
+
+ QJSValue var1 = qmlEngine.toScriptValue(QVariant(QStringList() << "a"));
+ QJSValue var2 = qmlEngine.toScriptValue(QVariant(QStringList() << "a"));
+ QVERIFY(!var1.isArray());
+ QVERIFY(!var2.isArray());
+ QVERIFY(!var1.strictlyEquals(var2));
+ }
}
Q_DECLARE_METATYPE(int*)
diff --git a/tests/auto/qml/qqmlitemmodels/data/itemselection.qml b/tests/auto/qml/qqmlitemmodels/data/itemselection.qml
index c2da71627a..c2b3884573 100644
--- a/tests/auto/qml/qqmlitemmodels/data/itemselection.qml
+++ b/tests/auto/qml/qqmlitemmodels/data/itemselection.qml
@@ -1,3 +1,4 @@
+import QtQml
import Test 1.0
ItemModelsTest {