diff --git a/plugins/autotest/testcodeparser.cpp b/plugins/autotest/testcodeparser.cpp index bf1aab0399b..1bc78f25b3a 100644 --- a/plugins/autotest/testcodeparser.cpp +++ b/plugins/autotest/testcodeparser.cpp @@ -459,6 +459,20 @@ static TestTreeItem *constructTestTreeItem(const QString &fileName, return treeItem; } +static TestTreeItem *constructGTestTreeItem(const QString &filePath, const QString &caseName, + const TestCodeLocationList &testNames) +{ + TestTreeItem *item = new TestTreeItem(caseName, QString(), TestTreeItem::GTestCase); + foreach (const TestCodeLocationAndType &locationAndType, testNames) { + TestTreeItem *treeItemChild = new TestTreeItem(locationAndType.m_name, filePath, + locationAndType.m_type); + treeItemChild->setLine(locationAndType.m_line); + treeItemChild->setColumn(locationAndType.m_column); + item->appendChild(treeItemChild); + } + return item; +} + /****** end of helpers ******/ // used internally to indicate a parse that failed due to having triggered a parse for a file that @@ -607,6 +621,7 @@ void TestCodeParser::handleGTest(const QString &filePath, const QSet &n QMap result = visitor.gtestFunctions(); QTC_CHECK(names.contains(result.keys().toSet())); + updateGTests(document, result); } void TestCodeParser::onCppDocumentUpdated(const CPlusPlus::Document::Ptr &document) @@ -801,6 +816,8 @@ void TestCodeParser::clearCache() m_cppDocMap.clear(); m_quickDocMap.clear(); m_unnamedQuickDocList.clear(); + m_gtestDocMap.clear(); + m_gtestDocList.clear(); emit cacheCleared(); } @@ -810,6 +827,9 @@ void TestCodeParser::removeTestsIfNecessary(const QString &fileName) if (m_cppDocMap.contains(fileName)) { m_cppDocMap.remove(fileName); emit testItemsRemoved(fileName, TestTreeModel::AutoTest); + } else if (m_gtestDocMap.contains(fileName)) { + m_gtestDocMap.remove(fileName); + emit testItemsRemoved(fileName, TestTreeModel::GoogleTest); } else { // handle Qt Quick Tests QList toBeRemoved; foreach (const QString &file, m_quickDocMap.keys()) { @@ -997,6 +1017,33 @@ void TestCodeParser::updateModelAndQuickDocMap(QmlJS::Document::Ptr document, } } +void TestCodeParser::updateGTests(const CPlusPlus::Document::Ptr &doc, + const QMap &tests) +{ + const QString &fileName = doc->fileName(); + removeGTestsByName(fileName); + + QString proFile; + const CppTools::CppModelManager *cppMM = CppTools::CppModelManager::instance(); + QList ppList = cppMM->projectPart(fileName); + if (ppList.size()) + proFile = ppList.at(0)->projectFile; + + foreach (const QString &testName, tests.keys()) { + TestTreeItem *item = constructGTestTreeItem(fileName, testName, tests.value(testName)); + TestInfo info(item->name(), item->getChildNames(), doc->revision(), doc->editorRevision()); + info.setProfile(proFile); + foreach (const TestCodeLocationAndType &testSet, tests.value(testName)) { + GTestInfo gtestInfo(testName, testSet.m_name, fileName); + if (testSet.m_type == TestTreeItem::GTestNameDisabled) + gtestInfo.setEnabled(false); + m_gtestDocList.append(gtestInfo); + } + emit testItemCreated(item, TestTreeModel::GoogleTest); + m_gtestDocMap.insert(fileName, info); + } +} + void TestCodeParser::removeUnnamedQuickTestsByName(const QString &fileName) { for (int i = m_unnamedQuickDocList.size() - 1; i >= 0; --i) { @@ -1006,6 +1053,15 @@ void TestCodeParser::removeUnnamedQuickTestsByName(const QString &fileName) emit unnamedQuickTestsRemoved(fileName); } +void TestCodeParser::removeGTestsByName(const QString &fileName) +{ + for (int i = m_gtestDocList.size() - 1; i >= 0; --i) + if (m_gtestDocList.at(i).fileName() == fileName) + m_gtestDocList.removeAt(i); + + emit gTestsRemoved(fileName); +} + #ifdef WITH_TESTS int TestCodeParser::autoTestsCount() const { diff --git a/plugins/autotest/testcodeparser.h b/plugins/autotest/testcodeparser.h index d966b363d4b..2889b5a041a 100644 --- a/plugins/autotest/testcodeparser.h +++ b/plugins/autotest/testcodeparser.h @@ -40,6 +40,7 @@ namespace Internal { struct TestCodeLocationAndType; class TestInfo; class UnnamedQuickTestInfo; +class GTestInfo; class TestCodeParser : public QObject { @@ -72,6 +73,7 @@ signals: void unnamedQuickTestsUpdated(const QString &mainFile, const QMap &functions); void unnamedQuickTestsRemoved(const QString &filePath); + void gTestsRemoved(const QString &filePath); void parsingStarted(); void parsingFinished(); void parsingFailed(); @@ -106,12 +108,17 @@ private: const QString &declaringFile, TestTreeItem *testItem); void updateModelAndQuickDocMap(QmlJS::Document::Ptr document, const QString &referencingFile, TestTreeItem *testItem); + void updateGTests(const CPlusPlus::Document::Ptr &doc, + const QMap &tests); void removeUnnamedQuickTestsByName(const QString &fileName); + void removeGTestsByName(const QString &fileName); TestTreeModel *m_model; QMap m_cppDocMap; QMap m_quickDocMap; + QMap m_gtestDocMap; QList m_unnamedQuickDocList; + QList m_gtestDocList; bool m_codeModelParsing; bool m_fullUpdatePostponed; bool m_partialUpdatePostponed; diff --git a/plugins/autotest/testinfo.cpp b/plugins/autotest/testinfo.cpp index b83c8b61d13..7385f159884 100644 --- a/plugins/autotest/testinfo.cpp +++ b/plugins/autotest/testinfo.cpp @@ -42,5 +42,13 @@ UnnamedQuickTestInfo::UnnamedQuickTestInfo(const QString &function, const QStrin { } +GTestInfo::GTestInfo(const QString &caseName, const QString &setName, const QString &file) + : m_caseName(caseName), + m_setName(setName), + m_fileName(file), + m_enabled(true) +{ +} + } // namespace Internal } // namespace Autotest diff --git a/plugins/autotest/testinfo.h b/plugins/autotest/testinfo.h index 21fc1200838..374102ed204 100644 --- a/plugins/autotest/testinfo.h +++ b/plugins/autotest/testinfo.h @@ -71,6 +71,26 @@ private: QString m_fileName; }; +class GTestInfo { +public: + explicit GTestInfo(const QString &caseName, const QString &setName, const QString &file); + + const QString caseName() const { return m_caseName; } + void setCaseName(const QString &caseName) { m_caseName = caseName; } + const QString setName() const { return m_setName; } + void setSetName(const QString &setName) { m_setName = setName; } + const QString fileName() const { return m_fileName; } + void setFileName(const QString &fileName) { m_fileName = fileName; } + bool isEnabled() const { return m_enabled; } + void setEnabled(bool enabled) { m_enabled = enabled; } + +private: + QString m_caseName; + QString m_setName; + QString m_fileName; + bool m_enabled; +}; + } // namespace Internal } // namespace Autotest diff --git a/plugins/autotest/testtreemodel.cpp b/plugins/autotest/testtreemodel.cpp index e1334725686..342ef7a184a 100644 --- a/plugins/autotest/testtreemodel.cpp +++ b/plugins/autotest/testtreemodel.cpp @@ -60,6 +60,8 @@ TestTreeModel::TestTreeModel(QObject *parent) : this, &TestTreeModel::updateUnnamedQuickTest, Qt::QueuedConnection); connect(m_parser, &TestCodeParser::unnamedQuickTestsRemoved, this, &TestTreeModel::removeUnnamedQuickTests, Qt::QueuedConnection); + connect(m_parser, &TestCodeParser::gTestsRemoved, + this, &TestTreeModel::removeGTests, Qt::QueuedConnection); // CppTools::CppModelManagerInterface *cppMM = CppTools::CppModelManagerInterface::instance(); // if (cppMM) { @@ -481,10 +483,45 @@ void TestTreeModel::removeUnnamedQuickTests(const QString &filePath) emit testTreeModelChanged(); } +void TestTreeModel::removeGTests(const QString &filePath) +{ + for (int childRow = m_googleTestRootItem->childCount() - 1; childRow >= 0; --childRow) { + TestTreeItem *child = m_googleTestRootItem->childItem(childRow); + for (int grandChildRow = child->childCount() - 1; grandChildRow >= 0; --grandChildRow) { + TestTreeItem *grandChild = child->childItem(grandChildRow); + if (filePath == grandChild->filePath()) + delete takeItem(grandChild); + } + if (child->childCount() == 0) + delete takeItem(child); + } + emit testTreeModelChanged(); +} + void TestTreeModel::addTestTreeItem(TestTreeItem *item, TestTreeModel::Type type) { TestTreeItem *parent = rootItemForType(type); - parent->appendChild(item); + if (type == TestTreeModel::GoogleTest) { + // check if there's already an item with the same test name... + TestTreeItem *toBeUpdated = 0; + for (int row = 0, count = parent->childCount(); row < count; ++row) { + TestTreeItem *current = parent->childItem(row); + if (current->name() == item->name()) { + toBeUpdated = current; + break; + } + } + // ...if so we have, to update this one instead of adding a new item + if (toBeUpdated) { + for (int row = 0, count = item->childCount(); row < count; ++row) + toBeUpdated->appendChild(new TestTreeItem(*item->childItem(row))); + delete item; + } else { + parent->appendChild(item); + } + } else { + parent->appendChild(item); + } emit testTreeModelChanged(); } diff --git a/plugins/autotest/testtreemodel.h b/plugins/autotest/testtreemodel.h index 0a2a5e0be58..bef6ec86f00 100644 --- a/plugins/autotest/testtreemodel.h +++ b/plugins/autotest/testtreemodel.h @@ -84,6 +84,7 @@ private: void removeAllTestItems(); void removeTestTreeItems(const QString &filePath, Type type); void removeUnnamedQuickTests(const QString &filePath); + void removeGTests(const QString &filePath); TestTreeItem *unnamedQuickTests() const; TestTreeItem *rootItemForType(Type type);