2016-05-11 13:02:42 +02:00
|
|
|
/****************************************************************************
|
|
|
|
|
**
|
|
|
|
|
** Copyright (C) 2016 The Qt Company Ltd.
|
|
|
|
|
** Contact: https://www.qt.io/licensing/
|
|
|
|
|
**
|
|
|
|
|
** This file is part of Qt Creator.
|
|
|
|
|
**
|
|
|
|
|
** Commercial License Usage
|
|
|
|
|
** Licensees holding valid commercial Qt licenses may use this file in
|
|
|
|
|
** accordance with the commercial license agreement provided with the
|
|
|
|
|
** Software or, alternatively, in accordance with the terms contained in
|
|
|
|
|
** 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.
|
|
|
|
|
**
|
|
|
|
|
** 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.
|
|
|
|
|
**
|
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
|
|
#include "qttestresult.h"
|
2017-10-25 14:31:57 +02:00
|
|
|
#include "../testframeworkmanager.h"
|
|
|
|
|
#include "../testtreeitem.h"
|
|
|
|
|
#include "../quick/quicktestframework.h" // FIXME BAD! - but avoids declaring QuickTestResult
|
2016-05-11 13:02:42 +02:00
|
|
|
|
2017-10-25 14:31:57 +02:00
|
|
|
#include <coreplugin/id.h>
|
2016-10-31 13:11:52 +01:00
|
|
|
#include <utils/qtcassert.h>
|
|
|
|
|
|
2016-05-11 13:02:42 +02:00
|
|
|
namespace Autotest {
|
|
|
|
|
namespace Internal {
|
|
|
|
|
|
2018-05-09 10:48:23 +02:00
|
|
|
QtTestResult::QtTestResult(const QString &id, const QString &projectFile, TestType type,
|
2017-09-28 15:57:34 +02:00
|
|
|
const QString &className)
|
2018-05-09 10:48:23 +02:00
|
|
|
: TestResult(id, className), m_projectFile(projectFile), m_type(type)
|
2017-06-27 15:15:43 +02:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2016-05-11 13:02:42 +02:00
|
|
|
const QString QtTestResult::outputString(bool selected) const
|
|
|
|
|
{
|
|
|
|
|
const QString &desc = description();
|
|
|
|
|
const QString &className = name();
|
|
|
|
|
QString output;
|
|
|
|
|
switch (result()) {
|
2019-02-06 14:11:19 +01:00
|
|
|
case ResultType::Pass:
|
|
|
|
|
case ResultType::Fail:
|
|
|
|
|
case ResultType::ExpectedFail:
|
|
|
|
|
case ResultType::UnexpectedPass:
|
|
|
|
|
case ResultType::BlacklistedFail:
|
|
|
|
|
case ResultType::BlacklistedPass:
|
2016-09-29 12:15:43 +02:00
|
|
|
output = className + "::" + m_function;
|
2016-05-11 13:02:42 +02:00
|
|
|
if (!m_dataTag.isEmpty())
|
2016-09-29 12:15:43 +02:00
|
|
|
output.append(QString(" (%1)").arg(m_dataTag));
|
2016-05-11 13:02:42 +02:00
|
|
|
if (selected && !desc.isEmpty()) {
|
2016-09-29 12:15:43 +02:00
|
|
|
output.append('\n').append(desc);
|
2016-05-11 13:02:42 +02:00
|
|
|
}
|
|
|
|
|
break;
|
2019-02-06 14:11:19 +01:00
|
|
|
case ResultType::Benchmark:
|
2016-09-29 12:15:43 +02:00
|
|
|
output = className + "::" + m_function;
|
2016-05-11 13:02:42 +02:00
|
|
|
if (!m_dataTag.isEmpty())
|
2016-09-29 12:15:43 +02:00
|
|
|
output.append(QString(" (%1)").arg(m_dataTag));
|
2016-05-11 13:02:42 +02:00
|
|
|
if (!desc.isEmpty()) {
|
2016-09-29 12:15:43 +02:00
|
|
|
int breakPos = desc.indexOf('(');
|
|
|
|
|
output.append(": ").append(desc.left(breakPos));
|
2016-05-11 13:02:42 +02:00
|
|
|
if (selected)
|
2019-01-17 01:38:54 +01:00
|
|
|
output.append('\n').append(desc.midRef(breakPos));
|
2016-05-11 13:02:42 +02:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
output = desc;
|
|
|
|
|
if (!selected)
|
2016-09-29 12:15:43 +02:00
|
|
|
output = output.split('\n').first();
|
2016-05-11 13:02:42 +02:00
|
|
|
}
|
|
|
|
|
return output;
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-31 13:11:52 +01:00
|
|
|
bool QtTestResult::isDirectParentOf(const TestResult *other, bool *needsIntermediate) const
|
|
|
|
|
{
|
|
|
|
|
if (!TestResult::isDirectParentOf(other, needsIntermediate))
|
|
|
|
|
return false;
|
|
|
|
|
const QtTestResult *qtOther = static_cast<const QtTestResult *>(other);
|
2017-01-19 12:15:59 +01:00
|
|
|
|
|
|
|
|
if (TestResult::isMessageCaseStart(result())) {
|
2016-10-31 13:11:52 +01:00
|
|
|
if (qtOther->isDataTag()) {
|
|
|
|
|
if (qtOther->m_function == m_function) {
|
|
|
|
|
if (m_dataTag.isEmpty()) {
|
|
|
|
|
// avoid adding function's TestCaseEnd to the data tag
|
2019-02-06 14:11:19 +01:00
|
|
|
*needsIntermediate = qtOther->result() != ResultType::TestEnd;
|
2016-10-31 13:11:52 +01:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return qtOther->m_dataTag == m_dataTag;
|
|
|
|
|
}
|
|
|
|
|
} else if (qtOther->isTestFunction()) {
|
|
|
|
|
return isTestCase() || m_function == qtOther->m_function;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool QtTestResult::isIntermediateFor(const TestResult *other) const
|
|
|
|
|
{
|
|
|
|
|
QTC_ASSERT(other, return false);
|
|
|
|
|
const QtTestResult *qtOther = static_cast<const QtTestResult *>(other);
|
|
|
|
|
return m_dataTag == qtOther->m_dataTag && m_function == qtOther->m_function
|
2018-05-09 10:48:23 +02:00
|
|
|
&& name() == qtOther->name() && id() == qtOther->id()
|
2017-09-28 15:57:34 +02:00
|
|
|
&& m_projectFile == qtOther->m_projectFile;
|
2016-10-31 13:11:52 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TestResult *QtTestResult::createIntermediateResultFor(const TestResult *other)
|
|
|
|
|
{
|
2017-02-13 10:05:06 +01:00
|
|
|
QTC_ASSERT(other, return nullptr);
|
2016-10-31 13:11:52 +01:00
|
|
|
const QtTestResult *qtOther = static_cast<const QtTestResult *>(other);
|
2018-05-09 10:48:23 +02:00
|
|
|
QtTestResult *intermediate = new QtTestResult(qtOther->id(), qtOther->m_projectFile,
|
2017-10-25 14:31:57 +02:00
|
|
|
m_type, qtOther->name());
|
2016-10-31 13:11:52 +01:00
|
|
|
intermediate->m_function = qtOther->m_function;
|
|
|
|
|
intermediate->m_dataTag = qtOther->m_dataTag;
|
|
|
|
|
// intermediates will be needed only for data tags
|
|
|
|
|
intermediate->setDescription("Data tag: " + qtOther->m_dataTag);
|
2017-09-28 15:57:34 +02:00
|
|
|
const auto correspondingItem = intermediate->findTestTreeItem();
|
|
|
|
|
if (correspondingItem && correspondingItem->line()) {
|
|
|
|
|
intermediate->setFileName(correspondingItem->filePath());
|
|
|
|
|
intermediate->setLine(static_cast<int>(correspondingItem->line()));
|
|
|
|
|
}
|
2016-10-31 13:11:52 +01:00
|
|
|
return intermediate;
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-28 15:57:34 +02:00
|
|
|
const TestTreeItem *QtTestResult::findTestTreeItem() const
|
|
|
|
|
{
|
2017-10-25 14:31:57 +02:00
|
|
|
Core::Id id;
|
|
|
|
|
if (m_type == TestType::QtTest)
|
|
|
|
|
id = Core::Id(Constants::FRAMEWORK_PREFIX).withSuffix(QtTest::Constants::FRAMEWORK_NAME);
|
|
|
|
|
else
|
|
|
|
|
id = Core::Id(Constants::FRAMEWORK_PREFIX).withSuffix(QuickTest::Constants::FRAMEWORK_NAME);
|
|
|
|
|
const TestTreeItem *rootNode = TestFrameworkManager::instance()->rootNodeForTestFramework(id);
|
|
|
|
|
QTC_ASSERT(rootNode, return nullptr);
|
|
|
|
|
|
|
|
|
|
const auto item = rootNode->findAnyChild([this](const Utils::TreeItem *item) {
|
2017-09-28 15:57:34 +02:00
|
|
|
const TestTreeItem *treeItem = static_cast<const TestTreeItem *>(item);
|
2017-10-25 14:31:57 +02:00
|
|
|
return treeItem && matches(treeItem);
|
2017-09-28 15:57:34 +02:00
|
|
|
});
|
|
|
|
|
return static_cast<const TestTreeItem *>(item);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool QtTestResult::matches(const TestTreeItem *item) const
|
|
|
|
|
{
|
|
|
|
|
QTC_ASSERT(item, return false);
|
|
|
|
|
TestTreeItem *parentItem = item->parentItem();
|
|
|
|
|
QTC_ASSERT(parentItem, return false);
|
|
|
|
|
|
|
|
|
|
TestTreeItem::Type type = item->type();
|
|
|
|
|
switch (type) {
|
|
|
|
|
case TestTreeItem::TestCase:
|
|
|
|
|
if (!isTestCase())
|
|
|
|
|
return false;
|
|
|
|
|
if (item->proFile() != m_projectFile)
|
|
|
|
|
return false;
|
|
|
|
|
return matchesTestCase(item);
|
|
|
|
|
case TestTreeItem::TestFunctionOrSet:
|
|
|
|
|
case TestTreeItem::TestSpecialFunction:
|
|
|
|
|
if (!isTestFunction())
|
|
|
|
|
return false;
|
|
|
|
|
if (parentItem->proFile() != m_projectFile)
|
|
|
|
|
return false;
|
|
|
|
|
return matchesTestFunction(item);
|
|
|
|
|
case TestTreeItem::TestDataTag: {
|
|
|
|
|
if (!isDataTag())
|
|
|
|
|
return false;
|
|
|
|
|
TestTreeItem *grandParentItem = parentItem->parentItem();
|
|
|
|
|
QTC_ASSERT(grandParentItem, return false);
|
|
|
|
|
if (grandParentItem->proFile() != m_projectFile)
|
|
|
|
|
return false;
|
|
|
|
|
return matchesTestFunction(item);
|
|
|
|
|
}
|
|
|
|
|
default:
|
2017-10-06 14:10:26 +02:00
|
|
|
break;
|
2017-09-28 15:57:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool QtTestResult::matchesTestCase(const TestTreeItem *item) const
|
|
|
|
|
{
|
|
|
|
|
// FIXME this will never work for Quick Tests
|
|
|
|
|
if (item->name() == name())
|
|
|
|
|
return true;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool QtTestResult::matchesTestFunction(const TestTreeItem *item) const
|
|
|
|
|
{
|
|
|
|
|
TestTreeItem *parentItem = item->parentItem();
|
|
|
|
|
TestTreeItem::Type type = item->type();
|
2017-10-25 14:31:57 +02:00
|
|
|
if (m_type == TestType::QuickTest) { // Quick tests have slightly different layout // BAD/WRONG!
|
2017-09-28 15:57:34 +02:00
|
|
|
const QStringList tmp = m_function.split("::");
|
2017-10-25 14:31:57 +02:00
|
|
|
return tmp.size() == 2 && item->name() == tmp.last() && parentItem->name() == tmp.first();
|
2017-09-28 15:57:34 +02:00
|
|
|
}
|
|
|
|
|
if (type == TestTreeItem::TestDataTag) {
|
|
|
|
|
TestTreeItem *grandParentItem = parentItem->parentItem();
|
2018-06-25 14:52:52 +02:00
|
|
|
return parentItem->name() == m_function && grandParentItem->name() == name()
|
|
|
|
|
&& item->name() == m_dataTag;
|
2017-09-28 15:57:34 +02:00
|
|
|
}
|
|
|
|
|
return item->name() == m_function && parentItem->name() == name();
|
|
|
|
|
}
|
|
|
|
|
|
2016-05-11 13:02:42 +02:00
|
|
|
} // namespace Internal
|
|
|
|
|
} // namespace Autotest
|