diff options
Diffstat (limited to 'tests/auto/qml/qqmlparser')
20 files changed, 224 insertions, 2 deletions
diff --git a/tests/auto/qml/qqmlparser/data/disallowedtypeannotations/anonfunctionexpr.js b/tests/auto/qml/qqmlparser/data/disallowedtypeannotations/anonfunctionexpr.js new file mode 100644 index 0000000000..f660edb69e --- /dev/null +++ b/tests/auto/qml/qqmlparser/data/disallowedtypeannotations/anonfunctionexpr.js @@ -0,0 +1,3 @@ +(function () : string { + return "ko" +}) diff --git a/tests/auto/qml/qqmlparser/data/disallowedtypeannotations/classmemberparam.js b/tests/auto/qml/qqmlparser/data/disallowedtypeannotations/classmemberparam.js new file mode 100644 index 0000000000..ab85d90880 --- /dev/null +++ b/tests/auto/qml/qqmlparser/data/disallowedtypeannotations/classmemberparam.js @@ -0,0 +1,6 @@ + +class Foo { + member(param: string) { + return "ko" + } +} diff --git a/tests/auto/qml/qqmlparser/data/disallowedtypeannotations/classreturnvalue.js b/tests/auto/qml/qqmlparser/data/disallowedtypeannotations/classreturnvalue.js new file mode 100644 index 0000000000..a7da9e0ca7 --- /dev/null +++ b/tests/auto/qml/qqmlparser/data/disallowedtypeannotations/classreturnvalue.js @@ -0,0 +1,6 @@ + +class Foo { + member(): string { + return "ko" + } +} diff --git a/tests/auto/qml/qqmlparser/data/disallowedtypeannotations/function.js b/tests/auto/qml/qqmlparser/data/disallowedtypeannotations/function.js new file mode 100644 index 0000000000..4d6021e835 --- /dev/null +++ b/tests/auto/qml/qqmlparser/data/disallowedtypeannotations/function.js @@ -0,0 +1,4 @@ + +function x() : string { + return "ok" +} diff --git a/tests/auto/qml/qqmlparser/data/disallowedtypeannotations/functionexpr.js b/tests/auto/qml/qqmlparser/data/disallowedtypeannotations/functionexpr.js new file mode 100644 index 0000000000..33f2abbb61 --- /dev/null +++ b/tests/auto/qml/qqmlparser/data/disallowedtypeannotations/functionexpr.js @@ -0,0 +1,3 @@ +(function x() : string { + return "ko" +}) diff --git a/tests/auto/qml/qqmlparser/data/disallowedtypeannotations/functionparams.js b/tests/auto/qml/qqmlparser/data/disallowedtypeannotations/functionparams.js new file mode 100644 index 0000000000..2c23628e3f --- /dev/null +++ b/tests/auto/qml/qqmlparser/data/disallowedtypeannotations/functionparams.js @@ -0,0 +1,3 @@ + +function test(x: string, y: string) { +} diff --git a/tests/auto/qml/qqmlparser/data/disallowedtypeannotations/iteration.js b/tests/auto/qml/qqmlparser/data/disallowedtypeannotations/iteration.js new file mode 100644 index 0000000000..a6cc00e38a --- /dev/null +++ b/tests/auto/qml/qqmlparser/data/disallowedtypeannotations/iteration.js @@ -0,0 +1,3 @@ + +for (var i: int = 0; i < 100; ++i) { +} diff --git a/tests/auto/qml/qqmlparser/data/disallowedtypeannotations/iteration2.js b/tests/auto/qml/qqmlparser/data/disallowedtypeannotations/iteration2.js new file mode 100644 index 0000000000..24d5acce98 --- /dev/null +++ b/tests/auto/qml/qqmlparser/data/disallowedtypeannotations/iteration2.js @@ -0,0 +1,5 @@ + +let y = [1, 2, 3]; + +for (let x: int of y) { +} diff --git a/tests/auto/qml/qqmlparser/data/disallowedtypeannotations/qmlnestedfunction.qml b/tests/auto/qml/qqmlparser/data/disallowedtypeannotations/qmlnestedfunction.qml new file mode 100644 index 0000000000..f435bf1b25 --- /dev/null +++ b/tests/auto/qml/qqmlparser/data/disallowedtypeannotations/qmlnestedfunction.qml @@ -0,0 +1,9 @@ +import QtQuick 2.12 as MyQuick +MyQuick.Item { + function factory(param: string) : MyQuick.Item { + function nested(foo: string) { + return this + } + return nested() + } +} diff --git a/tests/auto/qml/qqmlparser/data/disallowedtypeannotations/variables.js b/tests/auto/qml/qqmlparser/data/disallowedtypeannotations/variables.js new file mode 100644 index 0000000000..bf332ac7a8 --- /dev/null +++ b/tests/auto/qml/qqmlparser/data/disallowedtypeannotations/variables.js @@ -0,0 +1,2 @@ + +var x: string = "ko" diff --git a/tests/auto/qml/qqmlparser/data/typeannotations/basic_qmltypes_bool.qml b/tests/auto/qml/qqmlparser/data/typeannotations/basic_qmltypes_bool.qml new file mode 100644 index 0000000000..79a9ede3d4 --- /dev/null +++ b/tests/auto/qml/qqmlparser/data/typeannotations/basic_qmltypes_bool.qml @@ -0,0 +1,4 @@ +import QtQml 2.0 +QtObject { + function test() : bool { return true; } +} diff --git a/tests/auto/qml/qqmlparser/data/typeannotations/basic_qmltypes_double.qml b/tests/auto/qml/qqmlparser/data/typeannotations/basic_qmltypes_double.qml new file mode 100644 index 0000000000..f58e4b92d9 --- /dev/null +++ b/tests/auto/qml/qqmlparser/data/typeannotations/basic_qmltypes_double.qml @@ -0,0 +1,4 @@ +import QtQml 2.0 +QtObject { + function test() : double { return 0; } +} diff --git a/tests/auto/qml/qqmlparser/data/typeannotations/basic_qmltypes_int.qml b/tests/auto/qml/qqmlparser/data/typeannotations/basic_qmltypes_int.qml new file mode 100644 index 0000000000..267ad7191f --- /dev/null +++ b/tests/auto/qml/qqmlparser/data/typeannotations/basic_qmltypes_int.qml @@ -0,0 +1,4 @@ +import QtQml 2.0 +QtObject { + function test() : int { return 0; } +} diff --git a/tests/auto/qml/qqmlparser/data/typeannotations/basic_qmltypes_real.qml b/tests/auto/qml/qqmlparser/data/typeannotations/basic_qmltypes_real.qml new file mode 100644 index 0000000000..9973819ad2 --- /dev/null +++ b/tests/auto/qml/qqmlparser/data/typeannotations/basic_qmltypes_real.qml @@ -0,0 +1,4 @@ +import QtQml 2.0 +QtObject { + function test() : real { return 0; } +} diff --git a/tests/auto/qml/qqmlparser/data/typeannotations/basic_qmltypes_string.qml b/tests/auto/qml/qqmlparser/data/typeannotations/basic_qmltypes_string.qml new file mode 100644 index 0000000000..e632ec7154 --- /dev/null +++ b/tests/auto/qml/qqmlparser/data/typeannotations/basic_qmltypes_string.qml @@ -0,0 +1,4 @@ +import QtQml 2.0 +QtObject { + function test(s: string) {} +} diff --git a/tests/auto/qml/qqmlparser/data/typeannotations/basic_qmltypes_url.qml b/tests/auto/qml/qqmlparser/data/typeannotations/basic_qmltypes_url.qml new file mode 100644 index 0000000000..ebf3f32561 --- /dev/null +++ b/tests/auto/qml/qqmlparser/data/typeannotations/basic_qmltypes_url.qml @@ -0,0 +1,4 @@ +import QtQml 2.0 +QtObject { + function test(u: url) {} +} diff --git a/tests/auto/qml/qqmlparser/data/typeannotations/parametrized.qml b/tests/auto/qml/qqmlparser/data/typeannotations/parametrized.qml new file mode 100644 index 0000000000..d80b5e3f87 --- /dev/null +++ b/tests/auto/qml/qqmlparser/data/typeannotations/parametrized.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 as MyQuick +MyQuick.Item { + function factory() : list<MyQuick.Item> { + } +} diff --git a/tests/auto/qml/qqmlparser/data/typeannotations/qmlfunction.qml b/tests/auto/qml/qqmlparser/data/typeannotations/qmlfunction.qml new file mode 100644 index 0000000000..cd5c1f51e5 --- /dev/null +++ b/tests/auto/qml/qqmlparser/data/typeannotations/qmlfunction.qml @@ -0,0 +1,6 @@ +import QtQuick 2.12 as MyQuick +MyQuick.Item { + function factory(param: string) : MyQuick.Item { + return this + } +} diff --git a/tests/auto/qml/qqmlparser/qqmlparser.pro b/tests/auto/qml/qqmlparser/qqmlparser.pro index 74cb620f06..d8e4b0dd06 100644 --- a/tests/auto/qml/qqmlparser/qqmlparser.pro +++ b/tests/auto/qml/qqmlparser/qqmlparser.pro @@ -7,3 +7,7 @@ SOURCES += tst_qqmlparser.cpp DEFINES += SRCDIR=\\\"$$PWD\\\" cross_compile: DEFINES += QTEST_CROSS_COMPILED + +TESTDATA = data/* + +include (../../shared/util.pri) diff --git a/tests/auto/qml/qqmlparser/tst_qqmlparser.cpp b/tests/auto/qml/qqmlparser/tst_qqmlparser.cpp index f16e96a385..9d8818d01e 100644 --- a/tests/auto/qml/qqmlparser/tst_qqmlparser.cpp +++ b/tests/auto/qml/qqmlparser/tst_qqmlparser.cpp @@ -32,12 +32,14 @@ #include <private/qqmljsastvisitor_p.h> #include <private/qqmljsast_p.h> +#include "../../shared/util.h" + #include <qtest.h> #include <QDir> #include <QDebug> #include <cstdlib> -class tst_qqmlparser : public QObject +class tst_qqmlparser : public QQmlDataTest { Q_OBJECT public: @@ -55,6 +57,11 @@ private slots: void templateLiteral(); void leadingSemicolonInClass(); void templatedReadonlyProperty(); + void qmlImportInJSRequiresFullVersion(); + void typeAnnotations_data(); + void typeAnnotations(); + void disallowedTypeAnnotations_data(); + void disallowedTypeAnnotations(); private: QStringList excludedDirs; @@ -87,7 +94,7 @@ public: qDebug() << "first source loc failed: node:" << node->kind << "at" << node->firstSourceLocation().startLine << "/" << node->firstSourceLocation().startColumn << "parent" << parent->kind << "at" << parent->firstSourceLocation().startLine << "/" << parent->firstSourceLocation().startColumn; if (node->lastSourceLocation().end() > parentEnd) - qDebug() << "first source loc failed: node:" << node->kind << "at" << node->lastSourceLocation().startLine << "/" << node->lastSourceLocation().startColumn + qDebug() << "last source loc failed: node:" << node->kind << "at" << node->lastSourceLocation().startLine << "/" << node->lastSourceLocation().startColumn << "parent" << parent->kind << "at" << parent->lastSourceLocation().startLine << "/" << parent->lastSourceLocation().startColumn; QVERIFY(node->firstSourceLocation().begin() >= parentBegin); @@ -113,6 +120,27 @@ public: } }; +struct TypeAnnotationObserver: public AST::Visitor +{ + bool typeAnnotationSeen = false; + + void operator()(AST::Node *node) + { + AST::Node::accept(node, this); + } + + virtual bool visit(AST::TypeAnnotation *) + { + typeAnnotationSeen = true; + return true; + } + + void throwRecursionDepthError() final + { + QFAIL("Maximum statement or expression depth exceeded"); + } +}; + } tst_qqmlparser::tst_qqmlparser() @@ -121,6 +149,7 @@ tst_qqmlparser::tst_qqmlparser() void tst_qqmlparser::initTestCase() { + QQmlDataTest::initTestCase(); // Add directories you want excluded here // These snippets are not expected to run on their own. @@ -299,6 +328,116 @@ void tst_qqmlparser::templatedReadonlyProperty() QVERIFY(parser.parse()); } +void tst_qqmlparser::qmlImportInJSRequiresFullVersion() +{ + { + QQmlJS::Engine engine; + QQmlJS::Lexer lexer(&engine); + lexer.setCode(QLatin1String(".import Test 1.0 as T"), 0, false); + QQmlJS::Parser parser(&engine); + bool b = parser.parseProgram(); + qDebug() << parser.errorMessage(); + QVERIFY(b); + } + { + QQmlJS::Engine engine; + QQmlJS::Lexer lexer(&engine); + lexer.setCode(QLatin1String(".import Test 1 as T"), 0, false); + QQmlJS::Parser parser(&engine); + QVERIFY(!parser.parseProgram()); + } + { + QQmlJS::Engine engine; + QQmlJS::Lexer lexer(&engine); + lexer.setCode(QLatin1String(".import Test 1 as T"), 0, false); + QQmlJS::Parser parser(&engine); + QVERIFY(!parser.parseProgram()); + } + { + QQmlJS::Engine engine; + QQmlJS::Lexer lexer(&engine); + lexer.setCode(QLatin1String(".import Test as T"), 0, false); + QQmlJS::Parser parser(&engine); + QVERIFY(!parser.parseProgram()); + } +} + +void tst_qqmlparser::typeAnnotations_data() +{ + QTest::addColumn<QString>("file"); + + QString tests = dataDirectory() + "/typeannotations/"; + + QStringList files; + files << findFiles(QDir(tests)); + + for (const QString &file: qAsConst(files)) + QTest::newRow(qPrintable(file)) << file; +} + +void tst_qqmlparser::typeAnnotations() +{ + using namespace QQmlJS; + + QFETCH(QString, file); + + QString code; + + QFile f(file); + if (f.open(QFile::ReadOnly)) + code = QString::fromUtf8(f.readAll()); + + const bool qmlMode = file.endsWith(QLatin1String(".qml")); + + Engine engine; + Lexer lexer(&engine); + lexer.setCode(code, 1, qmlMode); + Parser parser(&engine); + bool ok = qmlMode ? parser.parse() : parser.parseProgram(); + QVERIFY(ok); + + check::TypeAnnotationObserver observer; + observer(parser.rootNode()); + + QVERIFY(observer.typeAnnotationSeen); +} + +void tst_qqmlparser::disallowedTypeAnnotations_data() +{ + QTest::addColumn<QString>("file"); + + QString tests = dataDirectory() + "/disallowedtypeannotations/"; + + QStringList files; + files << findFiles(QDir(tests)); + + for (const QString &file: qAsConst(files)) + QTest::newRow(qPrintable(file)) << file; +} + +void tst_qqmlparser::disallowedTypeAnnotations() +{ + using namespace QQmlJS; + + QFETCH(QString, file); + + QString code; + + QFile f(file); + if (f.open(QFile::ReadOnly)) + code = QString::fromUtf8(f.readAll()); + + const bool qmlMode = file.endsWith(QLatin1String(".qml")); + + Engine engine; + Lexer lexer(&engine); + lexer.setCode(code, 1, qmlMode); + Parser parser(&engine); + bool ok = qmlMode ? parser.parse() : parser.parseProgram(); + QVERIFY(!ok); + QVERIFY2(parser.errorMessage().startsWith("Type annotations are not permitted "), qPrintable(parser.errorMessage())); +} + QTEST_MAIN(tst_qqmlparser) #include "tst_qqmlparser.moc" |