AutoTest: Create tree item for each failure

Introduce special location item for this purpose.

Task-number: QTCREATORBUG-20967
Change-Id: Icb6c6ec8ff9d2e4e8e3d13834427bae50d74bd2a
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
Sergey Morozov
2018-08-18 21:48:34 +03:00
parent fa4693fd29
commit db85693690
6 changed files with 40 additions and 17 deletions

View File

@@ -144,7 +144,7 @@ void GTestOutputReader::processOutput(const QByteArray &outputLine)
TestResultPtr testResult = createDefaultResult();
testResult->setResult(Result::Fail);
m_description.chop(1);
testResult->setDescription(m_description);
QStringList resultDescription;
for (const QString &output : m_description.split('\n')) {
QRegExp *match = nullptr;
@@ -152,17 +152,23 @@ void GTestOutputReader::processOutput(const QByteArray &outputLine)
match = &failureLocation;
else if (errorLocation.exactMatch(output))
match = &errorLocation;
if (match) {
testResult->setLine(match->cap(2).toInt());
QString file = constructSourceFilePath(m_buildDir, match->cap(1));
if (!file.isEmpty())
testResult->setFileName(file);
break;
if (!match) {
resultDescription << output;
continue;
}
testResult->setDescription(resultDescription.join('\n'));
reportResult(testResult);
resultDescription.clear();
testResult = createDefaultResult();
testResult->setResult(Result::MessageLocation);
testResult->setLine(match->cap(2).toInt());
QString file = constructSourceFilePath(m_buildDir, match->cap(1));
if (!file.isEmpty())
testResult->setFileName(file);
resultDescription << output;
}
testResult->setDescription(resultDescription.join('\n'));
reportResult(testResult);
m_description.clear();
testResult = createDefaultResult();

View File

@@ -69,8 +69,11 @@ bool GTestResult::isDirectParentOf(const TestResult *other, bool *needsIntermedi
return false;
const GTestResult *gtOther = static_cast<const GTestResult *>(other);
if (m_testSetName == gtOther->m_testSetName && other->result() == Result::MessageInternal)
return true;
if (m_testSetName == gtOther->m_testSetName) {
const Result::Type otherResult = other->result();
if (otherResult == Result::MessageInternal || otherResult == Result::MessageLocation)
return result() != Result::MessageLocation;
}
if (m_iteration != gtOther->m_iteration)
return false;
return isTest() && gtOther->isTestSet();

View File

@@ -136,6 +136,8 @@ QString TestResult::resultToString(const Result::Type type)
return QString("BPASS");
case Result::BlacklistedFail:
return QString("BFAIL");
case Result::MessageLocation:
return QString();
default:
if (type >= Result::INTERNAL_MESSAGES_BEGIN && type <= Result::INTERNAL_MESSAGES_END)
return QString();

View File

@@ -52,6 +52,7 @@ enum Type {
MessageWarn,
MessageFatal,
MessageSystem,
MessageLocation,
MessageInternal, INTERNAL_MESSAGES_BEGIN = MessageInternal,
MessageDisabledTests,

View File

@@ -57,6 +57,7 @@ static QIcon testResultIcon(Result::Type result) {
Icons::RESULT_MESSAGEWARN.icon(),
Icons::RESULT_MESSAGEFATAL.icon(),
Icons::RESULT_MESSAGEFATAL.icon(), // System gets same handling as Fatal for now
QIcon(),
Icons::RESULT_MESSAGEPASSWARN.icon(),
Icons::RESULT_MESSAGEFAILWARN.icon(),
}; // provide an icon for unknown??
@@ -81,8 +82,14 @@ static QIcon testResultIcon(Result::Type result) {
QVariant TestResultItem::data(int column, int role) const
{
switch (role) {
case Qt::DecorationRole:
return m_testResult ? testResultIcon(m_testResult->result()) : QVariant();
case Qt::DecorationRole: {
if (!m_testResult)
return QVariant();
const Result::Type result = m_testResult->result();
if (result == Result::MessageLocation && parent())
return parent()->data(column, role);
return testResultIcon(result);
}
case Qt::DisplayRole:
return m_testResult ? m_testResult->outputString(true) : QVariant();
default:
@@ -354,7 +361,7 @@ void TestResultFilterModel::enableAllResultTypes()
{
m_enabled << Result::Pass << Result::Fail << Result::ExpectedFail
<< Result::UnexpectedPass << Result::Skip << Result::MessageDebug
<< Result::MessageWarn << Result::MessageInternal
<< Result::MessageWarn << Result::MessageInternal << Result::MessageLocation
<< Result::MessageFatal << Result::Invalid << Result::BlacklistedPass
<< Result::BlacklistedFail << Result::Benchmark << Result::MessageIntermediate
<< Result::MessageCurrentTest << Result::MessageTestCaseStart

View File

@@ -637,6 +637,9 @@ QString TestResultsPane::getWholeOutput(const QModelIndex &parent)
void TestResultsPane::createMarks(const QModelIndex &parent)
{
const TestResult *parentResult = m_model->testResult(parent);
Result::Type parentType = parentResult ? parentResult->result() : Result::Invalid;
const QVector<Result::Type> interested{Result::Fail, Result::UnexpectedPass};
for (int row = 0, count = m_model->rowCount(parent); row < count; ++row) {
const QModelIndex index = m_model->index(row, 0, parent);
const TestResult *result = m_model->testResult(index);
@@ -645,8 +648,9 @@ void TestResultsPane::createMarks(const QModelIndex &parent)
if (m_model->hasChildren(index))
createMarks(index);
const QVector<Result::Type> interested{Result::Fail, Result::UnexpectedPass};
if (interested.contains(result->result())) {
bool isLocationItem = result->result() == Result::MessageLocation;
if (interested.contains(result->result())
|| (isLocationItem && interested.contains(parentType))) {
const Utils::FileName fileName = Utils::FileName::fromString(result->fileName());
TestEditorMark *mark = new TestEditorMark(index, fileName, result->line());
mark->setIcon(index.data(Qt::DecorationRole).value<QIcon>());