diff --git a/src/plugins/autotest/testcodeparser.cpp b/src/plugins/autotest/testcodeparser.cpp index 5b772de7788..5e6403e75cb 100644 --- a/src/plugins/autotest/testcodeparser.cpp +++ b/src/plugins/autotest/testcodeparser.cpp @@ -456,7 +456,7 @@ static bool checkQmlDocumentForTestCode(QFutureInterface fut const TestCodeLocationAndType tcLocationAndType = qmlVisitor.testCaseLocation(); const QMap testFunctions = qmlVisitor.testFunctions(); - TestParseResultPtr parseResult(new TestParseResult(TestTreeModel::QuickTest)); + QuickTestParseResult *parseResult = new QuickTestParseResult(TestTreeModel::QuickTest); parseResult->proFile = proFile; parseResult->functions = testFunctions; if (!testCaseName.isEmpty()) { @@ -465,7 +465,7 @@ static bool checkQmlDocumentForTestCode(QFutureInterface fut parseResult->line = tcLocationAndType.m_line; parseResult->column = tcLocationAndType.m_column; } - futureInterface.reportResult(parseResult); + futureInterface.reportResult(TestParseResultPtr(parseResult)); return true; } @@ -498,16 +498,16 @@ static bool handleQtTest(QFutureInterface futureInterface, foreach (const QString &file, files) dataTags.unite(checkForDataTags(file)); - TestParseResultPtr parseResult(new TestParseResult(TestTreeModel::AutoTest)); + QtTestParseResult *parseResult = new QtTestParseResult(TestTreeModel::AutoTest); parseResult->fileName = declaringDoc->fileName(); parseResult->testCaseName = testCaseName; parseResult->line = line; parseResult->column = column; parseResult->functions = testFunctions; - parseResult->dataTagsOrTestSets = dataTags; + parseResult->dataTags = dataTags; parseResult->proFile = modelManager->projectPart(fileName).first()->projectFile; - futureInterface.reportResult(parseResult); + futureInterface.reportResult(TestParseResultPtr(parseResult)); return true; } return false; @@ -555,15 +555,15 @@ static bool handleGTest(QFutureInterface futureInterface, co proFile = ppList.first()->projectFile; foreach (const GTestCaseSpec &testSpec, result.keys()) { - TestParseResultPtr parseResult(new TestParseResult(TestTreeModel::GoogleTest)); + GoogleTestParseResult *parseResult = new GoogleTestParseResult(TestTreeModel::GoogleTest); parseResult->fileName = filePath; parseResult->testCaseName = testSpec.testCaseName; parseResult->parameterized = testSpec.parameterized; parseResult->typed = testSpec.typed; parseResult->disabled = testSpec.disabled; parseResult->proFile = proFile; - parseResult->dataTagsOrTestSets.insert(QString(), result.value(testSpec)); - futureInterface.reportResult(parseResult); + parseResult->testSets = result.value(testSpec); + futureInterface.reportResult(TestParseResultPtr(parseResult)); } return !result.keys().isEmpty(); } diff --git a/src/plugins/autotest/testcodeparser.h b/src/plugins/autotest/testcodeparser.h index d7d31b977a1..e7a139731ce 100644 --- a/src/plugins/autotest/testcodeparser.h +++ b/src/plugins/autotest/testcodeparser.h @@ -43,8 +43,46 @@ class Id; namespace Autotest { namespace Internal { -struct TestCodeLocationAndType; -struct GTestCaseSpec; +class TestParseResult +{ +public: + explicit TestParseResult(TestTreeModel::Type t = TestTreeModel::Invalid) : type(t) {} + virtual ~TestParseResult() {} + + TestTreeModel::Type type; + QString fileName; + QString proFile; + QString testCaseName; + unsigned line = 0; + unsigned column = 0; +}; + +class QtTestParseResult : public TestParseResult +{ +public: + QtTestParseResult(TestTreeModel::Type t = TestTreeModel::Invalid) : TestParseResult(t) {} + QMap functions; + QMap dataTags; +}; + +class QuickTestParseResult : public TestParseResult +{ +public: + QuickTestParseResult(TestTreeModel::Type t = TestTreeModel::Invalid) : TestParseResult(t) {} + QMap functions; +}; + +class GoogleTestParseResult : public TestParseResult +{ +public: + GoogleTestParseResult(TestTreeModel::Type t = TestTreeModel::Invalid) : TestParseResult(t) {} + bool parameterized = false; + bool typed = false; + bool disabled = false; + TestCodeLocationList testSets; +}; + +using TestParseResultPtr = QSharedPointer; class TestCodeParser : public QObject { @@ -106,3 +144,5 @@ private: } // namespace Internal } // Autotest + +Q_DECLARE_METATYPE(Autotest::Internal::TestParseResultPtr) diff --git a/src/plugins/autotest/testtreeitem.cpp b/src/plugins/autotest/testtreeitem.cpp index fec2216a76a..50d62c4d35d 100644 --- a/src/plugins/autotest/testtreeitem.cpp +++ b/src/plugins/autotest/testtreeitem.cpp @@ -25,6 +25,7 @@ #include "autotestconstants.h" #include "autotest_utils.h" +#include "testcodeparser.h" #include "testconfiguration.h" #include "testtreeitem.h" #include "testtreemodel.h" @@ -282,16 +283,17 @@ TestTreeItem *TestTreeItem::findChildBy(CompareFunction compare) AutoTestTreeItem *AutoTestTreeItem::createTestItem(const TestParseResult &result) { + const QtTestParseResult &parseResult = static_cast(result); AutoTestTreeItem *item = new AutoTestTreeItem(result.testCaseName, result.fileName, TestCase); - item->setProFile(result.proFile); - item->setLine(result.line); - item->setColumn(result.column); + item->setProFile(parseResult.proFile); + item->setLine(parseResult.line); + item->setColumn(parseResult.column); - foreach (const QString &functionName, result.functions.keys()) { - const TestCodeLocationAndType &locationAndType = result.functions.value(functionName); + foreach (const QString &functionName, parseResult.functions.keys()) { + const TestCodeLocationAndType &locationAndType = parseResult.functions.value(functionName); const QString qualifiedName = result.testCaseName + QLatin1String("::") + functionName; item->appendChild(createFunctionItem(functionName, locationAndType, - result.dataTagsOrTestSets.value(qualifiedName))); + parseResult.dataTags.value(qualifiedName))); } return item; } @@ -467,12 +469,14 @@ QList AutoTestTreeItem::getSelectedTestConfigurations() con QuickTestTreeItem *QuickTestTreeItem::createTestItem(const TestParseResult &result) { - QuickTestTreeItem *item = new QuickTestTreeItem(result.testCaseName, result.fileName, TestCase); + const QuickTestParseResult &parseResult = static_cast(result); + QuickTestTreeItem *item = new QuickTestTreeItem(parseResult.testCaseName, parseResult.fileName, + TestCase); item->setProFile(result.proFile); item->setLine(result.line); item->setColumn(result.column); - foreach (const QString &functionName, result.functions.keys()) - item->appendChild(createFunctionItem(functionName, result.functions.value(functionName))); + foreach (const QString &functionName, parseResult.functions.keys()) + item->appendChild(createFunctionItem(functionName, parseResult.functions.value(functionName))); return item; } @@ -487,20 +491,22 @@ QuickTestTreeItem *QuickTestTreeItem::createFunctionItem(const QString &function QuickTestTreeItem *QuickTestTreeItem::createUnnamedQuickTestItem(const TestParseResult &result) { + const QuickTestParseResult &parseResult = static_cast(result); QuickTestTreeItem *item = new QuickTestTreeItem(QString(), QString(), TestCase); - foreach (const QString &functionName, result.functions.keys()) - item->appendChild(createUnnamedQuickFunctionItem(functionName, result)); + foreach (const QString &functionName, parseResult.functions.keys()) + item->appendChild(createUnnamedQuickFunctionItem(functionName, parseResult)); return item; } QuickTestTreeItem *QuickTestTreeItem::createUnnamedQuickFunctionItem(const QString &functionName, const TestParseResult &result) { - const TestCodeLocationAndType &location = result.functions.value(functionName); + const QuickTestParseResult &parseResult = static_cast(result); + const TestCodeLocationAndType &location = parseResult.functions.value(functionName); QuickTestTreeItem *item = new QuickTestTreeItem(functionName, location.m_name, location.m_type); item->setLine(location.m_line); item->setColumn(location.m_column); - item->setProFile(result.proFile); + item->setProFile(parseResult.proFile); return item; } @@ -738,15 +744,16 @@ static QString gtestFilter(GoogleTestTreeItem::TestStates states) GoogleTestTreeItem *GoogleTestTreeItem::createTestItem(const TestParseResult &result) { - GoogleTestTreeItem *item = new GoogleTestTreeItem(result.testCaseName, QString(), TestCase); - item->setProFile(result.proFile); - if (result.parameterized) + const GoogleTestParseResult &parseResult = static_cast(result); + GoogleTestTreeItem *item = new GoogleTestTreeItem(parseResult.testCaseName, QString(), TestCase); + item->setProFile(parseResult.proFile); + if (parseResult.parameterized) item->setState(Parameterized); - if (result.typed) + if (parseResult.typed) item->setState(Typed); - if (result.disabled) + if (parseResult.disabled) item->setState(Disabled); - foreach (const TestCodeLocationAndType &location, result.dataTagsOrTestSets.first()) + foreach (const TestCodeLocationAndType &location, parseResult.testSets) item->appendChild(createTestSetItem(result, location)); return item; } diff --git a/src/plugins/autotest/testtreeitem.h b/src/plugins/autotest/testtreeitem.h index d641d9ad5e0..44524e7bc53 100644 --- a/src/plugins/autotest/testtreeitem.h +++ b/src/plugins/autotest/testtreeitem.h @@ -47,7 +47,7 @@ struct TestCodeLocationAndType; class AutoTestTreeItem; class QuickTestTreeItem; class GoogleTestTreeItem; -struct TestParseResult; +class TestParseResult; class TestConfiguration; class TestTreeItem : public Utils::TreeItem diff --git a/src/plugins/autotest/testtreemodel.cpp b/src/plugins/autotest/testtreemodel.cpp index 1210e9e1838..209326a497e 100644 --- a/src/plugins/autotest/testtreemodel.cpp +++ b/src/plugins/autotest/testtreemodel.cpp @@ -341,17 +341,12 @@ void TestTreeModel::onParseResultReady(const TestParseResultPtr result) { switch (result->type) { case AutoTest: - handleParseResult(result); + handleQtParseResult(result); break; case QuickTest: - if (result->testCaseName.isEmpty()) { - handleUnnamedQuickParseResult(result); - break; - } - handleParseResult(result); + handleQuickParseResult(result); break; case GoogleTest: - QTC_ASSERT(result->dataTagsOrTestSets.size() == 1, return); handleGTestParseResult(result); break; case Invalid: @@ -360,27 +355,12 @@ void TestTreeModel::onParseResultReady(const TestParseResultPtr result) } } -void TestTreeModel::handleParseResult(const TestParseResultPtr result) +void TestTreeModel::handleQtParseResult(const TestParseResultPtr result) { - TestTreeItem *root; - switch (result->type) { - case AutoTest: - root = m_autoTestRootItem; - break; - case QuickTest: - root = m_quickTestRootItem; - break; - default: - QTC_ASSERT(false, return); // should never happen, just to avoid warning - } - - TestTreeItem *toBeModified = root->findChildByFile(result->fileName); + TestTreeItem *toBeModified = m_autoTestRootItem->findChildByFile(result->fileName); // if there's no matching item, add the new one if (!toBeModified) { - if (result->type == AutoTest) - root->appendChild(AutoTestTreeItem::createTestItem(*result)); - else - root->appendChild(QuickTestTreeItem::createTestItem(*result)); + m_autoTestRootItem->appendChild(AutoTestTreeItem::createTestItem(*result)); return; } // else we have to check level by level.. first the current level... @@ -390,30 +370,26 @@ void TestTreeModel::handleParseResult(const TestParseResultPtr result) if (changed) emit dataChanged(indexForItem(toBeModified), indexForItem(toBeModified)); // ...now the functions - foreach (const QString &func, result->functions.keys()) { + const QtTestParseResult &parseResult = static_cast(*result); + foreach (const QString &func, parseResult.functions.keys()) { TestTreeItem *functionItem = toBeModified->findChildByName(func); - // if there's no function matching, add the new one if (!functionItem) { - const QString qualifiedName = result->testCaseName + QLatin1String("::") + func; - if (result->type == AutoTest) { - toBeModified->appendChild(AutoTestTreeItem::createFunctionItem( - func, result->functions.value(func), - result->dataTagsOrTestSets.value(qualifiedName))); - } else { - toBeModified->appendChild(QuickTestTreeItem::createFunctionItem( - func, result->functions.value(func))); - } + // if there's no function matching, add the new one + const QString qualifiedName = parseResult.testCaseName + QLatin1String("::") + func; + toBeModified->appendChild(AutoTestTreeItem::createFunctionItem( + func, parseResult.functions.value(func), + parseResult.dataTags.value(qualifiedName))); continue; } // else we have to check level by level.. first the current level... - changed = functionItem->modifyTestFunctionContent(result->functions.value(func)); + changed = functionItem->modifyTestFunctionContent(parseResult.functions.value(func)); functionItem->markForRemoval(false); if (changed) emit dataChanged(indexForItem(functionItem), indexForItem(functionItem)); - // ...now the data tags - actually these are supported only for AutoTestTreeItem - const QString &funcFileName = result->functions.value(func).m_name; - const QString qualifiedFunctionName = result->testCaseName + QLatin1String("::") + func; - foreach (const TestCodeLocationAndType &location, result->dataTagsOrTestSets.value(qualifiedFunctionName)) { + // ...now the data tags + const QString &funcFileName = parseResult.functions.value(func).m_name; + const QString qualifiedFunctionName = parseResult.testCaseName + QLatin1String("::") + func; + foreach (const TestCodeLocationAndType &location, parseResult.dataTags.value(qualifiedFunctionName)) { TestTreeItem *dataTagItem = functionItem->findChildByName(location.m_name); if (!dataTagItem) { functionItem->appendChild(AutoTestTreeItem::createDataTagItem(funcFileName, location)); @@ -427,20 +403,59 @@ void TestTreeModel::handleParseResult(const TestParseResultPtr result) } } +void TestTreeModel::handleQuickParseResult(const TestParseResultPtr result) +{ + if (result->testCaseName.isEmpty()) { + handleUnnamedQuickParseResult(result); + return; + } + + TestTreeItem *toBeModified = m_quickTestRootItem->findChildByFile(result->fileName); + // if there's no matching item, add the new one + if (!toBeModified) { + m_quickTestRootItem->appendChild(QuickTestTreeItem::createTestItem(*result)); + return; + } + // else we have to check level by level.. first the current level... + bool changed = toBeModified->modifyTestCaseContent(result->testCaseName, result->line, + result->column); + toBeModified->markForRemoval(false); + if (changed) + emit dataChanged(indexForItem(toBeModified), indexForItem(toBeModified)); + // ...now the functions + + const QuickTestParseResult &parseResult = static_cast(*result); + foreach (const QString &func, parseResult.functions.keys()) { + TestTreeItem *functionItem = toBeModified->findChildByName(func); + if (!functionItem) { + // if there's no matching, add the new one + toBeModified->appendChild(QuickTestTreeItem::createFunctionItem( + func, parseResult.functions.value(func))); + continue; + } + // else we have to modify.. + changed = functionItem->modifyTestFunctionContent(parseResult.functions.value(func)); + functionItem->markForRemoval(false); + if (changed) + emit dataChanged(indexForItem(functionItem), indexForItem(functionItem)); + } +} + void TestTreeModel::handleUnnamedQuickParseResult(const TestParseResultPtr result) { + const QuickTestParseResult &parseResult = static_cast(*result); TestTreeItem *toBeModified = unnamedQuickTests(); if (!toBeModified) { - m_quickTestRootItem->appendChild(QuickTestTreeItem::createUnnamedQuickTestItem(*result)); + m_quickTestRootItem->appendChild(QuickTestTreeItem::createUnnamedQuickTestItem(parseResult)); return; } // if we have already Unnamed Quick tests we might update them.. - foreach (const QString &func, result->functions.keys()) { - const TestCodeLocationAndType &location = result->functions.value(func); + foreach (const QString &func, parseResult.functions.keys()) { + const TestCodeLocationAndType &location = parseResult.functions.value(func); TestTreeItem *functionItem = toBeModified->findChildByNameAndFile(func, location.m_name); if (!functionItem) { toBeModified->appendChild(QuickTestTreeItem::createUnnamedQuickFunctionItem( - func, *result)); + func, parseResult)); continue; } functionItem->modifyLineAndColumn(location); @@ -450,27 +465,30 @@ void TestTreeModel::handleUnnamedQuickParseResult(const TestParseResultPtr resul void TestTreeModel::handleGTestParseResult(const TestParseResultPtr result) { + const GoogleTestParseResult &parseResult = static_cast(*result); + QTC_ASSERT(!parseResult.testSets.isEmpty(), return); + GoogleTestTreeItem::TestStates states = GoogleTestTreeItem::Enabled; - if (result->parameterized) + if (parseResult.parameterized) states |= GoogleTestTreeItem::Parameterized; - if (result->typed) + if (parseResult.typed) states |= GoogleTestTreeItem::Typed; TestTreeItem *toBeModified = m_googleTestRootItem->findChildByNameStateAndFile( - result->testCaseName, states, result->proFile); + parseResult.testCaseName, states, parseResult.proFile); if (!toBeModified) { - m_googleTestRootItem->appendChild(GoogleTestTreeItem::createTestItem(*result)); + m_googleTestRootItem->appendChild(GoogleTestTreeItem::createTestItem(parseResult)); return; } // if found nothing has to be updated as all relevant members are used to find the item - foreach (const TestCodeLocationAndType &location , result->dataTagsOrTestSets.first()) { + foreach (const TestCodeLocationAndType &location , parseResult.testSets) { TestTreeItem *testSetItem = toBeModified->findChildByNameAndFile(location.m_name, - result->fileName); + parseResult.fileName); if (!testSetItem) { - toBeModified->appendChild(GoogleTestTreeItem::createTestSetItem(*result, location)); + toBeModified->appendChild(GoogleTestTreeItem::createTestSetItem(parseResult, location)); continue; } bool changed = static_cast(testSetItem)->modifyTestSetContent( - result->fileName, location); + parseResult.fileName, location); testSetItem->markForRemoval(false); if (changed) emit dataChanged(indexForItem(testSetItem), indexForItem(testSetItem)); diff --git a/src/plugins/autotest/testtreemodel.h b/src/plugins/autotest/testtreemodel.h index 9667144f4dd..15a1591d54b 100644 --- a/src/plugins/autotest/testtreemodel.h +++ b/src/plugins/autotest/testtreemodel.h @@ -38,7 +38,7 @@ namespace Autotest { namespace Internal { class TestCodeParser; -struct TestParseResult; +class TestParseResult; using TestParseResultPtr = QSharedPointer; @@ -94,7 +94,8 @@ public slots: private: void onParseResultReady(const TestParseResultPtr result); - void handleParseResult(const TestParseResultPtr result); + void handleQtParseResult(const TestParseResultPtr result); + void handleQuickParseResult(const TestParseResultPtr result); void handleUnnamedQuickParseResult(const TestParseResultPtr result); void handleGTestParseResult(const TestParseResultPtr result); void removeAllTestItems(); @@ -149,25 +150,7 @@ private: }; -struct TestParseResult -{ - TestParseResult(TestTreeModel::Type t = TestTreeModel::Invalid) : type(t) {} - - TestTreeModel::Type type; - QString fileName; - QString proFile; - QString testCaseName; - unsigned line = 0; - unsigned column = 0; - bool parameterized = false; - bool typed = false; - bool disabled = false; - QMap functions; - QMap dataTagsOrTestSets; -}; - } // namespace Internal } // namespace Autotest Q_DECLARE_METATYPE(Autotest::Internal::TestTreeModel::Type) -Q_DECLARE_METATYPE(Autotest::Internal::TestParseResultPtr)