AutoTest: Use TestResult as value type

Don't construct it on heap and don't use shared pointer for it.

Change-Id: I51c9da405ed14d24b5f20242b4d049f9e2958f09
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
This commit is contained in:
Jarek Kobus
2023-01-14 16:25:51 +01:00
parent 3ff5661327
commit d05c5b7d07
54 changed files with 396 additions and 437 deletions

View File

@@ -17,7 +17,7 @@ namespace Autotest {
namespace Internal { namespace Internal {
TestOutputReader *BoostTestConfiguration::createOutputReader( TestOutputReader *BoostTestConfiguration::createOutputReader(
const QFutureInterface<TestResultPtr> &fi, Utils::QtcProcess *app) const const QFutureInterface<TestResult> &fi, Utils::QtcProcess *app) const
{ {
auto settings = static_cast<BoostTestSettings *>(framework()->testSettings()); auto settings = static_cast<BoostTestSettings *>(framework()->testSettings());
return new BoostTestOutputReader(fi, app, buildDirectory(), projectFile(), return new BoostTestOutputReader(fi, app, buildDirectory(), projectFile(),

View File

@@ -13,7 +13,7 @@ class BoostTestConfiguration : public DebuggableTestConfiguration
public: public:
explicit BoostTestConfiguration(ITestFramework *framework) explicit BoostTestConfiguration(ITestFramework *framework)
: DebuggableTestConfiguration(framework) {} : DebuggableTestConfiguration(framework) {}
TestOutputReader *createOutputReader(const QFutureInterface<TestResultPtr> &fi, TestOutputReader *createOutputReader(const QFutureInterface<TestResult> &fi,
Utils::QtcProcess *app) const override; Utils::QtcProcess *app) const override;
QStringList argumentsForTestRunner(QStringList *omitted = nullptr) const override; QStringList argumentsForTestRunner(QStringList *omitted = nullptr) const override;
Utils::Environment filteredEnvironment(const Utils::Environment &original) const override; Utils::Environment filteredEnvironment(const Utils::Environment &original) const override;

View File

@@ -18,10 +18,7 @@ ITestParser *BoostTestFramework::createTestParser()
ITestTreeItem *BoostTestFramework::createRootNode() ITestTreeItem *BoostTestFramework::createRootNode()
{ {
return new BoostTestTreeItem( return new BoostTestTreeItem(this, displayName(), {}, ITestTreeItem::Root);
this,
displayName(),
Utils::FilePath(), ITestTreeItem::Root);
} }
const char *BoostTestFramework::name() const const char *BoostTestFramework::name() const

View File

@@ -19,7 +19,7 @@ namespace Internal {
static Q_LOGGING_CATEGORY(orLog, "qtc.autotest.boost.outputreader", QtWarningMsg) static Q_LOGGING_CATEGORY(orLog, "qtc.autotest.boost.outputreader", QtWarningMsg)
BoostTestOutputReader::BoostTestOutputReader(const QFutureInterface<TestResultPtr> &futureInterface, BoostTestOutputReader::BoostTestOutputReader(const QFutureInterface<TestResult> &futureInterface,
Utils::QtcProcess *testApplication, Utils::QtcProcess *testApplication,
const Utils::FilePath &buildDirectory, const Utils::FilePath &buildDirectory,
const Utils::FilePath &projectFile, const Utils::FilePath &projectFile,
@@ -42,23 +42,23 @@ static QString caseFromContent(const QString &content)
if (index != 17 || length <= 18) { if (index != 17 || length <= 18) {
qCDebug(orLog) << "double quote position" << index << " or content length" << length qCDebug(orLog) << "double quote position" << index << " or content length" << length
<< "wrong on content" << content; << "wrong on content" << content;
return QString(); return {};
} }
index = content.indexOf('"', 18); index = content.indexOf('"', 18);
if (index == -1) { if (index == -1) {
qCDebug(orLog) << "no closing double quote" << content; qCDebug(orLog) << "no closing double quote" << content;
return QString(); return {};
} }
return content.mid(18, index - 1); return content.mid(18, index - 1);
} }
int index = content.indexOf(": in "); int index = content.indexOf(": in ");
if (index == -1) // "info: check true has passed" if (index == -1) // "info: check true has passed"
return QString(); return {};
if (index <= 4 || length < index + 4) { if (index <= 4 || length < index + 4) {
qCDebug(orLog) << "unexpected position" << index << "for info" << content; qCDebug(orLog) << "unexpected position" << index << "for info" << content;
return QString(); return {};
} }
QString result = content.mid(index + 5); QString result = content.mid(index + 5);
@@ -66,7 +66,7 @@ static QString caseFromContent(const QString &content)
const QRegularExpressionMatch matcher = functionName.match(result); const QRegularExpressionMatch matcher = functionName.match(result);
if (!matcher.hasMatch()) { if (!matcher.hasMatch()) {
qCDebug(orLog) << "got no match"; qCDebug(orLog) << "got no match";
return QString(); return {};
} }
return matcher.captured(1); return matcher.captured(1);
} }
@@ -74,19 +74,18 @@ static QString caseFromContent(const QString &content)
void BoostTestOutputReader::sendCompleteInformation() void BoostTestOutputReader::sendCompleteInformation()
{ {
QTC_ASSERT(m_result != ResultType::Invalid, return); QTC_ASSERT(m_result != ResultType::Invalid, return);
BoostTestResult *result = new BoostTestResult(id(), m_currentModule, m_projectFile, BoostTestResult result(id(), m_currentModule, m_projectFile, m_currentTest, m_currentSuite);
m_currentTest, m_currentSuite);
if (m_lineNumber) { if (m_lineNumber) {
result->setLine(m_lineNumber); result.setLine(m_lineNumber);
result->setFileName(m_fileName); result.setFileName(m_fileName);
} else if (const ITestTreeItem *it = result->findTestTreeItem()) { } else if (const ITestTreeItem *it = result.findTestTreeItem()) {
result->setLine(it->line()); result.setLine(it->line());
result->setFileName(it->filePath()); result.setFileName(it->filePath());
} }
result->setDescription(m_description); result.setDescription(m_description);
result->setResult(m_result); result.setResult(m_result);
reportResult(TestResultPtr(result)); reportResult(result);
m_result = ResultType::Invalid; m_result = ResultType::Invalid;
} }
@@ -212,10 +211,10 @@ void BoostTestOutputReader::processOutputLine(const QByteArray &outputLine)
if (match.hasMatch()) { if (match.hasMatch()) {
if (m_result != ResultType::Invalid) if (m_result != ResultType::Invalid)
sendCompleteInformation(); sendCompleteInformation();
BoostTestResult *result = new BoostTestResult(id(), m_currentModule, m_projectFile); BoostTestResult result(id(), m_currentModule, m_projectFile);
result->setDescription(match.captured(0)); result.setDescription(match.captured(0));
result->setResult(ResultType::MessageInfo); result.setResult(ResultType::MessageInfo);
reportResult(TestResultPtr(result)); reportResult(result);
return; return;
} }
@@ -234,17 +233,17 @@ void BoostTestOutputReader::processOutputLine(const QByteArray &outputLine)
sendCompleteInformation(); sendCompleteInformation();
if (match.captured(1).startsWith("Entering")) { if (match.captured(1).startsWith("Entering")) {
m_currentModule = match.captured(2); m_currentModule = match.captured(2);
BoostTestResult *result = new BoostTestResult(id(), m_currentModule, m_projectFile); BoostTestResult result(id(), m_currentModule, m_projectFile);
result->setDescription(Tr::tr("Executing test module %1").arg(m_currentModule)); result.setDescription(Tr::tr("Executing test module %1").arg(m_currentModule));
result->setResult(ResultType::TestStart); result.setResult(ResultType::TestStart);
reportResult(TestResultPtr(result)); reportResult(result);
m_description.clear(); m_description.clear();
} else { } else {
QTC_CHECK(m_currentModule == match.captured(3)); QTC_CHECK(m_currentModule == match.captured(3));
BoostTestResult *result = new BoostTestResult(id(), m_currentModule, m_projectFile); BoostTestResult result(id(), m_currentModule, m_projectFile);
result->setDescription(Tr::tr("Test module execution took %1").arg(match.captured(4))); result.setDescription(Tr::tr("Test module execution took %1").arg(match.captured(4)));
result->setResult(ResultType::TestEnd); result.setResult(ResultType::TestEnd);
reportResult(TestResultPtr(result)); reportResult(result);
m_currentTest.clear(); m_currentTest.clear();
m_currentSuite.clear(); m_currentSuite.clear();
@@ -325,16 +324,16 @@ void BoostTestOutputReader::processOutputLine(const QByteArray &outputLine)
if (match.hasMatch()) { if (match.hasMatch()) {
if (m_result != ResultType::Invalid) if (m_result != ResultType::Invalid)
sendCompleteInformation(); sendCompleteInformation();
BoostTestResult *result = new BoostTestResult(id(), {}, m_projectFile); BoostTestResult result(id(), {}, m_projectFile);
int failed = match.captured(1).toInt(); const int failed = match.captured(1).toInt();
int fatals = m_summary.value(ResultType::MessageFatal); const int fatals = m_summary.value(ResultType::MessageFatal);
QString txt = Tr::tr("%1 failures detected in %2.").arg(failed).arg(match.captured(3)); QString txt = Tr::tr("%1 failures detected in %2.").arg(failed).arg(match.captured(3));
int passed = qMax(0, m_testCaseCount - failed); const int passed = qMax(0, m_testCaseCount - failed);
if (m_testCaseCount != -1) if (m_testCaseCount != -1)
txt.append(' ').append(Tr::tr("%1 tests passed.").arg(passed)); txt.append(' ').append(Tr::tr("%1 tests passed.").arg(passed));
result->setDescription(txt); result.setDescription(txt);
result->setResult(ResultType::MessageInfo); result.setResult(ResultType::MessageInfo);
reportResult(TestResultPtr(result)); reportResult(result);
if (m_reportLevel == ReportLevel::Confirm) { // for the final summary if (m_reportLevel == ReportLevel::Confirm) { // for the final summary
m_summary[ResultType::Pass] += passed; m_summary[ResultType::Pass] += passed;
m_summary[ResultType::Fail] += failed - fatals; m_summary[ResultType::Fail] += failed - fatals;
@@ -346,13 +345,13 @@ void BoostTestOutputReader::processOutputLine(const QByteArray &outputLine)
if (line == noErrors) { if (line == noErrors) {
if (m_result != ResultType::Invalid) if (m_result != ResultType::Invalid)
sendCompleteInformation(); sendCompleteInformation();
BoostTestResult *result = new BoostTestResult(id(), {}, m_projectFile); BoostTestResult result(id(), {}, m_projectFile);
QString txt = Tr::tr("No errors detected."); QString txt = Tr::tr("No errors detected.");
if (m_testCaseCount != -1) if (m_testCaseCount != -1)
txt.append(' ').append(Tr::tr("%1 tests passed.").arg(m_testCaseCount)); txt.append(' ').append(Tr::tr("%1 tests passed.").arg(m_testCaseCount));
result->setDescription(txt); result.setDescription(txt);
result->setResult(ResultType::MessageInfo); result.setResult(ResultType::MessageInfo);
reportResult(TestResultPtr(result)); reportResult(result);
if (m_reportLevel == ReportLevel::Confirm) // for the final summary if (m_reportLevel == ReportLevel::Confirm) // for the final summary
m_summary.insert(ResultType::Pass, m_testCaseCount); m_summary.insert(ResultType::Pass, m_testCaseCount);
return; return;
@@ -372,10 +371,9 @@ void BoostTestOutputReader::processStdError(const QByteArray &outputLine)
emit newOutputLineAvailable(outputLine, OutputChannel::StdErr); emit newOutputLineAvailable(outputLine, OutputChannel::StdErr);
} }
TestResultPtr BoostTestOutputReader::createDefaultResult() const TestResult BoostTestOutputReader::createDefaultResult() const
{ {
return TestResultPtr(new BoostTestResult(id(), m_currentModule, m_projectFile, return BoostTestResult(id(), m_currentModule, m_projectFile, m_currentTest, m_currentSuite);
m_currentTest, m_currentSuite));
} }
void BoostTestOutputReader::onDone() { void BoostTestOutputReader::onDone() {
@@ -416,11 +414,11 @@ void BoostTestOutputReader::onDone() {
void BoostTestOutputReader::reportNoOutputFinish(const QString &description, ResultType type) void BoostTestOutputReader::reportNoOutputFinish(const QString &description, ResultType type)
{ {
BoostTestResult *result = new BoostTestResult(id(), m_currentModule, m_projectFile, BoostTestResult result(id(), m_currentModule, m_projectFile,
Tr::tr("Running tests without output.")); Tr::tr("Running tests without output."));
result->setDescription(description); result.setDescription(description);
result->setResult(type); result.setResult(type);
reportResult(TestResultPtr(result)); reportResult(result);
} }
} // namespace Internal } // namespace Internal

View File

@@ -15,13 +15,13 @@ class BoostTestOutputReader : public TestOutputReader
{ {
Q_OBJECT Q_OBJECT
public: public:
BoostTestOutputReader(const QFutureInterface<TestResultPtr> &futureInterface, BoostTestOutputReader(const QFutureInterface<TestResult> &futureInterface,
Utils::QtcProcess *testApplication, const Utils::FilePath &buildDirectory, Utils::QtcProcess *testApplication, const Utils::FilePath &buildDirectory,
const Utils::FilePath &projectFile, LogLevel log, ReportLevel report); const Utils::FilePath &projectFile, LogLevel log, ReportLevel report);
protected: protected:
void processOutputLine(const QByteArray &outputLine) override; void processOutputLine(const QByteArray &outputLine) override;
void processStdError(const QByteArray &outputLine) override; void processStdError(const QByteArray &outputLine) override;
TestResultPtr createDefaultResult() const override; TestResult createDefaultResult() const override;
private: private:
void onDone(); void onDone();

View File

@@ -120,7 +120,7 @@ QString BoostTestSettings::logLevelToOption(const LogLevel logLevel)
case LogLevel::Nothing: return QString("nothing"); case LogLevel::Nothing: return QString("nothing");
case LogLevel::Warning: return QString("warning"); case LogLevel::Warning: return QString("warning");
} }
return QString(); return {};
} }
QString BoostTestSettings::reportLevelToOption(const ReportLevel reportLevel) QString BoostTestSettings::reportLevelToOption(const ReportLevel reportLevel)
@@ -131,7 +131,7 @@ QString BoostTestSettings::reportLevelToOption(const ReportLevel reportLevel)
case ReportLevel::Detailed: return QString("detailed"); case ReportLevel::Detailed: return QString("detailed");
case ReportLevel::No: return QString("no"); case ReportLevel::No: return QString("no");
} }
return QString(); return {};
} }
} // namespace Internal } // namespace Internal

View File

@@ -27,8 +27,8 @@ public:
Q_DECLARE_FLAGS(TestStates, TestState) Q_DECLARE_FLAGS(TestStates, TestState)
explicit BoostTestTreeItem(ITestFramework *framework, explicit BoostTestTreeItem(ITestFramework *framework,
const QString &name = QString(), const QString &name = {},
const Utils::FilePath &filePath = Utils::FilePath(), const Utils::FilePath &filePath = {},
Type type = Root) Type type = Root)
: TestTreeItem(framework, name, filePath, type) : TestTreeItem(framework, name, filePath, type)
{} {}

View File

@@ -14,7 +14,7 @@
namespace Autotest { namespace Autotest {
namespace Internal { namespace Internal {
TestOutputReader *CatchConfiguration::createOutputReader(const QFutureInterface<TestResultPtr> &fi, TestOutputReader *CatchConfiguration::createOutputReader(const QFutureInterface<TestResult> &fi,
Utils::QtcProcess *app) const Utils::QtcProcess *app) const
{ {
return new CatchOutputReader(fi, app, buildDirectory(), projectFile()); return new CatchOutputReader(fi, app, buildDirectory(), projectFile());

View File

@@ -12,7 +12,7 @@ class CatchConfiguration : public DebuggableTestConfiguration
{ {
public: public:
CatchConfiguration(ITestFramework *framework) : DebuggableTestConfiguration(framework) {} CatchConfiguration(ITestFramework *framework) : DebuggableTestConfiguration(framework) {}
TestOutputReader *createOutputReader(const QFutureInterface<TestResultPtr> &fi, TestOutputReader *createOutputReader(const QFutureInterface<TestResult> &fi,
Utils::QtcProcess *app) const override; Utils::QtcProcess *app) const override;
QStringList argumentsForTestRunner(QStringList *omitted = nullptr) const override; QStringList argumentsForTestRunner(QStringList *omitted = nullptr) const override;
Utils::Environment filteredEnvironment(const Utils::Environment &original) const override; Utils::Environment filteredEnvironment(const Utils::Environment &original) const override;

View File

@@ -32,9 +32,7 @@ ITestParser *CatchFramework::createTestParser()
ITestTreeItem *CatchFramework::createRootNode() ITestTreeItem *CatchFramework::createRootNode()
{ {
return new CatchTreeItem(this, return new CatchTreeItem(this, displayName(), {}, ITestTreeItem::Root);
displayName(),
Utils::FilePath(), ITestTreeItem::Root);
} }
} // namespace Internal } // namespace Internal

View File

@@ -29,7 +29,7 @@ namespace CatchXml {
const char TestCaseResultElement[] = "OverallResult"; const char TestCaseResultElement[] = "OverallResult";
} }
CatchOutputReader::CatchOutputReader(const QFutureInterface<TestResultPtr> &futureInterface, CatchOutputReader::CatchOutputReader(const QFutureInterface<TestResult> &futureInterface,
Utils::QtcProcess *testApplication, Utils::QtcProcess *testApplication,
const Utils::FilePath &buildDirectory, const Utils::FilePath &buildDirectory,
const Utils::FilePath &projectFile) const Utils::FilePath &projectFile)
@@ -169,22 +169,17 @@ void CatchOutputReader::processOutputLine(const QByteArray &outputLineWithNewLin
} }
} }
TestResultPtr CatchOutputReader::createDefaultResult() const TestResult CatchOutputReader::createDefaultResult() const
{ {
CatchResult *result = nullptr; if (m_testCaseInfo.size() == 0)
if (m_testCaseInfo.size() > 0) { return CatchResult(id(), {}, m_sectionDepth);
result = new CatchResult(id(), m_testCaseInfo.first().name, m_sectionDepth); CatchResult result = CatchResult(id(), m_testCaseInfo.first().name, m_sectionDepth);
result->setDescription(m_testCaseInfo.last().name); result.setDescription(m_testCaseInfo.last().name);
result->setLine(m_testCaseInfo.last().line); result.setLine(m_testCaseInfo.last().line);
const QString givenPath = m_testCaseInfo.last().filename; const QString givenPath = m_testCaseInfo.last().filename;
if (!givenPath.isEmpty()) { if (!givenPath.isEmpty())
result->setFileName(constructSourceFilePath(m_buildDir, givenPath)); result.setFileName(constructSourceFilePath(m_buildDir, givenPath));
} return result;
} else {
result = new CatchResult(id(), {}, m_sectionDepth);
}
return TestResultPtr(result);
} }
void CatchOutputReader::recordTestInformation(const QXmlStreamAttributes &attributes) void CatchOutputReader::recordTestInformation(const QXmlStreamAttributes &attributes)
@@ -242,37 +237,38 @@ void CatchOutputReader::recordBenchmarkDetails(
void CatchOutputReader::sendResult(const ResultType result) void CatchOutputReader::sendResult(const ResultType result)
{ {
TestResultPtr catchResult = createDefaultResult(); TestResult catchResult = createDefaultResult();
catchResult->setResult(result); catchResult.setResult(result);
if (result == ResultType::TestStart && m_testCaseInfo.size() > 0) { if (result == ResultType::TestStart && m_testCaseInfo.size() > 0) {
catchResult->setDescription(Tr::tr("Executing %1 \"%2\"").arg(testOutputNodeToString().toLower()) catchResult.setDescription(Tr::tr("Executing %1 \"%2\"")
.arg(catchResult->description())); .arg(testOutputNodeToString().toLower(), catchResult.description()));
} else if (result == ResultType::Pass || result == ResultType::UnexpectedPass) { } else if (result == ResultType::Pass || result == ResultType::UnexpectedPass) {
if (result == ResultType::UnexpectedPass) if (result == ResultType::UnexpectedPass)
++m_xpassCount; ++m_xpassCount;
if (m_currentExpression.isEmpty()) { if (m_currentExpression.isEmpty()) {
catchResult->setDescription(Tr::tr("%1 \"%2\" passed").arg(testOutputNodeToString()) catchResult.setDescription(Tr::tr("%1 \"%2\" passed")
.arg(catchResult->description())); .arg(testOutputNodeToString(), catchResult.description()));
} else { } else {
catchResult->setDescription(Tr::tr("Expression passed") catchResult.setDescription(Tr::tr("Expression passed")
.append('\n').append(m_currentExpression)); .append('\n').append(m_currentExpression));
} }
m_reportedSectionResult = true; m_reportedSectionResult = true;
m_reportedResult = true; m_reportedResult = true;
} else if (result == ResultType::Fail || result == ResultType::ExpectedFail) { } else if (result == ResultType::Fail || result == ResultType::ExpectedFail) {
catchResult->setDescription(Tr::tr("Expression failed: %1").arg(m_currentExpression.trimmed())); catchResult.setDescription(Tr::tr("Expression failed: %1")
.arg(m_currentExpression.trimmed()));
if (!m_reportedSectionResult) if (!m_reportedSectionResult)
m_reportedSectionResult = true; m_reportedSectionResult = true;
m_reportedResult = true; m_reportedResult = true;
} else if (result == ResultType::TestEnd) { } else if (result == ResultType::TestEnd) {
catchResult->setDescription(Tr::tr("Finished executing %1 \"%2\"").arg(testOutputNodeToString().toLower()) catchResult.setDescription(Tr::tr("Finished executing %1 \"%2\"")
.arg(catchResult->description())); .arg(testOutputNodeToString().toLower(), catchResult.description()));
} else if (result == ResultType::Benchmark || result == ResultType::MessageFatal) { } else if (result == ResultType::Benchmark || result == ResultType::MessageFatal) {
catchResult->setDescription(m_currentExpression); catchResult.setDescription(m_currentExpression);
} else if (result == ResultType::MessageWarn || result == ResultType::MessageInfo) { } else if (result == ResultType::MessageWarn || result == ResultType::MessageInfo) {
catchResult->setDescription(m_currentExpression.trimmed()); catchResult.setDescription(m_currentExpression.trimmed());
} }
reportResult(catchResult); reportResult(catchResult);
@@ -319,8 +315,7 @@ QString CatchOutputReader::testOutputNodeToString() const
case SectionNode: case SectionNode:
return QStringLiteral("Section"); return QStringLiteral("Section");
} }
return {};
return QString();
} }
} // namespace Internal } // namespace Internal

View File

@@ -14,13 +14,13 @@ namespace Internal {
class CatchOutputReader : public TestOutputReader class CatchOutputReader : public TestOutputReader
{ {
public: public:
CatchOutputReader(const QFutureInterface<TestResultPtr> &futureInterface, CatchOutputReader(const QFutureInterface<TestResult> &futureInterface,
Utils::QtcProcess *testApplication, const Utils::FilePath &buildDirectory, Utils::QtcProcess *testApplication, const Utils::FilePath &buildDirectory,
const Utils::FilePath &projectFile); const Utils::FilePath &projectFile);
protected: protected:
void processOutputLine(const QByteArray &outputLineWithNewLine) override; void processOutputLine(const QByteArray &outputLineWithNewLine) override;
TestResultPtr createDefaultResult() const override; TestResult createDefaultResult() const override;
private: private:
enum TestOutputNodeType { enum TestOutputNodeType {

View File

@@ -20,8 +20,8 @@ public:
Q_FLAGS(TestState) Q_FLAGS(TestState)
Q_DECLARE_FLAGS(TestStates, TestState) Q_DECLARE_FLAGS(TestStates, TestState)
explicit CatchTreeItem(ITestFramework *testFramework, const QString &name = QString(), explicit CatchTreeItem(ITestFramework *testFramework, const QString &name = {},
const Utils::FilePath &filePath = Utils::FilePath(), Type type = Root) const Utils::FilePath &filePath = {}, Type type = Root)
: TestTreeItem(testFramework, name, filePath, type) {} : TestTreeItem(testFramework, name, filePath, type) {}
void setStates(CatchTreeItem::TestStates state) { m_state = state; } void setStates(CatchTreeItem::TestStates state) { m_state = state; }

View File

@@ -13,7 +13,7 @@ CTestConfiguration::CTestConfiguration(ITestBase *testBase)
setDisplayName("CTest"); setDisplayName("CTest");
} }
TestOutputReader *CTestConfiguration::createOutputReader(const QFutureInterface<TestResultPtr> &fi, TestOutputReader *CTestConfiguration::createOutputReader(const QFutureInterface<TestResult> &fi,
Utils::QtcProcess *app) const Utils::QtcProcess *app) const
{ {
return new CTestOutputReader(fi, app, workingDirectory()); return new CTestOutputReader(fi, app, workingDirectory());

View File

@@ -13,7 +13,7 @@ class CTestConfiguration final : public Autotest::TestToolConfiguration
public: public:
explicit CTestConfiguration(ITestBase *testBase); explicit CTestConfiguration(ITestBase *testBase);
TestOutputReader *createOutputReader(const QFutureInterface<TestResultPtr> &fi, TestOutputReader *createOutputReader(const QFutureInterface<TestResult> &fi,
Utils::QtcProcess *app) const final; Utils::QtcProcess *app) const final;
}; };

View File

@@ -52,7 +52,7 @@ public:
{} {}
}; };
CTestOutputReader::CTestOutputReader(const QFutureInterface<TestResultPtr> &futureInterface, CTestOutputReader::CTestOutputReader(const QFutureInterface<TestResult> &futureInterface,
Utils::QtcProcess *testApplication, Utils::QtcProcess *testApplication,
const Utils::FilePath &buildDirectory) const Utils::FilePath &buildDirectory)
: TestOutputReader(futureInterface, testApplication, buildDirectory) : TestOutputReader(futureInterface, testApplication, buildDirectory)
@@ -91,9 +91,9 @@ void CTestOutputReader::processOutputLine(const QByteArray &outputLine)
if (!m_testName.isEmpty()) // possible? if (!m_testName.isEmpty()) // possible?
sendCompleteInformation(); sendCompleteInformation();
m_project = match.captured(1); m_project = match.captured(1);
TestResultPtr testResult = createDefaultResult(); TestResult testResult = createDefaultResult();
testResult->setResult(ResultType::TestStart); testResult.setResult(ResultType::TestStart);
testResult->setDescription(Tr::tr("Running tests for %1").arg(m_project)); testResult.setDescription(Tr::tr("Running tests for %1").arg(m_project));
reportResult(testResult); reportResult(testResult);
} else if (ExactMatch match = testCase1.match(line)) { } else if (ExactMatch match = testCase1.match(line)) {
int current = match.captured("current").toInt(); int current = match.captured("current").toInt();
@@ -125,9 +125,9 @@ void CTestOutputReader::processOutputLine(const QByteArray &outputLine)
} else if (ExactMatch match = summary.match(line)) { } else if (ExactMatch match = summary.match(line)) {
if (!m_testName.isEmpty()) if (!m_testName.isEmpty())
sendCompleteInformation(); sendCompleteInformation();
TestResultPtr testResult = createDefaultResult(); TestResult testResult = createDefaultResult();
testResult->setResult(ResultType::MessageInfo); testResult.setResult(ResultType::MessageInfo);
testResult->setDescription(match.captured()); testResult.setDescription(match.captured());
reportResult(testResult); reportResult(testResult);
int failed = match.captured(1).toInt(); int failed = match.captured(1).toInt();
int testCount = match.captured(2).toInt(); int testCount = match.captured(2).toInt();
@@ -136,9 +136,9 @@ void CTestOutputReader::processOutputLine(const QByteArray &outputLine)
} else if (ExactMatch match = summaryTime.match(line)) { } else if (ExactMatch match = summaryTime.match(line)) {
if (!m_testName.isEmpty()) // possible? if (!m_testName.isEmpty()) // possible?
sendCompleteInformation(); sendCompleteInformation();
TestResultPtr testResult = createDefaultResult(); TestResult testResult = createDefaultResult();
testResult->setResult(ResultType::TestEnd); testResult.setResult(ResultType::TestEnd);
testResult->setDescription(match.captured()); testResult.setDescription(match.captured());
reportResult(testResult); reportResult(testResult);
} else if (ExactMatch match = testCrash.match(line)) { } else if (ExactMatch match = testCrash.match(line)) {
m_description = match.captured(); m_description = match.captured();
@@ -156,9 +156,9 @@ void CTestOutputReader::processOutputLine(const QByteArray &outputLine)
} }
} }
TestResultPtr CTestOutputReader::createDefaultResult() const TestResult CTestOutputReader::createDefaultResult() const
{ {
return TestResultPtr(new CTestResult(id(), m_project, m_testName)); return CTestResult(id(), m_project, m_testName);
} }
void CTestOutputReader::sendCompleteInformation() void CTestOutputReader::sendCompleteInformation()
@@ -168,10 +168,9 @@ void CTestOutputReader::sendCompleteInformation()
QTC_CHECK(m_currentTestNo == -1 && m_testName.isEmpty()); QTC_CHECK(m_currentTestNo == -1 && m_testName.isEmpty());
return; return;
} }
TestResult testResult = createDefaultResult();
TestResultPtr testResult = createDefaultResult(); testResult.setResult(m_result);
testResult->setResult(m_result); testResult.setDescription(m_description);
testResult->setDescription(m_description);
reportResult(testResult); reportResult(testResult);
m_testName.clear(); m_testName.clear();
m_description.clear(); m_description.clear();

View File

@@ -13,12 +13,12 @@ namespace Internal {
class CTestOutputReader final : public Autotest::TestOutputReader class CTestOutputReader final : public Autotest::TestOutputReader
{ {
public: public:
CTestOutputReader(const QFutureInterface<TestResultPtr> &futureInterface, CTestOutputReader(const QFutureInterface<TestResult> &futureInterface,
Utils::QtcProcess *testApplication, const Utils::FilePath &buildDirectory); Utils::QtcProcess *testApplication, const Utils::FilePath &buildDirectory);
protected: protected:
void processOutputLine(const QByteArray &outputLineWithNewLine) final; void processOutputLine(const QByteArray &outputLineWithNewLine) final;
TestResultPtr createDefaultResult() const final; TestResult createDefaultResult() const final;
private: private:
void sendCompleteInformation(); void sendCompleteInformation();
int m_currentTestNo = -1; int m_currentTestNo = -1;

View File

@@ -36,9 +36,7 @@ QString CTestTool::displayName() const
ITestTreeItem *CTestTool::createRootNode() ITestTreeItem *CTestTool::createRootNode()
{ {
return new CTestTreeItem(this, return new CTestTreeItem(this, displayName(), {}, ITestTreeItem::Root);
displayName(),
Utils::FilePath(), ITestTreeItem::Root);
} }
} // namespace Internal } // namespace Internal

View File

@@ -15,7 +15,7 @@
namespace Autotest { namespace Autotest {
namespace Internal { namespace Internal {
TestOutputReader *GTestConfiguration::createOutputReader(const QFutureInterface<TestResultPtr> &fi, TestOutputReader *GTestConfiguration::createOutputReader(const QFutureInterface<TestResult> &fi,
Utils::QtcProcess *app) const Utils::QtcProcess *app) const
{ {
return new GTestOutputReader(fi, app, buildDirectory(), projectFile()); return new GTestOutputReader(fi, app, buildDirectory(), projectFile());

View File

@@ -14,7 +14,7 @@ public:
explicit GTestConfiguration(ITestFramework *framework) explicit GTestConfiguration(ITestFramework *framework)
: DebuggableTestConfiguration(framework) {} : DebuggableTestConfiguration(framework) {}
TestOutputReader *createOutputReader(const QFutureInterface<TestResultPtr> &fi, TestOutputReader *createOutputReader(const QFutureInterface<TestResult> &fi,
Utils::QtcProcess *app) const override; Utils::QtcProcess *app) const override;
QStringList argumentsForTestRunner(QStringList *omitted = nullptr) const override; QStringList argumentsForTestRunner(QStringList *omitted = nullptr) const override;
Utils::Environment filteredEnvironment(const Utils::Environment &original) const override; Utils::Environment filteredEnvironment(const Utils::Environment &original) const override;

View File

@@ -25,10 +25,7 @@ ITestParser *GTestFramework::createTestParser()
ITestTreeItem *GTestFramework::createRootNode() ITestTreeItem *GTestFramework::createRootNode()
{ {
return new GTestTreeItem( return new GTestTreeItem(this, displayName(), {}, ITestTreeItem::Root);
this,
displayName(),
Utils::FilePath(), ITestTreeItem::Root);
} }
const char *GTestFramework::name() const const char *GTestFramework::name() const

View File

@@ -15,7 +15,7 @@
namespace Autotest { namespace Autotest {
namespace Internal { namespace Internal {
GTestOutputReader::GTestOutputReader(const QFutureInterface<TestResultPtr> &futureInterface, GTestOutputReader::GTestOutputReader(const QFutureInterface<TestResult> &futureInterface,
Utils::QtcProcess *testApplication, Utils::QtcProcess *testApplication,
const Utils::FilePath &buildDirectory, const Utils::FilePath &buildDirectory,
const Utils::FilePath &projectFile) const Utils::FilePath &projectFile)
@@ -70,9 +70,9 @@ void GTestOutputReader::processOutputLine(const QByteArray &outputLine)
m_description = line; m_description = line;
if (m_iteration > 1) if (m_iteration > 1)
m_description.append(' ' + Tr::tr("(iteration %1)").arg(m_iteration)); m_description.append(' ' + Tr::tr("(iteration %1)").arg(m_iteration));
TestResultPtr testResult = TestResultPtr(new GTestResult(id(), {}, m_projectFile)); GTestResult testResult(id(), {}, m_projectFile);
testResult->setResult(ResultType::MessageInternal); testResult.setResult(ResultType::MessageInternal);
testResult->setDescription(m_description); testResult.setDescription(m_description);
reportResult(testResult); reportResult(testResult);
m_description.clear(); m_description.clear();
} else if (ExactMatch match = disabledTests.match(line)) { } else if (ExactMatch match = disabledTests.match(line)) {
@@ -83,66 +83,66 @@ void GTestOutputReader::processOutputLine(const QByteArray &outputLine)
} }
if (ExactMatch match = testEnds.match(line)) { if (ExactMatch match = testEnds.match(line)) {
TestResultPtr testResult = createDefaultResult(); TestResult testResult = createDefaultResult();
testResult->setResult(ResultType::TestEnd); testResult.setResult(ResultType::TestEnd);
testResult->setDescription(Tr::tr("Test execution took %1").arg(match.captured(2))); testResult.setDescription(Tr::tr("Test execution took %1").arg(match.captured(2)));
reportResult(testResult); reportResult(testResult);
m_currentTestSuite.clear(); m_currentTestSuite.clear();
m_currentTestCase.clear(); m_currentTestCase.clear();
} else if (ExactMatch match = newTestStarts.match(line)) { } else if (ExactMatch match = newTestStarts.match(line)) {
setCurrentTestSuite(match.captured(1)); setCurrentTestSuite(match.captured(1));
TestResultPtr testResult = createDefaultResult(); TestResult testResult = createDefaultResult();
testResult->setResult(ResultType::TestStart); testResult.setResult(ResultType::TestStart);
if (m_iteration > 1) { if (m_iteration > 1) {
testResult->setDescription(Tr::tr("Repeating test suite %1 (iteration %2)") testResult.setDescription(Tr::tr("Repeating test suite %1 (iteration %2)")
.arg(m_currentTestSuite).arg(m_iteration)); .arg(m_currentTestSuite).arg(m_iteration));
} else { } else {
testResult->setDescription(Tr::tr("Executing test suite %1").arg(m_currentTestSuite)); testResult.setDescription(Tr::tr("Executing test suite %1").arg(m_currentTestSuite));
} }
reportResult(testResult); reportResult(testResult);
} else if (ExactMatch match = newTestSetStarts.match(line)) { } else if (ExactMatch match = newTestSetStarts.match(line)) {
m_testSetStarted = true; m_testSetStarted = true;
setCurrentTestCase(match.captured(1)); setCurrentTestCase(match.captured(1));
TestResultPtr testResult = TestResultPtr(new GTestResult({}, {}, m_projectFile)); GTestResult testResult("internal", {}, m_projectFile);
testResult->setResult(ResultType::MessageCurrentTest); testResult.setResult(ResultType::MessageCurrentTest);
testResult->setDescription(Tr::tr("Entering test case %1").arg(m_currentTestCase)); testResult.setDescription(Tr::tr("Entering test case %1").arg(m_currentTestCase));
reportResult(testResult); reportResult(testResult);
m_description.clear(); m_description.clear();
} else if (ExactMatch match = testSetSuccess.match(line)) { } else if (ExactMatch match = testSetSuccess.match(line)) {
m_testSetStarted = false; m_testSetStarted = false;
TestResultPtr testResult = createDefaultResult(); TestResult testResult = createDefaultResult();
testResult->setResult(ResultType::Pass); testResult.setResult(ResultType::Pass);
testResult->setDescription(m_description); testResult.setDescription(m_description);
reportResult(testResult); reportResult(testResult);
m_description.clear(); m_description.clear();
testResult = createDefaultResult(); testResult = createDefaultResult();
testResult->setResult(ResultType::MessageInternal); testResult.setResult(ResultType::MessageInternal);
testResult->setDescription(Tr::tr("Execution took %1.").arg(match.captured(2))); testResult.setDescription(Tr::tr("Execution took %1.").arg(match.captured(2)));
reportResult(testResult); reportResult(testResult);
m_futureInterface.setProgressValue(m_futureInterface.progressValue() + 1); m_futureInterface.setProgressValue(m_futureInterface.progressValue() + 1);
} else if (ExactMatch match = testSetFail.match(line)) { } else if (ExactMatch match = testSetFail.match(line)) {
m_testSetStarted = false; m_testSetStarted = false;
TestResultPtr testResult = createDefaultResult(); TestResult testResult = createDefaultResult();
testResult->setResult(ResultType::Fail); testResult.setResult(ResultType::Fail);
m_description.chop(1); m_description.chop(1);
handleDescriptionAndReportResult(testResult); handleDescriptionAndReportResult(testResult);
testResult = createDefaultResult(); testResult = createDefaultResult();
testResult->setResult(ResultType::MessageInternal); testResult.setResult(ResultType::MessageInternal);
testResult->setDescription(Tr::tr("Execution took %1.").arg(match.captured(2))); testResult.setDescription(Tr::tr("Execution took %1.").arg(match.captured(2)));
reportResult(testResult); reportResult(testResult);
m_futureInterface.setProgressValue(m_futureInterface.progressValue() + 1); m_futureInterface.setProgressValue(m_futureInterface.progressValue() + 1);
} else if (ExactMatch match = testSetSkipped.match(line)) { } else if (ExactMatch match = testSetSkipped.match(line)) {
if (!m_testSetStarted) // ignore SKIPPED at summary if (!m_testSetStarted) // ignore SKIPPED at summary
return; return;
m_testSetStarted = false; m_testSetStarted = false;
TestResultPtr testResult = createDefaultResult(); TestResult testResult = createDefaultResult();
testResult->setResult(ResultType::Skip); testResult.setResult(ResultType::Skip);
m_description.chop(1); m_description.chop(1);
m_description.prepend(match.captured(1) + '\n'); m_description.prepend(match.captured(1) + '\n');
handleDescriptionAndReportResult(testResult); handleDescriptionAndReportResult(testResult);
testResult = createDefaultResult(); testResult = createDefaultResult();
testResult->setResult(ResultType::MessageInternal); testResult.setResult(ResultType::MessageInternal);
testResult->setDescription(Tr::tr("Execution took %1.").arg(match.captured(2))); testResult.setDescription(Tr::tr("Execution took %1.").arg(match.captured(2)));
reportResult(testResult); reportResult(testResult);
} else if (ExactMatch match = logging.match(line)) { } else if (ExactMatch match = logging.match(line)) {
const QString severity = match.captured(1).trimmed(); const QString severity = match.captured(1).trimmed();
@@ -153,13 +153,13 @@ void GTestOutputReader::processOutputLine(const QByteArray &outputLine)
case 'E': type = ResultType::MessageError; break; // ERROR case 'E': type = ResultType::MessageError; break; // ERROR
case 'F': type = ResultType::MessageFatal; break; // FATAL case 'F': type = ResultType::MessageFatal; break; // FATAL
} }
TestResultPtr testResult = createDefaultResult(); TestResult testResult = createDefaultResult();
testResult->setResult(type); testResult.setResult(type);
testResult->setLine(match.captured(3).toInt()); testResult.setLine(match.captured(3).toInt());
const Utils::FilePath file = constructSourceFilePath(m_buildDir, match.captured(2)); const Utils::FilePath file = constructSourceFilePath(m_buildDir, match.captured(2));
if (file.exists()) if (file.exists())
testResult->setFileName(file); testResult.setFileName(file);
testResult->setDescription(match.captured(4)); testResult.setDescription(match.captured(4));
reportResult(testResult); reportResult(testResult);
} else if (ExactMatch match = testDeath.match(line)) { } else if (ExactMatch match = testDeath.match(line)) {
m_description.append(line); m_description.append(line);
@@ -175,19 +175,15 @@ void GTestOutputReader::processStdError(const QByteArray &outputLine)
emit newOutputLineAvailable(outputLine, OutputChannel::StdErr); emit newOutputLineAvailable(outputLine, OutputChannel::StdErr);
} }
TestResultPtr GTestOutputReader::createDefaultResult() const TestResult GTestOutputReader::createDefaultResult() const
{ {
GTestResult *result = new GTestResult(id(), m_currentTestSuite, m_projectFile, GTestResult result(id(), m_currentTestSuite, m_projectFile, m_currentTestCase, m_iteration);
m_currentTestCase, m_iteration); const ITestTreeItem *testItem = result.findTestTreeItem();
const ITestTreeItem *testItem = result->findTestTreeItem();
if (testItem && testItem->line()) { if (testItem && testItem->line()) {
result->setFileName(testItem->filePath()); result.setFileName(testItem->filePath());
result->setLine(testItem->line()); result.setLine(testItem->line());
} }
return result;
return TestResultPtr(result);
} }
void GTestOutputReader::setCurrentTestCase(const QString &testCase) void GTestOutputReader::setCurrentTestCase(const QString &testCase)
@@ -200,13 +196,13 @@ void GTestOutputReader::setCurrentTestSuite(const QString &testSuite)
m_currentTestSuite = testSuite; m_currentTestSuite = testSuite;
} }
void GTestOutputReader::handleDescriptionAndReportResult(TestResultPtr testResult) void GTestOutputReader::handleDescriptionAndReportResult(const TestResult &testResult)
{ {
static const QRegularExpression failureLocation("^(.*):(\\d+): Failure$"); static const QRegularExpression failureLocation("^(.*):(\\d+): Failure$");
static const QRegularExpression skipOrErrorLocation("^(.*)\\((\\d+)\\): (Skipped|error:.*)$"); static const QRegularExpression skipOrErrorLocation("^(.*)\\((\\d+)\\): (Skipped|error:.*)$");
QStringList resultDescription; QStringList resultDescription;
TestResult result = testResult;
for (const QString &output : m_description.split('\n')) { for (const QString &output : m_description.split('\n')) {
QRegularExpressionMatch innerMatch = failureLocation.match(output); QRegularExpressionMatch innerMatch = failureLocation.match(output);
if (!innerMatch.hasMatch()) { if (!innerMatch.hasMatch()) {
@@ -216,20 +212,20 @@ void GTestOutputReader::handleDescriptionAndReportResult(TestResultPtr testResul
continue; continue;
} }
} }
testResult->setDescription(resultDescription.join('\n')); result.setDescription(resultDescription.join('\n'));
reportResult(testResult); reportResult(testResult);
resultDescription.clear(); resultDescription.clear();
testResult = createDefaultResult(); result = createDefaultResult();
testResult->setResult(ResultType::MessageLocation); result.setResult(ResultType::MessageLocation);
testResult->setLine(innerMatch.captured(2).toInt()); result.setLine(innerMatch.captured(2).toInt());
const Utils::FilePath file = constructSourceFilePath(m_buildDir, innerMatch.captured(1)); const Utils::FilePath file = constructSourceFilePath(m_buildDir, innerMatch.captured(1));
if (file.exists()) if (file.exists())
testResult->setFileName(file); result.setFileName(file);
resultDescription << output; resultDescription << output;
} }
testResult->setDescription(resultDescription.join('\n')); result.setDescription(resultDescription.join('\n'));
reportResult(testResult); reportResult(result);
m_description.clear(); m_description.clear();
} }

View File

@@ -11,18 +11,18 @@ namespace Internal {
class GTestOutputReader : public TestOutputReader class GTestOutputReader : public TestOutputReader
{ {
public: public:
GTestOutputReader(const QFutureInterface<TestResultPtr> &futureInterface, GTestOutputReader(const QFutureInterface<TestResult> &futureInterface,
Utils::QtcProcess *testApplication, const Utils::FilePath &buildDirectory, Utils::QtcProcess *testApplication, const Utils::FilePath &buildDirectory,
const Utils::FilePath &projectFile); const Utils::FilePath &projectFile);
protected: protected:
void processOutputLine(const QByteArray &outputLine) override; void processOutputLine(const QByteArray &outputLine) override;
void processStdError(const QByteArray &outputLine) override; void processStdError(const QByteArray &outputLine) override;
TestResultPtr createDefaultResult() const override; TestResult createDefaultResult() const override;
private: private:
void setCurrentTestCase(const QString &testCase); void setCurrentTestCase(const QString &testCase);
void setCurrentTestSuite(const QString &testSuite); void setCurrentTestSuite(const QString &testSuite);
void handleDescriptionAndReportResult(TestResultPtr testResult); void handleDescriptionAndReportResult(const TestResult &testResult);
Utils::FilePath m_projectFile; Utils::FilePath m_projectFile;
QString m_currentTestSuite; QString m_currentTestSuite;

View File

@@ -30,7 +30,7 @@ GTestSettings::GTestSettings()
registerAspect(&seed); registerAspect(&seed);
seed.setSettingsKey("Seed"); seed.setSettingsKey("Seed");
seed.setSpecialValueText(QString()); seed.setSpecialValueText({});
seed.setEnabled(false); seed.setEnabled(false);
seed.setLabelText(Tr::tr("Seed:")); seed.setLabelText(Tr::tr("Seed:"));
seed.setToolTip(Tr::tr("A seed of 0 generates a seed based on the current timestamp.")); seed.setToolTip(Tr::tr("A seed of 0 generates a seed based on the current timestamp."));

View File

@@ -24,10 +24,8 @@ public:
Q_FLAGS(TestState) Q_FLAGS(TestState)
Q_DECLARE_FLAGS(TestStates, TestState) Q_DECLARE_FLAGS(TestStates, TestState)
explicit GTestTreeItem(ITestFramework *testFramework, explicit GTestTreeItem(ITestFramework *testFramework, const QString &name = {},
const QString &name = QString(), const Utils::FilePath &filePath = {}, Type type = Root)
const Utils::FilePath &filePath = Utils::FilePath(),
Type type = Root)
: TestTreeItem(testFramework, name, filePath, type), m_state(Enabled) : TestTreeItem(testFramework, name, filePath, type), m_state(Enabled)
{} {}

View File

@@ -72,7 +72,7 @@ public:
bool grouping() const { return m_grouping; } bool grouping() const { return m_grouping; }
void setGrouping(bool group) { m_grouping = group; } void setGrouping(bool group) { m_grouping = group; }
// framework specific tool tip to be displayed on the general settings page // framework specific tool tip to be displayed on the general settings page
virtual QString groupingToolTip() const { return QString(); } virtual QString groupingToolTip() const { return {}; }
ITestFramework *asFramework() final { return this; } ITestFramework *asFramework() final { return this; }

View File

@@ -26,7 +26,7 @@ static QStringList quoteIfNeeded(const QStringList &testCases, bool debugMode)
}); });
} }
TestOutputReader *QtTestConfiguration::createOutputReader(const QFutureInterface<TestResultPtr> &fi, TestOutputReader *QtTestConfiguration::createOutputReader(const QFutureInterface<TestResult> &fi,
Utils::QtcProcess *app) const Utils::QtcProcess *app) const
{ {
auto qtSettings = static_cast<QtTestSettings *>(framework()->testSettings()); auto qtSettings = static_cast<QtTestSettings *>(framework()->testSettings());

View File

@@ -13,7 +13,7 @@ class QtTestConfiguration : public DebuggableTestConfiguration
public: public:
explicit QtTestConfiguration(ITestFramework *framework) explicit QtTestConfiguration(ITestFramework *framework)
: DebuggableTestConfiguration(framework) {} : DebuggableTestConfiguration(framework) {}
TestOutputReader *createOutputReader(const QFutureInterface<TestResultPtr> &fi, TestOutputReader *createOutputReader(const QFutureInterface<TestResult> &fi,
Utils::QtcProcess *app) const override; Utils::QtcProcess *app) const override;
QStringList argumentsForTestRunner(QStringList *omitted = nullptr) const override; QStringList argumentsForTestRunner(QStringList *omitted = nullptr) const override;
Utils::Environment filteredEnvironment(const Utils::Environment &original) const override; Utils::Environment filteredEnvironment(const Utils::Environment &original) const override;

View File

@@ -18,10 +18,7 @@ ITestParser *QtTestFramework::createTestParser()
ITestTreeItem *QtTestFramework::createRootNode() ITestTreeItem *QtTestFramework::createRootNode()
{ {
return new QtTestTreeItem( return new QtTestTreeItem(this, displayName(), {}, ITestTreeItem::Root);
this,
displayName(),
Utils::FilePath(), ITestTreeItem::Root);
} }
const char *QtTestFramework::name() const const char *QtTestFramework::name() const

View File

@@ -103,7 +103,7 @@ static QString constructBenchmarkInformation(const QString &metric, double value
.arg(iterations); .arg(iterations);
} }
QtTestOutputReader::QtTestOutputReader(const QFutureInterface<TestResultPtr> &futureInterface, QtTestOutputReader::QtTestOutputReader(const QFutureInterface<TestResult> &futureInterface,
Utils::QtcProcess *testApplication, Utils::QtcProcess *testApplication,
const Utils::FilePath &buildDirectory, const Utils::FilePath &buildDirectory,
const Utils::FilePath &projectFile, const Utils::FilePath &projectFile,
@@ -130,11 +130,9 @@ void QtTestOutputReader::processOutputLine(const QByteArray &outputLine)
} }
} }
TestResultPtr QtTestOutputReader::createDefaultResult() const TestResult QtTestOutputReader::createDefaultResult() const
{ {
QtTestResult *result = new QtTestResult(id(), m_className, m_projectFile, m_testType, return QtTestResult(id(), m_className, m_projectFile, m_testType, m_testCase, m_dataTag);
m_testCase, m_dataTag);
return TestResultPtr(result);
} }
static QString trQtVersion(const QString &version) static QString trQtVersion(const QString &version)
@@ -455,73 +453,75 @@ void QtTestOutputReader::processSummaryFinishOutput()
void QtTestOutputReader::sendCompleteInformation() void QtTestOutputReader::sendCompleteInformation()
{ {
TestResultPtr testResult = createDefaultResult(); TestResult testResult = createDefaultResult();
testResult->setResult(m_result); testResult.setResult(m_result);
if (m_lineNumber) { if (m_lineNumber) {
testResult->setFileName(m_file); testResult.setFileName(m_file);
testResult->setLine(m_lineNumber); testResult.setLine(m_lineNumber);
} else { } else {
const ITestTreeItem *testItem = testResult->findTestTreeItem(); const ITestTreeItem *testItem = testResult.findTestTreeItem();
if (testItem && testItem->line()) { if (testItem && testItem->line()) {
testResult->setFileName(testItem->filePath()); testResult.setFileName(testItem->filePath());
testResult->setLine(testItem->line()); testResult.setLine(testItem->line());
} }
} }
testResult->setDescription(m_description); testResult.setDescription(m_description);
reportResult(testResult); reportResult(testResult);
} }
void QtTestOutputReader::sendMessageCurrentTest() void QtTestOutputReader::sendMessageCurrentTest()
{ {
QtTestResult *testResult = new QtTestResult({}, {}, m_projectFile, m_testType); QtTestResult result("internal", {}, m_projectFile, m_testType);
testResult->setResult(ResultType::MessageCurrentTest); result.setResult(ResultType::MessageCurrentTest);
testResult->setDescription(Tr::tr("Entering test function %1::%2").arg(m_className, m_testCase)); result.setDescription(Tr::tr("Entering test function %1::%2").arg(m_className, m_testCase));
reportResult(TestResultPtr(testResult)); reportResult(result);
} }
void QtTestOutputReader::sendStartMessage(bool isFunction) void QtTestOutputReader::sendStartMessage(bool isFunction)
{ {
TestResultPtr testResult = createDefaultResult(); TestResult result = createDefaultResult();
testResult->setResult(ResultType::TestStart); result.setResult(ResultType::TestStart);
testResult->setDescription(isFunction ? Tr::tr("Executing test function %1").arg(m_testCase) result.setDescription(isFunction ? Tr::tr("Executing test function %1").arg(m_testCase)
: Tr::tr("Executing test case %1").arg(m_className)); : Tr::tr("Executing test case %1").arg(m_className));
const ITestTreeItem *testItem = testResult->findTestTreeItem(); const ITestTreeItem *testItem = result.findTestTreeItem();
if (testItem && testItem->line()) { if (testItem && testItem->line()) {
testResult->setFileName(testItem->filePath()); result.setFileName(testItem->filePath());
testResult->setLine(testItem->line()); result.setLine(testItem->line());
} }
reportResult(testResult); reportResult(result);
} }
void QtTestOutputReader::sendFinishMessage(bool isFunction) void QtTestOutputReader::sendFinishMessage(bool isFunction)
{ {
TestResultPtr testResult = createDefaultResult(); TestResult result = createDefaultResult();
testResult->setResult(ResultType::TestEnd); result.setResult(ResultType::TestEnd);
if (!m_duration.isEmpty()) { if (!m_duration.isEmpty()) {
testResult->setDescription(isFunction ? Tr::tr("Execution took %1 ms.").arg(m_duration) result.setDescription(isFunction ? Tr::tr("Execution took %1 ms.").arg(m_duration)
: Tr::tr("Test execution took %1 ms.").arg(m_duration)); : Tr::tr("Test execution took %1 ms.").arg(m_duration));
} else { } else {
testResult->setDescription(isFunction ? Tr::tr("Test function finished.") result.setDescription(isFunction ? Tr::tr("Test function finished.")
: Tr::tr("Test finished.")); : Tr::tr("Test finished."));
} }
reportResult(testResult); reportResult(result);
} }
void QtTestOutputReader::handleAndSendConfigMessage(const QRegularExpressionMatch &config) void QtTestOutputReader::handleAndSendConfigMessage(const QRegularExpressionMatch &config)
{ {
TestResultPtr testResult = createDefaultResult(); TestResult result = createDefaultResult();
testResult->setResult(ResultType::MessageInternal); result.setResult(ResultType::MessageInternal);
testResult->setDescription(trQtVersion(config.captured(3))); result.setDescription(trQtVersion(config.captured(3)));
reportResult(testResult); reportResult(result);
testResult = createDefaultResult();
testResult->setResult(ResultType::MessageInternal); result = createDefaultResult();
testResult->setDescription(trQtBuild(config.captured(2))); result.setResult(ResultType::MessageInternal);
reportResult(testResult); result.setDescription(trQtBuild(config.captured(2)));
testResult = createDefaultResult(); reportResult(result);
testResult->setResult(ResultType::MessageInternal);
testResult->setDescription(trQtestVersion(config.captured(1))); result = createDefaultResult();
reportResult(testResult); result.setResult(ResultType::MessageInternal);
result.setDescription(trQtestVersion(config.captured(1)));
reportResult(result);
} }
} // namespace Internal } // namespace Internal

View File

@@ -22,12 +22,12 @@ public:
PlainText PlainText
}; };
QtTestOutputReader(const QFutureInterface<TestResultPtr> &futureInterface, QtTestOutputReader(const QFutureInterface<TestResult> &futureInterface,
Utils::QtcProcess *testApplication, const Utils::FilePath &buildDirectory, Utils::QtcProcess *testApplication, const Utils::FilePath &buildDirectory,
const Utils::FilePath &projectFile, OutputMode mode, TestType type); const Utils::FilePath &projectFile, OutputMode mode, TestType type);
protected: protected:
void processOutputLine(const QByteArray &outputLine) override; void processOutputLine(const QByteArray &outputLine) override;
TestResultPtr createDefaultResult() const override; TestResult createDefaultResult() const override;
private: private:
void processXMLOutput(const QByteArray &outputLine); void processXMLOutput(const QByteArray &outputLine);

View File

@@ -86,7 +86,7 @@ QString QtTestSettings::metricsTypeToOption(const MetricsType type)
{ {
switch (type) { switch (type) {
case MetricsType::Walltime: case MetricsType::Walltime:
return QString(); return {};
case MetricsType::TickCounter: case MetricsType::TickCounter:
return QString("-tickcounter"); return QString("-tickcounter");
case MetricsType::EventCounter: case MetricsType::EventCounter:
@@ -96,7 +96,7 @@ QString QtTestSettings::metricsTypeToOption(const MetricsType type)
case MetricsType::Perf: case MetricsType::Perf:
return QString("-perf"); return QString("-perf");
} }
return QString(); return {};
} }
QtTestSettingsPage::QtTestSettingsPage(QtTestSettings *settings, Id settingsId) QtTestSettingsPage::QtTestSettingsPage(QtTestSettings *settings, Id settingsId)

View File

@@ -11,8 +11,8 @@ namespace Internal {
class QtTestTreeItem : public TestTreeItem class QtTestTreeItem : public TestTreeItem
{ {
public: public:
explicit QtTestTreeItem(ITestFramework *framework, const QString &name = QString(), explicit QtTestTreeItem(ITestFramework *framework, const QString &name = {},
const Utils::FilePath &filePath = Utils::FilePath(), Type type = Root); const Utils::FilePath &filePath = {}, Type type = Root);
TestTreeItem *copyWithoutChildren() override; TestTreeItem *copyWithoutChildren() override;
QVariant data(int column, int role) const override; QVariant data(int column, int role) const override;

View File

@@ -189,7 +189,7 @@ QString TestDataFunctionVisitor::extractNameFromAST(StringLiteralAST *ast, bool
auto token = m_currentDoc->translationUnit()->tokenAt(ast->literal_token); auto token = m_currentDoc->translationUnit()->tokenAt(ast->literal_token);
if (!token.isStringLiteral()) { if (!token.isStringLiteral()) {
*ok = false; *ok = false;
return QString(); return {};
} }
*ok = true; *ok = true;
QString name = QString::fromUtf8(token.spell()); QString name = QString::fromUtf8(token.spell());

View File

@@ -22,7 +22,7 @@ QuickTestConfiguration::QuickTestConfiguration(ITestFramework *framework)
} }
TestOutputReader *QuickTestConfiguration::createOutputReader( TestOutputReader *QuickTestConfiguration::createOutputReader(
const QFutureInterface<TestResultPtr> &fi, Utils::QtcProcess *app) const const QFutureInterface<TestResult> &fi, Utils::QtcProcess *app) const
{ {
auto qtSettings = static_cast<QtTestSettings *>(framework()->testSettings()); auto qtSettings = static_cast<QtTestSettings *>(framework()->testSettings());
const QtTestOutputReader::OutputMode mode = qtSettings && qtSettings->useXMLOutput.value() const QtTestOutputReader::OutputMode mode = qtSettings && qtSettings->useXMLOutput.value()

View File

@@ -12,7 +12,7 @@ class QuickTestConfiguration : public DebuggableTestConfiguration
{ {
public: public:
explicit QuickTestConfiguration(ITestFramework *framework); explicit QuickTestConfiguration(ITestFramework *framework);
TestOutputReader *createOutputReader(const QFutureInterface<TestResultPtr> &fi, TestOutputReader *createOutputReader(const QFutureInterface<TestResult> &fi,
Utils::QtcProcess *app) const override; Utils::QtcProcess *app) const override;
QStringList argumentsForTestRunner(QStringList *omitted = nullptr) const override; QStringList argumentsForTestRunner(QStringList *omitted = nullptr) const override;
Utils::Environment filteredEnvironment(const Utils::Environment &original) const override; Utils::Environment filteredEnvironment(const Utils::Environment &original) const override;

View File

@@ -20,8 +20,7 @@ ITestParser *QuickTestFramework::createTestParser()
ITestTreeItem *QuickTestFramework::createRootNode() ITestTreeItem *QuickTestFramework::createRootNode()
{ {
return new QuickTestTreeItem(this, displayName(), return new QuickTestTreeItem(this, displayName(), {}, ITestTreeItem::Root);
Utils::FilePath(), ITestTreeItem::Root);
} }
const char *QuickTestFramework::name() const const char *QuickTestFramework::name() const

View File

@@ -121,7 +121,7 @@ QString QuickTestParser::quickTestName(const CPlusPlus::Document::Ptr &doc) cons
// check for using quick_test_main() directly // check for using quick_test_main() directly
CPlusPlus::Document::Ptr document = m_cppSnapshot.preprocessedDocument(fileContent, filePath); CPlusPlus::Document::Ptr document = m_cppSnapshot.preprocessedDocument(fileContent, filePath);
if (document.isNull()) if (document.isNull())
return QString(); return {};
document->check(); document->check();
CPlusPlus::AST *ast = document->translationUnit()->ast(); CPlusPlus::AST *ast = document->translationUnit()->ast();
QuickTestAstVisitor astVisitor(document, m_cppSnapshot); QuickTestAstVisitor astVisitor(document, m_cppSnapshot);
@@ -202,7 +202,7 @@ QList<Document::Ptr> QuickTestParser::scanDirectoryForQuickTestQmlFiles(const Ut
static bool checkQmlDocumentForQuickTestCode(QFutureInterface<TestParseResultPtr> &futureInterface, static bool checkQmlDocumentForQuickTestCode(QFutureInterface<TestParseResultPtr> &futureInterface,
const Document::Ptr &qmlJSDoc, const Document::Ptr &qmlJSDoc,
ITestFramework *framework, ITestFramework *framework,
const Utils::FilePath &proFile = Utils::FilePath(), const Utils::FilePath &proFile = {},
bool checkForDerivedTest = false) bool checkForDerivedTest = false)
{ {
if (qmlJSDoc.isNull()) if (qmlJSDoc.isNull())

View File

@@ -11,10 +11,8 @@ namespace Internal {
class QuickTestTreeItem : public TestTreeItem class QuickTestTreeItem : public TestTreeItem
{ {
public: public:
explicit QuickTestTreeItem(ITestFramework *testFramework, explicit QuickTestTreeItem(ITestFramework *testFramework, const QString &name = {},
const QString &name = QString(), const Utils::FilePath &filePath = {}, Type type = Root)
const Utils::FilePath &filePath = Utils::FilePath(),
Type type = Root)
: TestTreeItem(testFramework, name, filePath, type) : TestTreeItem(testFramework, name, filePath, type)
{} {}

View File

@@ -26,8 +26,6 @@ class TestOutputReader;
class TestResult; class TestResult;
enum class TestRunMode; enum class TestRunMode;
using TestResultPtr = QSharedPointer<TestResult>;
class ITestConfiguration class ITestConfiguration
{ {
public: public:
@@ -41,7 +39,7 @@ public:
bool hasExecutable() const; bool hasExecutable() const;
Utils::FilePath executableFilePath() const; Utils::FilePath executableFilePath() const;
virtual TestOutputReader *createOutputReader(const QFutureInterface<TestResultPtr> &fi, virtual TestOutputReader *createOutputReader(const QFutureInterface<TestResult> &fi,
Utils::QtcProcess *app) const = 0; Utils::QtcProcess *app) const = 0;
virtual Utils::Environment filteredEnvironment(const Utils::Environment &original) const; virtual Utils::Environment filteredEnvironment(const Utils::Environment &original) const;

View File

@@ -25,7 +25,7 @@ Utils::FilePath TestOutputReader::constructSourceFilePath(const Utils::FilePath
return filePath.isReadableFile() ? filePath : Utils::FilePath(); return filePath.isReadableFile() ? filePath : Utils::FilePath();
} }
TestOutputReader::TestOutputReader(const QFutureInterface<TestResultPtr> &futureInterface, TestOutputReader::TestOutputReader(const QFutureInterface<TestResult> &futureInterface,
Utils::QtcProcess *testApplication, Utils::QtcProcess *testApplication,
const Utils::FilePath &buildDirectory) const Utils::FilePath &buildDirectory)
: m_futureInterface(futureInterface) : m_futureInterface(futureInterface)
@@ -53,7 +53,7 @@ TestOutputReader::TestOutputReader(const QFutureInterface<TestResultPtr> &future
TestOutputReader::~TestOutputReader() TestOutputReader::~TestOutputReader()
{ {
if (m_sanitizerResult) if (m_sanitizerResult.isValid())
sendAndResetSanitizerResult(); sendAndResetSanitizerResult();
} }
@@ -71,17 +71,17 @@ void TestOutputReader::processStdError(const QByteArray &outputLine)
void TestOutputReader::reportCrash() void TestOutputReader::reportCrash()
{ {
TestResultPtr result = createDefaultResult(); TestResult result = createDefaultResult();
result->setDescription(Tr::tr("Test executable crashed.")); result.setDescription(Tr::tr("Test executable crashed."));
result->setResult(ResultType::MessageFatal); result.setResult(ResultType::MessageFatal);
m_futureInterface.reportResult(result); m_futureInterface.reportResult(result);
} }
void TestOutputReader::createAndReportResult(const QString &message, ResultType type) void TestOutputReader::createAndReportResult(const QString &message, ResultType type)
{ {
TestResultPtr result = createDefaultResult(); TestResult result = createDefaultResult();
result->setDescription(message); result.setDescription(message);
result->setResult(type); result.setResult(type);
reportResult(result); reportResult(result);
} }
@@ -105,9 +105,9 @@ QString TestOutputReader::removeCommandlineColors(const QString &original)
return result; return result;
} }
void TestOutputReader::reportResult(const TestResultPtr &result) void TestOutputReader::reportResult(const TestResult &result)
{ {
if (m_sanitizerResult) if (m_sanitizerResult.isValid())
sendAndResetSanitizerResult(); sendAndResetSanitizerResult();
m_futureInterface.reportResult(result); m_futureInterface.reportResult(result);
m_hadValidOutput = true; m_hadValidOutput = true;
@@ -141,7 +141,7 @@ void TestOutputReader::checkForSanitizerOutput(const QByteArray &line)
mode = SanitizerOutputMode::Ubsan; mode = SanitizerOutputMode::Ubsan;
} }
if (mode != SanitizerOutputMode::None) { if (mode != SanitizerOutputMode::None) {
if (m_sanitizerResult) // we have a result that has not been reported yet if (m_sanitizerResult.isValid()) // we have a result that has not been reported yet
sendAndResetSanitizerResult(); sendAndResetSanitizerResult();
m_sanitizerOutputMode = mode; m_sanitizerOutputMode = mode;
@@ -151,32 +151,32 @@ void TestOutputReader::checkForSanitizerOutput(const QByteArray &line)
if (m_sanitizerOutputMode == SanitizerOutputMode::Ubsan) { if (m_sanitizerOutputMode == SanitizerOutputMode::Ubsan) {
const Utils::FilePath path = constructSourceFilePath(m_buildDir, match.captured(1)); const Utils::FilePath path = constructSourceFilePath(m_buildDir, match.captured(1));
// path may be empty if not existing - so, provide at least what we have // path may be empty if not existing - so, provide at least what we have
m_sanitizerResult->setFileName( m_sanitizerResult.setFileName(
path.exists() ? path : Utils::FilePath::fromString(match.captured(1))); path.exists() ? path : Utils::FilePath::fromString(match.captured(1)));
m_sanitizerResult->setLine(match.captured(2).toInt()); m_sanitizerResult.setLine(match.captured(2).toInt());
} }
} }
} }
void TestOutputReader::sendAndResetSanitizerResult() void TestOutputReader::sendAndResetSanitizerResult()
{ {
QTC_ASSERT(m_sanitizerResult, return); QTC_ASSERT(m_sanitizerResult.isValid(), return);
m_sanitizerResult->setDescription(m_sanitizerLines.join('\n')); m_sanitizerResult.setDescription(m_sanitizerLines.join('\n'));
m_sanitizerResult->setResult(m_sanitizerOutputMode == SanitizerOutputMode::Ubsan m_sanitizerResult.setResult(m_sanitizerOutputMode == SanitizerOutputMode::Ubsan
? ResultType::Fail : ResultType::MessageFatal); ? ResultType::Fail : ResultType::MessageFatal);
if (m_sanitizerResult->fileName().isEmpty()) { if (m_sanitizerResult.fileName().isEmpty()) {
const ITestTreeItem *testItem = m_sanitizerResult->findTestTreeItem(); const ITestTreeItem *testItem = m_sanitizerResult.findTestTreeItem();
if (testItem && testItem->line()) { if (testItem && testItem->line()) {
m_sanitizerResult->setFileName(testItem->filePath()); m_sanitizerResult.setFileName(testItem->filePath());
m_sanitizerResult->setLine(testItem->line()); m_sanitizerResult.setLine(testItem->line());
} }
} }
m_futureInterface.reportResult(m_sanitizerResult); m_futureInterface.reportResult(m_sanitizerResult);
m_hadValidOutput = true; m_hadValidOutput = true;
m_sanitizerLines.clear(); m_sanitizerLines.clear();
m_sanitizerResult.reset(); m_sanitizerResult = {};
m_sanitizerOutputMode = SanitizerOutputMode::None; m_sanitizerOutputMode = SanitizerOutputMode::None;
} }

View File

@@ -17,7 +17,7 @@ class TestOutputReader : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
TestOutputReader(const QFutureInterface<TestResultPtr> &futureInterface, TestOutputReader(const QFutureInterface<TestResult> &futureInterface,
Utils::QtcProcess *testApplication, const Utils::FilePath &buildDirectory); Utils::QtcProcess *testApplication, const Utils::FilePath &buildDirectory);
virtual ~TestOutputReader(); virtual ~TestOutputReader();
void processStdOutput(const QByteArray &outputLine); void processStdOutput(const QByteArray &outputLine);
@@ -40,12 +40,12 @@ protected:
QString removeCommandlineColors(const QString &original); QString removeCommandlineColors(const QString &original);
virtual void processOutputLine(const QByteArray &outputLine) = 0; virtual void processOutputLine(const QByteArray &outputLine) = 0;
virtual TestResultPtr createDefaultResult() const = 0; virtual TestResult createDefaultResult() const = 0;
void checkForSanitizerOutput(const QByteArray &line); void checkForSanitizerOutput(const QByteArray &line);
void sendAndResetSanitizerResult(); void sendAndResetSanitizerResult();
void reportResult(const TestResultPtr &result); void reportResult(const TestResult &result);
QFutureInterface<TestResultPtr> m_futureInterface; QFutureInterface<TestResult> m_futureInterface;
Utils::QtcProcess *m_testApplication; // not owned Utils::QtcProcess *m_testApplication; // not owned
Utils::FilePath m_buildDir; Utils::FilePath m_buildDir;
QString m_id; QString m_id;
@@ -53,7 +53,7 @@ protected:
int m_disabled = -1; int m_disabled = -1;
private: private:
enum class SanitizerOutputMode { None, Asan, Ubsan}; enum class SanitizerOutputMode { None, Asan, Ubsan};
TestResultPtr m_sanitizerResult; TestResult m_sanitizerResult;
QStringList m_sanitizerLines; QStringList m_sanitizerLines;
SanitizerOutputMode m_sanitizerOutputMode = SanitizerOutputMode::None; SanitizerOutputMode m_sanitizerOutputMode = SanitizerOutputMode::None;
bool m_hadValidOutput = false; bool m_hadValidOutput = false;

View File

@@ -15,6 +15,11 @@ TestResult::TestResult(const QString &id, const QString &name, const ResultHooks
{ {
} }
bool TestResult::isValid() const
{
return !m_id.isEmpty();
}
const QString TestResult::outputString(bool selected) const const QString TestResult::outputString(bool selected) const
{ {
if (m_hooks.outputString) if (m_hooks.outputString)
@@ -113,10 +118,10 @@ QString TestResult::resultToString(const ResultType type)
return QString("BXFAIL"); return QString("BXFAIL");
case ResultType::MessageLocation: case ResultType::MessageLocation:
case ResultType::Application: case ResultType::Application:
return QString(); return {};
default: default:
if (type >= ResultType::INTERNAL_MESSAGES_BEGIN && type <= ResultType::INTERNAL_MESSAGES_END) if (type >= ResultType::INTERNAL_MESSAGES_BEGIN && type <= ResultType::INTERNAL_MESSAGES_END)
return QString(); return {};
return QString("UNKNOWN"); return QString("UNKNOWN");
} }
} }
@@ -156,34 +161,30 @@ QColor TestResult::colorForType(const ResultType type)
} }
} }
bool TestResult::isDirectParentOf(const TestResult *other, bool *needsIntermediate) const bool TestResult::isDirectParentOf(const TestResult &other, bool *needsIntermediate) const
{ {
QTC_ASSERT(other, return false); QTC_ASSERT(other.isValid(), return false);
const bool ret = !m_id.isEmpty() && m_id == other->m_id && m_name == other->m_name; const bool ret = !m_id.isEmpty() && m_id == other.m_id && m_name == other.m_name;
if (!ret) if (!ret)
return false; return false;
if (m_hooks.directParent) if (m_hooks.directParent)
return m_hooks.directParent(*this, *other, needsIntermediate); return m_hooks.directParent(*this, other, needsIntermediate);
return true; return true;
} }
bool TestResult::isIntermediateFor(const TestResult *other) const bool TestResult::isIntermediateFor(const TestResult &other) const
{ {
QTC_ASSERT(other, return false); QTC_ASSERT(other.isValid(), return false);
if (m_hooks.intermediate) if (m_hooks.intermediate)
return m_hooks.intermediate(*this, *other); return m_hooks.intermediate(*this, other);
return !m_id.isEmpty() && m_id == other->m_id && m_name == other->m_name; return !m_id.isEmpty() && m_id == other.m_id && m_name == other.m_name;
} }
TestResult *TestResult::createIntermediateResult() const TestResult TestResult::intermediateResult() const
{ {
if (m_hooks.createResult) { if (m_hooks.createResult)
TestResult *newResult = new TestResult; return m_hooks.createResult(*this);
*newResult = m_hooks.createResult(*this); return {m_id, m_name};
return newResult;
}
TestResult *intermediate = new TestResult(m_id, m_name);
return intermediate;
} }
} // namespace Autotest } // namespace Autotest

View File

@@ -5,12 +5,9 @@
#include "autotestconstants.h" #include "autotestconstants.h"
#include <utils/fileutils.h> #include <utils/filepath.h>
#include <QColor> #include <QColor>
#include <QMetaType>
#include <QSharedPointer>
#include <QString>
namespace Autotest { namespace Autotest {
@@ -82,6 +79,7 @@ public:
TestResult(const QString &id, const QString &name, const ResultHooks &hooks = {}); TestResult(const QString &id, const QString &name, const ResultHooks &hooks = {});
virtual ~TestResult() {} virtual ~TestResult() {}
bool isValid() const;
const QString outputString(bool selected) const; const QString outputString(bool selected) const;
const ITestTreeItem *findTestTreeItem() const; const ITestTreeItem *findTestTreeItem() const;
@@ -103,9 +101,9 @@ public:
static QString resultToString(const ResultType type); static QString resultToString(const ResultType type);
static QColor colorForType(const ResultType type); static QColor colorForType(const ResultType type);
bool isDirectParentOf(const TestResult *other, bool *needsIntermediate) const; bool isDirectParentOf(const TestResult &other, bool *needsIntermediate) const;
bool isIntermediateFor(const TestResult *other) const; bool isIntermediateFor(const TestResult &other) const;
TestResult *createIntermediateResult() const; TestResult intermediateResult() const;
private: private:
QString m_id; QString m_id;
@@ -117,8 +115,6 @@ private:
ResultHooks m_hooks; ResultHooks m_hooks;
}; };
using TestResultPtr = QSharedPointer<TestResult>;
} // namespace Autotest } // namespace Autotest
Q_DECLARE_METATYPE(Autotest::TestResult) Q_DECLARE_METATYPE(Autotest::TestResult)

View File

@@ -50,9 +50,9 @@ void TestResultDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op
painter->fillRect(opt.rect, background); painter->fillRect(opt.rect, background);
painter->setPen(foreground); painter->setPen(foreground);
LayoutPositions positions(opt, resultFilterModel); const LayoutPositions positions(opt, resultFilterModel);
const TestResult *testResult = resultFilterModel->testResult(index); const TestResult testResult = resultFilterModel->testResult(index);
QTC_ASSERT(testResult, painter->restore();return); QTC_ASSERT(testResult.isValid(), painter->restore(); return);
const QWidget *widget = dynamic_cast<const QWidget*>(painter->device()); const QWidget *widget = dynamic_cast<const QWidget*>(painter->device());
QWindow *window = widget ? widget->window()->windowHandle() : nullptr; QWindow *window = widget ? widget->window()->windowHandle() : nullptr;
@@ -69,15 +69,15 @@ void TestResultDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op
painter->drawText(positions.typeAreaLeft(), positions.top() + fm.ascent(), typeStr); painter->drawText(positions.typeAreaLeft(), positions.top() + fm.ascent(), typeStr);
} else { } else {
QPen tmp = painter->pen(); QPen tmp = painter->pen();
if (testResult->result() == ResultType::TestStart) if (testResult.result() == ResultType::TestStart)
painter->setPen(opt.palette.mid().color()); painter->setPen(opt.palette.mid().color());
else else
painter->setPen(TestResult::colorForType(testResult->result())); painter->setPen(TestResult::colorForType(testResult.result()));
painter->drawText(positions.typeAreaLeft(), positions.top() + fm.ascent(), typeStr); painter->drawText(positions.typeAreaLeft(), positions.top() + fm.ascent(), typeStr);
painter->setPen(tmp); painter->setPen(tmp);
} }
QString output = testResult->outputString(selected); QString output = testResult.outputString(selected);
if (selected) { if (selected) {
limitTextOutput(output); limitTextOutput(output);
@@ -92,12 +92,12 @@ void TestResultDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op
fm.elidedText(output.left(2000), Qt::ElideRight, positions.textAreaWidth())); fm.elidedText(output.left(2000), Qt::ElideRight, positions.textAreaWidth()));
} }
const QString file = testResult->fileName().fileName(); const QString file = testResult.fileName().fileName();
painter->setClipRect(positions.fileArea()); painter->setClipRect(positions.fileArea());
painter->drawText(positions.fileAreaLeft(), positions.top() + fm.ascent(), file); painter->drawText(positions.fileAreaLeft(), positions.top() + fm.ascent(), file);
if (testResult->line()) { if (testResult.line()) {
QString line = QString::number(testResult->line()); QString line = QString::number(testResult.line());
painter->setClipRect(positions.lineArea()); painter->setClipRect(positions.lineArea());
painter->drawText(positions.lineAreaLeft(), positions.top() + fm.ascent(), line); painter->drawText(positions.lineAreaLeft(), positions.top() + fm.ascent(), line);
} }
@@ -129,9 +129,9 @@ QSize TestResultDelegate::sizeHint(const QStyleOptionViewItem &option, const QMo
s.setWidth(opt.rect.width() - indentation); s.setWidth(opt.rect.width() - indentation);
if (selected) { if (selected) {
const TestResult *testResult = resultFilterModel->testResult(index); const TestResult testResult = resultFilterModel->testResult(index);
QTC_ASSERT(testResult, return QSize()); QTC_ASSERT(testResult.isValid(), return {});
QString output = testResult->outputString(selected); QString output = testResult.outputString(selected);
limitTextOutput(output); limitTextOutput(output);
output.replace('\n', QChar::LineSeparator); output.replace('\n', QChar::LineSeparator);
recalculateTextLayout(index, output, opt.font, positions.textAreaWidth() - indentation); recalculateTextLayout(index, output, opt.font, positions.textAreaWidth() - indentation);

View File

@@ -21,7 +21,7 @@ namespace Internal {
/********************************* TestResultItem ******************************************/ /********************************* TestResultItem ******************************************/
TestResultItem::TestResultItem(const TestResultPtr &testResult) TestResultItem::TestResultItem(const TestResult &testResult)
: m_testResult(testResult) : m_testResult(testResult)
{ {
} }
@@ -71,9 +71,9 @@ QVariant TestResultItem::data(int column, int role) const
{ {
switch (role) { switch (role) {
case Qt::DecorationRole: { case Qt::DecorationRole: {
if (!m_testResult) if (!m_testResult.isValid())
return QVariant(); return {};
const ResultType result = m_testResult->result(); const ResultType result = m_testResult.result();
if (result == ResultType::MessageLocation && parent()) if (result == ResultType::MessageLocation && parent())
return parent()->data(column, role); return parent()->data(column, role);
if (result == ResultType::TestStart) if (result == ResultType::TestStart)
@@ -81,7 +81,7 @@ QVariant TestResultItem::data(int column, int role) const
return testResultIcon(result); return testResultIcon(result);
} }
case Qt::DisplayRole: case Qt::DisplayRole:
return m_testResult ? m_testResult->outputString(true) : QVariant(); return m_testResult.isValid() ? m_testResult.outputString(true) : QVariant();
default: default:
return Utils::TreeItem::data(column, role); return Utils::TreeItem::data(column, role);
} }
@@ -89,9 +89,8 @@ QVariant TestResultItem::data(int column, int role) const
void TestResultItem::updateDescription(const QString &description) void TestResultItem::updateDescription(const QString &description)
{ {
QTC_ASSERT(m_testResult, return); QTC_ASSERT(m_testResult.isValid(), return);
m_testResult.setDescription(description);
m_testResult->setDescription(description);
} }
static bool isSignificant(ResultType type) static bool isSignificant(ResultType type)
@@ -117,7 +116,7 @@ void TestResultItem::updateResult(bool &changed, ResultType addedChildType,
const std::optional<SummaryEvaluation> &summary) const std::optional<SummaryEvaluation> &summary)
{ {
changed = false; changed = false;
if (m_testResult->result() != ResultType::TestStart) if (m_testResult.result() != ResultType::TestStart)
return; return;
if (!isSignificant(addedChildType) || (addedChildType == ResultType::TestStart && !summary)) if (!isSignificant(addedChildType) || (addedChildType == ResultType::TestStart && !summary))
@@ -165,13 +164,13 @@ void TestResultItem::updateResult(bool &changed, ResultType addedChildType,
TestResultItem *TestResultItem::intermediateFor(const TestResultItem *item) const TestResultItem *TestResultItem::intermediateFor(const TestResultItem *item) const
{ {
QTC_ASSERT(item, return nullptr); QTC_ASSERT(item, return nullptr);
const TestResult *otherResult = item->testResult(); const TestResult otherResult = item->testResult();
for (int row = childCount() - 1; row >= 0; --row) { for (int row = childCount() - 1; row >= 0; --row) {
TestResultItem *child = childAt(row); TestResultItem *child = childAt(row);
const TestResult *testResult = child->testResult(); const TestResult testResult = child->testResult();
if (testResult->result() != ResultType::TestStart) if (testResult.result() != ResultType::TestStart)
continue; continue;
if (testResult->isIntermediateFor(otherResult)) if (testResult.isIntermediateFor(otherResult))
return child; return child;
} }
return nullptr; return nullptr;
@@ -179,9 +178,9 @@ TestResultItem *TestResultItem::intermediateFor(const TestResultItem *item) cons
TestResultItem *TestResultItem::createAndAddIntermediateFor(const TestResultItem *child) TestResultItem *TestResultItem::createAndAddIntermediateFor(const TestResultItem *child)
{ {
TestResultPtr result(child->testResult()->createIntermediateResult()); TestResult result = child->testResult().intermediateResult();
QTC_ASSERT(!result.isNull(), return nullptr); QTC_ASSERT(result.isValid(), return nullptr);
result->setResult(ResultType::TestStart); result.setResult(ResultType::TestStart);
TestResultItem *intermediate = new TestResultItem(result); TestResultItem *intermediate = new TestResultItem(result);
appendChild(intermediate); appendChild(intermediate);
return intermediate; return intermediate;
@@ -189,17 +188,17 @@ TestResultItem *TestResultItem::createAndAddIntermediateFor(const TestResultItem
QString TestResultItem::resultString() const QString TestResultItem::resultString() const
{ {
if (testResult()->result() != ResultType::TestStart) if (testResult().result() != ResultType::TestStart)
return TestResult::resultToString(testResult()->result()); return TestResult::resultToString(testResult().result());
if (!m_summaryResult) if (!m_summaryResult)
return QString(); return {};
return m_summaryResult->failed ? QString("FAIL") : QString("PASS"); return m_summaryResult->failed ? QString("FAIL") : QString("PASS");
} }
/********************************* TestResultModel *****************************************/ /********************************* TestResultModel *****************************************/
TestResultModel::TestResultModel(QObject *parent) TestResultModel::TestResultModel(QObject *parent)
: Utils::TreeModel<TestResultItem>(new TestResultItem(TestResultPtr()), parent) : Utils::TreeModel<TestResultItem>(new TestResultItem({}), parent)
{ {
connect(TestRunner::instance(), &TestRunner::reportSummary, connect(TestRunner::instance(), &TestRunner::reportSummary,
this, [this](const QString &id, const QHash<ResultType, int> &summary){ this, [this](const QString &id, const QHash<ResultType, int> &summary){
@@ -210,12 +209,12 @@ TestResultModel::TestResultModel(QObject *parent)
void TestResultModel::updateParent(const TestResultItem *item) void TestResultModel::updateParent(const TestResultItem *item)
{ {
QTC_ASSERT(item, return); QTC_ASSERT(item, return);
QTC_ASSERT(item->testResult(), return); QTC_ASSERT(item->testResult().isValid(), return);
TestResultItem *parentItem = item->parent(); TestResultItem *parentItem = item->parent();
if (parentItem == rootItem()) // do not update invisible root item if (parentItem == rootItem()) // do not update invisible root item
return; return;
bool changed = false; bool changed = false;
parentItem->updateResult(changed, item->testResult()->result(), item->summaryResult()); parentItem->updateResult(changed, item->testResult().result(), item->summaryResult());
if (!changed) if (!changed)
return; return;
emit dataChanged(parentItem->index(), parentItem->index()); emit dataChanged(parentItem->index(), parentItem->index());
@@ -232,16 +231,16 @@ static bool isFailed(ResultType type)
} }
} }
void TestResultModel::addTestResult(const TestResultPtr &testResult, bool autoExpand) void TestResultModel::addTestResult(const TestResult &testResult, bool autoExpand)
{ {
const int lastRow = rootItem()->childCount() - 1; const int lastRow = rootItem()->childCount() - 1;
if (testResult->result() == ResultType::MessageCurrentTest) { if (testResult.result() == ResultType::MessageCurrentTest) {
// MessageCurrentTest should always be the last top level item // MessageCurrentTest should always be the last top level item
if (lastRow >= 0) { if (lastRow >= 0) {
TestResultItem *current = rootItem()->childAt(lastRow); TestResultItem *current = rootItem()->childAt(lastRow);
const TestResult *result = current->testResult(); const TestResult result = current->testResult();
if (result && result->result() == ResultType::MessageCurrentTest) { if (result.isValid() && result.result() == ResultType::MessageCurrentTest) {
current->updateDescription(testResult->description()); current->updateDescription(testResult.description());
emit dataChanged(current->index(), current->index()); emit dataChanged(current->index(), current->index());
return; return;
} }
@@ -251,22 +250,22 @@ void TestResultModel::addTestResult(const TestResultPtr &testResult, bool autoEx
return; return;
} }
m_testResultCount[testResult->id()][testResult->result()]++; m_testResultCount[testResult.id()][testResult.result()]++;
TestResultItem *newItem = new TestResultItem(testResult); TestResultItem *newItem = new TestResultItem(testResult);
TestResultItem *root = nullptr; TestResultItem *root = nullptr;
if (AutotestPlugin::settings()->displayApplication) { if (AutotestPlugin::settings()->displayApplication) {
const QString application = testResult->id(); const QString application = testResult.id();
if (!application.isEmpty()) { if (!application.isEmpty()) {
root = rootItem()->findFirstLevelChild([&application](TestResultItem *child) { root = rootItem()->findFirstLevelChild([&application](TestResultItem *child) {
QTC_ASSERT(child, return false); QTC_ASSERT(child, return false);
return child->testResult()->id() == application; return child->testResult().id() == application;
}); });
if (!root) { if (!root) {
TestResult *tmpAppResult = new TestResult(application, application); TestResult tmpAppResult(application, application);
tmpAppResult->setResult(ResultType::Application); tmpAppResult.setResult(ResultType::Application);
root = new TestResultItem(TestResultPtr(tmpAppResult)); root = new TestResultItem(tmpAppResult);
if (lastRow >= 0) if (lastRow >= 0)
rootItem()->insertChild(lastRow, root); rootItem()->insertChild(lastRow, root);
else else
@@ -276,7 +275,7 @@ void TestResultModel::addTestResult(const TestResultPtr &testResult, bool autoEx
} }
TestResultItem *parentItem = findParentItemFor(newItem, root); TestResultItem *parentItem = findParentItemFor(newItem, root);
addFileName(testResult->fileName().fileName()); // ensure we calculate the results pane correctly addFileName(testResult.fileName().fileName()); // ensure we calculate the results pane correctly
if (parentItem) { if (parentItem) {
parentItem->appendChild(newItem); parentItem->appendChild(newItem);
if (autoExpand) { if (autoExpand) {
@@ -288,8 +287,8 @@ void TestResultModel::addTestResult(const TestResultPtr &testResult, bool autoEx
} else { } else {
if (lastRow >= 0) { if (lastRow >= 0) {
TestResultItem *current = rootItem()->childAt(lastRow); TestResultItem *current = rootItem()->childAt(lastRow);
const TestResult *result = current->testResult(); const TestResult result = current->testResult();
if (result && result->result() == ResultType::MessageCurrentTest) { if (result.isValid() && result.result() == ResultType::MessageCurrentTest) {
rootItem()->insertChild(current->index().row(), newItem); rootItem()->insertChild(current->index().row(), newItem);
return; return;
} }
@@ -298,8 +297,8 @@ void TestResultModel::addTestResult(const TestResultPtr &testResult, bool autoEx
rootItem()->appendChild(newItem); rootItem()->appendChild(newItem);
} }
if (isFailed(testResult->result())) { if (isFailed(testResult.result())) {
if (const ITestTreeItem *it = testResult->findTestTreeItem()) { if (const ITestTreeItem *it = testResult.findTestTreeItem()) {
TestTreeModel *model = TestTreeModel::instance(); TestTreeModel *model = TestTreeModel::instance();
model->setData(model->indexForItem(it), true, FailedRole); model->setData(model->indexForItem(it), true, FailedRole);
} }
@@ -309,7 +308,7 @@ void TestResultModel::addTestResult(const TestResultPtr &testResult, bool autoEx
void TestResultModel::removeCurrentTestMessage() void TestResultModel::removeCurrentTestMessage()
{ {
TestResultItem *currentMessageItem = rootItem()->findFirstLevelChild([](TestResultItem *it) { TestResultItem *currentMessageItem = rootItem()->findFirstLevelChild([](TestResultItem *it) {
return (it->testResult()->result() == ResultType::MessageCurrentTest); return (it->testResult().result() == ResultType::MessageCurrentTest);
}); });
if (currentMessageItem) if (currentMessageItem)
destroyItem(currentMessageItem); destroyItem(currentMessageItem);
@@ -326,12 +325,11 @@ void TestResultModel::clearTestResults()
m_widthOfLineNumber = 0; m_widthOfLineNumber = 0;
} }
const TestResult *TestResultModel::testResult(const QModelIndex &idx) TestResult TestResultModel::testResult(const QModelIndex &idx)
{ {
if (idx.isValid()) if (idx.isValid())
return itemForIndex(idx)->testResult(); return itemForIndex(idx)->testResult();
return {};
return nullptr;
} }
void TestResultModel::recalculateMaxWidthOfFileName(const QFont &font) void TestResultModel::recalculateMaxWidthOfFileName(const QFont &font)
@@ -383,15 +381,15 @@ TestResultItem *TestResultModel::findParentItemFor(const TestResultItem *item,
{ {
QTC_ASSERT(item, return nullptr); QTC_ASSERT(item, return nullptr);
TestResultItem *root = startItem ? const_cast<TestResultItem *>(startItem) : nullptr; TestResultItem *root = startItem ? const_cast<TestResultItem *>(startItem) : nullptr;
const TestResult *result = item->testResult(); const TestResult result = item->testResult();
const QString &name = result->name(); const QString &name = result.name();
const QString &id = result->id(); const QString &id = result.id();
if (root == nullptr && !name.isEmpty()) { if (root == nullptr && !name.isEmpty()) {
for (int row = rootItem()->childCount() - 1; row >= 0; --row) { for (int row = rootItem()->childCount() - 1; row >= 0; --row) {
TestResultItem *tmp = rootItem()->childAt(row); TestResultItem *tmp = rootItem()->childAt(row);
auto tmpTestResult = tmp->testResult(); const TestResult tmpTestResult = tmp->testResult();
if (tmpTestResult->id() == id && tmpTestResult->name() == name) { if (tmpTestResult.id() == id && tmpTestResult.name() == name) {
root = tmp; root = tmp;
break; break;
} }
@@ -403,7 +401,7 @@ TestResultItem *TestResultModel::findParentItemFor(const TestResultItem *item,
bool needsIntermediate = false; bool needsIntermediate = false;
auto predicate = [result, &needsIntermediate](Utils::TreeItem *it) { auto predicate = [result, &needsIntermediate](Utils::TreeItem *it) {
TestResultItem *currentItem = static_cast<TestResultItem *>(it); TestResultItem *currentItem = static_cast<TestResultItem *>(it);
return currentItem->testResult()->isDirectParentOf(result, &needsIntermediate); return currentItem->testResult().isDirectParentOf(result, &needsIntermediate);
}; };
TestResultItem *parent = root->reverseFindAnyChild(predicate); TestResultItem *parent = root->reverseFindAnyChild(predicate);
if (parent) { if (parent) {
@@ -480,7 +478,7 @@ bool TestResultFilterModel::hasResults()
return rowCount(QModelIndex()); return rowCount(QModelIndex());
} }
const TestResult *TestResultFilterModel::testResult(const QModelIndex &index) const TestResult TestResultFilterModel::testResult(const QModelIndex &index) const
{ {
return m_sourceModel->testResult(mapToSource(index)); return m_sourceModel->testResult(mapToSource(index));
} }
@@ -495,7 +493,7 @@ bool TestResultFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &s
QModelIndex index = m_sourceModel->index(sourceRow, 0, sourceParent); QModelIndex index = m_sourceModel->index(sourceRow, 0, sourceParent);
if (!index.isValid()) if (!index.isValid())
return false; return false;
ResultType resultType = m_sourceModel->testResult(index)->result(); const ResultType resultType = m_sourceModel->testResult(index).result();
if (resultType == ResultType::TestStart) { if (resultType == ResultType::TestStart) {
TestResultItem *item = m_sourceModel->itemForIndex(index); TestResultItem *item = m_sourceModel->itemForIndex(index);
QTC_ASSERT(item, return false); QTC_ASSERT(item, return false);
@@ -511,7 +509,7 @@ bool TestResultFilterModel::acceptTestCaseResult(const QModelIndex &srcIndex) co
for (int row = 0, count = m_sourceModel->rowCount(srcIndex); row < count; ++row) { for (int row = 0, count = m_sourceModel->rowCount(srcIndex); row < count; ++row) {
const QModelIndex &child = m_sourceModel->index(row, 0, srcIndex); const QModelIndex &child = m_sourceModel->index(row, 0, srcIndex);
TestResultItem *item = m_sourceModel->itemForIndex(child); TestResultItem *item = m_sourceModel->itemForIndex(child);
ResultType type = item->testResult()->result(); const ResultType type = item->testResult().result();
if (type == ResultType::TestStart) { if (type == ResultType::TestStart) {
if (!item->summaryResult()) if (!item->summaryResult())

View File

@@ -20,9 +20,9 @@ namespace Internal {
class TestResultItem : public Utils::TypedTreeItem<TestResultItem, TestResultItem> class TestResultItem : public Utils::TypedTreeItem<TestResultItem, TestResultItem>
{ {
public: public:
explicit TestResultItem(const TestResultPtr &testResult); explicit TestResultItem(const TestResult &testResult);
QVariant data(int column, int role) const override; QVariant data(int column, int role) const override;
const TestResult *testResult() const { return m_testResult.data(); } TestResult testResult() const { return m_testResult; }
void updateDescription(const QString &description); void updateDescription(const QString &description);
struct SummaryEvaluation struct SummaryEvaluation
@@ -45,7 +45,7 @@ public:
std::optional<SummaryEvaluation> summaryResult() const { return m_summaryResult; } std::optional<SummaryEvaluation> summaryResult() const { return m_summaryResult; }
private: private:
TestResultPtr m_testResult; TestResult m_testResult;
std::optional<SummaryEvaluation> m_summaryResult; std::optional<SummaryEvaluation> m_summaryResult;
}; };
@@ -54,11 +54,11 @@ class TestResultModel : public Utils::TreeModel<TestResultItem>
public: public:
explicit TestResultModel(QObject *parent = nullptr); explicit TestResultModel(QObject *parent = nullptr);
void addTestResult(const TestResultPtr &testResult, bool autoExpand = false); void addTestResult(const TestResult &testResult, bool autoExpand = false);
void removeCurrentTestMessage(); void removeCurrentTestMessage();
void clearTestResults(); void clearTestResults();
const TestResult *testResult(const QModelIndex &idx); TestResult testResult(const QModelIndex &idx);
int maxWidthOfFileName(const QFont &font); int maxWidthOfFileName(const QFont &font);
int maxWidthOfLineNumber(const QFont &font); int maxWidthOfLineNumber(const QFont &font);
@@ -92,7 +92,7 @@ public:
void toggleTestResultType(ResultType type); void toggleTestResultType(ResultType type);
void clearTestResults(); void clearTestResults();
bool hasResults(); bool hasResults();
const TestResult *testResult(const QModelIndex &index) const; TestResult testResult(const QModelIndex &index) const;
TestResultItem *itemForIndex(const QModelIndex &index) const; TestResultItem *itemForIndex(const QModelIndex &index) const;
protected: protected:

View File

@@ -228,7 +228,7 @@ TestResultsPane::~TestResultsPane()
s_instance = nullptr; s_instance = nullptr;
} }
void TestResultsPane::addTestResult(const TestResultPtr &result) void TestResultsPane::addTestResult(const TestResult &result)
{ {
const QScrollBar *scrollBar = m_treeView->verticalScrollBar(); const QScrollBar *scrollBar = m_treeView->verticalScrollBar();
m_atEnd = scrollBar ? scrollBar->value() == scrollBar->maximum() : true; m_atEnd = scrollBar ? scrollBar->value() == scrollBar->maximum() : true;
@@ -457,9 +457,9 @@ void TestResultsPane::onItemActivated(const QModelIndex &index)
if (!index.isValid()) if (!index.isValid())
return; return;
const TestResult *testResult = m_filterModel->testResult(index); const TestResult testResult = m_filterModel->testResult(index);
if (testResult && !testResult->fileName().isEmpty()) if (testResult.isValid() && !testResult.fileName().isEmpty())
EditorManager::openEditorAt(Utils::Link{testResult->fileName(), testResult->line(), 0}); EditorManager::openEditorAt(Utils::Link{testResult.fileName(), testResult.line(), 0});
} }
void TestResultsPane::onRunAllTriggered() void TestResultsPane::onRunAllTriggered()
@@ -609,12 +609,12 @@ void TestResultsPane::onCustomContextMenuRequested(const QPoint &pos)
{ {
const bool resultsAvailable = m_filterModel->hasResults(); const bool resultsAvailable = m_filterModel->hasResults();
const bool enabled = !m_testRunning && resultsAvailable; const bool enabled = !m_testRunning && resultsAvailable;
const TestResult *clicked = getTestResult(m_treeView->indexAt(pos)); const TestResult clicked = getTestResult(m_treeView->indexAt(pos));
QMenu menu; QMenu menu;
QAction *action = new QAction(Tr::tr("Copy"), &menu); QAction *action = new QAction(Tr::tr("Copy"), &menu);
action->setShortcut(QKeySequence(QKeySequence::Copy)); action->setShortcut(QKeySequence(QKeySequence::Copy));
action->setEnabled(resultsAvailable && clicked); action->setEnabled(resultsAvailable && clicked.isValid());
connect(action, &QAction::triggered, this, [this, clicked] { connect(action, &QAction::triggered, this, [this, clicked] {
onCopyItemTriggered(clicked); onCopyItemTriggered(clicked);
}); });
@@ -630,7 +630,7 @@ void TestResultsPane::onCustomContextMenuRequested(const QPoint &pos)
connect(action, &QAction::triggered, this, &TestResultsPane::onSaveWholeTriggered); connect(action, &QAction::triggered, this, &TestResultsPane::onSaveWholeTriggered);
menu.addAction(action); menu.addAction(action);
const auto correlatingItem = (enabled && clicked) ? clicked->findTestTreeItem() : nullptr; const auto correlatingItem = (enabled && clicked.isValid()) ? clicked.findTestTreeItem() : nullptr;
action = new QAction(Tr::tr("Run This Test"), &menu); action = new QAction(Tr::tr("Run This Test"), &menu);
action->setEnabled(correlatingItem && correlatingItem->canProvideTestConfiguration()); action->setEnabled(correlatingItem && correlatingItem->canProvideTestConfiguration());
connect(action, &QAction::triggered, this, [this, clicked] { connect(action, &QAction::triggered, this, [this, clicked] {
@@ -669,21 +669,19 @@ void TestResultsPane::onCustomContextMenuRequested(const QPoint &pos)
menu.exec(m_treeView->mapToGlobal(pos)); menu.exec(m_treeView->mapToGlobal(pos));
} }
const TestResult *TestResultsPane::getTestResult(const QModelIndex &idx) TestResult TestResultsPane::getTestResult(const QModelIndex &idx)
{ {
if (!idx.isValid()) if (!idx.isValid())
return nullptr; return {};
const TestResult result = m_filterModel->testResult(idx);
const TestResult *result = m_filterModel->testResult(idx); QTC_CHECK(result.isValid());
QTC_CHECK(result);
return result; return result;
} }
void TestResultsPane::onCopyItemTriggered(const TestResult *result) void TestResultsPane::onCopyItemTriggered(const TestResult &result)
{ {
QTC_ASSERT(result, return); QTC_ASSERT(result.isValid(), return);
setClipboardAndSelection(result->outputString(true)); setClipboardAndSelection(result.outputString(true));
} }
void TestResultsPane::onCopyWholeTriggered() void TestResultsPane::onCopyWholeTriggered()
@@ -705,12 +703,11 @@ void TestResultsPane::onSaveWholeTriggered()
} }
} }
void TestResultsPane::onRunThisTestTriggered(TestRunMode runMode, const TestResult *result) void TestResultsPane::onRunThisTestTriggered(TestRunMode runMode, const TestResult &result)
{ {
QTC_ASSERT(result, return); QTC_ASSERT(result.isValid(), return);
const ITestTreeItem *item = result->findTestTreeItem();
const ITestTreeItem *item = result.findTestTreeItem();
if (item) if (item)
TestRunner::instance()->runTest(runMode, item); TestRunner::instance()->runTest(runMode, item);
} }
@@ -729,11 +726,11 @@ QString TestResultsPane::getWholeOutput(const QModelIndex &parent)
QString output; QString output;
for (int row = 0, count = m_model->rowCount(parent); row < count; ++row) { for (int row = 0, count = m_model->rowCount(parent); row < count; ++row) {
QModelIndex current = m_model->index(row, 0, parent); QModelIndex current = m_model->index(row, 0, parent);
const TestResult *result = m_model->testResult(current); const TestResult result = m_model->testResult(current);
QTC_ASSERT(result, continue); QTC_ASSERT(result.isValid(), continue);
if (auto item = m_model->itemForIndex(current)) if (auto item = m_model->itemForIndex(current))
output.append(item->resultString()).append('\t'); output.append(item->resultString()).append('\t');
output.append(result->outputString(true)).append('\n'); output.append(result.outputString(true)).append('\n');
output.append(getWholeOutput(current)); output.append(getWholeOutput(current));
} }
return output; return output;
@@ -741,25 +738,25 @@ QString TestResultsPane::getWholeOutput(const QModelIndex &parent)
void TestResultsPane::createMarks(const QModelIndex &parent) void TestResultsPane::createMarks(const QModelIndex &parent)
{ {
const TestResult *parentResult = m_model->testResult(parent); const TestResult parentResult = m_model->testResult(parent);
ResultType parentType = parentResult ? parentResult->result() : ResultType::Invalid; const ResultType parentType = parentResult.isValid() ? parentResult.result() : ResultType::Invalid;
const QVector<ResultType> interested{ResultType::Fail, ResultType::UnexpectedPass}; const QVector<ResultType> interested{ResultType::Fail, ResultType::UnexpectedPass};
for (int row = 0, count = m_model->rowCount(parent); row < count; ++row) { for (int row = 0, count = m_model->rowCount(parent); row < count; ++row) {
const QModelIndex index = m_model->index(row, 0, parent); const QModelIndex index = m_model->index(row, 0, parent);
const TestResult *result = m_model->testResult(index); const TestResult result = m_model->testResult(index);
QTC_ASSERT(result, continue); QTC_ASSERT(result.isValid(), continue);
if (m_model->hasChildren(index)) if (m_model->hasChildren(index))
createMarks(index); createMarks(index);
bool isLocationItem = result->result() == ResultType::MessageLocation; bool isLocationItem = result.result() == ResultType::MessageLocation;
if (interested.contains(result->result()) if (interested.contains(result.result())
|| (isLocationItem && interested.contains(parentType))) { || (isLocationItem && interested.contains(parentType))) {
TestEditorMark *mark = new TestEditorMark(index, result->fileName(), result->line()); TestEditorMark *mark = new TestEditorMark(index, result.fileName(), result.line());
mark->setIcon(index.data(Qt::DecorationRole).value<QIcon>()); mark->setIcon(index.data(Qt::DecorationRole).value<QIcon>());
mark->setColor(Utils::Theme::OutputPanes_TestFailTextColor); mark->setColor(Utils::Theme::OutputPanes_TestFailTextColor);
mark->setPriority(TextEditor::TextMark::NormalPriority); mark->setPriority(TextEditor::TextMark::NormalPriority);
mark->setToolTip(result->description()); mark->setToolTip(result.description());
m_marks << mark; m_marks << mark;
} }
} }

View File

@@ -72,7 +72,7 @@ public:
void goToNext() override; void goToNext() override;
void goToPrev() override; void goToPrev() override;
void addTestResult(const TestResultPtr &result); void addTestResult(const TestResult &result);
void addOutputLine(const QByteArray &outputLine, OutputChannel channel); void addOutputLine(const QByteArray &outputLine, OutputChannel channel);
void showTestResult(const QModelIndex &index); void showTestResult(const QModelIndex &index);
private: private:
@@ -92,11 +92,11 @@ private:
void onTestRunFinished(); void onTestRunFinished();
void onScrollBarRangeChanged(int, int max); void onScrollBarRangeChanged(int, int max);
void onCustomContextMenuRequested(const QPoint &pos); void onCustomContextMenuRequested(const QPoint &pos);
const TestResult *getTestResult(const QModelIndex &idx); TestResult getTestResult(const QModelIndex &idx);
void onCopyItemTriggered(const TestResult *result); void onCopyItemTriggered(const TestResult &result);
void onCopyWholeTriggered(); void onCopyWholeTriggered();
void onSaveWholeTriggered(); void onSaveWholeTriggered();
void onRunThisTestTriggered(TestRunMode runMode, const TestResult *result); void onRunThisTestTriggered(TestRunMode runMode, const TestResult &result);
void toggleOutputStyle(); void toggleOutputStyle();
QString getWholeOutput(const QModelIndex &parent = QModelIndex()); QString getWholeOutput(const QModelIndex &parent = QModelIndex());

View File

@@ -72,13 +72,13 @@ TestRunner::TestRunner()
m_cancelTimer.setSingleShot(true); m_cancelTimer.setSingleShot(true);
connect(&m_cancelTimer, &QTimer::timeout, this, [this] { cancelCurrent(Timeout); }); connect(&m_cancelTimer, &QTimer::timeout, this, [this] { cancelCurrent(Timeout); });
connect(&m_futureWatcher, &QFutureWatcher<TestResultPtr>::resultReadyAt, connect(&m_futureWatcher, &QFutureWatcher<TestResult>::resultReadyAt,
this, [this](int index) { emit testResultReady(m_futureWatcher.resultAt(index)); }); this, [this](int index) { emit testResultReady(m_futureWatcher.resultAt(index)); });
connect(&m_futureWatcher, &QFutureWatcher<TestResultPtr>::finished, connect(&m_futureWatcher, &QFutureWatcher<TestResult>::finished,
this, &TestRunner::onFinished); this, &TestRunner::onFinished);
connect(this, &TestRunner::requestStopTestRun, connect(this, &TestRunner::requestStopTestRun,
&m_futureWatcher, &QFutureWatcher<TestResultPtr>::cancel); &m_futureWatcher, &QFutureWatcher<TestResult>::cancel);
connect(&m_futureWatcher, &QFutureWatcher<TestResultPtr>::canceled, this, [this] { connect(&m_futureWatcher, &QFutureWatcher<TestResult>::canceled, this, [this] {
cancelCurrent(UserCanceled); cancelCurrent(UserCanceled);
reportResult(ResultType::MessageFatal, Tr::tr("Test run canceled by user.")); reportResult(ResultType::MessageFatal, Tr::tr("Test run canceled by user."));
}); });
@@ -537,8 +537,8 @@ void TestRunner::runTestsHelper()
int testCaseCount = precheckTestConfigurations(); int testCaseCount = precheckTestConfigurations();
// Fake future interface - destruction will be handled by QFuture/QFutureWatcher // Fake future interface - destruction will be handled by QFuture/QFutureWatcher
m_fakeFutureInterface = new QFutureInterface<TestResultPtr>(QFutureInterfaceBase::Running); m_fakeFutureInterface = new QFutureInterface<TestResult>(QFutureInterfaceBase::Running);
QFuture<TestResultPtr> future = m_fakeFutureInterface->future(); QFuture<TestResult> future = m_fakeFutureInterface->future();
m_fakeFutureInterface->setProgressRange(0, testCaseCount); m_fakeFutureInterface->setProgressRange(0, testCaseCount);
m_fakeFutureInterface->setProgressValue(0); m_fakeFutureInterface->setProgressValue(0);
m_futureWatcher.setFuture(future); m_futureWatcher.setFuture(future);
@@ -648,8 +648,8 @@ void TestRunner::debugTests()
} }
// We need a fake QFuture for the results. TODO: replace with QtConcurrent::run // We need a fake QFuture for the results. TODO: replace with QtConcurrent::run
QFutureInterface<TestResultPtr> *futureInterface QFutureInterface<TestResult> *futureInterface
= new QFutureInterface<TestResultPtr>(QFutureInterfaceBase::Running); = new QFutureInterface<TestResult>(QFutureInterfaceBase::Running);
m_futureWatcher.setFuture(futureInterface->future()); m_futureWatcher.setFuture(futureInterface->future());
if (useOutputProcessor) { if (useOutputProcessor) {
@@ -804,9 +804,9 @@ void TestRunner::onFinished()
void TestRunner::reportResult(ResultType type, const QString &description) void TestRunner::reportResult(ResultType type, const QString &description)
{ {
TestResultPtr result(new TestResult); TestResult result("internal", {});
result->setResult(type); result.setResult(type);
result->setDescription(description); result.setDescription(description);
emit testResultReady(result); emit testResultReady(result);
} }

View File

@@ -50,7 +50,7 @@ signals:
void testRunStarted(); void testRunStarted();
void testRunFinished(); void testRunFinished();
void requestStopTestRun(); void requestStopTestRun();
void testResultReady(const TestResultPtr &result); void testResultReady(const TestResult &result);
void hadDisabledTests(int disabled); void hadDisabledTests(int disabled);
void reportSummary(const QString &id, const QHash<ResultType, int> &summary); void reportSummary(const QString &id, const QHash<ResultType, int> &summary);
@@ -76,8 +76,8 @@ private:
bool postponeTestRunWithEmptyExecutable(ProjectExplorer::Project *project); bool postponeTestRunWithEmptyExecutable(ProjectExplorer::Project *project);
void onBuildSystemUpdated(); void onBuildSystemUpdated();
QFutureWatcher<TestResultPtr> m_futureWatcher; QFutureWatcher<TestResult> m_futureWatcher;
QFutureInterface<TestResultPtr> *m_fakeFutureInterface = nullptr; QFutureInterface<TestResult> *m_fakeFutureInterface = nullptr;
QList<ITestConfiguration *> m_selectedTests; QList<ITestConfiguration *> m_selectedTests;
bool m_executingTests = false; bool m_executingTests = false;
bool m_canceled = false; bool m_canceled = false;

View File

@@ -51,8 +51,8 @@ public:
}; };
explicit ITestTreeItem(ITestBase *testBase, explicit ITestTreeItem(ITestBase *testBase,
const QString &name = QString(), const QString &name = {},
const Utils::FilePath &filePath = Utils::FilePath(), const Utils::FilePath &filePath = {},
Type type = Root); Type type = Root);
virtual QVariant data(int column, int role) const override; virtual QVariant data(int column, int role) const override;
@@ -97,8 +97,8 @@ class TestTreeItem : public ITestTreeItem
{ {
public: public:
explicit TestTreeItem(ITestFramework *testFramework, explicit TestTreeItem(ITestFramework *testFramework,
const QString &name = QString(), const QString &name = {},
const Utils::FilePath &filePath = Utils::FilePath(), const Utils::FilePath &filePath = {},
Type type = Root); Type type = Root);
virtual TestTreeItem *copyWithoutChildren() = 0; virtual TestTreeItem *copyWithoutChildren() = 0;

View File

@@ -160,8 +160,7 @@ TestResult SquishResultFilterModel::testResult(const QModelIndex &idx) const
{ {
if (auto item = static_cast<SquishResultItem *>(m_sourceModel->itemForIndex(mapToSource(idx)))) if (auto item = static_cast<SquishResultItem *>(m_sourceModel->itemForIndex(mapToSource(idx))))
return item->result(); return item->result();
return {};
return TestResult();
} }
bool SquishResultFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const bool SquishResultFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const

View File

@@ -244,7 +244,7 @@ void SquishXmlOutputHandler::outputAvailable(const QByteArray &output)
// SquishReport tags will be ignored completely // SquishReport tags will be ignored completely
if (currentName == "epilog") { if (currentName == "epilog") {
QTC_ASSERT(testCaseRootItem, break); QTC_ASSERT(testCaseRootItem, break);
TestResult result(Result::End, QString(), time); const TestResult result(Result::End, QString(), time);
SquishResultItem *item = new SquishResultItem(result); SquishResultItem *item = new SquishResultItem(result);
testCaseRootItem->appendChild(item); testCaseRootItem->appendChild(item);
emit updateStatus(result.text()); emit updateStatus(result.text());
@@ -283,7 +283,7 @@ void SquishXmlOutputHandler::outputAvailable(const QByteArray &output)
if (!logDetailsList.isEmpty()) { if (!logDetailsList.isEmpty()) {
for (const QString &detail : std::as_const(logDetailsList)) { for (const QString &detail : std::as_const(logDetailsList)) {
TestResult childResult(Result::Detail, detail); const TestResult childResult(Result::Detail, detail);
SquishResultItem *childItem = new SquishResultItem(childResult); SquishResultItem *childItem = new SquishResultItem(childResult);
item->appendChild(childItem); item->appendChild(childItem);
emit updateStatus(childResult.text()); emit updateStatus(childResult.text());