qtdeclarative/tests/auto/qml/parserstress/tst_parserstress.cpp

146 lines
4.6 KiB
C++

// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <qtest.h>
#include <QQmlEngine>
#include <QQmlComponent>
#include <QDebug>
#include <QDir>
#include <QFile>
class tst_parserstress : public QObject
{
Q_OBJECT
public:
tst_parserstress() {}
private slots:
void init();
void ecmascript_data();
void ecmascript();
private:
static QFileInfoList findJSFiles(const QDir &);
QQmlEngine engine;
};
void tst_parserstress::init()
{
QTest::failOnWarning(QRegularExpression(QStringLiteral(".?")));
}
QFileInfoList tst_parserstress::findJSFiles(const QDir &d)
{
QFileInfoList rv;
const QFileInfoList files = d.entryInfoList(QStringList() << QLatin1String("*.js"),
QDir::Files);
for (const QFileInfo &fileInfo : files) {
if (fileInfo.fileName() == "browser.js")
continue;
rv << fileInfo;
}
QStringList dirs = d.entryList(QDir::Dirs | QDir::NoDotAndDotDot |
QDir::NoSymLinks);
foreach (const QString &dir, dirs) {
QDir sub = d;
sub.cd(dir);
rv << findJSFiles(sub);
}
return rv;
}
struct IgnoredWarning {
QString ignorePattern;
int timesToIgnore;
};
void tst_parserstress::ecmascript_data()
{
QString testDataDir = QFileInfo(QFINDTESTDATA("tests/shell.js")).absolutePath();
QVERIFY2(!testDataDir.isEmpty(), qPrintable("Cannot find testDataDir!"));
QDir dir(testDataDir);
const QFileInfoList files = findJSFiles(dir);
// We only care that the parser can parse, and warnings shouldn't affect that.
QHash<QString, IgnoredWarning> warningsToIgnore = {
{ "15.1.2.2-1.js", { "Variable \"POWER\" is used before its declaration at .*", 48 } },
{ "15.1.2.4.js", { "Variable \"index\" is used before its declaration at .*", 6 } },
{ "15.1.2.5-1.js", { "Variable \"index\" is used before its declaration at .*", 6 } },
{ "15.1.2.5-2.js", { "Variable \"index\" is used before its declaration at .*", 6 } },
{ "15.1.2.5-3.js", { "Variable \"index\" is used before its declaration at .*", 6 } },
{ "12.6.3-4.js", { "Variable \"value\" is used before its declaration at .*", 4 } },
{ "try-006.js", { "Variable \"EXCEPTION_STRING\" is used before its declaration at .*", 2 } },
{ "try-007.js", { "Variable \"EXCEPTION_STRING\" is used before its declaration at .*", 2 } },
{ "try-008.js", { "Variable \"INVALID_INTEGER_VALUE\" is used before its declaration at .*", 2 } },
{ "regress-94506.js", { "Variable \"arguments\" is used before its declaration at .*", 2 } },
};
QTest::addColumn<QFileInfo>("fileInfo");
QTest::addColumn<IgnoredWarning>("warningToIgnore");
for (const QFileInfo &fileInfo : files)
QTest::newRow(qPrintable(fileInfo.absoluteFilePath())) << fileInfo << warningsToIgnore.value(fileInfo.fileName());
}
void tst_parserstress::ecmascript()
{
QFETCH(QFileInfo, fileInfo);
QFETCH(IgnoredWarning, warningToIgnore);
QFile f(fileInfo.absoluteFilePath());
QVERIFY(f.open(QIODevice::ReadOnly));
QByteArray data = f.readAll();
QVERIFY(!data.isEmpty());
QString dataStr = QString::fromUtf8(data);
QString qml = "import QtQuick 2.0\n";
qml+= "\n";
qml+= "QtObject {\n";
qml+= " property int test\n";
qml+= " test: {\n";
qml+= dataStr + "\n";
qml+= " return 1;\n";
qml+= " }\n";
qml+= " function stress() {\n";
qml+= dataStr;
qml+= " }\n";
qml+= "}\n";
QByteArray qmlData = qml.toUtf8();
if (!warningToIgnore.ignorePattern.isEmpty()) {
for (int i = 0; i < warningToIgnore.timesToIgnore; ++i)
QTest::ignoreMessage(QtWarningMsg, QRegularExpression(warningToIgnore.ignorePattern));
}
QQmlComponent component(&engine);
component.setData(qmlData, QUrl());
if (fileInfo.fileName() == QLatin1String("regress-352044-02-n.js")) {
QVERIFY(component.isError());
QCOMPARE(component.errors().length(), 2);
QCOMPARE(component.errors().at(0).description(), QString("Expected token `;'"));
QCOMPARE(component.errors().at(0).line(), 66);
QCOMPARE(component.errors().at(1).description(), QString("Expected token `;'"));
QCOMPARE(component.errors().at(1).line(), 142);
} else {
QVERIFY2(!component.isError(), qPrintable(component.errorString()));
}
}
QTEST_MAIN(tst_parserstress)
#include "tst_parserstress.moc"