AutoTest: Fix detection of Quick tests name

Avoid setting and overwriting the test case name with
any string literal we find inside the TestCase item.
Instead use only the string literal used for the name
property and do not overwrite it after it had been set.

Task-number: QTCREATORBUG-20642
Change-Id: I69aedfc9f51df4943370c4736e6aa2af4c39b697
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Christian Stenger
2018-06-20 10:12:04 +02:00
parent 1b6a3fe493
commit 31050ad6fc
2 changed files with 32 additions and 8 deletions

View File

@@ -84,7 +84,9 @@ static bool isDerivedFromTestCase(QmlJS::AST::UiQualifiedId *id, const QmlJS::Do
bool TestQmlVisitor::visit(QmlJS::AST::UiObjectDefinition *ast) bool TestQmlVisitor::visit(QmlJS::AST::UiObjectDefinition *ast)
{ {
const QStringRef name = ast->qualifiedTypeNameId->name; const QStringRef name = ast->qualifiedTypeNameId->name;
m_objectStack.push(name.toString());
if (name != "TestCase") { if (name != "TestCase") {
m_insideTestCase = false;
if (!isDerivedFromTestCase(ast->qualifiedTypeNameId, m_currentDoc, m_snapshot)) if (!isDerivedFromTestCase(ast->qualifiedTypeNameId, m_currentDoc, m_snapshot))
return true; return true;
} else if (!documentImportsQtTest(m_currentDoc.data())) { } else if (!documentImportsQtTest(m_currentDoc.data())) {
@@ -92,6 +94,7 @@ bool TestQmlVisitor::visit(QmlJS::AST::UiObjectDefinition *ast)
} }
m_typeIsTestCase = true; m_typeIsTestCase = true;
m_insideTestCase = true;
m_currentTestCaseName.clear(); m_currentTestCaseName.clear();
const auto sourceLocation = ast->firstSourceLocation(); const auto sourceLocation = ast->firstSourceLocation();
m_testCaseLocation.m_name = m_currentDoc->fileName(); m_testCaseLocation.m_name = m_currentDoc->fileName();
@@ -101,6 +104,11 @@ bool TestQmlVisitor::visit(QmlJS::AST::UiObjectDefinition *ast)
return true; return true;
} }
void TestQmlVisitor::endVisit(QmlJS::AST::UiObjectDefinition *)
{
m_insideTestCase = m_objectStack.pop() == "TestCase";
}
bool TestQmlVisitor::visit(QmlJS::AST::ExpressionStatement *ast) bool TestQmlVisitor::visit(QmlJS::AST::ExpressionStatement *ast)
{ {
const QmlJS::AST::ExpressionNode *expr = ast->expression; const QmlJS::AST::ExpressionNode *expr = ast->expression;
@@ -109,8 +117,15 @@ bool TestQmlVisitor::visit(QmlJS::AST::ExpressionStatement *ast)
bool TestQmlVisitor::visit(QmlJS::AST::UiScriptBinding *ast) bool TestQmlVisitor::visit(QmlJS::AST::UiScriptBinding *ast)
{ {
const QStringRef name = ast->qualifiedId->name; if (m_insideTestCase)
return name == "name"; m_expectTestCaseName = ast->qualifiedId->name == "name";
return m_expectTestCaseName;
}
void TestQmlVisitor::endVisit(QmlJS::AST::UiScriptBinding *)
{
if (m_expectTestCaseName)
m_expectTestCaseName = false;
} }
bool TestQmlVisitor::visit(QmlJS::AST::FunctionDeclaration *ast) bool TestQmlVisitor::visit(QmlJS::AST::FunctionDeclaration *ast)
@@ -139,8 +154,10 @@ bool TestQmlVisitor::visit(QmlJS::AST::FunctionDeclaration *ast)
bool TestQmlVisitor::visit(QmlJS::AST::StringLiteral *ast) bool TestQmlVisitor::visit(QmlJS::AST::StringLiteral *ast)
{ {
if (m_typeIsTestCase) if (m_expectTestCaseName && m_currentTestCaseName.isEmpty()) {
m_currentTestCaseName = ast->value.toString(); m_currentTestCaseName = ast->value.toString();
m_expectTestCaseName = false;
}
return false; return false;
} }

View File

@@ -30,6 +30,8 @@
#include <qmljs/parser/qmljsastvisitor_p.h> #include <qmljs/parser/qmljsastvisitor_p.h>
#include <qmljs/qmljsdocument.h> #include <qmljs/qmljsdocument.h>
#include <QStack>
namespace Autotest { namespace Autotest {
namespace Internal { namespace Internal {
@@ -38,11 +40,13 @@ class TestQmlVisitor : public QmlJS::AST::Visitor
public: public:
explicit TestQmlVisitor(QmlJS::Document::Ptr doc, const QmlJS::Snapshot &snapshot); explicit TestQmlVisitor(QmlJS::Document::Ptr doc, const QmlJS::Snapshot &snapshot);
bool visit(QmlJS::AST::UiObjectDefinition *ast); bool visit(QmlJS::AST::UiObjectDefinition *ast) override;
bool visit(QmlJS::AST::ExpressionStatement *ast); void endVisit(QmlJS::AST::UiObjectDefinition *ast) override;
bool visit(QmlJS::AST::UiScriptBinding *ast); bool visit(QmlJS::AST::ExpressionStatement *ast) override;
bool visit(QmlJS::AST::FunctionDeclaration *ast); bool visit(QmlJS::AST::UiScriptBinding *ast) override;
bool visit(QmlJS::AST::StringLiteral *ast); void endVisit(QmlJS::AST::UiScriptBinding *ast) override;
bool visit(QmlJS::AST::FunctionDeclaration *ast) override;
bool visit(QmlJS::AST::StringLiteral *ast) override;
QString testCaseName() const { return m_currentTestCaseName; } QString testCaseName() const { return m_currentTestCaseName; }
TestCodeLocationAndType testCaseLocation() const { return m_testCaseLocation; } TestCodeLocationAndType testCaseLocation() const { return m_testCaseLocation; }
@@ -55,7 +59,10 @@ private:
QString m_currentTestCaseName; QString m_currentTestCaseName;
TestCodeLocationAndType m_testCaseLocation; TestCodeLocationAndType m_testCaseLocation;
QMap<QString, TestCodeLocationAndType> m_testFunctions; QMap<QString, TestCodeLocationAndType> m_testFunctions;
QStack<QString> m_objectStack;
bool m_typeIsTestCase = false; bool m_typeIsTestCase = false;
bool m_insideTestCase = false;
bool m_expectTestCaseName = false;
}; };
} // namespace Internal } // namespace Internal