diff --git a/src/plugins/autotest/gtest/gtestconfiguration.cpp b/src/plugins/autotest/gtest/gtestconfiguration.cpp index 62f910df2e5..7be52a69c12 100644 --- a/src/plugins/autotest/gtest/gtestconfiguration.cpp +++ b/src/plugins/autotest/gtest/gtestconfiguration.cpp @@ -35,7 +35,7 @@ namespace Internal { TestOutputReader *GTestConfiguration::outputReader(const QFutureInterface &fi, QProcess *app) const { - return new GTestOutputReader(fi, app, buildDirectory()); + return new GTestOutputReader(fi, app, buildDirectory(), projectFile()); } QStringList GTestConfiguration::argumentsForTestRunner() const diff --git a/src/plugins/autotest/gtest/gtestoutputreader.cpp b/src/plugins/autotest/gtest/gtestoutputreader.cpp index a455282476c..19712035110 100644 --- a/src/plugins/autotest/gtest/gtestoutputreader.cpp +++ b/src/plugins/autotest/gtest/gtestoutputreader.cpp @@ -25,6 +25,8 @@ #include "gtestoutputreader.h" #include "gtestresult.h" +#include "../testtreemodel.h" +#include "../testtreeitem.h" #include #include @@ -39,9 +41,11 @@ static QString constructSourceFilePath(const QString &path, const QString &fileP } GTestOutputReader::GTestOutputReader(const QFutureInterface &futureInterface, - QProcess *testApplication, const QString &buildDirectory) + QProcess *testApplication, const QString &buildDirectory, + const QString &projectFile) : TestOutputReader(futureInterface, testApplication, buildDirectory) , m_executable(testApplication ? testApplication->program() : QString()) + , m_projectFile(projectFile) { } @@ -94,8 +98,9 @@ void GTestOutputReader::processOutput(const QByteArray &outputLine) m_futureInterface.reportResult(TestResultPtr(testResult)); m_currentTestName.clear(); m_currentTestSet.clear(); + m_normalizedCurrentTestSet.clear(); } else if (newTestStarts.exactMatch(line)) { - m_currentTestName = newTestStarts.cap(1); + setCurrentTestName(newTestStarts.cap(1)); TestResultPtr testResult = TestResultPtr(createDefaultResult()); testResult->setResult(Result::MessageTestCaseStart); if (m_iteration > 1) { @@ -106,7 +111,7 @@ void GTestOutputReader::processOutput(const QByteArray &outputLine) } m_futureInterface.reportResult(testResult); } else if (newTestSetStarts.exactMatch(line)) { - m_currentTestSet = newTestSetStarts.cap(1); + setCurrentTestSet(newTestSetStarts.cap(1)); TestResultPtr testResult = TestResultPtr(new GTestResult); testResult->setResult(Result::MessageCurrentTest); testResult->setDescription(tr("Entering test set %1").arg(m_currentTestSet)); @@ -155,13 +160,87 @@ void GTestOutputReader::processOutput(const QByteArray &outputLine) } } +void GTestOutputReader::setCurrentTestSet(const QString &testSet) +{ + m_currentTestSet = testSet; + m_normalizedCurrentTestSet = normalizeName(testSet); +} + +void GTestOutputReader::setCurrentTestName(const QString &testName) +{ + m_currentTestName = testName; + m_normalizedTestName = normalizeTestName(testName); +} + +QString GTestOutputReader::normalizeName(const QString &name) const +{ + static QRegExp parameterIndex("/\\d+"); + + QString nameWithoutParameterIndices = name; + nameWithoutParameterIndices.remove(parameterIndex); + + return nameWithoutParameterIndices.split('/').last(); +} + +QString GTestOutputReader::normalizeTestName(const QString &testname) const +{ + QString nameWithoutTypeParam = testname.split(',').first(); + + return normalizeName(nameWithoutTypeParam); +} + GTestResult *GTestOutputReader::createDefaultResult() const { GTestResult *result = new GTestResult(m_executable, m_currentTestName); result->setTestSetName(m_currentTestSet); result->setIteration(m_iteration); + + const TestTreeItem *testItem = findTestTreeItemForCurrentLine(); + if (testItem && testItem->line()) { + result->setFileName(testItem->filePath()); + result->setLine(static_cast(testItem->line())); + } + return result; } +const TestTreeItem *GTestOutputReader::findTestTreeItemForCurrentLine() const +{ + const auto item = TestTreeModel::instance()->findNonRooItem([&](const Utils::TreeItem *item) { + const TestTreeItem &treeItem = static_cast(*item); + return matches(treeItem); + }); + + return static_cast(item); +} + +bool GTestOutputReader::matches(const TestTreeItem &treeItem) const +{ + if (treeItem.proFile() != m_projectFile) + return false; + + if (m_currentTestSet.isEmpty()) + return matchesTestCase(treeItem); + + return matchesTestFunctionOrSet(treeItem); +} + +bool GTestOutputReader::matchesTestFunctionOrSet(const TestTreeItem &treeItem) const +{ + if (treeItem.type() != TestTreeItem::TestFunctionOrSet) + return false; + + const QString testItemTestSet = treeItem.parentItem()->name() + '.' + treeItem.name(); + return testItemTestSet == m_normalizedCurrentTestSet; +} + +bool GTestOutputReader::matchesTestCase(const TestTreeItem &treeItem) const +{ + if (treeItem.type() != TestTreeItem::TestCase) + return false; + + return treeItem.name() == m_normalizedTestName; +} + } // namespace Internal } // namespace Autotest diff --git a/src/plugins/autotest/gtest/gtestoutputreader.h b/src/plugins/autotest/gtest/gtestoutputreader.h index 5cedffed006..e46e29fcd3f 100644 --- a/src/plugins/autotest/gtest/gtestoutputreader.h +++ b/src/plugins/autotest/gtest/gtestoutputreader.h @@ -33,6 +33,7 @@ namespace Autotest { namespace Internal { class GTestResult; +class TestTreeItem; class GTestOutputReader : public TestOutputReader { @@ -40,16 +41,29 @@ class GTestOutputReader : public TestOutputReader public: GTestOutputReader(const QFutureInterface &futureInterface, - QProcess *testApplication, const QString &buildDirectory); + QProcess *testApplication, const QString &buildDirectory, + const QString &projectFile); protected: void processOutput(const QByteArray &outputLine) override; private: + void setCurrentTestSet(const QString &testSet); + void setCurrentTestName(const QString &testName); + QString normalizeName(const QString &name) const; + QString normalizeTestName(const QString &testname) const; GTestResult *createDefaultResult() const; + const TestTreeItem *findTestTreeItemForCurrentLine() const; + bool matches(const TestTreeItem &treeItem) const; + bool matchesTestFunctionOrSet(const TestTreeItem &treeItem) const; + bool matchesTestCase(const TestTreeItem &treeItem) const; + QString m_executable; + QString m_projectFile; QString m_currentTestName; + QString m_normalizedTestName; QString m_currentTestSet; + QString m_normalizedCurrentTestSet; QString m_description; int m_iteration = 1; }; diff --git a/src/plugins/autotest/testconfiguration.h b/src/plugins/autotest/testconfiguration.h index 8d620859828..248b9aaeb76 100644 --- a/src/plugins/autotest/testconfiguration.h +++ b/src/plugins/autotest/testconfiguration.h @@ -73,6 +73,7 @@ public: QString executableFilePath() const; QString workingDirectory() const; QString buildDirectory() const { return m_buildDir; } + QString projectFile() const { return m_projectFile; } QString displayName() const { return m_displayName; } Utils::Environment environment() const { return m_environment; } ProjectExplorer::Project *project() const { return m_project.data(); }