aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/qml/qmllint/tst_qmllint.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/qml/qmllint/tst_qmllint.cpp')
-rw-r--r--tests/auto/qml/qmllint/tst_qmllint.cpp207
1 files changed, 139 insertions, 68 deletions
diff --git a/tests/auto/qml/qmllint/tst_qmllint.cpp b/tests/auto/qml/qmllint/tst_qmllint.cpp
index 582f146dca..8697495a6f 100644
--- a/tests/auto/qml/qmllint/tst_qmllint.cpp
+++ b/tests/auto/qml/qmllint/tst_qmllint.cpp
@@ -38,13 +38,21 @@ class TestQmllint: public QQmlDataTest
private Q_SLOTS:
void initTestCase() override;
- void test();
- void test_data();
+
void testUnqualified();
void testUnqualified_data();
- void testUnqualifiedNoSpuriousParentWarning();
- void catchIdentifierNoFalsePositive();
+
+ void cleanQmlCode_data();
+ void cleanQmlCode();
+
+ void dirtyQmlCode_data();
+ void dirtyQmlCode();
+
+ void testUnknownCausesFail();
+
private:
+ QString runQmllint(const QString &fileToLint, bool shouldSucceed);
+
QString m_qmllintPath;
};
@@ -61,37 +69,14 @@ void TestQmllint::initTestCase()
}
}
-void TestQmllint::test_data()
-{
- QTest::addColumn<QString>("filename");
- QTest::addColumn<bool>("isValid");
-
- // Valid files:
- QTest::newRow("Simple_QML") << QStringLiteral("Simple.qml") << true;
- QTest::newRow("QML_importing_JS") << QStringLiteral("importing_js.qml") << true;
- QTest::newRow("QTBUG-45916_JS_with_pragma_and_import") << QStringLiteral("QTBUG-45916.js") << true;
-
- // Invalid files:
- QTest::newRow("Invalid_syntax_QML") << QStringLiteral("failure1.qml") << false;
- QTest::newRow("Invalid_syntax_JS") << QStringLiteral("failure1.js") << false;
-}
-
void TestQmllint::testUnqualified()
{
- auto qmlImportDir = QLibraryInfo::location(QLibraryInfo::Qml2ImportsPath);
QFETCH(QString, filename);
QFETCH(QString, warningMessage);
QFETCH(int, warningLine);
QFETCH(int, warningColumn);
- QStringList args;
- args << QStringLiteral("-U") << testFile(filename) << QStringLiteral("-I") << qmlImportDir;
-
- QProcess process;
- process.start(m_qmllintPath, args);
- QVERIFY(process.waitForFinished());
- QVERIFY(process.exitStatus() == QProcess::NormalExit);
- QVERIFY(process.exitCode());
- QString output = process.readAllStandardError();
+
+ const QString output = runQmllint(filename, false);
QVERIFY(output.contains(QString::asprintf("Warning: unqualified access at %d:%d", warningLine, warningColumn)));
QVERIFY(output.contains(warningMessage));
}
@@ -118,56 +103,142 @@ void TestQmllint::testUnqualified_data()
QTest::newRow("SignalHandlerShort2") << QStringLiteral("SignalHandler.qml") << QStringLiteral("onPressAndHold: (mouse) => {...") << 12 << 34;
// access catch identifier outside catch block
QTest::newRow("CatchStatement") << QStringLiteral("CatchStatement.qml") << QStringLiteral("err") << 6 << 21;
+
+ QTest::newRow("NonSpuriousParent") << QStringLiteral("nonSpuriousParentWarning.qml") << QStringLiteral("property int x: <id>.parent.x") << 6 << 25;
}
-void TestQmllint::testUnqualifiedNoSpuriousParentWarning()
+void TestQmllint::testUnknownCausesFail()
{
- auto qmlImportDir = QLibraryInfo::location(QLibraryInfo::Qml2ImportsPath);
- {
- QString filename = testFile("spuriousParentWarning.qml");
- QStringList args;
- args << QStringLiteral("-U") << filename << QStringLiteral("-I") << qmlImportDir;
- QProcess process;
- process.start(m_qmllintPath, args);
- QVERIFY(process.waitForFinished());
- QVERIFY(process.exitStatus() == QProcess::NormalExit);
- QVERIFY(process.exitCode() == 0);
- }
- {
- QString filename = testFile("nonSpuriousParentWarning.qml");
- QStringList args;
- args << QStringLiteral("-U") << filename << QStringLiteral("-I") << qmlImportDir;
- QProcess process;
- process.start(m_qmllintPath, args);
- QVERIFY(process.waitForFinished());
- QVERIFY(process.exitStatus() == QProcess::NormalExit);
- QVERIFY(process.exitCode());
- }
+ const QString unknownNotFound = runQmllint("unknownElement.qml", false);
+ QVERIFY(unknownNotFound.contains(
+ QStringLiteral("warning: Unknown was not found. Did you add all import paths?")));
}
-void TestQmllint::catchIdentifierNoFalsePositive()
+void TestQmllint::dirtyQmlCode_data()
{
- auto qmlImportDir = QLibraryInfo::location(QLibraryInfo::Qml2ImportsPath);
- QString filename = QLatin1String("catchIdentifierNoWarning.qml");
- filename.prepend(QStringLiteral("data/"));
- QStringList args;
- args << QStringLiteral("-U") << filename << QStringLiteral("-I") << qmlImportDir;
- QProcess process;
- process.start(m_qmllintPath, args);
- QVERIFY(process.waitForFinished());
- QVERIFY(process.exitStatus() == QProcess::NormalExit);
- QVERIFY(process.exitCode() == 0);
+ QTest::addColumn<QString>("filename");
+ QTest::addColumn<QString>("warningMessage");
+ QTest::addColumn<QString>("notContained");
+
+ QTest::newRow("Invalid_syntax_QML")
+ << QStringLiteral("failure1.qml")
+ << QStringLiteral("failure1.qml:4 : Expected token `:'")
+ << QString();
+ QTest::newRow("Invalid_syntax_JS")
+ << QStringLiteral("failure1.js")
+ << QStringLiteral("failure1.js:4 : Expected token `;'")
+ << QString();
+ QTest::newRow("AutomatchedSignalHandler")
+ << QStringLiteral("AutomatchedSignalHandler.qml")
+ << QString("Warning: unqualified access at 12:36")
+ << QStringLiteral("no matching signal found");
+ QTest::newRow("MemberNotFound")
+ << QStringLiteral("memberNotFound.qml")
+ << QString("Warning: Property \"foo\" not found on type \"QtObject\" at 6:31")
+ << QString();
+ QTest::newRow("UnknownJavascriptMethd")
+ << QStringLiteral("unknownJavascriptMethod.qml")
+ << QString("Warning: Property \"foo2\" not found on type \"Methods\" at 5:25")
+ << QString();
+ QTest::newRow("badAlias")
+ << QStringLiteral("badAlias.qml")
+ << QString("Warning: unqualified access at 4:27")
+ << QString();
+ QTest::newRow("badAliasProperty")
+ << QStringLiteral("badAliasProperty.qml")
+ << QString("Warning: Property \"nowhere\" not found on type \"QtObject\" at 5:32")
+ << QString();
+ QTest::newRow("badParent")
+ << QStringLiteral("badParent.qml")
+ << QString("Warning: Property \"rrr\" not found on type \"Item\" at 5:34")
+ << QString();
+ QTest::newRow("parentIsComponent")
+ << QStringLiteral("parentIsComponent.qml")
+ << QString("Warning: Property \"progress\" not found on type \"QQuickItem\" at 7:39")
+ << QString();
+ QTest::newRow("badTypeAssertion")
+ << QStringLiteral("badTypeAssertion.qml")
+ << QString("Warning: Property \"rrr\" not found on type \"Item\" at 5:39")
+ << QString();
+ QTest::newRow("incompleteQmltypes")
+ << QStringLiteral("incompleteQmltypes.qml")
+ << QString("Warning: Type \"QPalette\" of member \"palette\" not found at 5:26")
+ << QString();
+ QTest::newRow("inheritanceCylce")
+ << QStringLiteral("Cycle1.qml")
+ << QString("Warning: Cycle2 is part of an inheritance cycle: Cycle2 -> Cycle3 -> Cycle1 -> Cycle2")
+ << QString();
}
-void TestQmllint::test()
+void TestQmllint::dirtyQmlCode()
{
QFETCH(QString, filename);
- QFETCH(bool, isValid);
- QStringList args;
- args << QStringLiteral("--silent") << testFile(filename);
+ QFETCH(QString, warningMessage);
+ QFETCH(QString, notContained);
+
+ const QString output = runQmllint(filename, false);
+ QVERIFY(output.contains(warningMessage));
+ if (!notContained.isEmpty())
+ QVERIFY(!output.contains(notContained));
+}
+
+void TestQmllint::cleanQmlCode_data()
+{
+ QTest::addColumn<QString>("filename");
+ QTest::newRow("Simple_QML") << QStringLiteral("Simple.qml");
+ QTest::newRow("QML_importing_JS") << QStringLiteral("importing_js.qml");
+ QTest::newRow("JS_with_pragma_and_import") << QStringLiteral("QTBUG-45916.js");
+ QTest::newRow("uiQml") << QStringLiteral("FormUser.qml");
+ QTest::newRow("methodInScope") << QStringLiteral("MethodInScope.qml");
+ QTest::newRow("importWithPrefix") << QStringLiteral("ImportWithPrefix.qml");
+ QTest::newRow("catchIdentifier") << QStringLiteral("catchIdentifierNoWarning.qml");
+ QTest::newRow("qmldirAndQmltypes") << QStringLiteral("qmldirAndQmltypes.qml");
+ QTest::newRow("forLoop") << QStringLiteral("forLoop.qml");
+ QTest::newRow("esmodule") << QStringLiteral("esmodule.mjs");
+ QTest::newRow("methodsInJavascript") << QStringLiteral("javascriptMethods.qml");
+ QTest::newRow("goodAlias") << QStringLiteral("goodAlias.qml");
+ QTest::newRow("goodParent") << QStringLiteral("goodParent.qml");
+ QTest::newRow("goodTypeAssertion") << QStringLiteral("goodTypeAssertion.qml");
+ QTest::newRow("AttachedProps") << QStringLiteral("AttachedProps.qml");
+ QTest::newRow("unknownBuiltinFont") << QStringLiteral("ButtonLoader.qml");
+ QTest::newRow("confusingImport") << QStringLiteral("Dialog.qml");
+ QTest::newRow("qualifiedAttached") << QStringLiteral("Drawer.qml");
+}
+
+void TestQmllint::cleanQmlCode()
+{
+ QFETCH(QString, filename);
+ const QString warnings = runQmllint(filename, true);
+ QVERIFY(warnings.isEmpty());
+}
- bool success = QProcess::execute(m_qmllintPath, args) == 0;
- QCOMPARE(success, isValid);
+QString TestQmllint::runQmllint(const QString &fileToLint, bool shouldSucceed)
+{
+ auto qmlImportDir = QLibraryInfo::location(QLibraryInfo::Qml2ImportsPath);
+ QStringList args;
+ args << QStringLiteral("-U") << testFile(fileToLint)
+ << QStringLiteral("-I") << qmlImportDir
+ << QStringLiteral("-I") << dataDirectory()
+ << QStringLiteral("--silent");
+ QString errors;
+ auto verify = [&](bool isSilent) {
+ QProcess process;
+ process.start(m_qmllintPath, args);
+ QVERIFY(process.waitForFinished());
+ QCOMPARE(process.exitStatus(), QProcess::NormalExit);
+ if (shouldSucceed)
+ QCOMPARE(process.exitCode(), 0);
+ else
+ QVERIFY(process.exitCode() != 0);
+ errors = process.readAllStandardError();
+
+ if (isSilent)
+ QVERIFY(errors.isEmpty());
+ };
+ verify(true);
+ args.removeLast();
+ verify(false);
+ return errors;
}
QTEST_MAIN(TestQmllint)