diff --git a/src/plugins/autotest/qtest/qttesttreeitem.cpp b/src/plugins/autotest/qtest/qttesttreeitem.cpp index b44c79eed37..0c535fa9f81 100644 --- a/src/plugins/autotest/qtest/qttesttreeitem.cpp +++ b/src/plugins/autotest/qtest/qttesttreeitem.cpp @@ -8,7 +8,9 @@ #include "../autotesttr.h" #include "../itestframework.h" +#include #include +#include #include @@ -16,8 +18,7 @@ using namespace Utils; -namespace Autotest { -namespace Internal { +namespace Autotest::Internal { QtTestTreeItem::QtTestTreeItem(ITestFramework *testFramework, const QString &name, const FilePath &filePath, TestTreeItem::Type type) @@ -49,9 +50,11 @@ QVariant QtTestTreeItem::data(int column, int role) const toolTip.append(Tr::tr("

Multiple testcases inside a single executable are not officially " "supported. Depending on the implementation they might get executed " "or not, but never will be explicitly selectable.

")); + } else if (type() == TestFunction) { + // avoid confusion (displaying header file, but ending up inside source) + toolTip = parentItem()->name() + "::" + name(); } return toolTip; - break; } case Qt::CheckStateRole: switch (type()) { @@ -69,6 +72,13 @@ QVariant QtTestTreeItem::data(int column, int role) const default: return m_multiTest; } + case LinkRole: + if (type() == GroupNode) + return QVariant(); + if (type() == TestDataFunction || type() == TestDataTag) + return TestTreeItem::data(column, role); + // other functions would end up inside declaration - so, find its definition + return linkForTreeItem(); } return TestTreeItem::data(column, role); } @@ -403,6 +413,26 @@ bool QtTestTreeItem::isGroupable() const return type() == TestCase; } +QVariant QtTestTreeItem::linkForTreeItem() const +{ + QVariant itemLink; + using namespace CPlusPlus; + const Snapshot snapshot = CppEditor::CppModelManager::instance()->snapshot(); + const Document::Ptr doc = snapshot.document(filePath()); + Symbol *symbol = doc->lastVisibleSymbolAt(line(), this->column() + 1); + if (auto decl = symbol->asDeclaration()) { + static CppEditor::SymbolFinder symbolFinder; + if (Symbol *definition = symbolFinder.findMatchingDefinition(decl, snapshot, true); + definition && definition->fileId()) { + itemLink.setValue(Link(FilePath::fromUtf8(definition->fileName()), + definition->line(), definition->column() - 1)); + } + } + if (!itemLink.isValid()) // fallback in case we failed to find the definition + itemLink.setValue(Link(filePath(), line(), this->column())); + return itemLink; +} + TestTreeItem *QtTestTreeItem::findChildByFileNameAndType(const FilePath &file, const QString &name, Type type) const { @@ -438,5 +468,4 @@ QString QtTestTreeItem::nameSuffix() const return suffix.isEmpty() ? suffix : QString{" [" + suffix + "]"}; } -} // namespace Internal -} // namespace Autotest +} // namespace Autotest::Internal diff --git a/src/plugins/autotest/qtest/qttesttreeitem.h b/src/plugins/autotest/qtest/qttesttreeitem.h index ebcc8b89dfe..51ad5b97657 100644 --- a/src/plugins/autotest/qtest/qttesttreeitem.h +++ b/src/plugins/autotest/qtest/qttesttreeitem.h @@ -5,8 +5,7 @@ #include "../testtreeitem.h" -namespace Autotest { -namespace Internal { +namespace Autotest::Internal { class QtTestTreeItem : public TestTreeItem { @@ -36,6 +35,7 @@ public: TestTreeItem *createParentGroupNode() const override; bool isGroupable() const override; private: + QVariant linkForTreeItem() const; TestTreeItem *findChildByFileNameAndType(const Utils::FilePath &file, const QString &name, Type type) const; TestTreeItem *findChildByNameAndInheritanceAndMultiTest(const QString &name, bool inherited, @@ -53,5 +53,4 @@ public: typedef QVector QtTestCodeLocationList; -} // namespace Internal -} // namespace Autotest +} // namespace Autotest::Internal diff --git a/src/plugins/autotest/qtest/qttestvisitors.cpp b/src/plugins/autotest/qtest/qttestvisitors.cpp index 51f62febb00..f19b855d559 100644 --- a/src/plugins/autotest/qtest/qttestvisitors.cpp +++ b/src/plugins/autotest/qtest/qttestvisitors.cpp @@ -14,8 +14,7 @@ using namespace CPlusPlus; using namespace Utils; -namespace Autotest { -namespace Internal { +namespace Autotest::Internal { static QStringList specialFunctions({"initTestCase", "cleanupTestCase", "init", "cleanup"}); @@ -49,10 +48,13 @@ bool TestVisitor::visit(Class *symbol) const QString name = o.prettyName(func->name()); QtTestCodeLocationAndType locationAndType; - Function *functionDefinition = m_symbolFinder.findMatchingDefinition( - func, m_snapshot, true); - if (functionDefinition && functionDefinition->fileId()) - member = functionDefinition; + if (name.endsWith("_data")) { + // costly.. but we need at least the correct entry for finding data tags + Function *functionDefinition = m_symbolFinder.findMatchingDefinition( + func, m_snapshot, true); + if (functionDefinition && functionDefinition->fileId()) + member = functionDefinition; + } locationAndType.m_filePath = FilePath::fromUtf8(member->fileName()); locationAndType.m_line = member->line(); locationAndType.m_column = member->column() - 1; @@ -281,5 +283,4 @@ bool TestDataFunctionVisitor::newRowCallFound(CallAST *ast, unsigned *firstToken return found; } -} // namespace Internal -} // namespace Autotest +} // namespace Autotest::Internal diff --git a/src/plugins/autotest/qtest/qttestvisitors.h b/src/plugins/autotest/qtest/qttestvisitors.h index dc18914b544..cf1f14642ec 100644 --- a/src/plugins/autotest/qtest/qttestvisitors.h +++ b/src/plugins/autotest/qtest/qttestvisitors.h @@ -16,8 +16,7 @@ #include #include -namespace Autotest { -namespace Internal { +namespace Autotest::Internal { class TestVisitor : public CPlusPlus::SymbolVisitor { @@ -84,5 +83,4 @@ private: bool m_insideUsingQTest = false; }; -} // namespace Internal -} // namespace Autotest +} // namespace Autotest::Internal