tst_qmlformat: in memory formatting when reformatting all qmlfiles

avoid copying the file, and calling the qmlformat tool when scanning
all qmlfiles.
Improvements in the reformatting made some more incorrect files fail,
adding them to the invalid files.

Change-Id: I007654340ac325be89188c1680c38c2bc37a0340
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
Fawzi Mohamed 2021-09-15 09:38:49 +02:00
parent 5b36c041b4
commit fc05eb9187
2 changed files with 71 additions and 3 deletions

View File

@ -16,7 +16,8 @@ qt_internal_add_test(tst_qmlformat
DEFINES DEFINES
SRCDIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}\\\" SRCDIR=\\\"${CMAKE_CURRENT_SOURCE_DIR}\\\"
PUBLIC_LIBRARIES PUBLIC_LIBRARIES
Qt::Gui Qt::Core
Qt::QmlDomPrivate
Qt::TestPrivate Qt::TestPrivate
Qt::QuickTestUtilsPrivate Qt::QuickTestUtilsPrivate
TESTDATA ${test_data} TESTDATA ${test_data}

View File

@ -34,6 +34,12 @@
#include <QTemporaryDir> #include <QTemporaryDir>
#include <QtTest/private/qemulationdetector_p.h> #include <QtTest/private/qemulationdetector_p.h>
#include <QtQuickTestUtils/private/qmlutils_p.h> #include <QtQuickTestUtils/private/qmlutils_p.h>
#include <QtQmlDom/private/qqmldomitem_p.h>
#include <QtQmlDom/private/qqmldomlinewriter_p.h>
#include <QtQmlDom/private/qqmldomoutwriter_p.h>
#include <QtQmlDom/private/qqmldomtop_p.h>
using namespace QQmlJS::Dom;
class TestQmlformat: public QQmlDataTest class TestQmlformat: public QQmlDataTest
{ {
@ -59,6 +65,10 @@ private:
QString readTestFile(const QString &path); QString readTestFile(const QString &path);
QString runQmlformat(const QString &fileToFormat, QStringList args, bool shouldSucceed = true, QString runQmlformat(const QString &fileToFormat, QStringList args, bool shouldSucceed = true,
RunOption rOption = RunOption::OnCopy); RunOption rOption = RunOption::OnCopy);
QString formatInMemory(const QString &fileToFormat, bool *didSucceed = nullptr,
LineWriterOptions options = LineWriterOptions(),
WriteOutChecks extraChecks = WriteOutCheck::ReparseCompare,
WriteOutChecks largeChecks = WriteOutCheck::None);
QString m_qmlformatPath; QString m_qmlformatPath;
QStringList m_excludedDirs; QStringList m_excludedDirs;
@ -111,6 +121,8 @@ void TestQmlformat::initTestCase()
m_invalidFiles << "tests/auto/qml/qqmllanguage/data/invalidRoot.1.qml"; m_invalidFiles << "tests/auto/qml/qqmllanguage/data/invalidRoot.1.qml";
m_invalidFiles << "tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.1.qml"; m_invalidFiles << "tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.1.qml";
m_invalidFiles << "tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.2.qml"; m_invalidFiles << "tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.2.qml";
m_invalidFiles << "tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.3.qml";
m_invalidFiles << "tests/auto/qml/qqmllanguage/data/invalidID.4.qml";
m_invalidFiles << "tests/auto/qml/qqmllanguage/data/questionDotEOF.qml"; m_invalidFiles << "tests/auto/qml/qqmllanguage/data/questionDotEOF.qml";
m_invalidFiles << "tests/auto/qml/qquickfolderlistmodel/data/dummy.qml"; m_invalidFiles << "tests/auto/qml/qquickfolderlistmodel/data/dummy.qml";
m_invalidFiles << "tests/auto/qml/qqmlecmascript/data/stringParsing_error.1.qml"; m_invalidFiles << "tests/auto/qml/qqmlecmascript/data/stringParsing_error.1.qml";
@ -135,6 +147,20 @@ void TestQmlformat::initTestCase()
m_invalidFiles << "tests/auto/qml/qqmllanguage/data/typeAnnotations.2.qml"; m_invalidFiles << "tests/auto/qml/qqmllanguage/data/typeAnnotations.2.qml";
m_invalidFiles << "tests/auto/qml/qqmlparser/data/disallowedtypeannotations/qmlnestedfunction.qml"; m_invalidFiles << "tests/auto/qml/qqmlparser/data/disallowedtypeannotations/qmlnestedfunction.qml";
// Files that get changed:
// rewrite of import "bla/bla/.." to import "bla"
m_invalidFiles << "tests/auto/qml/qqmlcomponent/data/componentUrlCanonicalization.4.qml";
// block -> object in internal update
m_invalidFiles << "tests/auto/qml/qqmlpromise/data/promise-executor-throw-exception.qml";
// removal of unsupported indexing of Object declaration
m_invalidFiles << "tests/auto/qml/qqmllanguage/data/hangOnWarning.qml";
// removal of duplicated id
m_invalidFiles << "tests/auto/qml/qqmllanguage/data/component.3.qml";
// Optional chains are not permitted on the left-hand-side in assignments
m_invalidFiles << "tests/auto/qml/qqmllanguage/data/optionalChaining.LHS.qml";
// object literal with = assignements
m_invalidFiles << "tests/auto/quickcontrols2/controls/data/tst_scrollbar.qml";
// These files rely on exact formatting // These files rely on exact formatting
m_invalidFiles << "tests/auto/qml/qqmlecmascript/data/incrDecrSemicolon1.qml"; m_invalidFiles << "tests/auto/qml/qqmlecmascript/data/incrDecrSemicolon1.qml";
m_invalidFiles << "tests/auto/qml/qqmlecmascript/data/incrDecrSemicolon_error1.qml"; m_invalidFiles << "tests/auto/qml/qqmlecmascript/data/incrDecrSemicolon_error1.qml";
@ -305,10 +331,13 @@ void TestQmlformat::testExample()
{ {
QFETCH(QString, file); QFETCH(QString, file);
const bool isInvalid = isInvalidFile(QFileInfo(file)); const bool isInvalid = isInvalidFile(QFileInfo(file));
QString output = runQmlformat(file, {}, !isInvalid); bool wasSuccessful;
LineWriterOptions opts;
opts.attributesSequence = LineWriterOptions::AttributesSequence::Preserve;
QString output = formatInMemory(file, &wasSuccessful, opts);
if (!isInvalid) if (!isInvalid)
QVERIFY(!output.isEmpty()); QVERIFY(wasSuccessful && !output.isEmpty());
} }
#endif #endif
@ -347,5 +376,43 @@ QString TestQmlformat::runQmlformat(const QString &fileToFormat, QStringList arg
return formatted; return formatted;
} }
QString TestQmlformat::formatInMemory(const QString &fileToFormat, bool *didSucceed,
LineWriterOptions options, WriteOutChecks extraChecks,
WriteOutChecks largeChecks)
{
DomItem env = DomEnvironment::create(
QStringList(), // as we load no dependencies we do not need any paths
QQmlJS::Dom::DomEnvironment::Option::SingleThreaded
| QQmlJS::Dom::DomEnvironment::Option::NoDependencies);
DomItem tFile;
env.loadFile(
fileToFormat, QString(),
[&tFile](Path, const DomItem &, const DomItem &newIt) { tFile = newIt; },
LoadOption::DefaultLoad);
env.loadPendingDependencies();
MutableDomItem myFile = tFile.field(Fields::currentItem);
DomItem writtenOut;
QString resultStr;
if (myFile.field(Fields::isValid).value().toBool()) {
WriteOutChecks checks = extraChecks;
const qsizetype largeFileSize = 32000;
if (tFile.field(Fields::code).value().toString().size() > largeFileSize)
checks = largeChecks;
QTextStream res(&resultStr);
LineWriter lw([&res](QStringView s) { res << s; }, QLatin1String("*testStream*"), options);
OutWriter ow(lw);
ow.indentNextlines = true;
DomItem qmlFile = tFile.field(Fields::currentItem);
writtenOut = qmlFile.writeOutForFile(ow, checks);
lw.eof();
res.flush();
}
if (didSucceed)
*didSucceed = bool(writtenOut);
return resultStr;
}
QTEST_MAIN(TestQmlformat) QTEST_MAIN(TestQmlformat)
#include "tst_qmlformat.moc" #include "tst_qmlformat.moc"