aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp')
-rw-r--r--tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp338
1 files changed, 322 insertions, 16 deletions
diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
index f460dc3cad..8203ab1d33 100644
--- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
+++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
@@ -517,6 +517,22 @@ private slots:
void argumentsUsageInBindings_data();
void argumentsUsageInBindings();
+ void aliasToLargeRevision();
+ void propertyCycle();
+
+ void urlWithFragment();
+
+ void enumScoping();
+ void enumStringToValue();
+ void enumValueToString();
+ void enumValueToStrings();
+
+ void enumTypeAnnotations();
+
+ void assignWrongTypeToObjectList();
+
+ void variantAssociationHasOwnProperty();
+
private:
QQmlEngine engine;
QStringList defaultImportPathList;
@@ -704,6 +720,7 @@ void tst_qqmllanguage::errors_data()
QTest::newRow("invalidGroupedProperty.8") << "invalidGroupedProperty.8.qml" << "invalidGroupedProperty.8.errors.txt" << false;
QTest::newRow("invalidGroupedProperty.9") << "invalidGroupedProperty.9.qml" << "invalidGroupedProperty.9.errors.txt" << false;
QTest::newRow("invalidGroupedProperty.10") << "invalidGroupedProperty.10.qml" << "invalidGroupedProperty.10.errors.txt" << false;
+ QTest::newRow("invalidGroupedProperty.11") << "invalidGroupedProperty.11.qml" << "invalidGroupedProperty.11.errors.txt" << false;
QTest::newRow("importNamespaceConflict") << "importNamespaceConflict.qml" << "importNamespaceConflict.errors.txt" << false;
QTest::newRow("importVersionMissing (builtin)") << "importVersionMissingBuiltIn.qml" << "importVersionMissingBuiltIn.errors.txt" << false;
@@ -2740,8 +2757,7 @@ void tst_qqmllanguage::scriptStringWithoutSourceCode()
QUrl url = testFileUrl("scriptString7.qml");
QScopedPointer<const QV4::CompiledData::Unit, FreeUnitData> readOnlyQmlUnit;
{
- QQmlEnginePrivate *eng = QQmlEnginePrivate::get(&engine);
- QQmlRefPointer<QQmlTypeData> td = eng->typeLoader.getType(url);
+ QQmlRefPointer<QQmlTypeData> td = QQmlTypeLoader::get(&engine)->getType(url);
Q_ASSERT(td);
QVERIFY(!td->backupSourceCode().isValid());
@@ -2942,12 +2958,9 @@ void tst_qqmllanguage::reservedWords_data()
QTest::newRow("abstract") << QByteArray("abstract");
QTest::newRow("as") << QByteArray("as");
- QTest::newRow("boolean") << QByteArray("boolean");
QTest::newRow("break") << QByteArray("break");
- QTest::newRow("byte") << QByteArray("byte");
QTest::newRow("case") << QByteArray("case");
QTest::newRow("catch") << QByteArray("catch");
- QTest::newRow("char") << QByteArray("char");
QTest::newRow("class") << QByteArray("class");
QTest::newRow("continue") << QByteArray("continue");
QTest::newRow("const") << QByteArray("const");
@@ -2955,7 +2968,6 @@ void tst_qqmllanguage::reservedWords_data()
QTest::newRow("default") << QByteArray("default");
QTest::newRow("delete") << QByteArray("delete");
QTest::newRow("do") << QByteArray("do");
- QTest::newRow("double") << QByteArray("double");
QTest::newRow("else") << QByteArray("else");
QTest::newRow("enum") << QByteArray("enum");
QTest::newRow("export") << QByteArray("export");
@@ -2963,19 +2975,15 @@ void tst_qqmllanguage::reservedWords_data()
QTest::newRow("false") << QByteArray("false");
QTest::newRow("final") << QByteArray("final");
QTest::newRow("finally") << QByteArray("finally");
- QTest::newRow("float") << QByteArray("float");
QTest::newRow("for") << QByteArray("for");
QTest::newRow("function") << QByteArray("function");
- QTest::newRow("goto") << QByteArray("goto");
QTest::newRow("if") << QByteArray("if");
QTest::newRow("implements") << QByteArray("implements");
QTest::newRow("import") << QByteArray("import");
QTest::newRow("pragma") << QByteArray("pragma");
QTest::newRow("in") << QByteArray("in");
QTest::newRow("instanceof") << QByteArray("instanceof");
- QTest::newRow("int") << QByteArray("int");
QTest::newRow("interface") << QByteArray("interface");
- QTest::newRow("long") << QByteArray("long");
QTest::newRow("native") << QByteArray("native");
QTest::newRow("new") << QByteArray("new");
QTest::newRow("null") << QByteArray("null");
@@ -2984,7 +2992,6 @@ void tst_qqmllanguage::reservedWords_data()
QTest::newRow("protected") << QByteArray("protected");
QTest::newRow("public") << QByteArray("public");
QTest::newRow("return") << QByteArray("return");
- QTest::newRow("short") << QByteArray("short");
QTest::newRow("static") << QByteArray("static");
QTest::newRow("super") << QByteArray("super");
QTest::newRow("switch") << QByteArray("switch");
@@ -6320,12 +6327,12 @@ void tst_qqmllanguage::nonExistingInlineComponent_data()
QTest::addColumn<int>("line");
QTest::addColumn<int>("column");
- QTest::newRow("Property type") << testFileUrl("nonExistingICUser1.qml") << QString("Type InlineComponentProvider has no inline component type called NonExisting") << 4 << 5;
+ QTest::newRow("Property type") << testFileUrl("nonExistingICUser1.qml") << QString("Type InlineComponentProvider has no inline component type called NotExisting") << 4 << 58;
QTest::newRow("Instantiation") << testFileUrl("nonExistingICUser2.qml") << QString("Type InlineComponentProvider has no inline component type called NotExisting") << 4 << 5;
QTest::newRow("Inheritance") << testFileUrl("nonExistingICUser3.qml") << QString("Type InlineComponentProvider has no inline component type called NotExisting") << 3 << 1;
- QTest::newRow("From singleton") << testFileUrl("nonExistingICUser4.qml") << QString("Type MySingleton.SingletonTypeWithIC has no inline component type called NonExisting") << 5 << 5;
+ QTest::newRow("From singleton") << testFileUrl("nonExistingICUser4.qml") << QString("Type MySingleton.SingletonTypeWithIC has no inline component type called NonExisting") << 5 << 71;
- QTest::newRow("Cannot access parent inline components from child") << testFileUrl("nonExistingICUser5.qml") << QString("Type InlineComponentProviderChild has no inline component type called StyledRectangle") << 4 << 5;
+ QTest::newRow("Cannot access parent inline components from child") << testFileUrl("nonExistingICUser5.qml") << QString("Type InlineComponentProviderChild has no inline component type called StyledRectangle") << 4 << 67;
}
void tst_qqmllanguage::nonExistingInlineComponent()
@@ -8980,8 +8987,8 @@ void tst_qqmllanguage::overrideDefaultProperty()
QQmlComponent c(&e, url);
QVERIFY(c.isError());
- QCOMPARE(c.errorString(),
- url.toString() + QLatin1String(":5 Cannot assign object to list property \"data\"\n"));
+ QCOMPARE(c.errorString(), url.toString() + QLatin1String(
+ ":5 Cannot assign object of type \"QQuickItem\" to list property \"data\"; expected \"QVariant\"\n"));
}
void tst_qqmllanguage::enumScopes()
@@ -9767,6 +9774,305 @@ void tst_qqmllanguage::argumentsUsageInBindings() {
QCOMPARE(object->property("result").toString(), object->property("expected").toString());
}
+void tst_qqmllanguage::aliasToLargeRevision()
+{
+ QQmlEngine engine;
+ QQmlComponent c(&engine, testFileUrl("aliasToLargeRevision.qml"));
+
+ QVERIFY2(c.isReady(), qPrintable(c.errorString()));
+ QScopedPointer<QObject> o(c.create());
+ QVERIFY(!o.isNull());
+
+ QCOMPARE(o->property("aa"), 13);
+ QCOMPARE(o->property("bb"), 14);
+ QCOMPARE(o->property("cc"), 15);
+ QCOMPARE(o->property("dd"), 16);
+}
+
+void tst_qqmllanguage::urlWithFragment()
+{
+ QQmlEngine engine;
+ QQmlComponent c(&engine, testFileUrl("urlWithFragment.qml"));
+ QVERIFY2(c.isReady(), qPrintable(c.errorString()));
+ QScopedPointer<QObject> o(c.create());
+ QVERIFY(!o.isNull());
+
+ QCOMPARE(o->objectName(), "outer");
+}
+
+void tst_qqmllanguage::enumScoping()
+{
+ QQmlEngine engine;
+ QQmlComponent c(&engine, testFileUrl("EnumScoping.qml"));
+
+ QVERIFY2(c.isReady(), qPrintable(c.errorString()));
+ QScopedPointer<QObject> o(c.create());
+ QVERIFY(!o.isNull());
+
+ QCOMPARE(o->property("qmlAsScoped").toInt(), 1);
+ QCOMPARE(o->property("qmlAsUnscoped").toInt(), 1);
+
+ QCOMPARE(o->property("cppScopedAsScoped").toInt(), 1);
+ QCOMPARE(o->property("cppScopedAsUnscoped").toInt(), 1);
+
+ QCOMPARE(o->property("cppUnscopedAsScoped").toInt(), 1);
+ QCOMPARE(o->property("cppUnscopedAsUnscoped").toInt(), 1);
+
+ QCOMPARE(o->property("nsScopedAsScoped").toInt(), 1);
+ QCOMPARE(o->property("nsScopedAsUnscoped").toInt(), 1);
+
+ QCOMPARE(o->property("nsUnscopedAsScoped").toInt(), 1);
+ QCOMPARE(o->property("nsUnscopedAsUnscoped").toInt(), 1);
+}
+
+void tst_qqmllanguage::enumStringToValue()
+{
+ QQmlEngine engine;
+ QUrl url(testFileUrl("EnumStringToValue.qml"));
+ QQmlComponent c(&engine, url);
+
+ QVERIFY2(c.isReady(), qPrintable(c.errorString()));
+ QScopedPointer<QObject> o(c.create());
+ QVERIFY(!o.isNull());
+
+ // QML
+ QCOMPARE(o->property("p1").toInt(), 1);
+ // CppEnum
+ QCOMPARE(o->property("p2").toInt(), (int)CppEnum::Scoped::S2);
+ QCOMPARE(o->property("p3").toInt(), (int)CppEnum::Unscoped::U2);
+ // EnumNamespace
+ QCOMPARE(o->property("p4").toInt(), (int)EnumNamespace::Scoped::S2);
+ QCOMPARE(o->property("p5").toInt(), (int)EnumNamespace::Unscoped::U2);
+
+
+ // Invalid arg
+ QCOMPARE(o->property("p7"), QVariant());
+ QCOMPARE(o->property("p8"), QVariant());
+
+ // Conflicts
+ QCOMPARE(o->property("p9").toInt(), (int)ConflictingEnums::E1::A);
+ QCOMPARE(o->property("p10").toInt(), (int)ConflictingEnums::E2::A);
+}
+
+void tst_qqmllanguage::enumValueToString()
+{
+ QQmlEngine engine;
+ QUrl url(testFileUrl("EnumValueToString.qml"));
+ QQmlComponent c(&engine, url);
+
+ QVERIFY2(c.isReady(), qPrintable(c.errorString()));
+ QScopedPointer<QObject> o(c.create());
+ QVERIFY(!o.isNull());
+
+ // QML
+ QCOMPARE(o->property("p1").toString(), "B");
+ QCOMPARE(o->property("p2").toString(), "B");
+
+ // CppEnum
+ QCOMPARE(o->property("p3").toString(), "S2");
+ QCOMPARE(o->property("p4").toString(), "S2");
+
+ QCOMPARE(o->property("p5").toString(), "U2");
+ QCOMPARE(o->property("p6").toString(), "U2");
+
+ // EnumNamespace
+ QCOMPARE(o->property("p7").toString(), "S2");
+ QCOMPARE(o->property("p8").toString(), "S2");
+
+ QCOMPARE(o->property("p9").toString(), "U2");
+ QCOMPARE(o->property("p10").toString(), "U2");
+
+
+ // Invalid arg
+ QCOMPARE(o->property("p11"), QVariant());
+ QCOMPARE(o->property("p12"), QVariant());
+ QCOMPARE(o->property("p13"), QVariant());
+
+ // Conflicts
+ QCOMPARE(o->property("p14"), QVariant("A"));
+ QCOMPARE(o->property("p15"), QVariant());
+}
+
+void tst_qqmllanguage::enumValueToStrings()
+{
+ QQmlEngine engine;
+ QUrl url(testFileUrl("EnumValueToStrings.qml"));
+ QQmlComponent c(&engine, url);
+
+ QVERIFY2(c.isReady(), qPrintable(c.errorString()));
+ QScopedPointer<QObject> o(c.create());
+ QVERIFY(!o.isNull());
+
+ // QML
+ QList l({ QVariant("A") });
+ QCOMPARE(o->property("p1").toList(), l);
+
+ l = QList({ QVariant("B"), QVariant("C") });
+ QCOMPARE(o->property("p2").toList(), l);
+
+ // CppEnum
+ l = QList({ QVariant("S1") });
+ QCOMPARE(o->property("p3").toList(), l);
+
+ l = QList({ QVariant("S3"), QVariant("S4") });
+ QCOMPARE(o->property("p4").toList(), l);
+
+ l = QList({ QVariant("U1") });
+ QCOMPARE(o->property("p5").toList(), l);
+
+ l = QList({ QVariant("U3"), QVariant("U4") });
+ QCOMPARE(o->property("p6").toList(), l);
+
+ // EnumNamespace
+ l = QList({ QVariant("S1") });
+ QCOMPARE(o->property("p7").toList(), l);
+
+ l = QList({ QVariant("S3"), QVariant("S4") });
+ QCOMPARE(o->property("p8").toList(), l);
+
+ l = QList({ QVariant("U1") });
+ QCOMPARE(o->property("p9").toList(), l);
+
+ l = QList({ QVariant("U3"), QVariant("U4") });
+ QCOMPARE(o->property("p10").toList(), l);
+
+
+ // Invalid arg
+ QCOMPARE(o->property("p11"), QVariant());
+ QCOMPARE(o->property("p12"), QVariant());
+
+ // Conflicts
+ l = QList({ QVariant("A") });
+ QCOMPARE(o->property("p13").toList(), l);
+ QCOMPARE(o->property("p14"), QVariant());
+}
+
+void tst_qqmllanguage::propertyCycle()
+{
+ QQmlEngine engine;
+
+
+ QQmlComponent c1(&engine, testFileUrl("PropertyCycle1.qml"));
+ QVERIFY2(c1.isReady(), qPrintable(c1.errorString()));
+ QScopedPointer<QObject> o1(c1.create());
+ QVERIFY(!o1.isNull());
+
+ const QVariant self1 = o1->property("self");
+ QVERIFY(QByteArray(self1.metaType().name()).startsWith("PropertyCycle1_QMLTYPE_"));
+ QCOMPARE(self1.value<QObject *>(), nullptr);
+ o1->setProperty("self", QVariant::fromValue(o1.data()));
+ QCOMPARE(o1->property("self").value<QObject *>(), o1.data());
+
+ const QVariant cycle1 = o1->property("cycle");
+ QVERIFY(QByteArray(cycle1.metaType().name()).startsWith("PropertyCycle2_QMLTYPE_"));
+ QCOMPARE(cycle1.value<QObject *>(), nullptr);
+ o1->setProperty("cycle", QVariant::fromValue(o1.data()));
+ QCOMPARE(o1->property("cycle").value<QObject *>(), nullptr);
+
+
+ QQmlComponent c2(&engine, testFileUrl("PropertyCycle2.qml"));
+ QVERIFY2(c2.isReady(), qPrintable(c2.errorString()));
+ QScopedPointer<QObject> o2(c2.create());
+ QVERIFY(!o2.isNull());
+
+ const QVariant self2 = o2->property("self");
+ QVERIFY(QByteArray(self2.metaType().name()).startsWith("PropertyCycle2_QMLTYPE_"));
+ QCOMPARE(self2.value<QObject *>(), nullptr);
+ o2->setProperty("self", QVariant::fromValue(o2.data()));
+ QCOMPARE(o2->property("self").value<QObject *>(), o2.data());
+
+ const QVariant cycle2 = o2->property("cycle");
+ QVERIFY(QByteArray(cycle2.metaType().name()).startsWith("PropertyCycle1_QMLTYPE_"));
+ QCOMPARE(cycle2.value<QObject *>(), nullptr);
+ o2->setProperty("cycle", QVariant::fromValue(o2.data()));
+ QCOMPARE(o2->property("cycle").value<QObject *>(), nullptr);
+
+
+
+ o1->setProperty("cycle", QVariant::fromValue(o2.data()));
+ QCOMPARE(o1->property("cycle").value<QObject *>(), o2.data());
+
+ o2->setProperty("cycle", QVariant::fromValue(o1.data()));
+ QCOMPARE(o2->property("cycle").value<QObject *>(), o1.data());
+}
+
+void tst_qqmllanguage::enumTypeAnnotations()
+{
+ QQmlEngine engine;
+ QUrl url(testFileUrl("EnumTypeAnnotations.qml"));
+ QQmlComponent c(&engine, url);
+
+ const auto msg = [&](int line, int function, int param) {
+ auto where = param == -1 ? QStringLiteral("return type")
+ : QStringLiteral("parameter ") + QString::number(param);
+ auto msg = QStringLiteral(" Type annotation for %1 of function %2: Enumerations are not "
+ "types. Use underlying type (int or double) instead.")
+ .arg(where, "f"_L1 + QString::number(function));
+
+ return url.toString() + u':' + QString::number(line) + ":5:"_L1 + msg;
+ };
+
+ int ret = -1;
+
+ QTest::ignoreMessage(QtWarningMsg, msg(7, 1, 0).toStdString().c_str());
+ QTest::ignoreMessage(QtWarningMsg, msg(8, 2, ret).toStdString().c_str());
+ QTest::ignoreMessage(QtWarningMsg, msg(9, 3, ret).toStdString().c_str());
+ QTest::ignoreMessage(QtWarningMsg, msg(9, 3, 0).toStdString().c_str());
+ QTest::ignoreMessage(QtWarningMsg, msg(10, 4, 1).toStdString().c_str());
+
+ QTest::ignoreMessage(QtWarningMsg, msg(12, 5, 0).toStdString().c_str());
+ QTest::ignoreMessage(QtWarningMsg, msg(13, 6, ret).toStdString().c_str());
+ QTest::ignoreMessage(QtWarningMsg, msg(14, 7, ret).toStdString().c_str());
+ QTest::ignoreMessage(QtWarningMsg, msg(14, 7, 0).toStdString().c_str());
+ QTest::ignoreMessage(QtWarningMsg, msg(15, 8, 1).toStdString().c_str());
+
+ QTest::ignoreMessage(QtWarningMsg, msg(17, 9, 0).toStdString().c_str());
+ QTest::ignoreMessage(QtWarningMsg, msg(18, 10, ret).toStdString().c_str());
+ QTest::ignoreMessage(QtWarningMsg, msg(19, 11, ret).toStdString().c_str());
+ QTest::ignoreMessage(QtWarningMsg, msg(19, 11, 0).toStdString().c_str());
+ QTest::ignoreMessage(QtWarningMsg, msg(20, 12, 1).toStdString().c_str());
+
+ QTest::ignoreMessage(QtWarningMsg, msg(22, 13, 0).toStdString().c_str());
+
+ QVERIFY2(c.isReady(), qPrintable(c.errorString()));
+ QScopedPointer<QObject> o(c.create());
+ QVERIFY(!o.isNull());
+}
+
+void tst_qqmllanguage::assignWrongTypeToObjectList()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine, testFileUrl("assignWrongTypeToObjectList.qml"));
+ QVERIFY(!component.isReady());
+ QVERIFY(QRegularExpression(".*Cannot assign object of type \"QQuickFrameAnimation\""_L1
+ + " to list property \"animations\"; expected \"QQuickAbstractAnimation\""_L1).match(component.errorString()).hasMatch());
+}
+
+class VariantAssociationContainer : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QVariant variantobj MEMBER m_qvariant)
+public:
+ VariantAssociationContainer()
+ : m_qvariant(QVariantMap{{"key1", "value1"}, {"key2", "value2"}})
+ {}
+private:
+ QVariant m_qvariant;
+};
+
+void tst_qqmllanguage::variantAssociationHasOwnProperty()
+{
+ QJSEngine engine;
+ VariantAssociationContainer obj;
+ engine.globalObject().setProperty("qobject", engine.newQObject(&obj));
+ QCOMPARE(engine.evaluate("typeof qobject.variantobj").toString(), "object");
+ QCOMPARE(engine.evaluate("qobject.variantobj.key1").toString(), "value1");
+ QCOMPARE(engine.evaluate("qobject.variantobj.key2").toString(), "value2");
+ QCOMPARE(engine.evaluate("typeof qobject.variantobj.hasOwnProperty").toString(), "function");
+ QVERIFY(engine.evaluate("qobject.variantobj.hasOwnProperty('key1')").toBool());
+ QVERIFY(!engine.evaluate("qobject.variantobj.hasOwnProperty('key3')").toBool());
+}
+
QTEST_MAIN(tst_qqmllanguage)
#include "tst_qqmllanguage.moc"