2014-10-07 15:51:02 +02:00
|
|
|
/****************************************************************************
|
|
|
|
|
**
|
2016-01-22 10:37:55 +01:00
|
|
|
** Copyright (C) 2016 The Qt Company Ltd.
|
|
|
|
|
** Contact: https://www.qt.io/licensing/
|
2014-10-07 15:51:02 +02:00
|
|
|
**
|
2016-01-22 10:37:55 +01:00
|
|
|
** This file is part of Qt Creator.
|
2014-10-07 15:51:02 +02:00
|
|
|
**
|
2016-01-22 10:37:55 +01:00
|
|
|
** Commercial License Usage
|
|
|
|
|
** Licensees holding valid commercial Qt licenses may use this file in
|
|
|
|
|
** accordance with the commercial license agreement provided with the
|
2014-10-07 15:51:02 +02:00
|
|
|
** Software or, alternatively, in accordance with the terms contained in
|
2016-01-22 10:37:55 +01:00
|
|
|
** a written agreement between you and The Qt Company. For licensing terms
|
|
|
|
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
|
|
|
|
** information use the contact form at https://www.qt.io/contact-us.
|
2014-10-07 15:51:02 +02:00
|
|
|
**
|
2016-01-22 10:37:55 +01:00
|
|
|
** GNU General Public License Usage
|
|
|
|
|
** Alternatively, this file may be used under the terms of the GNU
|
|
|
|
|
** General Public License version 3 as published by the Free Software
|
|
|
|
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
|
|
|
|
** included in the packaging of this file. Please review the following
|
|
|
|
|
** information to ensure the GNU General Public License requirements will
|
|
|
|
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
2014-10-07 15:51:02 +02:00
|
|
|
**
|
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
2016-11-03 16:35:55 +01:00
|
|
|
#include "autotesticons.h"
|
2019-02-01 12:24:56 +01:00
|
|
|
#include "autotestplugin.h"
|
2016-02-29 09:56:30 +01:00
|
|
|
#include "testresultdelegate.h"
|
2014-10-07 15:51:02 +02:00
|
|
|
#include "testresultmodel.h"
|
2019-02-01 12:24:56 +01:00
|
|
|
#include "testsettings.h"
|
2014-10-07 15:51:02 +02:00
|
|
|
|
2019-02-01 12:24:56 +01:00
|
|
|
#include <projectexplorer/projectexplorericons.h>
|
2016-05-04 16:41:15 +02:00
|
|
|
#include <utils/qtcassert.h>
|
|
|
|
|
|
2014-10-07 15:51:02 +02:00
|
|
|
#include <QFontMetrics>
|
|
|
|
|
#include <QIcon>
|
|
|
|
|
|
|
|
|
|
namespace Autotest {
|
|
|
|
|
namespace Internal {
|
|
|
|
|
|
2015-08-20 15:59:15 +02:00
|
|
|
/********************************* TestResultItem ******************************************/
|
2014-10-07 15:51:02 +02:00
|
|
|
|
2016-02-25 13:02:31 +01:00
|
|
|
TestResultItem::TestResultItem(const TestResultPtr &testResult)
|
2015-08-20 15:59:15 +02:00
|
|
|
: m_testResult(testResult)
|
2014-10-07 15:51:02 +02:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-08 13:46:28 +01:00
|
|
|
static QIcon testResultIcon(Result::Type result) {
|
2016-11-03 16:35:55 +01:00
|
|
|
const static QIcon icons[] = {
|
|
|
|
|
Icons::RESULT_PASS.icon(),
|
|
|
|
|
Icons::RESULT_FAIL.icon(),
|
|
|
|
|
Icons::RESULT_XFAIL.icon(),
|
|
|
|
|
Icons::RESULT_XPASS.icon(),
|
|
|
|
|
Icons::RESULT_SKIP.icon(),
|
|
|
|
|
Icons::RESULT_BLACKLISTEDPASS.icon(),
|
|
|
|
|
Icons::RESULT_BLACKLISTEDFAIL.icon(),
|
2019-01-24 08:53:31 +01:00
|
|
|
Icons::RESULT_BLACKLISTEDXPASS.icon(),
|
|
|
|
|
Icons::RESULT_BLACKLISTEDXFAIL.icon(),
|
2016-11-03 16:35:55 +01:00
|
|
|
Icons::RESULT_BENCHMARK.icon(),
|
|
|
|
|
Icons::RESULT_MESSAGEDEBUG.icon(),
|
|
|
|
|
Icons::RESULT_MESSAGEDEBUG.icon(), // Info gets the same handling as Debug for now
|
|
|
|
|
Icons::RESULT_MESSAGEWARN.icon(),
|
|
|
|
|
Icons::RESULT_MESSAGEFATAL.icon(),
|
|
|
|
|
Icons::RESULT_MESSAGEFATAL.icon(), // System gets same handling as Fatal for now
|
2018-08-18 21:48:34 +03:00
|
|
|
QIcon(),
|
2017-07-10 15:02:24 +02:00
|
|
|
Icons::RESULT_MESSAGEPASSWARN.icon(),
|
|
|
|
|
Icons::RESULT_MESSAGEFAILWARN.icon(),
|
2019-02-01 12:24:56 +01:00
|
|
|
ProjectExplorer::Icons::DESKTOP_DEVICE.icon(), // for now
|
2014-10-21 13:10:37 +02:00
|
|
|
}; // provide an icon for unknown??
|
2014-10-07 15:51:02 +02:00
|
|
|
|
2015-12-07 08:26:54 +01:00
|
|
|
if (result < 0 || result >= Result::MessageInternal) {
|
2015-08-20 15:59:15 +02:00
|
|
|
switch (result) {
|
2015-12-07 08:26:54 +01:00
|
|
|
case Result::MessageTestCaseSuccess:
|
|
|
|
|
return icons[Result::Pass];
|
|
|
|
|
case Result::MessageTestCaseFail:
|
|
|
|
|
return icons[Result::Fail];
|
2017-07-10 15:02:24 +02:00
|
|
|
case Result::MessageTestCaseSuccessWarn:
|
2019-01-24 08:53:31 +01:00
|
|
|
return icons[16];
|
2018-09-28 09:10:03 +02:00
|
|
|
case Result::MessageTestCaseFailWarn:
|
2019-01-24 08:53:31 +01:00
|
|
|
return icons[17];
|
2019-02-01 12:24:56 +01:00
|
|
|
case Result::Application:
|
|
|
|
|
return icons[18];
|
2015-08-20 15:59:15 +02:00
|
|
|
default:
|
|
|
|
|
return QIcon();
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-10-07 15:51:02 +02:00
|
|
|
return icons[result];
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-20 15:59:15 +02:00
|
|
|
QVariant TestResultItem::data(int column, int role) const
|
2014-10-07 15:51:02 +02:00
|
|
|
{
|
2016-02-29 09:56:30 +01:00
|
|
|
switch (role) {
|
2018-08-18 21:48:34 +03:00
|
|
|
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);
|
|
|
|
|
}
|
2016-02-29 09:56:30 +01:00
|
|
|
case Qt::DisplayRole:
|
2016-04-13 10:20:17 +02:00
|
|
|
return m_testResult ? m_testResult->outputString(true) : QVariant();
|
2016-02-29 09:56:30 +01:00
|
|
|
default:
|
|
|
|
|
return Utils::TreeItem::data(column, role);
|
|
|
|
|
}
|
2015-08-20 15:59:15 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TestResultItem::updateDescription(const QString &description)
|
|
|
|
|
{
|
|
|
|
|
QTC_ASSERT(m_testResult, return);
|
|
|
|
|
|
|
|
|
|
m_testResult->setDescription(description);
|
|
|
|
|
}
|
|
|
|
|
|
2017-12-13 13:10:00 +01:00
|
|
|
void TestResultItem::updateResult(bool &changed, Result::Type addedChildType)
|
2015-08-20 15:59:15 +02:00
|
|
|
{
|
2017-12-13 13:10:00 +01:00
|
|
|
changed = false;
|
|
|
|
|
const Result::Type old = m_testResult->result();
|
|
|
|
|
if (old == Result::MessageTestCaseFailWarn) // can't become worse
|
|
|
|
|
return;
|
|
|
|
|
if (!TestResult::isMessageCaseStart(old))
|
2015-08-20 15:59:15 +02:00
|
|
|
return;
|
|
|
|
|
|
2015-12-07 08:26:54 +01:00
|
|
|
Result::Type newResult = Result::MessageTestCaseSuccess;
|
2017-12-13 13:10:00 +01:00
|
|
|
switch (addedChildType) {
|
|
|
|
|
case Result::Fail:
|
|
|
|
|
case Result::MessageFatal:
|
|
|
|
|
case Result::UnexpectedPass:
|
|
|
|
|
case Result::MessageTestCaseFail:
|
|
|
|
|
newResult = (old == Result::MessageTestCaseSuccessWarn) ? Result::MessageTestCaseFailWarn
|
|
|
|
|
: Result::MessageTestCaseFail;
|
|
|
|
|
break;
|
|
|
|
|
case Result::MessageTestCaseFailWarn:
|
|
|
|
|
newResult = Result::MessageTestCaseFailWarn;
|
|
|
|
|
break;
|
|
|
|
|
case Result::ExpectedFail:
|
|
|
|
|
case Result::MessageWarn:
|
2018-02-13 10:54:28 +01:00
|
|
|
case Result::MessageSystem:
|
2017-12-13 13:10:00 +01:00
|
|
|
case Result::Skip:
|
|
|
|
|
case Result::BlacklistedFail:
|
|
|
|
|
case Result::BlacklistedPass:
|
2019-01-24 08:53:31 +01:00
|
|
|
case Result::BlacklistedXFail:
|
|
|
|
|
case Result::BlacklistedXPass:
|
2017-12-13 13:10:00 +01:00
|
|
|
case Result::MessageTestCaseSuccessWarn:
|
|
|
|
|
newResult = (old == Result::MessageTestCaseFail) ? Result::MessageTestCaseFailWarn
|
|
|
|
|
: Result::MessageTestCaseSuccessWarn;
|
|
|
|
|
break;
|
|
|
|
|
case Result::Pass:
|
|
|
|
|
case Result::MessageTestCaseSuccess:
|
|
|
|
|
newResult = (old == Result::MessageIntermediate || old == Result::MessageTestCaseStart)
|
|
|
|
|
? Result::MessageTestCaseSuccess : old;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
2019-01-31 15:45:28 +01:00
|
|
|
break;
|
2014-10-07 15:51:02 +02:00
|
|
|
}
|
2017-12-13 13:10:00 +01:00
|
|
|
changed = old != newResult;
|
|
|
|
|
if (changed)
|
2017-07-10 15:02:24 +02:00
|
|
|
m_testResult->setResult(newResult);
|
2016-10-31 13:11:52 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TestResultItem *TestResultItem::intermediateFor(const TestResultItem *item) const
|
|
|
|
|
{
|
|
|
|
|
QTC_ASSERT(item, return nullptr);
|
|
|
|
|
const TestResult *otherResult = item->testResult();
|
|
|
|
|
for (int row = childCount() - 1; row >= 0; --row) {
|
2019-02-06 08:57:33 +01:00
|
|
|
TestResultItem *child = childAt(row);
|
2016-10-31 13:11:52 +01:00
|
|
|
const TestResult *testResult = child->testResult();
|
|
|
|
|
if (testResult->result() != Result::MessageIntermediate)
|
|
|
|
|
continue;
|
|
|
|
|
if (testResult->isIntermediateFor(otherResult))
|
|
|
|
|
return child;
|
|
|
|
|
}
|
2017-02-13 10:05:06 +01:00
|
|
|
return nullptr;
|
2016-10-31 13:11:52 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TestResultItem *TestResultItem::createAndAddIntermediateFor(const TestResultItem *child)
|
|
|
|
|
{
|
|
|
|
|
TestResultPtr result(m_testResult->createIntermediateResultFor(child->testResult()));
|
2017-02-13 10:05:06 +01:00
|
|
|
QTC_ASSERT(!result.isNull(), return nullptr);
|
2016-10-31 13:11:52 +01:00
|
|
|
result->setResult(Result::MessageIntermediate);
|
|
|
|
|
TestResultItem *intermediate = new TestResultItem(result);
|
|
|
|
|
appendChild(intermediate);
|
|
|
|
|
return intermediate;
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-20 15:59:15 +02:00
|
|
|
/********************************* TestResultModel *****************************************/
|
|
|
|
|
|
|
|
|
|
TestResultModel::TestResultModel(QObject *parent)
|
2019-02-06 08:57:33 +01:00
|
|
|
: Utils::TreeModel<TestResultItem>(new TestResultItem(TestResultPtr()), parent)
|
2015-08-20 15:59:15 +02:00
|
|
|
{
|
2014-10-07 15:51:02 +02:00
|
|
|
}
|
|
|
|
|
|
2017-12-13 13:10:00 +01:00
|
|
|
void TestResultModel::updateParent(const TestResultItem *item)
|
|
|
|
|
{
|
|
|
|
|
QTC_ASSERT(item, return);
|
|
|
|
|
QTC_ASSERT(item->testResult(), return);
|
2019-02-06 08:57:33 +01:00
|
|
|
TestResultItem *parentItem = item->parent();
|
2017-12-13 13:10:00 +01:00
|
|
|
if (parentItem == rootItem()) // do not update invisible root item
|
|
|
|
|
return;
|
|
|
|
|
bool changed = false;
|
2019-02-06 08:57:33 +01:00
|
|
|
parentItem->updateResult(changed, item->testResult()->result());
|
2017-12-13 13:10:00 +01:00
|
|
|
if (!changed)
|
|
|
|
|
return;
|
|
|
|
|
emit dataChanged(parentItem->index(), parentItem->index());
|
2019-02-06 08:57:33 +01:00
|
|
|
updateParent(parentItem);
|
2017-12-13 13:10:00 +01:00
|
|
|
}
|
|
|
|
|
|
2016-02-25 13:02:31 +01:00
|
|
|
void TestResultModel::addTestResult(const TestResultPtr &testResult, bool autoExpand)
|
2015-08-20 15:59:15 +02:00
|
|
|
{
|
2016-10-31 13:11:52 +01:00
|
|
|
const int lastRow = rootItem()->childCount() - 1;
|
2016-10-31 10:32:34 +01:00
|
|
|
if (testResult->result() == Result::MessageCurrentTest) {
|
2015-12-07 08:26:54 +01:00
|
|
|
// MessageCurrentTest should always be the last top level item
|
2015-08-20 15:59:15 +02:00
|
|
|
if (lastRow >= 0) {
|
2019-02-06 08:57:33 +01:00
|
|
|
TestResultItem *current = rootItem()->childAt(lastRow);
|
2015-08-20 15:59:15 +02:00
|
|
|
const TestResult *result = current->testResult();
|
2015-12-07 08:26:54 +01:00
|
|
|
if (result && result->result() == Result::MessageCurrentTest) {
|
2015-08-20 15:59:15 +02:00
|
|
|
current->updateDescription(testResult->description());
|
|
|
|
|
emit dataChanged(current->index(), current->index());
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-09 07:52:15 +01:00
|
|
|
rootItem()->appendChild(new TestResultItem(testResult));
|
2015-08-20 15:59:15 +02:00
|
|
|
return;
|
2014-12-05 14:01:16 +01:00
|
|
|
}
|
|
|
|
|
|
2016-10-31 10:32:34 +01:00
|
|
|
if (testResult->result() == Result::MessageDisabledTests)
|
|
|
|
|
m_disabled += testResult->line();
|
|
|
|
|
m_testResultCount[testResult->result()]++;
|
|
|
|
|
|
2015-12-09 07:52:15 +01:00
|
|
|
TestResultItem *newItem = new TestResultItem(testResult);
|
2019-02-01 12:24:56 +01:00
|
|
|
|
|
|
|
|
TestResultItem *root = nullptr;
|
|
|
|
|
if (AutotestPlugin::settings()->displayApplication) {
|
|
|
|
|
const QString application = testResult->id();
|
|
|
|
|
if (!application.isEmpty()) {
|
2019-02-06 08:57:33 +01:00
|
|
|
root = rootItem()->findFirstLevelChild([&application](TestResultItem *child) {
|
|
|
|
|
QTC_ASSERT(child, return false);
|
|
|
|
|
return child->testResult()->id() == application;
|
|
|
|
|
});
|
|
|
|
|
|
2019-02-01 12:24:56 +01:00
|
|
|
if (!root) {
|
|
|
|
|
TestResult *tmpAppResult = new TestResult(application, application);
|
|
|
|
|
tmpAppResult->setResult(Result::Application);
|
|
|
|
|
root = new TestResultItem(TestResultPtr(tmpAppResult));
|
|
|
|
|
if (lastRow >= 0)
|
|
|
|
|
rootItem()->insertChild(lastRow, root);
|
|
|
|
|
else
|
|
|
|
|
rootItem()->appendChild(root);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TestResultItem *parentItem = findParentItemFor(newItem, root);
|
2016-10-31 13:11:52 +01:00
|
|
|
addFileName(testResult->fileName()); // ensure we calculate the results pane correctly
|
|
|
|
|
if (parentItem) {
|
|
|
|
|
parentItem->appendChild(newItem);
|
|
|
|
|
if (autoExpand)
|
|
|
|
|
parentItem->expand();
|
2017-12-13 13:10:00 +01:00
|
|
|
updateParent(newItem);
|
2016-10-31 13:11:52 +01:00
|
|
|
} else {
|
|
|
|
|
if (lastRow >= 0) {
|
2019-02-06 08:57:33 +01:00
|
|
|
TestResultItem *current = rootItem()->childAt(lastRow);
|
2015-12-09 09:46:33 +01:00
|
|
|
const TestResult *result = current->testResult();
|
2016-10-31 13:11:52 +01:00
|
|
|
if (result && result->result() == Result::MessageCurrentTest) {
|
|
|
|
|
rootItem()->insertChild(current->index().row(), newItem);
|
2015-12-09 09:46:33 +01:00
|
|
|
return;
|
2015-08-20 15:59:15 +02:00
|
|
|
}
|
|
|
|
|
}
|
2016-10-31 13:11:52 +01:00
|
|
|
// there is no MessageCurrentTest at the last row, but we have a toplevel item - just add it
|
|
|
|
|
rootItem()->appendChild(newItem);
|
2014-12-05 14:01:16 +01:00
|
|
|
}
|
2014-10-07 15:51:02 +02:00
|
|
|
}
|
|
|
|
|
|
2014-12-05 14:01:16 +01:00
|
|
|
void TestResultModel::removeCurrentTestMessage()
|
|
|
|
|
{
|
2019-02-06 08:57:33 +01:00
|
|
|
TestResultItem *currentMessageItem = rootItem()->findFirstLevelChild([](TestResultItem *it) {
|
|
|
|
|
return (it->testResult()->result() == Result::MessageCurrentTest);
|
|
|
|
|
});
|
|
|
|
|
if (currentMessageItem)
|
|
|
|
|
destroyItem(currentMessageItem);
|
2014-12-05 14:01:16 +01:00
|
|
|
}
|
|
|
|
|
|
2014-10-07 15:51:02 +02:00
|
|
|
void TestResultModel::clearTestResults()
|
|
|
|
|
{
|
2015-08-20 15:59:15 +02:00
|
|
|
clear();
|
2014-11-05 15:27:49 +01:00
|
|
|
m_testResultCount.clear();
|
2015-12-14 12:48:58 +01:00
|
|
|
m_disabled = 0;
|
2016-10-31 13:11:52 +01:00
|
|
|
m_fileNames.clear();
|
2014-10-21 13:10:37 +02:00
|
|
|
m_maxWidthOfFileName = 0;
|
|
|
|
|
m_widthOfLineNumber = 0;
|
2014-10-07 15:51:02 +02:00
|
|
|
}
|
|
|
|
|
|
2016-04-13 10:20:17 +02:00
|
|
|
const TestResult *TestResultModel::testResult(const QModelIndex &idx)
|
2014-10-07 15:51:02 +02:00
|
|
|
{
|
2015-08-20 15:59:15 +02:00
|
|
|
if (idx.isValid())
|
2019-02-06 08:57:33 +01:00
|
|
|
return itemForIndex(idx)->testResult();
|
2015-08-20 15:59:15 +02:00
|
|
|
|
2018-05-31 07:38:04 +02:00
|
|
|
return nullptr;
|
2014-10-07 15:51:02 +02:00
|
|
|
}
|
|
|
|
|
|
2016-10-31 13:11:52 +01:00
|
|
|
void TestResultModel::recalculateMaxWidthOfFileName(const QFont &font)
|
2014-10-07 15:51:02 +02:00
|
|
|
{
|
2015-08-20 15:59:15 +02:00
|
|
|
const QFontMetrics fm(font);
|
2016-10-31 13:11:52 +01:00
|
|
|
m_maxWidthOfFileName = 0;
|
|
|
|
|
for (const QString &fileName : m_fileNames) {
|
|
|
|
|
int pos = fileName.lastIndexOf('/');
|
|
|
|
|
m_maxWidthOfFileName = qMax(m_maxWidthOfFileName, fm.width(fileName.mid(pos + 1)));
|
2014-10-07 15:51:02 +02:00
|
|
|
}
|
2016-10-31 13:11:52 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TestResultModel::addFileName(const QString &fileName)
|
|
|
|
|
{
|
|
|
|
|
const QFontMetrics fm(m_measurementFont);
|
|
|
|
|
int pos = fileName.lastIndexOf('/');
|
|
|
|
|
m_maxWidthOfFileName = qMax(m_maxWidthOfFileName, fm.width(fileName.mid(pos + 1)));
|
|
|
|
|
m_fileNames.insert(fileName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int TestResultModel::maxWidthOfFileName(const QFont &font)
|
|
|
|
|
{
|
|
|
|
|
if (font != m_measurementFont)
|
|
|
|
|
recalculateMaxWidthOfFileName(font);
|
2014-10-07 15:51:02 +02:00
|
|
|
return m_maxWidthOfFileName;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int TestResultModel::maxWidthOfLineNumber(const QFont &font)
|
|
|
|
|
{
|
|
|
|
|
if (m_widthOfLineNumber == 0 || font != m_measurementFont) {
|
|
|
|
|
QFontMetrics fm(font);
|
|
|
|
|
m_measurementFont = font;
|
2016-09-29 12:15:43 +02:00
|
|
|
m_widthOfLineNumber = fm.width("88888");
|
2014-10-07 15:51:02 +02:00
|
|
|
}
|
|
|
|
|
return m_widthOfLineNumber;
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-31 13:11:52 +01:00
|
|
|
TestResultItem *TestResultModel::findParentItemFor(const TestResultItem *item,
|
|
|
|
|
const TestResultItem *startItem) const
|
|
|
|
|
{
|
|
|
|
|
QTC_ASSERT(item, return nullptr);
|
|
|
|
|
TestResultItem *root = startItem ? const_cast<TestResultItem *>(startItem) : nullptr;
|
|
|
|
|
const TestResult *result = item->testResult();
|
|
|
|
|
const QString &name = result->name();
|
2018-05-09 10:48:23 +02:00
|
|
|
const QString &id = result->id();
|
2016-10-31 13:11:52 +01:00
|
|
|
|
2016-12-19 13:54:53 +01:00
|
|
|
if (root == nullptr && !name.isEmpty()) {
|
2016-10-31 13:11:52 +01:00
|
|
|
for (int row = rootItem()->childCount() - 1; row >= 0; --row) {
|
2019-02-06 08:57:33 +01:00
|
|
|
TestResultItem *tmp = rootItem()->childAt(row);
|
2017-06-27 15:15:43 +02:00
|
|
|
auto tmpTestResult = tmp->testResult();
|
2018-05-09 10:48:23 +02:00
|
|
|
if (tmpTestResult->id() == id && tmpTestResult->name() == name) {
|
2016-10-31 13:11:52 +01:00
|
|
|
root = tmp;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (root == nullptr)
|
|
|
|
|
return root;
|
|
|
|
|
|
|
|
|
|
bool needsIntermediate = false;
|
|
|
|
|
auto predicate = [result, &needsIntermediate](Utils::TreeItem *it) {
|
|
|
|
|
TestResultItem *currentItem = static_cast<TestResultItem *>(it);
|
|
|
|
|
return currentItem->testResult()->isDirectParentOf(result, &needsIntermediate);
|
|
|
|
|
};
|
2019-02-06 08:57:33 +01:00
|
|
|
TestResultItem *parent = root->reverseFindAnyChild(predicate);
|
2016-10-31 13:11:52 +01:00
|
|
|
if (parent) {
|
|
|
|
|
if (needsIntermediate) {
|
|
|
|
|
// check if the intermediate is present already
|
|
|
|
|
if (TestResultItem *intermediate = parent->intermediateFor(item))
|
|
|
|
|
return intermediate;
|
|
|
|
|
return parent->createAndAddIntermediateFor(item);
|
|
|
|
|
}
|
|
|
|
|
return parent;
|
|
|
|
|
}
|
|
|
|
|
return root;
|
|
|
|
|
}
|
|
|
|
|
|
2014-10-21 13:10:37 +02:00
|
|
|
/********************************** Filter Model **********************************/
|
|
|
|
|
|
|
|
|
|
TestResultFilterModel::TestResultFilterModel(TestResultModel *sourceModel, QObject *parent)
|
|
|
|
|
: QSortFilterProxyModel(parent),
|
|
|
|
|
m_sourceModel(sourceModel)
|
|
|
|
|
{
|
|
|
|
|
setSourceModel(sourceModel);
|
|
|
|
|
enableAllResultTypes();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TestResultFilterModel::enableAllResultTypes()
|
|
|
|
|
{
|
2015-12-07 08:26:54 +01:00
|
|
|
m_enabled << Result::Pass << Result::Fail << Result::ExpectedFail
|
|
|
|
|
<< Result::UnexpectedPass << Result::Skip << Result::MessageDebug
|
2018-08-18 21:48:34 +03:00
|
|
|
<< Result::MessageWarn << Result::MessageInternal << Result::MessageLocation
|
2015-12-07 08:26:54 +01:00
|
|
|
<< Result::MessageFatal << Result::Invalid << Result::BlacklistedPass
|
2019-01-24 08:53:31 +01:00
|
|
|
<< Result::BlacklistedFail << Result::BlacklistedXFail << Result::BlacklistedXPass
|
|
|
|
|
<< Result::Benchmark << Result::MessageIntermediate
|
2015-12-07 08:26:54 +01:00
|
|
|
<< Result::MessageCurrentTest << Result::MessageTestCaseStart
|
2017-07-10 15:02:24 +02:00
|
|
|
<< Result::MessageTestCaseSuccess << Result::MessageTestCaseSuccessWarn
|
|
|
|
|
<< Result::MessageTestCaseFail << Result::MessageTestCaseFailWarn
|
|
|
|
|
<< Result::MessageTestCaseEnd
|
2019-02-01 12:24:56 +01:00
|
|
|
<< Result::MessageInfo << Result::MessageSystem << Result::Application;
|
2014-10-21 13:10:37 +02:00
|
|
|
invalidateFilter();
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-08 13:46:28 +01:00
|
|
|
void TestResultFilterModel::toggleTestResultType(Result::Type type)
|
2014-10-21 13:10:37 +02:00
|
|
|
{
|
|
|
|
|
if (m_enabled.contains(type)) {
|
|
|
|
|
m_enabled.remove(type);
|
2015-12-07 08:26:54 +01:00
|
|
|
if (type == Result::MessageInternal)
|
|
|
|
|
m_enabled.remove(Result::MessageTestCaseEnd);
|
2016-07-11 10:55:43 +02:00
|
|
|
if (type == Result::MessageDebug)
|
|
|
|
|
m_enabled.remove(Result::MessageInfo);
|
2018-02-13 14:11:42 +01:00
|
|
|
if (type == Result::MessageWarn)
|
|
|
|
|
m_enabled.remove(Result::MessageSystem);
|
2014-10-21 13:10:37 +02:00
|
|
|
} else {
|
|
|
|
|
m_enabled.insert(type);
|
2015-12-07 08:26:54 +01:00
|
|
|
if (type == Result::MessageInternal)
|
|
|
|
|
m_enabled.insert(Result::MessageTestCaseEnd);
|
2016-07-11 10:55:43 +02:00
|
|
|
if (type == Result::MessageDebug)
|
|
|
|
|
m_enabled.insert(Result::MessageInfo);
|
2018-02-13 14:11:42 +01:00
|
|
|
if (type == Result::MessageWarn)
|
|
|
|
|
m_enabled.insert(Result::MessageSystem);
|
2014-10-21 13:10:37 +02:00
|
|
|
}
|
|
|
|
|
invalidateFilter();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TestResultFilterModel::clearTestResults()
|
|
|
|
|
{
|
|
|
|
|
m_sourceModel->clearTestResults();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool TestResultFilterModel::hasResults()
|
|
|
|
|
{
|
|
|
|
|
return rowCount(QModelIndex());
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-13 10:20:17 +02:00
|
|
|
const TestResult *TestResultFilterModel::testResult(const QModelIndex &index) const
|
2014-10-21 13:10:37 +02:00
|
|
|
{
|
|
|
|
|
return m_sourceModel->testResult(mapToSource(index));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool TestResultFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
|
|
|
|
|
{
|
|
|
|
|
QModelIndex index = m_sourceModel->index(sourceRow, 0, sourceParent);
|
|
|
|
|
if (!index.isValid())
|
|
|
|
|
return false;
|
2016-06-15 13:28:50 +02:00
|
|
|
Result::Type resultType = m_sourceModel->testResult(index)->result();
|
|
|
|
|
switch (resultType) {
|
|
|
|
|
case Result::MessageTestCaseSuccess:
|
|
|
|
|
return m_enabled.contains(Result::Pass);
|
|
|
|
|
case Result::MessageTestCaseFail:
|
2017-07-10 15:02:24 +02:00
|
|
|
case Result::MessageTestCaseSuccessWarn:
|
|
|
|
|
case Result::MessageTestCaseFailWarn:
|
2016-06-15 13:28:50 +02:00
|
|
|
return acceptTestCaseResult(index);
|
|
|
|
|
default:
|
|
|
|
|
return m_enabled.contains(resultType);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-31 13:11:52 +01:00
|
|
|
bool TestResultFilterModel::acceptTestCaseResult(const QModelIndex &srcIndex) const
|
2016-06-15 13:28:50 +02:00
|
|
|
{
|
2016-10-31 13:11:52 +01:00
|
|
|
for (int row = 0, count = m_sourceModel->rowCount(srcIndex); row < count; ++row) {
|
2018-09-21 02:08:41 +03:00
|
|
|
const QModelIndex &child = m_sourceModel->index(row, 0, srcIndex);
|
2016-10-31 13:11:52 +01:00
|
|
|
Result::Type type = m_sourceModel->testResult(child)->result();
|
|
|
|
|
if (type == Result::MessageTestCaseSuccess)
|
|
|
|
|
type = Result::Pass;
|
2017-07-10 15:02:24 +02:00
|
|
|
if (type == Result::MessageTestCaseFail || type == Result::MessageTestCaseFailWarn
|
|
|
|
|
|| type == Result::MessageTestCaseSuccessWarn) {
|
2016-10-31 13:11:52 +01:00
|
|
|
if (acceptTestCaseResult(child))
|
|
|
|
|
return true;
|
|
|
|
|
} else if (m_enabled.contains(type)) {
|
2016-06-15 13:28:50 +02:00
|
|
|
return true;
|
2016-10-31 13:11:52 +01:00
|
|
|
}
|
2016-06-15 13:28:50 +02:00
|
|
|
}
|
|
|
|
|
return false;
|
2014-10-21 13:10:37 +02:00
|
|
|
}
|
|
|
|
|
|
2014-10-07 15:51:02 +02:00
|
|
|
} // namespace Internal
|
|
|
|
|
} // namespace Autotest
|