From 51f93c0dfc479830e5a419cd99ffa5463f6cca9f Mon Sep 17 00:00:00 2001 From: Marco Benelli Date: Tue, 11 Dec 2018 11:59:21 +0100 Subject: [PATCH] qmljs: basic ECMAscript 7 test suite Change-Id: Ib313ba1be60265784fc6f699b5aa6990277fa33f Reviewed-by: Ulf Hermann --- tests/auto/qml/codemodel/codemodel.pro | 3 +- .../qml/codemodel/ecmascript7/ecmascript7.pro | 28 +++ .../samples/basic/arrow-functions.js | 27 +++ .../ecmascript7/samples/basic/class.js | 28 +++ .../ecmascript7/samples/basic/constructor.js | 32 +++ .../ecmascript7/samples/basic/extends.js | 33 +++ .../ecmascript7/samples/basic/let.js | 29 +++ .../ecmascript7/samples/basic/super.js | 42 ++++ .../samples/basic/template-strings.js | 28 +++ .../ecmascript7/samples/basic/yield.js | 29 +++ .../codemodel/ecmascript7/tst_ecmascript7.cpp | 212 ++++++++++++++++++ 11 files changed, 490 insertions(+), 1 deletion(-) create mode 100644 tests/auto/qml/codemodel/ecmascript7/ecmascript7.pro create mode 100644 tests/auto/qml/codemodel/ecmascript7/samples/basic/arrow-functions.js create mode 100644 tests/auto/qml/codemodel/ecmascript7/samples/basic/class.js create mode 100644 tests/auto/qml/codemodel/ecmascript7/samples/basic/constructor.js create mode 100644 tests/auto/qml/codemodel/ecmascript7/samples/basic/extends.js create mode 100644 tests/auto/qml/codemodel/ecmascript7/samples/basic/let.js create mode 100644 tests/auto/qml/codemodel/ecmascript7/samples/basic/super.js create mode 100644 tests/auto/qml/codemodel/ecmascript7/samples/basic/template-strings.js create mode 100644 tests/auto/qml/codemodel/ecmascript7/samples/basic/yield.js create mode 100644 tests/auto/qml/codemodel/ecmascript7/tst_ecmascript7.cpp diff --git a/tests/auto/qml/codemodel/codemodel.pro b/tests/auto/qml/codemodel/codemodel.pro index 61114626c16..18618a8ea23 100644 --- a/tests/auto/qml/codemodel/codemodel.pro +++ b/tests/auto/qml/codemodel/codemodel.pro @@ -2,5 +2,6 @@ TEMPLATE = subdirs SUBDIRS += check \ importscheck \ - dependencies + dependencies \ + ecmascript7 diff --git a/tests/auto/qml/codemodel/ecmascript7/ecmascript7.pro b/tests/auto/qml/codemodel/ecmascript7/ecmascript7.pro new file mode 100644 index 00000000000..8ce22638385 --- /dev/null +++ b/tests/auto/qml/codemodel/ecmascript7/ecmascript7.pro @@ -0,0 +1,28 @@ +QTC_LIB_DEPENDS += qmljs +QTC_PLUGIN_DEPENDS += qmljstools + +include(../../../qttest.pri) + +DEFINES+=QTCREATORDIR=\\\"$$IDE_SOURCE_TREE\\\" +DEFINES+=TESTSRCDIR=\\\"$$PWD\\\" + +QT += core +QT -= gui + +TARGET = tst_ecmascript7 +CONFIG += console +CONFIG -= app_bundle + +TEMPLATE = app + +SOURCES += tst_ecmascript7.cpp + +DISTFILES += \ + samples/basic/arrow-functions.js \ + samples/basic/class.js \ + samples/basic/constructor.js \ + samples/basic/extends.js \ + samples/basic/let.js \ + samples/basic/super.js \ + samples/basic/template-strings.js \ + samples/basic/yield.js diff --git a/tests/auto/qml/codemodel/ecmascript7/samples/basic/arrow-functions.js b/tests/auto/qml/codemodel/ecmascript7/samples/basic/arrow-functions.js new file mode 100644 index 00000000000..3332f7d6e9f --- /dev/null +++ b/tests/auto/qml/codemodel/ecmascript7/samples/basic/arrow-functions.js @@ -0,0 +1,27 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +var f = (x, y) => { return x + y; } + diff --git a/tests/auto/qml/codemodel/ecmascript7/samples/basic/class.js b/tests/auto/qml/codemodel/ecmascript7/samples/basic/class.js new file mode 100644 index 00000000000..2534fe209bd --- /dev/null +++ b/tests/auto/qml/codemodel/ecmascript7/samples/basic/class.js @@ -0,0 +1,28 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +class MyClass +{ +} diff --git a/tests/auto/qml/codemodel/ecmascript7/samples/basic/constructor.js b/tests/auto/qml/codemodel/ecmascript7/samples/basic/constructor.js new file mode 100644 index 00000000000..68b78082792 --- /dev/null +++ b/tests/auto/qml/codemodel/ecmascript7/samples/basic/constructor.js @@ -0,0 +1,32 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +class MyClass +{ + constructor(id) + { + this.id = id; + } +} diff --git a/tests/auto/qml/codemodel/ecmascript7/samples/basic/extends.js b/tests/auto/qml/codemodel/ecmascript7/samples/basic/extends.js new file mode 100644 index 00000000000..e6a647a98c2 --- /dev/null +++ b/tests/auto/qml/codemodel/ecmascript7/samples/basic/extends.js @@ -0,0 +1,33 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +class MyClass +{ +} + +class MySuperClass extends MyClass +{ +} + diff --git a/tests/auto/qml/codemodel/ecmascript7/samples/basic/let.js b/tests/auto/qml/codemodel/ecmascript7/samples/basic/let.js new file mode 100644 index 00000000000..a119db8ef6e --- /dev/null +++ b/tests/auto/qml/codemodel/ecmascript7/samples/basic/let.js @@ -0,0 +1,29 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +let x = 4; +let y = 2; +let z = x + y; + diff --git a/tests/auto/qml/codemodel/ecmascript7/samples/basic/super.js b/tests/auto/qml/codemodel/ecmascript7/samples/basic/super.js new file mode 100644 index 00000000000..b5f52791bfe --- /dev/null +++ b/tests/auto/qml/codemodel/ecmascript7/samples/basic/super.js @@ -0,0 +1,42 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +class MyClass +{ + constructor(id) + { + this.id = id; + } +} + +class MySuperClass extends MyClass +{ + constructor(id, data) + { + this.data = data; + super(id); + } +} + diff --git a/tests/auto/qml/codemodel/ecmascript7/samples/basic/template-strings.js b/tests/auto/qml/codemodel/ecmascript7/samples/basic/template-strings.js new file mode 100644 index 00000000000..42a5b606e7f --- /dev/null +++ b/tests/auto/qml/codemodel/ecmascript7/samples/basic/template-strings.js @@ -0,0 +1,28 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +var x = 42; +var s = `x = ${x}` + diff --git a/tests/auto/qml/codemodel/ecmascript7/samples/basic/yield.js b/tests/auto/qml/codemodel/ecmascript7/samples/basic/yield.js new file mode 100644 index 00000000000..0030069b63c --- /dev/null +++ b/tests/auto/qml/codemodel/ecmascript7/samples/basic/yield.js @@ -0,0 +1,29 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +function* f(i) { + yield i; +} + diff --git a/tests/auto/qml/codemodel/ecmascript7/tst_ecmascript7.cpp b/tests/auto/qml/codemodel/ecmascript7/tst_ecmascript7.cpp new file mode 100644 index 00000000000..fd6a54b59b9 --- /dev/null +++ b/tests/auto/qml/codemodel/ecmascript7/tst_ecmascript7.cpp @@ -0,0 +1,212 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace QmlJS; +using namespace QmlJS::AST; +using namespace QmlJS::StaticAnalysis; + +static QString getValue(const QString &data, + const QString &re, + const QString &defaultValue = QString::number(0)) +{ + const QRegularExpressionMatch m = QRegularExpression(re).match(data); + return m.hasMatch() ? m.captured(1) : defaultValue; +} + +struct TestData +{ + TestData(Document::MutablePtr document, int nSemanticMessages, int nStaticMessages) + : doc(document) + , semanticMessages(nSemanticMessages) + , staticMessages(nStaticMessages) + {} + Document::MutablePtr doc; + const int semanticMessages; + const int staticMessages; +}; + +static TestData testData(const QString &path) +{ + QFile file(path); + file.open(QFile::ReadOnly | QFile::Text); + const QString content = QString(file.readAll()); + file.close(); + + Document::MutablePtr doc = Document::create(path, Dialect::Qml); + doc->setSource(content); + doc->parse(); + const QString nSemantic = getValue(content, "//\\s*ExpectedSemanticMessages: (\\d+)"); + const QString nStatic = getValue(content, "//\\s*ExpectedStaticMessages: (\\d+)"); + return TestData(doc, nSemantic.toInt(), nStatic.toInt()); +} + +static QStringList readSkipList(const QDir &dir, const QString &filename) +{ + QFile f(dir.absoluteFilePath(filename)); + QStringList result; + + if (!f.open(QIODevice::ReadOnly | QIODevice::Text)) + return QStringList(); + + while (!f.atEnd()) { + const QString s = f.readLine().trimmed(); + if (!s.isEmpty()) + result << dir.absoluteFilePath(s); + } + return result; +} + +void printUnexpectedMessages(const QmlJSTools::SemanticInfo &info, int nSemantic, int nStatic) +{ + if (nSemantic == 0 && info.semanticMessages.length() > 0) + for (auto msg: info.semanticMessages) + qDebug() << msg.message; + if (nStatic == 0 && info.staticAnalysisMessages.length() > 0) + for (auto msg: info.staticAnalysisMessages) + qDebug() << msg.message; + return; +} + +class tst_Ecmascript : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + void test_data(); + void test(); + +private: + QList m_files; + QStringList m_basePaths; +}; + +void tst_Ecmascript::initTestCase() +{ + QDir sampledir(TESTSRCDIR "/samples/"); + + QDirIterator it(sampledir, QDirIterator::Subdirectories); + + QStringList skipList = readSkipList(sampledir, QLatin1Literal("skip.txt")); + while (it.hasNext()) { + QString path = it.next(); + if (skipList.contains(path)) + continue; + QFileInfo f(path); + if (f.isFile() && f.suffix() == QLatin1Literal("js")) + m_files << f; + } + + m_basePaths.append(QLibraryInfo::location(QLibraryInfo::Qml2ImportsPath)); + + if (!ModelManagerInterface::instance()) + new ModelManagerInterface; + + if (!ExtensionSystem::PluginManager::instance()) + new ExtensionSystem::PluginManager; +} + +void tst_Ecmascript::test_data() +{ + QTest::addColumn("filename"); + QTest::addColumn("nSemanticMessages"); + QTest::addColumn("nStaticMessages"); + + + for (const QFileInfo& f: m_files) + QTest::newRow(f.fileName().toLatin1().data()) << f.absoluteFilePath(); +} + +void tst_Ecmascript::test() +{ + QFETCH(QString, filename); + + ModelManagerInterface *modelManager = ModelManagerInterface::instance(); + + QFutureInterface result; + PathsAndLanguages lPaths; + QStringList paths(m_basePaths); + for (auto p: paths) + lPaths.maybeInsert(Utils::FileName::fromString(p), Dialect::Qml); + ModelManagerInterface::importScan(result, ModelManagerInterface::workingCopy(), lPaths, + ModelManagerInterface::instance(), false); + + TestData data = testData(filename); + Document::MutablePtr doc = data.doc; + int nExpectedSemanticMessages = data.semanticMessages; + int nExpectedStaticMessages = data.staticMessages; + QVERIFY(!doc->source().isEmpty()); + + Snapshot snapshot = modelManager->snapshot(); + + QmlJSTools::SemanticInfo semanticInfo; + semanticInfo.document = doc; + semanticInfo.snapshot = snapshot; + + Link link(semanticInfo.snapshot, modelManager->defaultVContext(doc->language(), doc), + modelManager->builtins(doc)); + + semanticInfo.context = link(doc, &semanticInfo.semanticMessages); + + ScopeChain *scopeChain = new ScopeChain(doc, semanticInfo.context); + semanticInfo.setRootScopeChain(QSharedPointer(scopeChain)); + + Check checker(doc, semanticInfo.context); + semanticInfo.staticAnalysisMessages = checker(); + + printUnexpectedMessages(semanticInfo, nExpectedSemanticMessages, nExpectedStaticMessages); + + QCOMPARE(semanticInfo.semanticMessages.length(), nExpectedSemanticMessages); + QCOMPARE(semanticInfo.staticAnalysisMessages.length(), nExpectedStaticMessages); +} + +QTEST_MAIN(tst_Ecmascript) + +#include "tst_ecmascript7.moc"