diff options
Diffstat (limited to 'tests/auto/qml/qmllint/tst_qmllint.cpp')
-rw-r--r-- | tests/auto/qml/qmllint/tst_qmllint.cpp | 207 |
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) |