summaryrefslogtreecommitdiff
path: root/src/plugins/autotest
diff options
context:
space:
mode:
authorEike Ziller <eike.ziller@qt.io>2019-07-31 08:27:20 +0200
committerEike Ziller <eike.ziller@qt.io>2019-07-31 08:27:20 +0200
commit7de82409fc39248bf2af4ad1146d9e0855afde11 (patch)
treed2f5eb76e54d9e17769bea274df4045244d90cf1 /src/plugins/autotest
parent86c4416af6c0ab08acab33b9b34abd9cdebfa5a1 (diff)
parente425d88b6b4ff7762a441693fc814c1b2cf87377 (diff)
downloadqt-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.cpp8
-rw-r--r--src/plugins/autotest/quick/quicktestparser.cpp57
-rw-r--r--src/plugins/autotest/quick/quicktesttreeitem.cpp20
-rw-r--r--src/plugins/autotest/quick/quicktesttreeitem.h2
-rw-r--r--src/plugins/autotest/quick/quicktestvisitors.cpp34
-rw-r--r--src/plugins/autotest/quick/quicktestvisitors.h30
-rw-r--r--src/plugins/autotest/unit_test/mixed_atp/tests/auto/quickauto/tst_test2.qml49
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);
+ }
+ }
}