diff options
author | Eike Ziller <eike.ziller@qt.io> | 2019-07-31 08:27:20 +0200 |
---|---|---|
committer | Eike Ziller <eike.ziller@qt.io> | 2019-07-31 08:27:20 +0200 |
commit | 7de82409fc39248bf2af4ad1146d9e0855afde11 (patch) | |
tree | d2f5eb76e54d9e17769bea274df4045244d90cf1 /src/plugins/autotest | |
parent | 86c4416af6c0ab08acab33b9b34abd9cdebfa5a1 (diff) | |
parent | e425d88b6b4ff7762a441693fc814c1b2cf87377 (diff) | |
download | qt-creator-7de82409fc39248bf2af4ad1146d9e0855afde11.tar.gz |
Merge remote-tracking branch 'origin/4.10'
Change-Id: I7a7bc552e09de1fbee98402c97e3a35f0e2c952a
Diffstat (limited to 'src/plugins/autotest')
-rw-r--r-- | src/plugins/autotest/autotestunittests.cpp | 8 | ||||
-rw-r--r-- | src/plugins/autotest/quick/quicktestparser.cpp | 57 | ||||
-rw-r--r-- | src/plugins/autotest/quick/quicktesttreeitem.cpp | 20 | ||||
-rw-r--r-- | src/plugins/autotest/quick/quicktesttreeitem.h | 2 | ||||
-rw-r--r-- | src/plugins/autotest/quick/quicktestvisitors.cpp | 34 | ||||
-rw-r--r-- | src/plugins/autotest/quick/quicktestvisitors.h | 30 | ||||
-rw-r--r-- | src/plugins/autotest/unit_test/mixed_atp/tests/auto/quickauto/tst_test2.qml | 49 |
7 files changed, 123 insertions, 77 deletions
diff --git a/src/plugins/autotest/autotestunittests.cpp b/src/plugins/autotest/autotestunittests.cpp index 614a61a6c2..b571ed1354 100644 --- a/src/plugins/autotest/autotestunittests.cpp +++ b/src/plugins/autotest/autotestunittests.cpp @@ -131,13 +131,13 @@ void AutoTestUnitTests::testCodeParser_data() << 1 << 0 << 0 << 0; QTest::newRow("mixedAutoTestAndQuickTests") << QString(m_tmpDir->path() + "/mixed_atp/mixed_atp.pro") - << 4 << 7 << 3 << 10; + << 4 << 10 << 4 << 10; QTest::newRow("plainAutoTestQbs") << QString(m_tmpDir->path() + "/plain/plain.qbs") << 1 << 0 << 0 << 0; QTest::newRow("mixedAutoTestAndQuickTestsQbs") << QString(m_tmpDir->path() + "/mixed_atp/mixed_atp.qbs") - << 4 << 7 << 3 << 10; + << 4 << 10 << 4 << 10; } void AutoTestUnitTests::testCodeParserSwitchStartup() @@ -183,8 +183,8 @@ void AutoTestUnitTests::testCodeParserSwitchStartup_data() m_tmpDir->path() + "/mixed_atp/mixed_atp.qbs"}); QList<int> expectedAutoTests = QList<int>() << 1 << 4 << 1 << 4; - QList<int> expectedNamedQuickTests = QList<int>() << 0 << 7 << 0 << 7; - QList<int> expectedUnnamedQuickTests = QList<int>() << 0 << 3 << 0 << 3; + QList<int> expectedNamedQuickTests = QList<int>() << 0 << 10 << 0 << 10; + QList<int> expectedUnnamedQuickTests = QList<int>() << 0 << 4 << 0 << 4; QList<int> expectedDataTagsCount = QList<int>() << 0 << 10 << 0 << 10; QTest::newRow("loadMultipleProjects") diff --git a/src/plugins/autotest/quick/quicktestparser.cpp b/src/plugins/autotest/quick/quicktestparser.cpp index 2542325510..72592b32a0 100644 --- a/src/plugins/autotest/quick/quicktestparser.cpp +++ b/src/plugins/autotest/quick/quicktestparser.cpp @@ -190,35 +190,36 @@ static bool checkQmlDocumentForQuickTestCode(QFutureInterface<TestParseResultPtr if (!qmlVisitor.isValid()) return false; - const QString testCaseName = qmlVisitor.testCaseName(); - const TestCodeLocationAndType tcLocationAndType = qmlVisitor.testCaseLocation(); - const QMap<QString, TestCodeLocationAndType> &testFunctions = qmlVisitor.testFunctions(); - - QuickTestParseResult *parseResult = new QuickTestParseResult(id); - parseResult->proFile = proFile; - parseResult->itemType = TestTreeItem::TestCase; - QMap<QString, TestCodeLocationAndType>::ConstIterator it = testFunctions.begin(); - const QMap<QString, TestCodeLocationAndType>::ConstIterator end = testFunctions.end(); - for ( ; it != end; ++it) { - const TestCodeLocationAndType &loc = it.value(); - QuickTestParseResult *funcResult = new QuickTestParseResult(id); - funcResult->name = it.key(); - funcResult->displayName = it.key(); - funcResult->itemType = loc.m_type; - funcResult->fileName = loc.m_name; - funcResult->line = loc.m_line; - funcResult->column = loc.m_column; - funcResult->proFile = proFile; - - parseResult->children.append(funcResult); - } - if (!testCaseName.isEmpty()) { - parseResult->fileName = tcLocationAndType.m_name; - parseResult->name = testCaseName; - parseResult->line = tcLocationAndType.m_line; - parseResult->column = tcLocationAndType.m_column; + const QVector<QuickTestCaseSpec> &testCases = qmlVisitor.testCases(); + + for (const QuickTestCaseSpec &testCase : testCases) { + const QString testCaseName = testCase.m_caseName; + + QuickTestParseResult *parseResult = new QuickTestParseResult(id); + parseResult->proFile = proFile; + parseResult->itemType = TestTreeItem::TestCase; + if (!testCaseName.isEmpty()) { + parseResult->fileName = testCase.m_locationAndType.m_name; + parseResult->name = testCaseName; + parseResult->line = testCase.m_locationAndType.m_line; + parseResult->column = testCase.m_locationAndType.m_column; + } + + for (auto function : testCase.m_functions) { + QuickTestParseResult *funcResult = new QuickTestParseResult(id); + funcResult->name = function.m_functionName; + funcResult->displayName = function.m_functionName; + funcResult->itemType = function.m_locationAndType.m_type; + funcResult->fileName = function.m_locationAndType.m_name; + funcResult->line = function.m_locationAndType.m_line; + funcResult->column = function.m_locationAndType.m_column; + funcResult->proFile = proFile; + + parseResult->children.append(funcResult); + } + + futureInterface.reportResult(TestParseResultPtr(parseResult)); } - futureInterface.reportResult(TestParseResultPtr(parseResult)); return true; } diff --git a/src/plugins/autotest/quick/quicktesttreeitem.cpp b/src/plugins/autotest/quick/quicktesttreeitem.cpp index 52d3796463..c18de0ee9e 100644 --- a/src/plugins/autotest/quick/quicktesttreeitem.cpp +++ b/src/plugins/autotest/quick/quicktesttreeitem.cpp @@ -323,11 +323,11 @@ TestTreeItem *QuickTestTreeItem::find(const TestParseResult *result) TestTreeItem *group = findFirstLevelChild([path](TestTreeItem *group) { return group->filePath() == path; }); - return group ? group->findChildByFile(result->fileName) : nullptr; + return group ? group->findChildByNameAndFile(result->name, result->fileName) : nullptr; } - return findChildByFile(result->fileName); + return findChildByNameAndFile(result->name, result->fileName); case GroupNode: - return findChildByFile(result->fileName); + return findChildByNameAndFile(result->name, result->fileName); case TestCase: return name().isEmpty() ? findChildByNameAndFile(result->name, result->fileName) : findChildByName(result->name); @@ -345,9 +345,9 @@ TestTreeItem *QuickTestTreeItem::findChild(const TestTreeItem *other) case Root: if (otherType == TestCase && other->name().isEmpty()) return unnamedQuickTests(); - return findChildByFileAndType(other->filePath(), otherType); + return findChildByFileNameAndType(other->filePath(), other->name(), otherType); case GroupNode: - return findChildByFileAndType(other->filePath(), otherType); + return findChildByFileNameAndType(other->filePath(), other->name(), otherType); case TestCase: if (otherType != TestFunction && otherType != TestDataFunction && otherType != TestSpecialFunction) return nullptr; @@ -444,6 +444,16 @@ void QuickTestTreeItem::markForRemovalRecursively(const QString &filePath) } } +TestTreeItem *QuickTestTreeItem::findChildByFileNameAndType(const QString &filePath, + const QString &name, + TestTreeItem::Type tType) + +{ + return findFirstLevelChild([filePath, name, tType](const TestTreeItem *other) { + return other->type() == tType && other->name() == name && other->filePath() == filePath; + }); +} + TestTreeItem *QuickTestTreeItem::unnamedQuickTests() const { if (type() != Root) diff --git a/src/plugins/autotest/quick/quicktesttreeitem.h b/src/plugins/autotest/quick/quicktesttreeitem.h index b9f06d6a07..a9e48fca94 100644 --- a/src/plugins/autotest/quick/quicktesttreeitem.h +++ b/src/plugins/autotest/quick/quicktesttreeitem.h @@ -57,6 +57,8 @@ public: QSet<QString> internalTargets() const override; void markForRemovalRecursively(const QString &filePath) override; private: + TestTreeItem *findChildByFileNameAndType(const QString &filePath, const QString &name, + Type tType); TestTreeItem *unnamedQuickTests() const; }; diff --git a/src/plugins/autotest/quick/quicktestvisitors.cpp b/src/plugins/autotest/quick/quicktestvisitors.cpp index f9934e735d..f60b59b368 100644 --- a/src/plugins/autotest/quick/quicktestvisitors.cpp +++ b/src/plugins/autotest/quick/quicktestvisitors.cpp @@ -31,6 +31,7 @@ #include <qmljs/qmljslink.h> #include <qmljs/qmljsutils.h> #include <utils/algorithm.h> +#include <utils/qtcassert.h> namespace Autotest { namespace Internal { @@ -85,29 +86,29 @@ static bool isDerivedFromTestCase(QmlJS::AST::UiQualifiedId *id, const QmlJS::Do bool TestQmlVisitor::visit(QmlJS::AST::UiObjectDefinition *ast) { const QStringRef name = ast->qualifiedTypeNameId->name; - m_objectStack.push(name.toString()); + m_objectIsTestStack.push(false); if (name != "TestCase") { - m_insideTestCase = false; if (!isDerivedFromTestCase(ast->qualifiedTypeNameId, m_currentDoc, m_snapshot)) return true; } else if (!documentImportsQtTest(m_currentDoc.data())) { return true; // find nested TestCase items as well } - m_typeIsTestCase = true; - m_insideTestCase = true; - m_currentTestCaseName.clear(); + m_objectIsTestStack.top() = true; const auto sourceLocation = ast->firstSourceLocation(); - m_testCaseLocation.m_name = m_currentDoc->fileName(); - m_testCaseLocation.m_line = sourceLocation.startLine; - m_testCaseLocation.m_column = sourceLocation.startColumn - 1; - m_testCaseLocation.m_type = TestTreeItem::TestCase; + QuickTestCaseSpec currentSpec; + currentSpec.m_locationAndType.m_name = m_currentDoc->fileName(); + currentSpec.m_locationAndType.m_line = sourceLocation.startLine; + currentSpec.m_locationAndType.m_column = sourceLocation.startColumn - 1; + currentSpec.m_locationAndType.m_type = TestTreeItem::TestCase; + m_caseParseStack.push(currentSpec); return true; } void TestQmlVisitor::endVisit(QmlJS::AST::UiObjectDefinition *) { - m_insideTestCase = m_objectStack.pop() == "TestCase"; + if (!m_objectIsTestStack.isEmpty() && m_objectIsTestStack.pop() && !m_caseParseStack.isEmpty()) + m_testCases << m_caseParseStack.pop(); } bool TestQmlVisitor::visit(QmlJS::AST::ExpressionStatement *ast) @@ -118,7 +119,7 @@ bool TestQmlVisitor::visit(QmlJS::AST::ExpressionStatement *ast) bool TestQmlVisitor::visit(QmlJS::AST::UiScriptBinding *ast) { - if (m_insideTestCase) + if (m_objectIsTestStack.top()) m_expectTestCaseName = ast->qualifiedId->name == "name"; return m_expectTestCaseName; } @@ -131,6 +132,9 @@ void TestQmlVisitor::endVisit(QmlJS::AST::UiScriptBinding *) bool TestQmlVisitor::visit(QmlJS::AST::FunctionDeclaration *ast) { + if (m_caseParseStack.isEmpty()) + return false; + const QStringRef name = ast->name; if (name.startsWith("test_") || name.startsWith("benchmark_") @@ -148,15 +152,17 @@ bool TestQmlVisitor::visit(QmlJS::AST::FunctionDeclaration *ast) else locationAndType.m_type = TestTreeItem::TestFunction; - m_testFunctions.insert(name.toString(), locationAndType); + m_caseParseStack.top().m_functions.append( + QuickTestFunctionSpec{name.toString(), locationAndType}); } return false; } bool TestQmlVisitor::visit(QmlJS::AST::StringLiteral *ast) { - if (m_expectTestCaseName && m_currentTestCaseName.isEmpty()) { - m_currentTestCaseName = ast->value.toString(); + if (m_expectTestCaseName) { + QTC_ASSERT(!m_caseParseStack.isEmpty(), return false); + m_caseParseStack.top().m_caseName = ast->value.toString(); m_expectTestCaseName = false; } return false; diff --git a/src/plugins/autotest/quick/quicktestvisitors.h b/src/plugins/autotest/quick/quicktestvisitors.h index 025ce0198d..e4af8661c2 100644 --- a/src/plugins/autotest/quick/quicktestvisitors.h +++ b/src/plugins/autotest/quick/quicktestvisitors.h @@ -37,6 +37,21 @@ namespace Autotest { namespace Internal { +class QuickTestFunctionSpec +{ +public: + QString m_functionName; + TestCodeLocationAndType m_locationAndType; +}; + +class QuickTestCaseSpec +{ +public: + QString m_caseName; + TestCodeLocationAndType m_locationAndType; + QVector<QuickTestFunctionSpec> m_functions; +}; + class TestQmlVisitor : public QmlJS::AST::Visitor { public: @@ -50,20 +65,15 @@ public: bool visit(QmlJS::AST::FunctionDeclaration *ast) override; bool visit(QmlJS::AST::StringLiteral *ast) override; - QString testCaseName() const { return m_currentTestCaseName; } - TestCodeLocationAndType testCaseLocation() const { return m_testCaseLocation; } - QMap<QString, TestCodeLocationAndType> testFunctions() const { return m_testFunctions; } - bool isValid() const { return m_typeIsTestCase; } + QVector<QuickTestCaseSpec> testCases() const { return m_testCases; } + bool isValid() const { return !m_testCases.isEmpty(); } private: QmlJS::Document::Ptr m_currentDoc; QmlJS::Snapshot m_snapshot; - QString m_currentTestCaseName; - TestCodeLocationAndType m_testCaseLocation; - QMap<QString, TestCodeLocationAndType> m_testFunctions; - QStack<QString> m_objectStack; - bool m_typeIsTestCase = false; - bool m_insideTestCase = false; + QStack<QuickTestCaseSpec> m_caseParseStack; + QVector<QuickTestCaseSpec> m_testCases; + QStack<bool> m_objectIsTestStack; bool m_expectTestCaseName = false; }; diff --git a/src/plugins/autotest/unit_test/mixed_atp/tests/auto/quickauto/tst_test2.qml b/src/plugins/autotest/unit_test/mixed_atp/tests/auto/quickauto/tst_test2.qml index d0115c5dd7..b6330ac4ea 100644 --- a/src/plugins/autotest/unit_test/mixed_atp/tests/auto/quickauto/tst_test2.qml +++ b/src/plugins/autotest/unit_test/mixed_atp/tests/auto/quickauto/tst_test2.qml @@ -34,21 +34,38 @@ TestCase { verify(blubb == bla, "Comparing concat equality") } -// nested TestCases actually fail -// TestCase { -// name: "boo" - -// function test_boo() { -// verify(true); -// } - -// TestCase { -// name: "far" - -// function test_far() { -// verify(true); -// } -// } -// } + TestCase { + name: "boo" + + function test_boo() { + verify(true); + } + + TestCase { + name: "far" + + function test_far() { + verify(true); + } + } + + function test_boo2() { // should not get added to "far", but to "boo" + verify(false); + } + } + + TestCase { + name: "secondBoo" + + function test_bar() { + compare(1, 1); + } + } + + TestCase { // unnamed + function test_func() { + verify(true); + } + } } |