AutoTest: Refactor TestResult

* use enum class
* remove superfluous enum value
* remove superfluous subclass
* remove superfluous constructors
* simplify handling

Change-Id: Iecf11e62eb842c9d455d9238939244496f6b66f4
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Christian Stenger
2019-02-06 14:11:19 +01:00
parent 443d8e4713
commit cbab457cf4
17 changed files with 308 additions and 338 deletions

View File

@@ -52,7 +52,7 @@ GTestOutputReader::GTestOutputReader(const QFutureInterface<TestResultPtr> &futu
this, [this] (int exitCode, QProcess::ExitStatus /*exitStatus*/) { this, [this] (int exitCode, QProcess::ExitStatus /*exitStatus*/) {
if (exitCode == 1 && !m_description.isEmpty()) { if (exitCode == 1 && !m_description.isEmpty()) {
createAndReportResult(tr("Running tests failed.\n %1\nExecutable: %2") createAndReportResult(tr("Running tests failed.\n %1\nExecutable: %2")
.arg(m_description).arg(id()), Result::MessageFatal); .arg(m_description).arg(id()), ResultType::MessageFatal);
} }
// on Windows abort() will result in normal termination, but exit code will be set to 3 // on Windows abort() will result in normal termination, but exit code will be set to 3
if (Utils::HostOsInfo::isWindowsHost() && exitCode == 3) if (Utils::HostOsInfo::isWindowsHost() && exitCode == 3)
@@ -87,7 +87,7 @@ void GTestOutputReader::processOutputLine(const QByteArray &outputLineWithNewLin
if (m_iteration > 1) if (m_iteration > 1)
m_description.append(' ' + tr("(iteration %1)").arg(m_iteration)); m_description.append(' ' + tr("(iteration %1)").arg(m_iteration));
TestResultPtr testResult = TestResultPtr(new GTestResult(id(), m_projectFile, QString())); TestResultPtr testResult = TestResultPtr(new GTestResult(id(), m_projectFile, QString()));
testResult->setResult(Result::MessageInternal); testResult->setResult(ResultType::MessageInternal);
testResult->setDescription(m_description); testResult->setDescription(m_description);
reportResult(testResult); reportResult(testResult);
m_description.clear(); m_description.clear();
@@ -100,7 +100,7 @@ void GTestOutputReader::processOutputLine(const QByteArray &outputLineWithNewLin
if (testEnds.exactMatch(line)) { if (testEnds.exactMatch(line)) {
TestResultPtr testResult = createDefaultResult(); TestResultPtr testResult = createDefaultResult();
testResult->setResult(Result::MessageTestCaseEnd); testResult->setResult(ResultType::TestEnd);
testResult->setDescription(tr("Test execution took %1").arg(testEnds.cap(2))); testResult->setDescription(tr("Test execution took %1").arg(testEnds.cap(2)));
reportResult(testResult); reportResult(testResult);
m_currentTestName.clear(); m_currentTestName.clear();
@@ -108,7 +108,7 @@ void GTestOutputReader::processOutputLine(const QByteArray &outputLineWithNewLin
} else if (newTestStarts.exactMatch(line)) { } else if (newTestStarts.exactMatch(line)) {
setCurrentTestName(newTestStarts.cap(1)); setCurrentTestName(newTestStarts.cap(1));
TestResultPtr testResult = createDefaultResult(); TestResultPtr testResult = createDefaultResult();
testResult->setResult(Result::MessageTestCaseStart); testResult->setResult(ResultType::TestStart);
if (m_iteration > 1) { if (m_iteration > 1) {
testResult->setDescription(tr("Repeating test case %1 (iteration %2)") testResult->setDescription(tr("Repeating test case %1 (iteration %2)")
.arg(m_currentTestName).arg(m_iteration)); .arg(m_currentTestName).arg(m_iteration));
@@ -118,25 +118,26 @@ void GTestOutputReader::processOutputLine(const QByteArray &outputLineWithNewLin
reportResult(testResult); reportResult(testResult);
} else if (newTestSetStarts.exactMatch(line)) { } else if (newTestSetStarts.exactMatch(line)) {
setCurrentTestSet(newTestSetStarts.cap(1)); setCurrentTestSet(newTestSetStarts.cap(1));
TestResultPtr testResult = TestResultPtr(new GTestResult(m_projectFile)); TestResultPtr testResult = TestResultPtr(new GTestResult(QString(), m_projectFile,
testResult->setResult(Result::MessageCurrentTest); QString()));
testResult->setResult(ResultType::MessageCurrentTest);
testResult->setDescription(tr("Entering test set %1").arg(m_currentTestSet)); testResult->setDescription(tr("Entering test set %1").arg(m_currentTestSet));
reportResult(testResult); reportResult(testResult);
m_description.clear(); m_description.clear();
} else if (testSetSuccess.exactMatch(line)) { } else if (testSetSuccess.exactMatch(line)) {
TestResultPtr testResult = createDefaultResult(); TestResultPtr testResult = createDefaultResult();
testResult->setResult(Result::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(Result::MessageInternal); testResult->setResult(ResultType::MessageInternal);
testResult->setDescription(tr("Execution took %1.").arg(testSetSuccess.cap(2))); testResult->setDescription(tr("Execution took %1.").arg(testSetSuccess.cap(2)));
reportResult(testResult); reportResult(testResult);
m_futureInterface.setProgressValue(m_futureInterface.progressValue() + 1); m_futureInterface.setProgressValue(m_futureInterface.progressValue() + 1);
} else if (testSetFail.exactMatch(line)) { } else if (testSetFail.exactMatch(line)) {
TestResultPtr testResult = createDefaultResult(); TestResultPtr testResult = createDefaultResult();
testResult->setResult(Result::Fail); testResult->setResult(ResultType::Fail);
m_description.chop(1); m_description.chop(1);
QStringList resultDescription; QStringList resultDescription;
@@ -155,7 +156,7 @@ void GTestOutputReader::processOutputLine(const QByteArray &outputLineWithNewLin
resultDescription.clear(); resultDescription.clear();
testResult = createDefaultResult(); testResult = createDefaultResult();
testResult->setResult(Result::MessageLocation); testResult->setResult(ResultType::MessageLocation);
testResult->setLine(match->cap(2).toInt()); testResult->setLine(match->cap(2).toInt());
QString file = constructSourceFilePath(m_buildDir, match->cap(1)); QString file = constructSourceFilePath(m_buildDir, match->cap(1));
if (!file.isEmpty()) if (!file.isEmpty())
@@ -166,7 +167,7 @@ void GTestOutputReader::processOutputLine(const QByteArray &outputLineWithNewLin
reportResult(testResult); reportResult(testResult);
m_description.clear(); m_description.clear();
testResult = createDefaultResult(); testResult = createDefaultResult();
testResult->setResult(Result::MessageInternal); testResult->setResult(ResultType::MessageInternal);
testResult->setDescription(tr("Execution took %1.").arg(testSetFail.cap(2))); testResult->setDescription(tr("Execution took %1.").arg(testSetFail.cap(2)));
reportResult(testResult); reportResult(testResult);
m_futureInterface.setProgressValue(m_futureInterface.progressValue() + 1); m_futureInterface.setProgressValue(m_futureInterface.progressValue() + 1);

View File

@@ -33,11 +33,6 @@
namespace Autotest { namespace Autotest {
namespace Internal { namespace Internal {
GTestResult::GTestResult(const QString &projectFile, const QString &name)
: TestResult(name), m_projectFile(projectFile)
{
}
GTestResult::GTestResult(const QString &id, const QString &projectFile, GTestResult::GTestResult(const QString &id, const QString &projectFile,
const QString &name) const QString &name)
: TestResult(id, name), m_projectFile(projectFile) : TestResult(id, name), m_projectFile(projectFile)
@@ -49,8 +44,8 @@ const QString GTestResult::outputString(bool selected) const
const QString &desc = description(); const QString &desc = description();
QString output; QString output;
switch (result()) { switch (result()) {
case Result::Pass: case ResultType::Pass:
case Result::Fail: case ResultType::Fail:
output = m_testSetName; output = m_testSetName;
if (selected && !desc.isEmpty()) if (selected && !desc.isEmpty())
output.append('\n').append(desc); output.append('\n').append(desc);
@@ -70,9 +65,9 @@ bool GTestResult::isDirectParentOf(const TestResult *other, bool *needsIntermedi
const GTestResult *gtOther = static_cast<const GTestResult *>(other); const GTestResult *gtOther = static_cast<const GTestResult *>(other);
if (m_testSetName == gtOther->m_testSetName) { if (m_testSetName == gtOther->m_testSetName) {
const Result::Type otherResult = other->result(); const ResultType otherResult = other->result();
if (otherResult == Result::MessageInternal || otherResult == Result::MessageLocation) if (otherResult == ResultType::MessageInternal || otherResult == ResultType::MessageLocation)
return result() != Result::MessageInternal && result() != Result::MessageLocation; return result() != ResultType::MessageInternal && result() != ResultType::MessageLocation;
} }
if (m_iteration != gtOther->m_iteration) if (m_iteration != gtOther->m_iteration)
return false; return false;

View File

@@ -33,7 +33,6 @@ namespace Internal {
class GTestResult : public TestResult class GTestResult : public TestResult
{ {
public: public:
explicit GTestResult(const QString &projectFile, const QString &name = QString());
GTestResult(const QString &id, const QString &projectFile, const QString &name); GTestResult(const QString &id, const QString &projectFile, const QString &name);
const QString outputString(bool selected) const override; const QString outputString(bool selected) const override;

View File

@@ -221,7 +221,7 @@ void QtTestOutputReader::processXMLOutput(const QByteArray &outputLine)
m_description.clear(); m_description.clear();
m_duration.clear(); m_duration.clear();
m_file.clear(); m_file.clear();
m_result = Result::Invalid; m_result = ResultType::Invalid;
m_lineNumber = 0; m_lineNumber = 0;
const QXmlStreamAttributes &attributes = m_xmlReader.attributes(); const QXmlStreamAttributes &attributes = m_xmlReader.attributes();
m_result = TestResult::resultFromString( m_result = TestResult::resultFromString(
@@ -237,19 +237,19 @@ void QtTestOutputReader::processXMLOutput(const QByteArray &outputLine)
const int iterations = attributes.value(QStringLiteral("iterations")).toInt(); const int iterations = attributes.value(QStringLiteral("iterations")).toInt();
m_dataTag = attributes.value(QStringLiteral("tag")).toString(); m_dataTag = attributes.value(QStringLiteral("tag")).toString();
m_description = constructBenchmarkInformation(metric, value, iterations); m_description = constructBenchmarkInformation(metric, value, iterations);
m_result = Result::Benchmark; m_result = ResultType::Benchmark;
} else if (currentTag == QStringLiteral("DataTag")) { } else if (currentTag == QStringLiteral("DataTag")) {
m_cdataMode = DataTag; m_cdataMode = DataTag;
} else if (currentTag == QStringLiteral("Description")) { } else if (currentTag == QStringLiteral("Description")) {
m_cdataMode = Description; m_cdataMode = Description;
} else if (currentTag == QStringLiteral("QtVersion")) { } else if (currentTag == QStringLiteral("QtVersion")) {
m_result = Result::MessageInternal; m_result = ResultType::MessageInternal;
m_cdataMode = QtVersion; m_cdataMode = QtVersion;
} else if (currentTag == QStringLiteral("QtBuild")) { } else if (currentTag == QStringLiteral("QtBuild")) {
m_result = Result::MessageInternal; m_result = ResultType::MessageInternal;
m_cdataMode = QtBuild; m_cdataMode = QtBuild;
} else if (currentTag == QStringLiteral("QTestVersion")) { } else if (currentTag == QStringLiteral("QTestVersion")) {
m_result = Result::MessageInternal; m_result = ResultType::MessageInternal;
m_cdataMode = QTestVersion; m_cdataMode = QTestVersion;
} }
break; break;
@@ -308,7 +308,7 @@ void QtTestOutputReader::processXMLOutput(const QByteArray &outputLine)
&& m_xmlReader.error() != QXmlStreamReader::PrematureEndOfDocumentError) { && m_xmlReader.error() != QXmlStreamReader::PrematureEndOfDocumentError) {
createAndReportResult(tr("XML parsing failed.") createAndReportResult(tr("XML parsing failed.")
+ QString(" (%1) ").arg(m_xmlReader.error()) + QString(" (%1) ").arg(m_xmlReader.error())
+ m_xmlReader.errorString(), Result::MessageFatal); + m_xmlReader.errorString(), ResultType::MessageFatal);
} }
break; break;
} }
@@ -317,7 +317,7 @@ void QtTestOutputReader::processXMLOutput(const QByteArray &outputLine)
static QStringList extractFunctionInformation(const QString &testClassName, static QStringList extractFunctionInformation(const QString &testClassName,
const QString &lineWithoutResultType, const QString &lineWithoutResultType,
Result::Type resultType) ResultType resultType)
{ {
static QRegularExpression classInformation("^(.+?)\\((.*?)\\)(.*)$"); static QRegularExpression classInformation("^(.+?)\\((.*?)\\)(.*)$");
QStringList result; QStringList result;
@@ -327,7 +327,7 @@ static QStringList extractFunctionInformation(const QString &testClassName,
QTC_ASSERT(fullQualifiedFunc.startsWith(testClassName + "::"), return result); QTC_ASSERT(fullQualifiedFunc.startsWith(testClassName + "::"), return result);
fullQualifiedFunc = fullQualifiedFunc.mid(testClassName.length() + 2); fullQualifiedFunc = fullQualifiedFunc.mid(testClassName.length() + 2);
result.append(fullQualifiedFunc); result.append(fullQualifiedFunc);
if (resultType == Result::Benchmark) { // tag is displayed differently if (resultType == ResultType::Benchmark) { // tag is displayed differently
QString possiblyTag = match.captured(3); QString possiblyTag = match.captured(3);
if (!possiblyTag.isEmpty()) if (!possiblyTag.isEmpty())
possiblyTag = possiblyTag.mid(2, possiblyTag.length() - 4); possiblyTag = possiblyTag.mid(2, possiblyTag.length() - 4);
@@ -452,7 +452,7 @@ void QtTestOutputReader::processSummaryFinishOutput()
sendFinishMessage(false); sendFinishMessage(false);
m_className.clear(); m_className.clear();
m_description.clear(); m_description.clear();
m_result = Result::Invalid; m_result = ResultType::Invalid;
m_file.clear(); m_file.clear();
m_lineNumber = 0; m_lineNumber = 0;
} }
@@ -478,16 +478,16 @@ void QtTestOutputReader::sendCompleteInformation()
void QtTestOutputReader::sendMessageCurrentTest() void QtTestOutputReader::sendMessageCurrentTest()
{ {
TestResultPtr testResult = TestResultPtr(new QtTestResult(m_projectFile, m_testType)); QtTestResult *testResult = new QtTestResult(QString(), m_projectFile, m_testType, QString());
testResult->setResult(Result::MessageCurrentTest); testResult->setResult(ResultType::MessageCurrentTest);
testResult->setDescription(tr("Entering test function %1::%2").arg(m_className, m_testCase)); testResult->setDescription(tr("Entering test function %1::%2").arg(m_className, m_testCase));
reportResult(testResult); reportResult(TestResultPtr(testResult));
} }
void QtTestOutputReader::sendStartMessage(bool isFunction) void QtTestOutputReader::sendStartMessage(bool isFunction)
{ {
TestResultPtr testResult = createDefaultResult(); TestResultPtr testResult = createDefaultResult();
testResult->setResult(Result::MessageTestCaseStart); testResult->setResult(ResultType::TestStart);
testResult->setDescription(isFunction ? tr("Executing test function %1").arg(m_testCase) testResult->setDescription(isFunction ? tr("Executing test function %1").arg(m_testCase)
: tr("Executing test case %1").arg(m_className)); : tr("Executing test case %1").arg(m_className));
const TestTreeItem *testItem = testResult->findTestTreeItem(); const TestTreeItem *testItem = testResult->findTestTreeItem();
@@ -501,7 +501,7 @@ void QtTestOutputReader::sendStartMessage(bool isFunction)
void QtTestOutputReader::sendFinishMessage(bool isFunction) void QtTestOutputReader::sendFinishMessage(bool isFunction)
{ {
TestResultPtr testResult = createDefaultResult(); TestResultPtr testResult = createDefaultResult();
testResult->setResult(Result::MessageTestCaseEnd); testResult->setResult(ResultType::TestEnd);
if (!m_duration.isEmpty()) { if (!m_duration.isEmpty()) {
testResult->setDescription(isFunction ? tr("Execution took %1 ms.").arg(m_duration) testResult->setDescription(isFunction ? tr("Execution took %1 ms.").arg(m_duration)
: tr("Test execution took %1 ms.").arg(m_duration)); : tr("Test execution took %1 ms.").arg(m_duration));
@@ -515,15 +515,15 @@ void QtTestOutputReader::sendFinishMessage(bool isFunction)
void QtTestOutputReader::handleAndSendConfigMessage(const QRegularExpressionMatch &config) void QtTestOutputReader::handleAndSendConfigMessage(const QRegularExpressionMatch &config)
{ {
TestResultPtr testResult = createDefaultResult(); TestResultPtr testResult = createDefaultResult();
testResult->setResult(Result::MessageInternal); testResult->setResult(ResultType::MessageInternal);
testResult->setDescription(trQtVersion(config.captured(3))); testResult->setDescription(trQtVersion(config.captured(3)));
reportResult(testResult); reportResult(testResult);
testResult = createDefaultResult(); testResult = createDefaultResult();
testResult->setResult(Result::MessageInternal); testResult->setResult(ResultType::MessageInternal);
testResult->setDescription(trQtBuild(config.captured(2))); testResult->setDescription(trQtBuild(config.captured(2)));
reportResult(testResult); reportResult(testResult);
testResult = createDefaultResult(); testResult = createDefaultResult();
testResult->setResult(Result::MessageInternal); testResult->setResult(ResultType::MessageInternal);
testResult->setDescription(trQtestVersion(config.captured(1))); testResult->setDescription(trQtestVersion(config.captured(1)));
reportResult(testResult); reportResult(testResult);
} }

View File

@@ -83,7 +83,7 @@ private:
QString m_testCase; QString m_testCase;
QString m_formerTestCase; QString m_formerTestCase;
QString m_dataTag; QString m_dataTag;
Result::Type m_result = Result::Invalid; ResultType m_result = ResultType::Invalid;
QString m_description; QString m_description;
QString m_file; QString m_file;
int m_lineNumber = 0; int m_lineNumber = 0;

View File

@@ -34,11 +34,6 @@
namespace Autotest { namespace Autotest {
namespace Internal { namespace Internal {
QtTestResult::QtTestResult(const QString &projectFile, TestType type, const QString &className)
: TestResult(className), m_projectFile(projectFile), m_type(type)
{
}
QtTestResult::QtTestResult(const QString &id, const QString &projectFile, TestType type, QtTestResult::QtTestResult(const QString &id, const QString &projectFile, TestType type,
const QString &className) const QString &className)
: TestResult(id, className), m_projectFile(projectFile), m_type(type) : TestResult(id, className), m_projectFile(projectFile), m_type(type)
@@ -51,12 +46,12 @@ const QString QtTestResult::outputString(bool selected) const
const QString &className = name(); const QString &className = name();
QString output; QString output;
switch (result()) { switch (result()) {
case Result::Pass: case ResultType::Pass:
case Result::Fail: case ResultType::Fail:
case Result::ExpectedFail: case ResultType::ExpectedFail:
case Result::UnexpectedPass: case ResultType::UnexpectedPass:
case Result::BlacklistedFail: case ResultType::BlacklistedFail:
case Result::BlacklistedPass: case ResultType::BlacklistedPass:
output = className + "::" + m_function; output = className + "::" + m_function;
if (!m_dataTag.isEmpty()) if (!m_dataTag.isEmpty())
output.append(QString(" (%1)").arg(m_dataTag)); output.append(QString(" (%1)").arg(m_dataTag));
@@ -64,7 +59,7 @@ const QString QtTestResult::outputString(bool selected) const
output.append('\n').append(desc); output.append('\n').append(desc);
} }
break; break;
case Result::Benchmark: case ResultType::Benchmark:
output = className + "::" + m_function; output = className + "::" + m_function;
if (!m_dataTag.isEmpty()) if (!m_dataTag.isEmpty())
output.append(QString(" (%1)").arg(m_dataTag)); output.append(QString(" (%1)").arg(m_dataTag));
@@ -94,7 +89,7 @@ bool QtTestResult::isDirectParentOf(const TestResult *other, bool *needsIntermed
if (qtOther->m_function == m_function) { if (qtOther->m_function == m_function) {
if (m_dataTag.isEmpty()) { if (m_dataTag.isEmpty()) {
// avoid adding function's TestCaseEnd to the data tag // avoid adding function's TestCaseEnd to the data tag
*needsIntermediate = qtOther->result() != Result::MessageTestCaseEnd; *needsIntermediate = qtOther->result() != ResultType::TestEnd;
return true; return true;
} }
return qtOther->m_dataTag == m_dataTag; return qtOther->m_dataTag == m_dataTag;

View File

@@ -34,7 +34,6 @@ namespace Internal {
class QtTestResult : public TestResult class QtTestResult : public TestResult
{ {
public: public:
QtTestResult(const QString &projectFile, TestType type, const QString &className = QString());
QtTestResult(const QString &id, const QString &projectFile, TestType type, QtTestResult(const QString &id, const QString &projectFile, TestType type,
const QString &className); const QString &className);
const QString outputString(bool selected) const override; const QString outputString(bool selected) const override;

View File

@@ -74,11 +74,11 @@ void TestOutputReader::reportCrash()
{ {
TestResultPtr result = createDefaultResult(); TestResultPtr result = createDefaultResult();
result->setDescription(tr("Test executable crashed.")); result->setDescription(tr("Test executable crashed."));
result->setResult(Result::MessageFatal); result->setResult(ResultType::MessageFatal);
m_futureInterface.reportResult(result); m_futureInterface.reportResult(result);
} }
void TestOutputReader::createAndReportResult(const QString &message, Result::Type type) void TestOutputReader::createAndReportResult(const QString &message, ResultType type)
{ {
TestResultPtr result = createDefaultResult(); TestResultPtr result = createDefaultResult();
result->setDescription(message); result->setDescription(message);

View File

@@ -45,7 +45,7 @@ public:
void processOutput(const QByteArray &output); void processOutput(const QByteArray &output);
virtual void processStdError(const QByteArray &outputLineWithNewLine); virtual void processStdError(const QByteArray &outputLineWithNewLine);
void reportCrash(); void reportCrash();
void createAndReportResult(const QString &message, Result::Type type); void createAndReportResult(const QString &message, ResultType type);
bool hadValidOutput() const { return m_hadValidOutput; } bool hadValidOutput() const { return m_hadValidOutput; }
int disabledTests() const { return m_disabled; } int disabledTests() const { return m_disabled; }
void setId(const QString &id) { m_id = id; } void setId(const QString &id) { m_id = id; }

View File

@@ -31,22 +31,6 @@
namespace Autotest { namespace Autotest {
namespace Internal { namespace Internal {
FaultyTestResult::FaultyTestResult(Result::Type result, const QString &description)
{
setResult(result);
setDescription(description);
}
TestResult::TestResult()
: TestResult(QString())
{
}
TestResult::TestResult(const QString &name)
: m_name(name)
{
}
TestResult::TestResult(const QString &id, const QString &name) TestResult::TestResult(const QString &id, const QString &name)
: m_id(id) : m_id(id)
, m_name(name) , m_name(name)
@@ -55,7 +39,7 @@ TestResult::TestResult(const QString &id, const QString &name)
const QString TestResult::outputString(bool selected) const const QString TestResult::outputString(bool selected) const
{ {
if (m_result == Result::Application) if (m_result == ResultType::Application)
return m_id; return m_id;
return selected ? m_description : m_description.split('\n').first(); return selected ? m_description : m_description.split('\n').first();
} }
@@ -65,136 +49,136 @@ const TestTreeItem *TestResult::findTestTreeItem() const
return nullptr; return nullptr;
} }
Result::Type TestResult::resultFromString(const QString &resultString) ResultType TestResult::resultFromString(const QString &resultString)
{ {
if (resultString == "pass") if (resultString == "pass")
return Result::Pass; return ResultType::Pass;
if (resultString == "fail" || resultString == "fail!") if (resultString == "fail" || resultString == "fail!")
return Result::Fail; return ResultType::Fail;
if (resultString == "xfail") if (resultString == "xfail")
return Result::ExpectedFail; return ResultType::ExpectedFail;
if (resultString == "xpass") if (resultString == "xpass")
return Result::UnexpectedPass; return ResultType::UnexpectedPass;
if (resultString == "skip") if (resultString == "skip")
return Result::Skip; return ResultType::Skip;
if (resultString == "result") if (resultString == "result")
return Result::Benchmark; return ResultType::Benchmark;
if (resultString == "qdebug") if (resultString == "qdebug")
return Result::MessageDebug; return ResultType::MessageDebug;
if (resultString == "qinfo" || resultString == "info") if (resultString == "qinfo" || resultString == "info")
return Result::MessageInfo; return ResultType::MessageInfo;
if (resultString == "warn" || resultString == "qwarn" || resultString == "warning") if (resultString == "warn" || resultString == "qwarn" || resultString == "warning")
return Result::MessageWarn; return ResultType::MessageWarn;
if (resultString == "qfatal") if (resultString == "qfatal")
return Result::MessageFatal; return ResultType::MessageFatal;
if ((resultString == "system") || (resultString == "qsystem")) if ((resultString == "system") || (resultString == "qsystem"))
return Result::MessageSystem; return ResultType::MessageSystem;
if (resultString == "bpass") if (resultString == "bpass")
return Result::BlacklistedPass; return ResultType::BlacklistedPass;
if (resultString == "bfail") if (resultString == "bfail")
return Result::BlacklistedFail; return ResultType::BlacklistedFail;
if (resultString == "bxpass") if (resultString == "bxpass")
return Result::BlacklistedXPass; return ResultType::BlacklistedXPass;
if (resultString == "bxfail") if (resultString == "bxfail")
return Result::BlacklistedXFail; return ResultType::BlacklistedXFail;
qDebug("Unexpected test result: %s", qPrintable(resultString)); qDebug("Unexpected test result: %s", qPrintable(resultString));
return Result::Invalid; return ResultType::Invalid;
} }
Result::Type TestResult::toResultType(int rt) ResultType TestResult::toResultType(int rt)
{ {
if (rt < Result::FIRST_TYPE || rt > Result::LAST_TYPE) if (rt < int(ResultType::FIRST_TYPE) || rt > int(ResultType::LAST_TYPE))
return Result::Invalid; return ResultType::Invalid;
return Result::Type(rt); return ResultType(rt);
} }
QString TestResult::resultToString(const Result::Type type) QString TestResult::resultToString(const ResultType type)
{ {
switch (type) { switch (type) {
case Result::Pass: case ResultType::Pass:
case Result::MessageTestCaseSuccess: case ResultType::MessageTestCaseSuccess:
case Result::MessageTestCaseSuccessWarn: case ResultType::MessageTestCaseSuccessWarn:
return QString("PASS"); return QString("PASS");
case Result::Fail: case ResultType::Fail:
case Result::MessageTestCaseFail: case ResultType::MessageTestCaseFail:
case Result::MessageTestCaseFailWarn: case ResultType::MessageTestCaseFailWarn:
return QString("FAIL"); return QString("FAIL");
case Result::ExpectedFail: case ResultType::ExpectedFail:
return QString("XFAIL"); return QString("XFAIL");
case Result::UnexpectedPass: case ResultType::UnexpectedPass:
return QString("XPASS"); return QString("XPASS");
case Result::Skip: case ResultType::Skip:
return QString("SKIP"); return QString("SKIP");
case Result::Benchmark: case ResultType::Benchmark:
return QString("BENCH"); return QString("BENCH");
case Result::MessageDebug: case ResultType::MessageDebug:
return QString("DEBUG"); return QString("DEBUG");
case Result::MessageInfo: case ResultType::MessageInfo:
return QString("INFO"); return QString("INFO");
case Result::MessageWarn: case ResultType::MessageWarn:
return QString("WARN"); return QString("WARN");
case Result::MessageFatal: case ResultType::MessageFatal:
return QString("FATAL"); return QString("FATAL");
case Result::MessageSystem: case ResultType::MessageSystem:
return QString("SYSTEM"); return QString("SYSTEM");
case Result::BlacklistedPass: case ResultType::BlacklistedPass:
return QString("BPASS"); return QString("BPASS");
case Result::BlacklistedFail: case ResultType::BlacklistedFail:
return QString("BFAIL"); return QString("BFAIL");
case Result::BlacklistedXPass: case ResultType::BlacklistedXPass:
return QString("BXPASS"); return QString("BXPASS");
case Result::BlacklistedXFail: case ResultType::BlacklistedXFail:
return QString("BXFAIL"); return QString("BXFAIL");
case Result::MessageLocation: case ResultType::MessageLocation:
case Result::Application: case ResultType::Application:
return QString(); return QString();
default: default:
if (type >= Result::INTERNAL_MESSAGES_BEGIN && type <= Result::INTERNAL_MESSAGES_END) if (type >= ResultType::INTERNAL_MESSAGES_BEGIN && type <= ResultType::INTERNAL_MESSAGES_END)
return QString(); return QString();
return QString("UNKNOWN"); return QString("UNKNOWN");
} }
} }
QColor TestResult::colorForType(const Result::Type type) QColor TestResult::colorForType(const ResultType type)
{ {
if (type >= Result::INTERNAL_MESSAGES_BEGIN && type <= Result::INTERNAL_MESSAGES_END) if (type >= ResultType::INTERNAL_MESSAGES_BEGIN && type <= ResultType::INTERNAL_MESSAGES_END)
return QColor("transparent"); return QColor("transparent");
Utils::Theme *creatorTheme = Utils::creatorTheme(); Utils::Theme *creatorTheme = Utils::creatorTheme();
switch (type) { switch (type) {
case Result::Pass: case ResultType::Pass:
return creatorTheme->color(Utils::Theme::OutputPanes_TestPassTextColor); return creatorTheme->color(Utils::Theme::OutputPanes_TestPassTextColor);
case Result::Fail: case ResultType::Fail:
return creatorTheme->color(Utils::Theme::OutputPanes_TestFailTextColor); return creatorTheme->color(Utils::Theme::OutputPanes_TestFailTextColor);
case Result::ExpectedFail: case ResultType::ExpectedFail:
return creatorTheme->color(Utils::Theme::OutputPanes_TestXFailTextColor); return creatorTheme->color(Utils::Theme::OutputPanes_TestXFailTextColor);
case Result::UnexpectedPass: case ResultType::UnexpectedPass:
return creatorTheme->color(Utils::Theme::OutputPanes_TestXPassTextColor); return creatorTheme->color(Utils::Theme::OutputPanes_TestXPassTextColor);
case Result::Skip: case ResultType::Skip:
return creatorTheme->color(Utils::Theme::OutputPanes_TestSkipTextColor); return creatorTheme->color(Utils::Theme::OutputPanes_TestSkipTextColor);
case Result::MessageDebug: case ResultType::MessageDebug:
case Result::MessageInfo: case ResultType::MessageInfo:
return creatorTheme->color(Utils::Theme::OutputPanes_TestDebugTextColor); return creatorTheme->color(Utils::Theme::OutputPanes_TestDebugTextColor);
case Result::MessageWarn: case ResultType::MessageWarn:
return creatorTheme->color(Utils::Theme::OutputPanes_TestWarnTextColor); return creatorTheme->color(Utils::Theme::OutputPanes_TestWarnTextColor);
case Result::MessageFatal: case ResultType::MessageFatal:
case Result::MessageSystem: case ResultType::MessageSystem:
return creatorTheme->color(Utils::Theme::OutputPanes_TestFatalTextColor); return creatorTheme->color(Utils::Theme::OutputPanes_TestFatalTextColor);
case Result::BlacklistedPass: case ResultType::BlacklistedPass:
case Result::BlacklistedFail: case ResultType::BlacklistedFail:
case Result::BlacklistedXPass: case ResultType::BlacklistedXPass:
case Result::BlacklistedXFail: case ResultType::BlacklistedXFail:
default: default:
return creatorTheme->color(Utils::Theme::OutputPanes_StdOutTextColor); return creatorTheme->color(Utils::Theme::OutputPanes_StdOutTextColor);
} }
} }
bool TestResult::isMessageCaseStart(const Result::Type type) bool TestResult::isMessageCaseStart(const ResultType type)
{ {
return type == Result::MessageTestCaseStart || type == Result::MessageTestCaseSuccess return type == ResultType::TestStart || type == ResultType::MessageTestCaseSuccess
|| type == Result::MessageTestCaseFail || type == Result::MessageTestCaseSuccessWarn || type == ResultType::MessageTestCaseFail || type == ResultType::MessageTestCaseSuccessWarn
|| type == Result::MessageTestCaseFailWarn || type == Result::MessageIntermediate; || type == ResultType::MessageTestCaseFailWarn;
} }
bool TestResult::isDirectParentOf(const TestResult *other, bool * /*needsIntermediate*/) const bool TestResult::isDirectParentOf(const TestResult *other, bool * /*needsIntermediate*/) const

View File

@@ -37,8 +37,8 @@ namespace Internal {
class TestTreeItem; class TestTreeItem;
namespace Result{ enum class ResultType {
enum Type { // result types (have icon, color, short text)
Pass, FIRST_TYPE = Pass, Pass, FIRST_TYPE = Pass,
Fail, Fail,
ExpectedFail, ExpectedFail,
@@ -48,36 +48,44 @@ enum Type {
BlacklistedFail, BlacklistedFail,
BlacklistedXPass, BlacklistedXPass,
BlacklistedXFail, BlacklistedXFail,
// special (message) types (have icon, color, short text)
Benchmark, Benchmark,
MessageDebug, MessageDebug,
MessageInfo, MessageInfo,
MessageWarn, MessageWarn,
MessageFatal, MessageFatal,
MessageSystem, MessageSystem,
MessageLocation,
// special message - get's icon (but no color/short text) from parent
MessageLocation,
// anything below is an internal message (or a pure message without icon)
MessageInternal, INTERNAL_MESSAGES_BEGIN = MessageInternal, MessageInternal, INTERNAL_MESSAGES_BEGIN = MessageInternal,
MessageTestCaseStart, // TODO make the following 5 a single start item (get icon/short text depending on children)
TestStart,
MessageTestCaseSuccess, MessageTestCaseSuccess,
MessageTestCaseSuccessWarn, MessageTestCaseSuccessWarn,
MessageTestCaseFail, MessageTestCaseFail,
MessageTestCaseFailWarn, MessageTestCaseFailWarn,
MessageTestCaseEnd, // usually no icon/short text - more or less an indicator (and can contain test duration)
MessageIntermediate, TestEnd,
// special global (temporary) message
MessageCurrentTest, INTERNAL_MESSAGES_END = MessageCurrentTest, MessageCurrentTest, INTERNAL_MESSAGES_END = MessageCurrentTest,
Application, Application, // special.. not to be used outside of testresultmodel
Invalid, // indicator for unknown result items
Invalid,
LAST_TYPE = Invalid LAST_TYPE = Invalid
}; };
inline uint qHash(const ResultType &result)
{
return QT_PREPEND_NAMESPACE(qHash(int(result)));
} }
class TestResult class TestResult
{ {
public: public:
TestResult(); TestResult() = default;
explicit TestResult(const QString &name);
TestResult(const QString &id, const QString &name); TestResult(const QString &id, const QString &name);
virtual ~TestResult() {} virtual ~TestResult() {}
@@ -86,7 +94,7 @@ public:
QString id() const { return m_id; } QString id() const { return m_id; }
QString name() const { return m_name; } QString name() const { return m_name; }
Result::Type result() const { return m_result; } ResultType result() const { return m_result; }
QString description() const { return m_description; } QString description() const { return m_description; }
QString fileName() const { return m_file; } QString fileName() const { return m_file; }
int line() const { return m_line; } int line() const { return m_line; }
@@ -94,22 +102,21 @@ public:
void setDescription(const QString &description) { m_description = description; } void setDescription(const QString &description) { m_description = description; }
void setFileName(const QString &fileName) { m_file = fileName; } void setFileName(const QString &fileName) { m_file = fileName; }
void setLine(int line) { m_line = line; } void setLine(int line) { m_line = line; }
void setResult(Result::Type type) { m_result = type; } void setResult(ResultType type) { m_result = type; }
static Result::Type resultFromString(const QString &resultString); static ResultType resultFromString(const QString &resultString);
static Result::Type toResultType(int rt); static ResultType toResultType(int rt);
static QString resultToString(const Result::Type type); static QString resultToString(const ResultType type);
static QColor colorForType(const Result::Type type); static QColor colorForType(const ResultType type);
static bool isMessageCaseStart(const Result::Type type); static bool isMessageCaseStart(const ResultType type);
virtual bool isDirectParentOf(const TestResult *other, bool *needsIntermediate) const; virtual bool isDirectParentOf(const TestResult *other, bool *needsIntermediate) const;
virtual bool isIntermediateFor(const TestResult *other) const; virtual bool isIntermediateFor(const TestResult *other) const;
virtual TestResult *createIntermediateResultFor(const TestResult *other); virtual TestResult *createIntermediateResultFor(const TestResult *other);
private: private:
QString m_id; QString m_id;
QString m_name; QString m_name;
Result::Type m_result = Result::Invalid; ResultType m_result = ResultType::Invalid; // the real result..
QString m_description; QString m_description;
QString m_file; QString m_file;
int m_line = 0; int m_line = 0;
@@ -117,14 +124,8 @@ private:
using TestResultPtr = QSharedPointer<TestResult>; using TestResultPtr = QSharedPointer<TestResult>;
class FaultyTestResult : public TestResult
{
public:
FaultyTestResult(Result::Type result, const QString &description);
};
} // namespace Internal } // namespace Internal
} // namespace Autotest } // namespace Autotest
Q_DECLARE_METATYPE(Autotest::Internal::TestResult) Q_DECLARE_METATYPE(Autotest::Internal::TestResult)
Q_DECLARE_METATYPE(Autotest::Internal::Result::Type) Q_DECLARE_METATYPE(Autotest::Internal::ResultType)

View File

@@ -40,12 +40,6 @@ namespace Internal {
constexpr int outputLimit = 100000; constexpr int outputLimit = 100000;
static bool isSummaryItem(Result::Type type)
{
return type == Result::MessageTestCaseSuccess || type == Result::MessageTestCaseSuccessWarn
|| type == Result::MessageTestCaseFail || type == Result::MessageTestCaseFailWarn;
}
TestResultDelegate::TestResultDelegate(QObject *parent) TestResultDelegate::TestResultDelegate(QObject *parent)
: QStyledItemDelegate(parent) : QStyledItemDelegate(parent)
{ {
@@ -94,7 +88,7 @@ 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 (isSummaryItem(testResult->result())) if (TestResult::isMessageCaseStart(testResult->result()))
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()));

View File

@@ -45,7 +45,7 @@ TestResultItem::TestResultItem(const TestResultPtr &testResult)
{ {
} }
static QIcon testResultIcon(Result::Type result) { static QIcon testResultIcon(ResultType result) {
const static QIcon icons[] = { const static QIcon icons[] = {
Icons::RESULT_PASS.icon(), Icons::RESULT_PASS.icon(),
Icons::RESULT_FAIL.icon(), Icons::RESULT_FAIL.icon(),
@@ -68,23 +68,23 @@ static QIcon testResultIcon(Result::Type result) {
ProjectExplorer::Icons::DESKTOP_DEVICE.icon(), // for now ProjectExplorer::Icons::DESKTOP_DEVICE.icon(), // for now
}; // provide an icon for unknown?? }; // provide an icon for unknown??
if (result < 0 || result >= Result::MessageInternal) { if (result < ResultType::FIRST_TYPE || result >= ResultType::MessageInternal) {
switch (result) { switch (result) {
case Result::MessageTestCaseSuccess: case ResultType::MessageTestCaseSuccess:
return icons[Result::Pass]; return icons[int(ResultType::Pass)];
case Result::MessageTestCaseFail: case ResultType::MessageTestCaseFail:
return icons[Result::Fail]; return icons[int(ResultType::Fail)];
case Result::MessageTestCaseSuccessWarn: case ResultType::MessageTestCaseSuccessWarn:
return icons[16]; return icons[16];
case Result::MessageTestCaseFailWarn: case ResultType::MessageTestCaseFailWarn:
return icons[17]; return icons[17];
case Result::Application: case ResultType::Application:
return icons[18]; return icons[18];
default: default:
return QIcon(); return QIcon();
} }
} }
return icons[result]; return icons[int(result)];
} }
QVariant TestResultItem::data(int column, int role) const QVariant TestResultItem::data(int column, int role) const
@@ -93,8 +93,8 @@ QVariant TestResultItem::data(int column, int role) const
case Qt::DecorationRole: { case Qt::DecorationRole: {
if (!m_testResult) if (!m_testResult)
return QVariant(); return QVariant();
const Result::Type result = m_testResult->result(); const ResultType result = m_testResult->result();
if (result == Result::MessageLocation && parent()) if (result == ResultType::MessageLocation && parent())
return parent()->data(column, role); return parent()->data(column, role);
return testResultIcon(result); return testResultIcon(result);
} }
@@ -112,43 +112,42 @@ void TestResultItem::updateDescription(const QString &description)
m_testResult->setDescription(description); m_testResult->setDescription(description);
} }
void TestResultItem::updateResult(bool &changed, Result::Type addedChildType) void TestResultItem::updateResult(bool &changed, ResultType addedChildType)
{ {
changed = false; changed = false;
const Result::Type old = m_testResult->result(); const ResultType old = m_testResult->result();
if (old == Result::MessageTestCaseFailWarn) // can't become worse if (old == ResultType::MessageTestCaseFailWarn) // can't become worse
return; return;
if (!TestResult::isMessageCaseStart(old)) if (!TestResult::isMessageCaseStart(old))
return; return;
Result::Type newResult = old; ResultType newResult = old;
switch (addedChildType) { switch (addedChildType) {
case Result::Fail: case ResultType::Fail:
case Result::MessageFatal: case ResultType::MessageFatal:
case Result::UnexpectedPass: case ResultType::UnexpectedPass:
case Result::MessageTestCaseFail: case ResultType::MessageTestCaseFail:
newResult = (old == Result::MessageTestCaseSuccessWarn) ? Result::MessageTestCaseFailWarn newResult = (old == ResultType::MessageTestCaseSuccessWarn) ? ResultType::MessageTestCaseFailWarn
: Result::MessageTestCaseFail; : ResultType::MessageTestCaseFail;
break; break;
case Result::MessageTestCaseFailWarn: case ResultType::MessageTestCaseFailWarn:
newResult = Result::MessageTestCaseFailWarn; newResult = ResultType::MessageTestCaseFailWarn;
break; break;
case Result::ExpectedFail: case ResultType::ExpectedFail:
case Result::MessageWarn: case ResultType::MessageWarn:
case Result::MessageSystem: case ResultType::MessageSystem:
case Result::Skip: case ResultType::Skip:
case Result::BlacklistedFail: case ResultType::BlacklistedFail:
case Result::BlacklistedPass: case ResultType::BlacklistedPass:
case Result::BlacklistedXFail: case ResultType::BlacklistedXFail:
case Result::BlacklistedXPass: case ResultType::BlacklistedXPass:
case Result::MessageTestCaseSuccessWarn: case ResultType::MessageTestCaseSuccessWarn:
newResult = (old == Result::MessageTestCaseFail) ? Result::MessageTestCaseFailWarn newResult = (old == ResultType::MessageTestCaseFail) ? ResultType::MessageTestCaseFailWarn
: Result::MessageTestCaseSuccessWarn; : ResultType::MessageTestCaseSuccessWarn;
break; break;
case Result::Pass: case ResultType::Pass:
case Result::MessageTestCaseSuccess: case ResultType::MessageTestCaseSuccess:
newResult = (old == Result::MessageIntermediate || old == Result::MessageTestCaseStart) newResult = (old == ResultType::TestStart) ? ResultType::MessageTestCaseSuccess : old;
? Result::MessageTestCaseSuccess : old;
break; break;
default: default:
break; break;
@@ -165,7 +164,7 @@ TestResultItem *TestResultItem::intermediateFor(const TestResultItem *item) cons
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() != Result::MessageIntermediate) if (testResult->result() != ResultType::TestStart)
continue; continue;
if (testResult->isIntermediateFor(otherResult)) if (testResult->isIntermediateFor(otherResult))
return child; return child;
@@ -177,7 +176,7 @@ TestResultItem *TestResultItem::createAndAddIntermediateFor(const TestResultItem
{ {
TestResultPtr result(m_testResult->createIntermediateResultFor(child->testResult())); TestResultPtr result(m_testResult->createIntermediateResultFor(child->testResult()));
QTC_ASSERT(!result.isNull(), return nullptr); QTC_ASSERT(!result.isNull(), return nullptr);
result->setResult(Result::MessageIntermediate); result->setResult(ResultType::TestStart);
TestResultItem *intermediate = new TestResultItem(result); TestResultItem *intermediate = new TestResultItem(result);
appendChild(intermediate); appendChild(intermediate);
return intermediate; return intermediate;
@@ -208,12 +207,12 @@ void TestResultModel::updateParent(const TestResultItem *item)
void TestResultModel::addTestResult(const TestResultPtr &testResult, bool autoExpand) void TestResultModel::addTestResult(const TestResultPtr &testResult, bool autoExpand)
{ {
const int lastRow = rootItem()->childCount() - 1; const int lastRow = rootItem()->childCount() - 1;
if (testResult->result() == Result::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() == Result::MessageCurrentTest) { if (result && 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;
@@ -238,7 +237,7 @@ void TestResultModel::addTestResult(const TestResultPtr &testResult, bool autoEx
if (!root) { if (!root) {
TestResult *tmpAppResult = new TestResult(application, application); TestResult *tmpAppResult = new TestResult(application, application);
tmpAppResult->setResult(Result::Application); tmpAppResult->setResult(ResultType::Application);
root = new TestResultItem(TestResultPtr(tmpAppResult)); root = new TestResultItem(TestResultPtr(tmpAppResult));
if (lastRow >= 0) if (lastRow >= 0)
rootItem()->insertChild(lastRow, root); rootItem()->insertChild(lastRow, root);
@@ -259,7 +258,7 @@ void TestResultModel::addTestResult(const TestResultPtr &testResult, bool autoEx
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() == Result::MessageCurrentTest) { if (result && result->result() == ResultType::MessageCurrentTest) {
rootItem()->insertChild(current->index().row(), newItem); rootItem()->insertChild(current->index().row(), newItem);
return; return;
} }
@@ -272,7 +271,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() == Result::MessageCurrentTest); return (it->testResult()->result() == ResultType::MessageCurrentTest);
}); });
if (currentMessageItem) if (currentMessageItem)
destroyItem(currentMessageItem); destroyItem(currentMessageItem);
@@ -383,38 +382,38 @@ TestResultFilterModel::TestResultFilterModel(TestResultModel *sourceModel, QObje
void TestResultFilterModel::enableAllResultTypes() void TestResultFilterModel::enableAllResultTypes()
{ {
m_enabled << Result::Pass << Result::Fail << Result::ExpectedFail m_enabled << ResultType::Pass << ResultType::Fail << ResultType::ExpectedFail
<< Result::UnexpectedPass << Result::Skip << Result::MessageDebug << ResultType::UnexpectedPass << ResultType::Skip << ResultType::MessageDebug
<< Result::MessageWarn << Result::MessageInternal << Result::MessageLocation << ResultType::MessageWarn << ResultType::MessageInternal << ResultType::MessageLocation
<< Result::MessageFatal << Result::Invalid << Result::BlacklistedPass << ResultType::MessageFatal << ResultType::Invalid << ResultType::BlacklistedPass
<< Result::BlacklistedFail << Result::BlacklistedXFail << Result::BlacklistedXPass << ResultType::BlacklistedFail << ResultType::BlacklistedXFail << ResultType::BlacklistedXPass
<< Result::Benchmark << Result::MessageIntermediate << ResultType::Benchmark
<< Result::MessageCurrentTest << Result::MessageTestCaseStart << ResultType::MessageCurrentTest << ResultType::TestStart
<< Result::MessageTestCaseSuccess << Result::MessageTestCaseSuccessWarn << ResultType::MessageTestCaseSuccess << ResultType::MessageTestCaseSuccessWarn
<< Result::MessageTestCaseFail << Result::MessageTestCaseFailWarn << ResultType::MessageTestCaseFail << ResultType::MessageTestCaseFailWarn
<< Result::MessageTestCaseEnd << ResultType::TestEnd
<< Result::MessageInfo << Result::MessageSystem << Result::Application; << ResultType::MessageInfo << ResultType::MessageSystem << ResultType::Application;
invalidateFilter(); invalidateFilter();
} }
void TestResultFilterModel::toggleTestResultType(Result::Type type) void TestResultFilterModel::toggleTestResultType(ResultType type)
{ {
if (m_enabled.contains(type)) { if (m_enabled.contains(type)) {
m_enabled.remove(type); m_enabled.remove(type);
if (type == Result::MessageInternal) if (type == ResultType::MessageInternal)
m_enabled.remove(Result::MessageTestCaseEnd); m_enabled.remove(ResultType::TestEnd);
if (type == Result::MessageDebug) if (type == ResultType::MessageDebug)
m_enabled.remove(Result::MessageInfo); m_enabled.remove(ResultType::MessageInfo);
if (type == Result::MessageWarn) if (type == ResultType::MessageWarn)
m_enabled.remove(Result::MessageSystem); m_enabled.remove(ResultType::MessageSystem);
} else { } else {
m_enabled.insert(type); m_enabled.insert(type);
if (type == Result::MessageInternal) if (type == ResultType::MessageInternal)
m_enabled.insert(Result::MessageTestCaseEnd); m_enabled.insert(ResultType::TestEnd);
if (type == Result::MessageDebug) if (type == ResultType::MessageDebug)
m_enabled.insert(Result::MessageInfo); m_enabled.insert(ResultType::MessageInfo);
if (type == Result::MessageWarn) if (type == ResultType::MessageWarn)
m_enabled.insert(Result::MessageSystem); m_enabled.insert(ResultType::MessageSystem);
} }
invalidateFilter(); invalidateFilter();
} }
@@ -439,13 +438,13 @@ 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;
Result::Type resultType = m_sourceModel->testResult(index)->result(); ResultType resultType = m_sourceModel->testResult(index)->result();
switch (resultType) { switch (resultType) {
case Result::MessageTestCaseSuccess: case ResultType::MessageTestCaseSuccess:
return m_enabled.contains(Result::Pass); return m_enabled.contains(ResultType::Pass);
case Result::MessageTestCaseFail: case ResultType::MessageTestCaseFail:
case Result::MessageTestCaseSuccessWarn: case ResultType::MessageTestCaseSuccessWarn:
case Result::MessageTestCaseFailWarn: case ResultType::MessageTestCaseFailWarn:
return acceptTestCaseResult(index); return acceptTestCaseResult(index);
default: default:
return m_enabled.contains(resultType); return m_enabled.contains(resultType);
@@ -456,11 +455,11 @@ 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);
Result::Type type = m_sourceModel->testResult(child)->result(); ResultType type = m_sourceModel->testResult(child)->result();
if (type == Result::MessageTestCaseSuccess) if (type == ResultType::MessageTestCaseSuccess)
type = Result::Pass; type = ResultType::Pass;
if (type == Result::MessageTestCaseFail || type == Result::MessageTestCaseFailWarn if (type == ResultType::MessageTestCaseFail || type == ResultType::MessageTestCaseFailWarn
|| type == Result::MessageTestCaseSuccessWarn) { || type == ResultType::MessageTestCaseSuccessWarn) {
if (acceptTestCaseResult(child)) if (acceptTestCaseResult(child))
return true; return true;
} else if (m_enabled.contains(type)) { } else if (m_enabled.contains(type)) {

View File

@@ -44,7 +44,7 @@ public:
QVariant data(int column, int role) const override; QVariant data(int column, int role) const override;
const TestResult *testResult() const { return m_testResult.data(); } const TestResult *testResult() const { return m_testResult.data(); }
void updateDescription(const QString &description); void updateDescription(const QString &description);
void updateResult(bool &changed, Result::Type addedChildType); void updateResult(bool &changed, ResultType addedChildType);
TestResultItem *intermediateFor(const TestResultItem *item) const; TestResultItem *intermediateFor(const TestResultItem *item) const;
TestResultItem *createAndAddIntermediateFor(const TestResultItem *child); TestResultItem *createAndAddIntermediateFor(const TestResultItem *child);
@@ -67,7 +67,7 @@ public:
int maxWidthOfFileName(const QFont &font); int maxWidthOfFileName(const QFont &font);
int maxWidthOfLineNumber(const QFont &font); int maxWidthOfLineNumber(const QFont &font);
int resultTypeCount(Result::Type type) const { return m_testResultCount.value(type, 0); } int resultTypeCount(ResultType type) const { return m_testResultCount.value(type, 0); }
int disabledTests() const { return m_disabled; } int disabledTests() const { return m_disabled; }
void raiseDisabledTests(int amount) { m_disabled += amount; } void raiseDisabledTests(int amount) { m_disabled += amount; }
@@ -77,7 +77,7 @@ private:
TestResultItem *findParentItemFor(const TestResultItem *item, TestResultItem *findParentItemFor(const TestResultItem *item,
const TestResultItem *startItem = nullptr) const; const TestResultItem *startItem = nullptr) const;
void updateParent(const TestResultItem *item); void updateParent(const TestResultItem *item);
QMap<Result::Type, int> m_testResultCount; QMap<ResultType, int> m_testResultCount;
int m_widthOfLineNumber = 0; int m_widthOfLineNumber = 0;
int m_maxWidthOfFileName = 0; int m_maxWidthOfFileName = 0;
int m_disabled = 0; int m_disabled = 0;
@@ -92,7 +92,7 @@ public:
explicit TestResultFilterModel(TestResultModel *sourceModel, QObject *parent = nullptr); explicit TestResultFilterModel(TestResultModel *sourceModel, QObject *parent = nullptr);
void enableAllResultTypes(); void enableAllResultTypes();
void toggleTestResultType(Result::Type type); void toggleTestResultType(ResultType type);
void clearTestResults(); void clearTestResults();
bool hasResults(); bool hasResults();
const TestResult *testResult(const QModelIndex &index) const; const TestResult *testResult(const QModelIndex &index) const;
@@ -103,7 +103,7 @@ protected:
private: private:
bool acceptTestCaseResult(const QModelIndex &srcIndex) const; bool acceptTestCaseResult(const QModelIndex &srcIndex) const;
TestResultModel *m_sourceModel; TestResultModel *m_sourceModel;
QSet<Result::Type> m_enabled; QSet<ResultType> m_enabled;
}; };
} // namespace Internal } // namespace Internal

View File

@@ -230,9 +230,9 @@ void TestResultsPane::addTestResult(const TestResultPtr &result)
m_atEnd = scrollBar ? scrollBar->value() == scrollBar->maximum() : true; m_atEnd = scrollBar ? scrollBar->value() == scrollBar->maximum() : true;
m_model->addTestResult(result, m_expandCollapse->isChecked()); m_model->addTestResult(result, m_expandCollapse->isChecked());
setIconBadgeNumber(m_model->resultTypeCount(Result::Fail) setIconBadgeNumber(m_model->resultTypeCount(ResultType::Fail)
+ m_model->resultTypeCount(Result::MessageFatal) + m_model->resultTypeCount(ResultType::MessageFatal)
+ m_model->resultTypeCount(Result::UnexpectedPass)); + m_model->resultTypeCount(ResultType::UnexpectedPass));
flash(); flash();
navigateStateChanged(); navigateStateChanged();
} }
@@ -425,24 +425,24 @@ void TestResultsPane::initializeFilterMenu()
const bool omitIntern = AutotestPlugin::settings()->omitInternalMssg; const bool omitIntern = AutotestPlugin::settings()->omitInternalMssg;
// FilterModel has all messages enabled by default // FilterModel has all messages enabled by default
if (omitIntern) if (omitIntern)
m_filterModel->toggleTestResultType(Result::MessageInternal); m_filterModel->toggleTestResultType(ResultType::MessageInternal);
QMap<Result::Type, QString> textAndType; QMap<ResultType, QString> textAndType;
textAndType.insert(Result::Pass, tr("Pass")); textAndType.insert(ResultType::Pass, tr("Pass"));
textAndType.insert(Result::Fail, tr("Fail")); textAndType.insert(ResultType::Fail, tr("Fail"));
textAndType.insert(Result::ExpectedFail, tr("Expected Fail")); textAndType.insert(ResultType::ExpectedFail, tr("Expected Fail"));
textAndType.insert(Result::UnexpectedPass, tr("Unexpected Pass")); textAndType.insert(ResultType::UnexpectedPass, tr("Unexpected Pass"));
textAndType.insert(Result::Skip, tr("Skip")); textAndType.insert(ResultType::Skip, tr("Skip"));
textAndType.insert(Result::Benchmark, tr("Benchmarks")); textAndType.insert(ResultType::Benchmark, tr("Benchmarks"));
textAndType.insert(Result::MessageDebug, tr("Debug Messages")); textAndType.insert(ResultType::MessageDebug, tr("Debug Messages"));
textAndType.insert(Result::MessageWarn, tr("Warning Messages")); textAndType.insert(ResultType::MessageWarn, tr("Warning Messages"));
textAndType.insert(Result::MessageInternal, tr("Internal Messages")); textAndType.insert(ResultType::MessageInternal, tr("Internal Messages"));
for (Result::Type result : textAndType.keys()) { for (ResultType result : textAndType.keys()) {
QAction *action = new QAction(m_filterMenu); QAction *action = new QAction(m_filterMenu);
action->setText(textAndType.value(result)); action->setText(textAndType.value(result));
action->setCheckable(true); action->setCheckable(true);
action->setChecked(result != Result::MessageInternal || !omitIntern); action->setChecked(result != ResultType::MessageInternal || !omitIntern);
action->setData(result); action->setData(int(result));
m_filterMenu->addAction(action); m_filterMenu->addAction(action);
} }
m_filterMenu->addSeparator(); m_filterMenu->addSeparator();
@@ -459,26 +459,26 @@ void TestResultsPane::updateSummaryLabel()
QString labelText = QString("<p>"); QString labelText = QString("<p>");
labelText.append(tr("Test summary")); labelText.append(tr("Test summary"));
labelText.append(":&nbsp;&nbsp; "); labelText.append(":&nbsp;&nbsp; ");
int count = m_model->resultTypeCount(Result::Pass); int count = m_model->resultTypeCount(ResultType::Pass);
labelText += QString::number(count) + ' ' + tr("passes"); labelText += QString::number(count) + ' ' + tr("passes");
count = m_model->resultTypeCount(Result::Fail); count = m_model->resultTypeCount(ResultType::Fail);
labelText += ", " + QString::number(count) + ' ' + tr("fails"); labelText += ", " + QString::number(count) + ' ' + tr("fails");
count = m_model->resultTypeCount(Result::UnexpectedPass); count = m_model->resultTypeCount(ResultType::UnexpectedPass);
if (count) if (count)
labelText += ", " + QString::number(count) + ' ' + tr("unexpected passes"); labelText += ", " + QString::number(count) + ' ' + tr("unexpected passes");
count = m_model->resultTypeCount(Result::ExpectedFail); count = m_model->resultTypeCount(ResultType::ExpectedFail);
if (count) if (count)
labelText += ", " + QString::number(count) + ' ' + tr("expected fails"); labelText += ", " + QString::number(count) + ' ' + tr("expected fails");
count = m_model->resultTypeCount(Result::MessageFatal); count = m_model->resultTypeCount(ResultType::MessageFatal);
if (count) if (count)
labelText += ", " + QString::number(count) + ' ' + tr("fatals"); labelText += ", " + QString::number(count) + ' ' + tr("fatals");
count = m_model->resultTypeCount(Result::BlacklistedFail) count = m_model->resultTypeCount(ResultType::BlacklistedFail)
+ m_model->resultTypeCount(Result::BlacklistedXFail) + m_model->resultTypeCount(ResultType::BlacklistedXFail)
+ m_model->resultTypeCount(Result::BlacklistedPass) + m_model->resultTypeCount(ResultType::BlacklistedPass)
+ m_model->resultTypeCount(Result::BlacklistedXPass); + m_model->resultTypeCount(ResultType::BlacklistedXPass);
if (count) if (count)
labelText += ", " + QString::number(count) + ' ' + tr("blacklisted"); labelText += ", " + QString::number(count) + ' ' + tr("blacklisted");
count = m_model->resultTypeCount(Result::Skip); count = m_model->resultTypeCount(ResultType::Skip);
if (count) if (count)
labelText += ", " + QString::number(count) + ' ' + tr("skipped"); labelText += ", " + QString::number(count) + ' ' + tr("skipped");
count = m_model->disabledTests(); count = m_model->disabledTests();
@@ -513,9 +513,9 @@ void TestResultsPane::onTestRunStarted()
static bool hasFailedTests(const TestResultModel *model) static bool hasFailedTests(const TestResultModel *model)
{ {
return (model->resultTypeCount(Result::Fail) > 0 return (model->resultTypeCount(ResultType::Fail) > 0
|| model->resultTypeCount(Result::MessageFatal) > 0 || model->resultTypeCount(ResultType::MessageFatal) > 0
|| model->resultTypeCount(Result::UnexpectedPass) > 0); || model->resultTypeCount(ResultType::UnexpectedPass) > 0);
} }
void TestResultsPane::onTestRunFinished() void TestResultsPane::onTestRunFinished()
@@ -658,8 +658,8 @@ 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);
Result::Type parentType = parentResult ? parentResult->result() : Result::Invalid; ResultType parentType = parentResult ? parentResult->result() : ResultType::Invalid;
const QVector<Result::Type> interested{Result::Fail, Result::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);
@@ -668,7 +668,7 @@ void TestResultsPane::createMarks(const QModelIndex &parent)
if (m_model->hasChildren(index)) if (m_model->hasChildren(index))
createMarks(index); createMarks(index);
bool isLocationItem = result->result() == Result::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))) {
const Utils::FileName fileName = Utils::FileName::fromString(result->fileName()); const Utils::FileName fileName = Utils::FileName::fromString(result->fileName());

View File

@@ -89,8 +89,7 @@ TestRunner::TestRunner(QObject *parent) :
connect(&m_futureWatcher, &QFutureWatcher<TestResultPtr>::canceled, connect(&m_futureWatcher, &QFutureWatcher<TestResultPtr>::canceled,
this, [this]() { this, [this]() {
cancelCurrent(UserCanceled); cancelCurrent(UserCanceled);
emit testResultReady(TestResultPtr(new FaultyTestResult( reportResult(ResultType::MessageFatal, tr("Test run canceled by user."));
Result::MessageFatal, tr("Test run canceled by user."))));
}); });
} }
@@ -171,8 +170,8 @@ void TestRunner::scheduleNext()
QString commandFilePath = m_currentConfig->executableFilePath(); QString commandFilePath = m_currentConfig->executableFilePath();
if (commandFilePath.isEmpty()) { if (commandFilePath.isEmpty()) {
emit testResultReady(TestResultPtr(new FaultyTestResult(Result::MessageFatal, reportResult(ResultType::MessageFatal,
tr("Executable path is empty. (%1)").arg(m_currentConfig->displayName())))); tr("Executable path is empty. (%1)").arg(m_currentConfig->displayName()));
delete m_currentConfig; delete m_currentConfig;
m_currentConfig = nullptr; m_currentConfig = nullptr;
if (m_selectedTests.isEmpty()) if (m_selectedTests.isEmpty())
@@ -200,8 +199,7 @@ void TestRunner::scheduleNext()
m_currentProcess->setArguments(m_currentConfig->argumentsForTestRunner(&omitted)); m_currentProcess->setArguments(m_currentConfig->argumentsForTestRunner(&omitted));
if (!omitted.isEmpty()) { if (!omitted.isEmpty()) {
const QString &details = constructOmittedDetailsString(omitted); const QString &details = constructOmittedDetailsString(omitted);
emit testResultReady(TestResultPtr(new FaultyTestResult(Result::MessageWarn, reportResult(ResultType::MessageWarn, details.arg(m_currentConfig->displayName()));
details.arg(m_currentConfig->displayName()))));
} }
m_currentProcess->setWorkingDirectory(m_currentConfig->workingDirectory()); m_currentProcess->setWorkingDirectory(m_currentConfig->workingDirectory());
const Utils::Environment &original = m_currentConfig->environment(); const Utils::Environment &original = m_currentConfig->environment();
@@ -213,7 +211,7 @@ void TestRunner::scheduleNext()
if (!removedVariables.isEmpty()) { if (!removedVariables.isEmpty()) {
const QString &details = constructOmittedVariablesDetailsString(removedVariables) const QString &details = constructOmittedVariablesDetailsString(removedVariables)
.arg(m_currentConfig->displayName()); .arg(m_currentConfig->displayName());
emit testResultReady(TestResultPtr(new FaultyTestResult(Result::MessageWarn, details))); reportResult(ResultType::MessageWarn, details);
} }
m_currentProcess->setProcessEnvironment(environment.toProcessEnvironment()); m_currentProcess->setProcessEnvironment(environment.toProcessEnvironment());
@@ -224,9 +222,9 @@ void TestRunner::scheduleNext()
m_currentProcess->start(); m_currentProcess->start();
if (!m_currentProcess->waitForStarted()) { if (!m_currentProcess->waitForStarted()) {
emit testResultReady(TestResultPtr(new FaultyTestResult(Result::MessageFatal, reportResult(ResultType::MessageFatal,
tr("Failed to start test for project \"%1\".").arg(m_currentConfig->displayName()) tr("Failed to start test for project \"%1\".").arg(m_currentConfig->displayName())
+ processInformation(m_currentProcess) + rcInfo(m_currentConfig)))); + processInformation(m_currentProcess) + rcInfo(m_currentConfig));
} }
} }
@@ -237,14 +235,10 @@ void TestRunner::cancelCurrent(TestRunner::CancelReason reason)
if (m_fakeFutureInterface) if (m_fakeFutureInterface)
m_fakeFutureInterface->reportCanceled(); m_fakeFutureInterface->reportCanceled();
auto reportResult = [this](Result::Type type, const QString &detail){
emit testResultReady(TestResultPtr(new FaultyTestResult(type, detail)));
};
if (reason == KitChanged) if (reason == KitChanged)
reportResult(Result::MessageWarn, tr("Current kit has changed. Canceling test run.")); reportResult(ResultType::MessageWarn, tr("Current kit has changed. Canceling test run."));
else if (reason == Timeout) else if (reason == Timeout)
reportResult(Result::MessageFatal, tr("Test case canceled due to timeout.\nMaybe raise the timeout?")); reportResult(ResultType::MessageFatal, tr("Test case canceled due to timeout.\nMaybe raise the timeout?"));
// if user or timeout cancels the current run ensure to kill the running process // if user or timeout cancels the current run ensure to kill the running process
if (m_currentProcess && m_currentProcess->state() != QProcess::NotRunning) { if (m_currentProcess && m_currentProcess->state() != QProcess::NotRunning) {
@@ -262,14 +256,14 @@ void TestRunner::onProcessFinished()
if (!m_fakeFutureInterface->isCanceled()) { if (!m_fakeFutureInterface->isCanceled()) {
if (m_currentProcess->exitStatus() == QProcess::CrashExit) { if (m_currentProcess->exitStatus() == QProcess::CrashExit) {
m_currentOutputReader->reportCrash(); m_currentOutputReader->reportCrash();
emit testResultReady(TestResultPtr(new FaultyTestResult(Result::MessageFatal, reportResult(ResultType::MessageFatal,
tr("Test for project \"%1\" crashed.").arg(m_currentConfig->displayName()) tr("Test for project \"%1\" crashed.").arg(m_currentConfig->displayName())
+ processInformation(m_currentProcess) + rcInfo(m_currentConfig)))); + processInformation(m_currentProcess) + rcInfo(m_currentConfig));
} else if (!m_currentOutputReader->hadValidOutput()) { } else if (!m_currentOutputReader->hadValidOutput()) {
emit testResultReady(TestResultPtr(new FaultyTestResult(Result::MessageFatal, reportResult(ResultType::MessageFatal,
tr("Test for project \"%1\" did not produce any expected output.") tr("Test for project \"%1\" did not produce any expected output.")
.arg(m_currentConfig->displayName()) + processInformation(m_currentProcess) .arg(m_currentConfig->displayName()) + processInformation(m_currentProcess)
+ rcInfo(m_currentConfig)))); + rcInfo(m_currentConfig));
} }
} }
} }
@@ -317,18 +311,17 @@ void TestRunner::prepareToRunTests(TestRunMode mode)
TestResultsPane::instance()->clearContents(); TestResultsPane::instance()->clearContents();
if (m_selectedTests.empty()) { if (m_selectedTests.empty()) {
emit testResultReady(TestResultPtr(new FaultyTestResult(Result::MessageWarn, reportResult(ResultType::MessageWarn, tr("No tests selected. Canceling test run."));
tr("No tests selected. Canceling test run."))));
onFinished(); onFinished();
return; return;
} }
ProjectExplorer::Project *project = m_selectedTests.at(0)->project(); ProjectExplorer::Project *project = m_selectedTests.at(0)->project();
if (!project) { if (!project) {
emit testResultReady(TestResultPtr(new FaultyTestResult(Result::MessageWarn, reportResult(ResultType::MessageWarn,
tr("Project is null. Canceling test run.\n" tr("Project is null. Canceling test run.\n"
"Only desktop kits are supported. Make sure the " "Only desktop kits are supported. Make sure the "
"currently active kit is a desktop kit.")))); "currently active kit is a desktop kit."));
onFinished(); onFinished();
return; return;
} }
@@ -342,8 +335,8 @@ void TestRunner::prepareToRunTests(TestRunMode mode)
} else if (project->hasActiveBuildSettings()) { } else if (project->hasActiveBuildSettings()) {
buildProject(project); buildProject(project);
} else { } else {
emit testResultReady(TestResultPtr(new FaultyTestResult(Result::MessageFatal, reportResult(ResultType::MessageFatal,
tr("Project is not configured. Canceling test run.")))); tr("Project is not configured. Canceling test run."));
onFinished(); onFinished();
} }
} }
@@ -416,13 +409,12 @@ int TestRunner::precheckTestConfigurations()
"This might cause trouble during execution.\n" "This might cause trouble during execution.\n"
"(deduced from \"%2\")"); "(deduced from \"%2\")");
message = message.arg(config->displayName()).arg(config->runConfigDisplayName()); message = message.arg(config->displayName()).arg(config->runConfigDisplayName());
emit testResultReady( reportResult(ResultType::MessageWarn, message);
TestResultPtr(new FaultyTestResult(Result::MessageWarn, message)));
} }
} else { } else {
emit testResultReady(TestResultPtr(new FaultyTestResult(Result::MessageWarn, reportResult(ResultType::MessageWarn,
tr("Project is null for \"%1\". Removing from test run.\n" tr("Project is null for \"%1\". Removing from test run.\n"
"Check the test environment.").arg(config->displayName())))); "Check the test environment.").arg(config->displayName()));
} }
} }
return testCaseCount; return testCaseCount;
@@ -452,7 +444,7 @@ void TestRunner::runTests()
QString mssg = projectChanged ? tr("Startup project has changed. Canceling test run.") QString mssg = projectChanged ? tr("Startup project has changed. Canceling test run.")
: tr("No test cases left for execution. Canceling test run."); : tr("No test cases left for execution. Canceling test run.");
emit testResultReady(TestResultPtr(new FaultyTestResult(Result::MessageWarn, mssg))); reportResult(ResultType::MessageWarn, mssg);
onFinished(); onFinished();
return; return;
} }
@@ -518,8 +510,8 @@ void TestRunner::debugTests()
TestConfiguration *config = m_selectedTests.first(); TestConfiguration *config = m_selectedTests.first();
config->completeTestInformation(TestRunMode::Debug); config->completeTestInformation(TestRunMode::Debug);
if (!config->project()) { if (!config->project()) {
emit testResultReady(TestResultPtr(new FaultyTestResult(Result::MessageWarn, reportResult(ResultType::MessageWarn,
TestRunner::tr("Startup project has changed. Canceling test run.")))); tr("Startup project has changed. Canceling test run."));
onFinished(); onFinished();
return; return;
} }
@@ -529,18 +521,16 @@ void TestRunner::debugTests()
} }
if (!config->runConfiguration()) { if (!config->runConfiguration()) {
emit testResultReady(TestResultPtr(new FaultyTestResult(Result::MessageFatal, reportResult(ResultType::MessageFatal, tr("Failed to get run configuration."));
TestRunner::tr("Failed to get run configuration."))));
onFinished(); onFinished();
return; return;
} }
const QString &commandFilePath = config->executableFilePath(); const QString &commandFilePath = config->executableFilePath();
if (commandFilePath.isEmpty()) { if (commandFilePath.isEmpty()) {
emit testResultReady(TestResultPtr(new FaultyTestResult(Result::MessageFatal, reportResult(ResultType::MessageFatal, tr("Could not find command \"%1\". (%2)")
TestRunner::tr("Could not find command \"%1\". (%2)")
.arg(config->executableFilePath()) .arg(config->executableFilePath())
.arg(config->displayName())))); .arg(config->displayName()));
onFinished(); onFinished();
return; return;
} }
@@ -548,6 +538,12 @@ void TestRunner::debugTests()
QString errorMessage; QString errorMessage;
auto runControl = new ProjectExplorer::RunControl(ProjectExplorer::Constants::DEBUG_RUN_MODE); auto runControl = new ProjectExplorer::RunControl(ProjectExplorer::Constants::DEBUG_RUN_MODE);
runControl->setRunConfiguration(config->runConfiguration()); runControl->setRunConfiguration(config->runConfiguration());
if (!runControl) {
reportResult(ResultType::MessageFatal,
tr("Failed to create run configuration.\n%1").arg(errorMessage));
onFinished();
return;
}
QStringList omitted; QStringList omitted;
ProjectExplorer::Runnable inferior = config->runnable(); ProjectExplorer::Runnable inferior = config->runnable();
@@ -557,8 +553,7 @@ void TestRunner::debugTests()
inferior.commandLineArguments = Utils::QtcProcess::joinArgs(args); inferior.commandLineArguments = Utils::QtcProcess::joinArgs(args);
if (!omitted.isEmpty()) { if (!omitted.isEmpty()) {
const QString &details = constructOmittedDetailsString(omitted); const QString &details = constructOmittedDetailsString(omitted);
emit testResultReady(TestResultPtr(new FaultyTestResult(Result::MessageWarn, reportResult(ResultType::MessageWarn, details.arg(config->displayName()));
details.arg(config->displayName()))));
} }
Utils::Environment original(inferior.environment); Utils::Environment original(inferior.environment);
inferior.environment = config->filteredEnvironment(original); inferior.environment = config->filteredEnvironment(original);
@@ -569,7 +564,7 @@ void TestRunner::debugTests()
if (!removedVariables.isEmpty()) { if (!removedVariables.isEmpty()) {
const QString &details = constructOmittedVariablesDetailsString(removedVariables) const QString &details = constructOmittedVariablesDetailsString(removedVariables)
.arg(config->displayName()); .arg(config->displayName());
emit testResultReady(TestResultPtr(new FaultyTestResult(Result::MessageWarn, details))); reportResult(ResultType::MessageWarn, details);
} }
auto debugger = new Debugger::DebuggerRunTool(runControl); auto debugger = new Debugger::DebuggerRunTool(runControl);
debugger->setInferior(inferior); debugger->setInferior(inferior);
@@ -578,8 +573,8 @@ void TestRunner::debugTests()
bool useOutputProcessor = true; bool useOutputProcessor = true;
if (ProjectExplorer::Target *targ = config->project()->activeTarget()) { if (ProjectExplorer::Target *targ = config->project()->activeTarget()) {
if (Debugger::DebuggerKitAspect::engineType(targ->kit()) == Debugger::CdbEngineType) { if (Debugger::DebuggerKitAspect::engineType(targ->kit()) == Debugger::CdbEngineType) {
emit testResultReady(TestResultPtr(new FaultyTestResult(Result::MessageWarn, reportResult(ResultType::MessageWarn,
TestRunner::tr("Unable to display test results when using CDB.")))); tr("Unable to display test results when using CDB."));
useOutputProcessor = false; useOutputProcessor = false;
} }
} }
@@ -653,8 +648,7 @@ void TestRunner::buildFinished(bool success)
else if (m_executingTests) else if (m_executingTests)
onFinished(); onFinished();
} else { } else {
emit testResultReady(TestResultPtr(new FaultyTestResult(Result::MessageFatal, reportResult(ResultType::MessageFatal, tr("Build failed. Canceling test run."));
tr("Build failed. Canceling test run."))));
onFinished(); onFinished();
} }
} }
@@ -672,6 +666,14 @@ void TestRunner::onFinished()
emit testRunFinished(); emit testRunFinished();
} }
void TestRunner::reportResult(ResultType type, const QString &description)
{
TestResultPtr result(new TestResult);
result->setResult(type);
result->setDescription(description);
emit testResultReady(result);
}
/*************************************************************************************************/ /*************************************************************************************************/
static QFrame *createLine(QWidget *parent) static QFrame *createLine(QWidget *parent)

View File

@@ -86,6 +86,7 @@ private:
void runTests(); void runTests();
void debugTests(); void debugTests();
void runOrDebugTests(); void runOrDebugTests();
void reportResult(ResultType type, const QString &description);
explicit TestRunner(QObject *parent = nullptr); explicit TestRunner(QObject *parent = nullptr);
QFutureWatcher<TestResultPtr> m_futureWatcher; QFutureWatcher<TestResultPtr> m_futureWatcher;