diff options
author | Christian Stenger <christian.stenger@qt.io> | 2018-07-09 10:43:31 +0200 |
---|---|---|
committer | Christian Stenger <christian.stenger@qt.io> | 2018-07-12 11:26:07 +0000 |
commit | 3a4592609c510dd18041cf3635d4c14477c585a6 (patch) | |
tree | b40b9d28ac2709324b1dda1a75dfadc111a97688 | |
parent | 0471fc0f4685c8e2f821322fd2c56a4beafbd245 (diff) |
AutoTest: Handle direct usage of quick_test_main
If users need to register additional QML types before Qt5.12
they need to bend the Quick tests magic a bit and use
quick_test_main or quick_test_main_with_setup directly.
The plugin supports something similar for QTest::qExec, so
allow this for Quick tests as well.
Task-number: QTCREATORBUG-20746
Change-Id: I672f8410914c6cc77abc901998f419dda35755ae
Reviewed-by: Ivan Donchevskii <ivan.donchevskii@qt.io>
-rw-r--r-- | src/plugins/autotest/quick/quicktestparser.cpp | 18 | ||||
-rw-r--r-- | src/plugins/autotest/quick/quicktestvisitors.cpp | 44 | ||||
-rw-r--r-- | src/plugins/autotest/quick/quicktestvisitors.h | 16 |
3 files changed, 75 insertions, 3 deletions
diff --git a/src/plugins/autotest/quick/quicktestparser.cpp b/src/plugins/autotest/quick/quicktestparser.cpp index 91c1bfb36e..6e9b4ae82e 100644 --- a/src/plugins/autotest/quick/quicktestparser.cpp +++ b/src/plugins/autotest/quick/quicktestparser.cpp @@ -108,7 +108,8 @@ static QString quickTestSrcDir(const CppTools::CppModelManager *cppMM, return QString(); } -static QString quickTestName(const CPlusPlus::Document::Ptr &doc) +static QString quickTestName(const CPlusPlus::Document::Ptr &doc, + const CPlusPlus::Snapshot &snapshot) { const QList<CPlusPlus::Document::MacroUse> macros = doc->macroUses(); @@ -122,7 +123,18 @@ static QString quickTestName(const CPlusPlus::Document::Ptr &doc) .mid(arg.bytesBegin(), arg.bytesEnd() - arg.bytesBegin())); } } - return QString(); + + // check for using quick_test_main() directly + const QString fileName = doc->fileName(); + const QByteArray &fileContent = CppParser::getFileContent(fileName); + CPlusPlus::Document::Ptr document = snapshot.preprocessedDocument(fileContent, fileName); + if (document.isNull()) + return QString(); + document->check(); + CPlusPlus::AST *ast = document->translationUnit()->ast(); + QuickTestAstVisitor astVisitor(document, snapshot); + astVisitor.accept(ast); + return astVisitor.testBaseName(); } QList<QmlJS::Document::Ptr> QuickTestParser::scanDirectoryForQuickTestQmlFiles(const QString &srcDir) const @@ -215,7 +227,7 @@ bool QuickTestParser::handleQtQuickTest(QFutureInterface<TestParseResultPtr> fut const Core::Id &id) { const CppTools::CppModelManager *modelManager = CppTools::CppModelManager::instance(); - if (quickTestName(document).isEmpty()) + if (quickTestName(document, m_cppSnapshot).isEmpty()) return false; const QString cppFileName = document->fileName(); diff --git a/src/plugins/autotest/quick/quicktestvisitors.cpp b/src/plugins/autotest/quick/quicktestvisitors.cpp index 9e4752821b..cbc5f9b2a2 100644 --- a/src/plugins/autotest/quick/quicktestvisitors.cpp +++ b/src/plugins/autotest/quick/quicktestvisitors.cpp @@ -25,6 +25,7 @@ #include "quicktestvisitors.h" +#include <cplusplus/Overview.h> #include <qmljs/parser/qmljsast_p.h> #include <qmljs/qmljsbind.h> #include <qmljs/qmljslink.h> @@ -161,5 +162,48 @@ bool TestQmlVisitor::visit(QmlJS::AST::StringLiteral *ast) return false; } +/************************************** QuickTestAstVisitor *************************************/ + +QuickTestAstVisitor::QuickTestAstVisitor(CPlusPlus::Document::Ptr doc, + const CPlusPlus::Snapshot &snapshot) + : ASTVisitor(doc->translationUnit()) + , m_currentDoc(doc) + , m_snapshot(snapshot) +{ +} + +bool QuickTestAstVisitor::visit(CPlusPlus::CallAST *ast) +{ + if (m_currentDoc.isNull()) + return false; + + if (const auto expressionAST = ast->base_expression) { + if (const auto idExpressionAST = expressionAST->asIdExpression()) { + if (const auto simpleNameAST = idExpressionAST->name->asSimpleName()) { + const CPlusPlus::Overview o; + const QString prettyName = o.prettyName(simpleNameAST->name); + if (prettyName == "quick_test_main" || prettyName == "quick_test_main_with_setup") { + if (auto expressionListAST = ast->expression_list) { + // third argument is the one we need, so skip current and next + expressionListAST = expressionListAST->next; // argv + expressionListAST = expressionListAST ? expressionListAST->next : nullptr; // testcase literal + + if (expressionListAST && expressionListAST->value) { + const auto *stringLitAST = expressionListAST->value->asStringLiteral(); + const auto *string + = translationUnit()->stringLiteral(stringLitAST->literal_token); + if (string) { + m_testBaseName = QString::fromUtf8(string->chars(), + int(string->size())); + } + } + } + } + } + } + } + return false; +} + } // namespace Internal } // namespace Autotest diff --git a/src/plugins/autotest/quick/quicktestvisitors.h b/src/plugins/autotest/quick/quicktestvisitors.h index f131339475..025ce0198d 100644 --- a/src/plugins/autotest/quick/quicktestvisitors.h +++ b/src/plugins/autotest/quick/quicktestvisitors.h @@ -27,6 +27,8 @@ #include "quicktesttreeitem.h" +#include <cplusplus/ASTVisitor.h> +#include <cplusplus/CppDocument.h> #include <qmljs/parser/qmljsastvisitor_p.h> #include <qmljs/qmljsdocument.h> @@ -65,5 +67,19 @@ private: bool m_expectTestCaseName = false; }; +class QuickTestAstVisitor : public CPlusPlus::ASTVisitor +{ +public: + QuickTestAstVisitor(CPlusPlus::Document::Ptr doc, const CPlusPlus::Snapshot &snapshot); + + bool visit(CPlusPlus::CallAST *ast) override; + + QString testBaseName() const { return m_testBaseName; } +private: + QString m_testBaseName; + CPlusPlus::Document::Ptr m_currentDoc; + CPlusPlus::Snapshot m_snapshot; +}; + } // namespace Internal } // namespace Autotest |