forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/master' into 10.0
Change-Id: I4dd2149e046d33b65e6d9c3497d0153f81fd3f31
This commit is contained in:
@@ -974,6 +974,11 @@ void StringAspect::setEnvironmentChange(const EnvironmentChange &change)
|
|||||||
d->m_pathChooserDisplay->setEnvironmentChange(change);
|
d->m_pathChooserDisplay->setEnvironmentChange(change);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StringAspect::setEnvironment(const Environment &env)
|
||||||
|
{
|
||||||
|
setEnvironmentChange(EnvironmentChange::fromDictionary(env.toDictionary()));
|
||||||
|
}
|
||||||
|
|
||||||
void StringAspect::setBaseFileName(const FilePath &baseFileName)
|
void StringAspect::setBaseFileName(const FilePath &baseFileName)
|
||||||
{
|
{
|
||||||
d->m_baseFileName = baseFileName;
|
d->m_baseFileName = baseFileName;
|
||||||
|
@@ -356,6 +356,7 @@ public:
|
|||||||
void setHistoryCompleter(const QString &historyCompleterKey);
|
void setHistoryCompleter(const QString &historyCompleterKey);
|
||||||
void setExpectedKind(const PathChooser::Kind expectedKind);
|
void setExpectedKind(const PathChooser::Kind expectedKind);
|
||||||
void setEnvironmentChange(const EnvironmentChange &change);
|
void setEnvironmentChange(const EnvironmentChange &change);
|
||||||
|
void setEnvironment(const Environment &env);
|
||||||
void setBaseFileName(const FilePath &baseFileName);
|
void setBaseFileName(const FilePath &baseFileName);
|
||||||
void setUndoRedoEnabled(bool readOnly);
|
void setUndoRedoEnabled(bool readOnly);
|
||||||
void setAcceptRichText(bool acceptRichText);
|
void setAcceptRichText(bool acceptRichText);
|
||||||
|
@@ -23,7 +23,7 @@ NameValueItems Environment::diff(const Environment &other, bool checkAppendPrepe
|
|||||||
return m_dict.diff(other.m_dict, checkAppendPrepend);
|
return m_dict.diff(other.m_dict, checkAppendPrepend);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Environment::isValid() const
|
bool Environment::hasChanges() const
|
||||||
{
|
{
|
||||||
return m_dict.size() != 0;
|
return m_dict.size() != 0;
|
||||||
}
|
}
|
||||||
@@ -417,10 +417,10 @@ void EnvironmentChange::addAppendToPath(const FilePaths &values)
|
|||||||
m_changeItems.append(Item{std::in_place_index_t<AppendToPath>(), value});
|
m_changeItems.append(Item{std::in_place_index_t<AppendToPath>(), value});
|
||||||
}
|
}
|
||||||
|
|
||||||
EnvironmentChange EnvironmentChange::fromFixedEnvironment(const Environment &fixedEnv)
|
EnvironmentChange EnvironmentChange::fromDictionary(const NameValueDictionary &dict)
|
||||||
{
|
{
|
||||||
EnvironmentChange change;
|
EnvironmentChange change;
|
||||||
change.m_changeItems.append(Item{std::in_place_index_t<SetFixedEnvironment>(), fixedEnv});
|
change.m_changeItems.append(Item{std::in_place_index_t<SetFixedDictionary>(), dict});
|
||||||
return change;
|
return change;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -431,8 +431,8 @@ void EnvironmentChange::applyToEnvironment(Environment &env) const
|
|||||||
case SetSystemEnvironment:
|
case SetSystemEnvironment:
|
||||||
env = Environment::systemEnvironment();
|
env = Environment::systemEnvironment();
|
||||||
break;
|
break;
|
||||||
case SetFixedEnvironment:
|
case SetFixedDictionary:
|
||||||
env = std::get<SetFixedEnvironment>(item);
|
env = Environment(std::get<SetFixedDictionary>(item));
|
||||||
break;
|
break;
|
||||||
case SetValue: {
|
case SetValue: {
|
||||||
const QPair<QString, QString> data = std::get<SetValue>(item);
|
const QPair<QString, QString> data = std::get<SetValue>(item);
|
||||||
|
@@ -35,7 +35,7 @@ public:
|
|||||||
void unset(const QString &key) { m_dict.unset(key); }
|
void unset(const QString &key) { m_dict.unset(key); }
|
||||||
void modify(const NameValueItems &items) { m_dict.modify(items); }
|
void modify(const NameValueItems &items) { m_dict.modify(items); }
|
||||||
|
|
||||||
int isValid() const;
|
bool hasChanges() const;
|
||||||
void clear() { return m_dict.clear(); }
|
void clear() { return m_dict.clear(); }
|
||||||
|
|
||||||
QStringList toStringList() const { return m_dict.toStringList(); }
|
QStringList toStringList() const { return m_dict.toStringList(); }
|
||||||
@@ -111,7 +111,7 @@ public:
|
|||||||
|
|
||||||
enum Type {
|
enum Type {
|
||||||
SetSystemEnvironment,
|
SetSystemEnvironment,
|
||||||
SetFixedEnvironment,
|
SetFixedDictionary,
|
||||||
SetValue,
|
SetValue,
|
||||||
UnsetValue,
|
UnsetValue,
|
||||||
PrependToPath,
|
PrependToPath,
|
||||||
@@ -120,14 +120,14 @@ public:
|
|||||||
|
|
||||||
using Item = std::variant<
|
using Item = std::variant<
|
||||||
std::monostate, // SetSystemEnvironment dummy
|
std::monostate, // SetSystemEnvironment dummy
|
||||||
Environment, // SetFixedEnvironment
|
NameValueDictionary, // SetFixedDictionary
|
||||||
QPair<QString, QString>, // SetValue
|
QPair<QString, QString>, // SetValue
|
||||||
QString, // UnsetValue
|
QString, // UnsetValue
|
||||||
FilePath, // PrependToPath
|
FilePath, // PrependToPath
|
||||||
FilePath // AppendToPath
|
FilePath // AppendToPath
|
||||||
>;
|
>;
|
||||||
|
|
||||||
static EnvironmentChange fromFixedEnvironment(const Environment &fixedEnv);
|
static EnvironmentChange fromDictionary(const NameValueDictionary &dict);
|
||||||
|
|
||||||
void applyToEnvironment(Environment &) const;
|
void applyToEnvironment(Environment &) const;
|
||||||
|
|
||||||
|
@@ -324,6 +324,11 @@ void PathChooser::setBaseDirectory(const FilePath &base)
|
|||||||
triggerChanged();
|
triggerChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PathChooser::setEnvironment(const Environment &env)
|
||||||
|
{
|
||||||
|
setEnvironmentChange(EnvironmentChange::fromDictionary(env.toDictionary()));
|
||||||
|
}
|
||||||
|
|
||||||
FilePath PathChooser::baseDirectory() const
|
FilePath PathChooser::baseDirectory() const
|
||||||
{
|
{
|
||||||
return d->m_baseDirectory;
|
return d->m_baseDirectory;
|
||||||
|
@@ -76,6 +76,7 @@ public:
|
|||||||
FilePath baseDirectory() const;
|
FilePath baseDirectory() const;
|
||||||
void setBaseDirectory(const FilePath &base);
|
void setBaseDirectory(const FilePath &base);
|
||||||
|
|
||||||
|
void setEnvironment(const Environment &env);
|
||||||
void setEnvironmentChange(const EnvironmentChange &change);
|
void setEnvironmentChange(const EnvironmentChange &change);
|
||||||
|
|
||||||
/** Returns the suggested label title when used in a form layout. */
|
/** Returns the suggested label title when used in a form layout. */
|
||||||
|
@@ -668,7 +668,7 @@ public:
|
|||||||
Environment fullEnvironment() const
|
Environment fullEnvironment() const
|
||||||
{
|
{
|
||||||
Environment env = m_setup.m_environment;
|
Environment env = m_setup.m_environment;
|
||||||
if (!env.isValid()) {
|
if (!env.hasChanges()) {
|
||||||
// FIXME: Either switch to using EnvironmentChange instead of full Environments, or
|
// FIXME: Either switch to using EnvironmentChange instead of full Environments, or
|
||||||
// feed the full environment into the QtcProcess instead of fixing it up here.
|
// feed the full environment into the QtcProcess instead of fixing it up here.
|
||||||
// qWarning("QtcProcess::start: Empty environment set when running '%s'.",
|
// qWarning("QtcProcess::start: Empty environment set when running '%s'.",
|
||||||
@@ -1190,7 +1190,7 @@ QString QtcProcess::toStandaloneCommandLine() const
|
|||||||
d->m_setup.m_workingDirectory.path();
|
d->m_setup.m_workingDirectory.path();
|
||||||
}
|
}
|
||||||
parts.append("-i");
|
parts.append("-i");
|
||||||
if (d->m_setup.m_environment.isValid()) {
|
if (d->m_setup.m_environment.hasChanges()) {
|
||||||
const QStringList envVars = d->m_setup.m_environment.toStringList();
|
const QStringList envVars = d->m_setup.m_environment.toStringList();
|
||||||
std::transform(envVars.cbegin(), envVars.cend(),
|
std::transform(envVars.cbegin(), envVars.cend(),
|
||||||
std::back_inserter(parts), ProcessArgs::quoteArgUnix);
|
std::back_inserter(parts), ProcessArgs::quoteArgUnix);
|
||||||
|
@@ -22,6 +22,7 @@ add_subdirectory(silversearcher)
|
|||||||
# Level 3: (only depends on Level 2 and below)
|
# Level 3: (only depends on Level 2 and below)
|
||||||
add_subdirectory(bookmarks)
|
add_subdirectory(bookmarks)
|
||||||
add_subdirectory(cppeditor)
|
add_subdirectory(cppeditor)
|
||||||
|
add_subdirectory(haskell)
|
||||||
add_subdirectory(help)
|
add_subdirectory(help)
|
||||||
add_subdirectory(resourceeditor)
|
add_subdirectory(resourceeditor)
|
||||||
add_subdirectory(nim)
|
add_subdirectory(nim)
|
||||||
|
@@ -605,7 +605,7 @@ void AndroidRunnerWorker::asyncStartHelper()
|
|||||||
<< QString::fromLatin1(appArgs.join(' ').toUtf8().toBase64());
|
<< QString::fromLatin1(appArgs.join(' ').toUtf8().toBase64());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_extraEnvVars.isValid()) {
|
if (m_extraEnvVars.hasChanges()) {
|
||||||
args << "-e" << "extraenvvars"
|
args << "-e" << "extraenvvars"
|
||||||
<< QString::fromLatin1(m_extraEnvVars.toStringList().join('\t')
|
<< QString::fromLatin1(m_extraEnvVars.toStringList().join('\t')
|
||||||
.toUtf8().toBase64());
|
.toUtf8().toBase64());
|
||||||
|
@@ -66,6 +66,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
using namespace Core;
|
using namespace Core;
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
namespace Autotest {
|
namespace Autotest {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
@@ -361,7 +362,7 @@ void AutotestPluginPrivate::onRunFileTriggered()
|
|||||||
if (!document)
|
if (!document)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const Utils::FilePath &fileName = document->filePath();
|
const FilePath &fileName = document->filePath();
|
||||||
if (fileName.isEmpty())
|
if (fileName.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -398,7 +399,7 @@ void AutotestPluginPrivate::onRunUnderCursorTriggered(TestRunMode mode)
|
|||||||
|
|
||||||
// check whether we have been triggered on a test function definition
|
// check whether we have been triggered on a test function definition
|
||||||
const int line = currentEditor->currentLine();
|
const int line = currentEditor->currentLine();
|
||||||
const Utils::FilePath &filePath = currentEditor->textDocument()->filePath();
|
const FilePath &filePath = currentEditor->textDocument()->filePath();
|
||||||
QList<ITestTreeItem *> filteredItems = Utils::filtered(testsItems, [&](ITestTreeItem *it){
|
QList<ITestTreeItem *> filteredItems = Utils::filtered(testsItems, [&](ITestTreeItem *it){
|
||||||
return it->line() == line && it->filePath() == filePath;
|
return it->line() == line && it->filePath() == filePath;
|
||||||
});
|
});
|
||||||
|
@@ -68,7 +68,7 @@ void AutoTestUnitTests::initTestCase()
|
|||||||
if (!qtcEnvironmentVariableIsEmpty("BOOST_INCLUDE_DIR")) {
|
if (!qtcEnvironmentVariableIsEmpty("BOOST_INCLUDE_DIR")) {
|
||||||
m_checkBoost = true;
|
m_checkBoost = true;
|
||||||
} else {
|
} else {
|
||||||
if (Utils::HostOsInfo::isLinuxHost()
|
if (HostOsInfo::isLinuxHost()
|
||||||
&& (QFileInfo::exists("/usr/include/boost/version.hpp")
|
&& (QFileInfo::exists("/usr/include/boost/version.hpp")
|
||||||
|| QFileInfo::exists("/usr/local/include/boost/version.hpp"))) {
|
|| QFileInfo::exists("/usr/local/include/boost/version.hpp"))) {
|
||||||
qDebug() << "Found boost at system level - will run boost parser test.";
|
qDebug() << "Found boost at system level - will run boost parser test.";
|
||||||
@@ -77,7 +77,7 @@ void AutoTestUnitTests::initTestCase()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Enable quick check for derived tests
|
// Enable quick check for derived tests
|
||||||
static const Utils::Id id = Utils::Id("AutoTest.Framework.QtTest");
|
static const Id id = Id("AutoTest.Framework.QtTest");
|
||||||
static_cast<Autotest::Internal::QtTestSettings *>(
|
static_cast<Autotest::Internal::QtTestSettings *>(
|
||||||
TestFrameworkManager::frameworkForId(id)->testSettings())
|
TestFrameworkManager::frameworkForId(id)->testSettings())
|
||||||
->quickCheckForDerivedTests.setValue(true);
|
->quickCheckForDerivedTests.setValue(true);
|
||||||
@@ -257,7 +257,7 @@ void AutoTestUnitTests::testCodeParserBoostTest()
|
|||||||
|
|
||||||
QCOMPARE(m_model->boostTestNamesCount(), 5);
|
QCOMPARE(m_model->boostTestNamesCount(), 5);
|
||||||
|
|
||||||
const Utils::FilePath basePath = projectInfo->projectRoot();
|
const FilePath basePath = projectInfo->projectRoot();
|
||||||
QVERIFY(!basePath.isEmpty());
|
QVERIFY(!basePath.isEmpty());
|
||||||
|
|
||||||
QMap<QString, int> expectedSuitesAndTests;
|
QMap<QString, int> expectedSuitesAndTests;
|
||||||
|
@@ -13,11 +13,13 @@
|
|||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
#include <utils/stringutils.h>
|
#include <utils/stringutils.h>
|
||||||
|
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
namespace Autotest {
|
namespace Autotest {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
TestOutputReader *BoostTestConfiguration::createOutputReader(
|
TestOutputReader *BoostTestConfiguration::createOutputReader(
|
||||||
const QFutureInterface<TestResultPtr> &fi, Utils::QtcProcess *app) const
|
const QFutureInterface<TestResult> &fi, QtcProcess *app) const
|
||||||
{
|
{
|
||||||
auto settings = static_cast<BoostTestSettings *>(framework()->testSettings());
|
auto settings = static_cast<BoostTestSettings *>(framework()->testSettings());
|
||||||
return new BoostTestOutputReader(fi, app, buildDirectory(), projectFile(),
|
return new BoostTestOutputReader(fi, app, buildDirectory(), projectFile(),
|
||||||
@@ -113,11 +115,11 @@ QStringList BoostTestConfiguration::argumentsForTestRunner(QStringList *omitted)
|
|||||||
return arguments;
|
return arguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
Utils::Environment BoostTestConfiguration::filteredEnvironment(const Utils::Environment &original) const
|
Environment BoostTestConfiguration::filteredEnvironment(const Environment &original) const
|
||||||
{
|
{
|
||||||
const QStringList interferingEnv = interfering(InterferingType::EnvironmentVariables);
|
const QStringList interferingEnv = interfering(InterferingType::EnvironmentVariables);
|
||||||
|
|
||||||
Utils::Environment result = original;
|
Environment result = original;
|
||||||
if (!result.hasKey("BOOST_TEST_COLOR_OUTPUT"))
|
if (!result.hasKey("BOOST_TEST_COLOR_OUTPUT"))
|
||||||
result.set("BOOST_TEST_COLOR_OUTPUT", "1"); // use colored output by default
|
result.set("BOOST_TEST_COLOR_OUTPUT", "1"); // use colored output by default
|
||||||
for (const QString &key : interferingEnv)
|
for (const QString &key : interferingEnv)
|
||||||
|
@@ -13,7 +13,7 @@ class BoostTestConfiguration : public DebuggableTestConfiguration
|
|||||||
public:
|
public:
|
||||||
explicit BoostTestConfiguration(ITestFramework *framework)
|
explicit BoostTestConfiguration(ITestFramework *framework)
|
||||||
: DebuggableTestConfiguration(framework) {}
|
: DebuggableTestConfiguration(framework) {}
|
||||||
TestOutputReader *createOutputReader(const QFutureInterface<TestResultPtr> &fi,
|
TestOutputReader *createOutputReader(const QFutureInterface<TestResult> &fi,
|
||||||
Utils::QtcProcess *app) const override;
|
Utils::QtcProcess *app) const override;
|
||||||
QStringList argumentsForTestRunner(QStringList *omitted = nullptr) const override;
|
QStringList argumentsForTestRunner(QStringList *omitted = nullptr) const override;
|
||||||
Utils::Environment filteredEnvironment(const Utils::Environment &original) const override;
|
Utils::Environment filteredEnvironment(const Utils::Environment &original) const override;
|
||||||
|
@@ -18,10 +18,7 @@ ITestParser *BoostTestFramework::createTestParser()
|
|||||||
|
|
||||||
ITestTreeItem *BoostTestFramework::createRootNode()
|
ITestTreeItem *BoostTestFramework::createRootNode()
|
||||||
{
|
{
|
||||||
return new BoostTestTreeItem(
|
return new BoostTestTreeItem(this, displayName(), {}, ITestTreeItem::Root);
|
||||||
this,
|
|
||||||
displayName(),
|
|
||||||
Utils::FilePath(), ITestTreeItem::Root);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *BoostTestFramework::name() const
|
const char *BoostTestFramework::name() const
|
||||||
|
@@ -14,23 +14,29 @@
|
|||||||
#include <QLoggingCategory>
|
#include <QLoggingCategory>
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
|
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
namespace Autotest {
|
namespace Autotest {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
static Q_LOGGING_CATEGORY(orLog, "qtc.autotest.boost.outputreader", QtWarningMsg)
|
static Q_LOGGING_CATEGORY(orLog, "qtc.autotest.boost.outputreader", QtWarningMsg)
|
||||||
|
|
||||||
BoostTestOutputReader::BoostTestOutputReader(const QFutureInterface<TestResultPtr> &futureInterface,
|
BoostTestOutputReader::BoostTestOutputReader(const QFutureInterface<TestResult> &futureInterface,
|
||||||
Utils::QtcProcess *testApplication,
|
QtcProcess *testApplication,
|
||||||
const Utils::FilePath &buildDirectory,
|
const FilePath &buildDirectory,
|
||||||
const Utils::FilePath &projectFile,
|
const FilePath &projectFile,
|
||||||
LogLevel log, ReportLevel report)
|
LogLevel log, ReportLevel report)
|
||||||
: TestOutputReader(futureInterface, testApplication, buildDirectory)
|
: TestOutputReader(futureInterface, testApplication, buildDirectory)
|
||||||
, m_projectFile(projectFile)
|
, m_projectFile(projectFile)
|
||||||
, m_logLevel(log)
|
, m_logLevel(log)
|
||||||
, m_reportLevel(report)
|
, m_reportLevel(report)
|
||||||
{
|
{
|
||||||
if (m_testApplication)
|
if (!testApplication)
|
||||||
connect(m_testApplication, &Utils::QtcProcess::done, this, &BoostTestOutputReader::onDone);
|
return;
|
||||||
|
|
||||||
|
connect(testApplication, &QtcProcess::done, this, [this, testApplication] {
|
||||||
|
onDone(testApplication->exitCode());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// content of "error:..." / "info:..." / ... messages
|
// content of "error:..." / "info:..." / ... messages
|
||||||
@@ -42,23 +48,23 @@ static QString caseFromContent(const QString &content)
|
|||||||
if (index != 17 || length <= 18) {
|
if (index != 17 || length <= 18) {
|
||||||
qCDebug(orLog) << "double quote position" << index << " or content length" << length
|
qCDebug(orLog) << "double quote position" << index << " or content length" << length
|
||||||
<< "wrong on content" << content;
|
<< "wrong on content" << content;
|
||||||
return QString();
|
return {};
|
||||||
}
|
}
|
||||||
index = content.indexOf('"', 18);
|
index = content.indexOf('"', 18);
|
||||||
if (index == -1) {
|
if (index == -1) {
|
||||||
qCDebug(orLog) << "no closing double quote" << content;
|
qCDebug(orLog) << "no closing double quote" << content;
|
||||||
return QString();
|
return {};
|
||||||
}
|
}
|
||||||
return content.mid(18, index - 1);
|
return content.mid(18, index - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int index = content.indexOf(": in ");
|
int index = content.indexOf(": in ");
|
||||||
if (index == -1) // "info: check true has passed"
|
if (index == -1) // "info: check true has passed"
|
||||||
return QString();
|
return {};
|
||||||
|
|
||||||
if (index <= 4 || length < index + 4) {
|
if (index <= 4 || length < index + 4) {
|
||||||
qCDebug(orLog) << "unexpected position" << index << "for info" << content;
|
qCDebug(orLog) << "unexpected position" << index << "for info" << content;
|
||||||
return QString();
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
QString result = content.mid(index + 5);
|
QString result = content.mid(index + 5);
|
||||||
@@ -66,7 +72,7 @@ static QString caseFromContent(const QString &content)
|
|||||||
const QRegularExpressionMatch matcher = functionName.match(result);
|
const QRegularExpressionMatch matcher = functionName.match(result);
|
||||||
if (!matcher.hasMatch()) {
|
if (!matcher.hasMatch()) {
|
||||||
qCDebug(orLog) << "got no match";
|
qCDebug(orLog) << "got no match";
|
||||||
return QString();
|
return {};
|
||||||
}
|
}
|
||||||
return matcher.captured(1);
|
return matcher.captured(1);
|
||||||
}
|
}
|
||||||
@@ -74,19 +80,18 @@ static QString caseFromContent(const QString &content)
|
|||||||
void BoostTestOutputReader::sendCompleteInformation()
|
void BoostTestOutputReader::sendCompleteInformation()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(m_result != ResultType::Invalid, return);
|
QTC_ASSERT(m_result != ResultType::Invalid, return);
|
||||||
BoostTestResult *result = new BoostTestResult(id(), m_currentModule, m_projectFile,
|
BoostTestResult result(id(), m_currentModule, m_projectFile, m_currentTest, m_currentSuite);
|
||||||
m_currentTest, m_currentSuite);
|
|
||||||
if (m_lineNumber) {
|
if (m_lineNumber) {
|
||||||
result->setLine(m_lineNumber);
|
result.setLine(m_lineNumber);
|
||||||
result->setFileName(m_fileName);
|
result.setFileName(m_fileName);
|
||||||
} else if (const ITestTreeItem *it = result->findTestTreeItem()) {
|
} else if (const ITestTreeItem *it = result.findTestTreeItem()) {
|
||||||
result->setLine(it->line());
|
result.setLine(it->line());
|
||||||
result->setFileName(it->filePath());
|
result.setFileName(it->filePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
result->setDescription(m_description);
|
result.setDescription(m_description);
|
||||||
result->setResult(m_result);
|
result.setResult(m_result);
|
||||||
reportResult(TestResultPtr(result));
|
reportResult(result);
|
||||||
m_result = ResultType::Invalid;
|
m_result = ResultType::Invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,10 +217,10 @@ void BoostTestOutputReader::processOutputLine(const QByteArray &outputLine)
|
|||||||
if (match.hasMatch()) {
|
if (match.hasMatch()) {
|
||||||
if (m_result != ResultType::Invalid)
|
if (m_result != ResultType::Invalid)
|
||||||
sendCompleteInformation();
|
sendCompleteInformation();
|
||||||
BoostTestResult *result = new BoostTestResult(id(), m_currentModule, m_projectFile);
|
BoostTestResult result(id(), m_currentModule, m_projectFile);
|
||||||
result->setDescription(match.captured(0));
|
result.setDescription(match.captured(0));
|
||||||
result->setResult(ResultType::MessageInfo);
|
result.setResult(ResultType::MessageInfo);
|
||||||
reportResult(TestResultPtr(result));
|
reportResult(result);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,17 +239,17 @@ void BoostTestOutputReader::processOutputLine(const QByteArray &outputLine)
|
|||||||
sendCompleteInformation();
|
sendCompleteInformation();
|
||||||
if (match.captured(1).startsWith("Entering")) {
|
if (match.captured(1).startsWith("Entering")) {
|
||||||
m_currentModule = match.captured(2);
|
m_currentModule = match.captured(2);
|
||||||
BoostTestResult *result = new BoostTestResult(id(), m_currentModule, m_projectFile);
|
BoostTestResult result(id(), m_currentModule, m_projectFile);
|
||||||
result->setDescription(Tr::tr("Executing test module %1").arg(m_currentModule));
|
result.setDescription(Tr::tr("Executing test module %1").arg(m_currentModule));
|
||||||
result->setResult(ResultType::TestStart);
|
result.setResult(ResultType::TestStart);
|
||||||
reportResult(TestResultPtr(result));
|
reportResult(result);
|
||||||
m_description.clear();
|
m_description.clear();
|
||||||
} else {
|
} else {
|
||||||
QTC_CHECK(m_currentModule == match.captured(3));
|
QTC_CHECK(m_currentModule == match.captured(3));
|
||||||
BoostTestResult *result = new BoostTestResult(id(), m_currentModule, m_projectFile);
|
BoostTestResult result(id(), m_currentModule, m_projectFile);
|
||||||
result->setDescription(Tr::tr("Test module execution took %1").arg(match.captured(4)));
|
result.setDescription(Tr::tr("Test module execution took %1").arg(match.captured(4)));
|
||||||
result->setResult(ResultType::TestEnd);
|
result.setResult(ResultType::TestEnd);
|
||||||
reportResult(TestResultPtr(result));
|
reportResult(result);
|
||||||
|
|
||||||
m_currentTest.clear();
|
m_currentTest.clear();
|
||||||
m_currentSuite.clear();
|
m_currentSuite.clear();
|
||||||
@@ -325,16 +330,16 @@ void BoostTestOutputReader::processOutputLine(const QByteArray &outputLine)
|
|||||||
if (match.hasMatch()) {
|
if (match.hasMatch()) {
|
||||||
if (m_result != ResultType::Invalid)
|
if (m_result != ResultType::Invalid)
|
||||||
sendCompleteInformation();
|
sendCompleteInformation();
|
||||||
BoostTestResult *result = new BoostTestResult(id(), {}, m_projectFile);
|
BoostTestResult result(id(), {}, m_projectFile);
|
||||||
int failed = match.captured(1).toInt();
|
const int failed = match.captured(1).toInt();
|
||||||
int fatals = m_summary.value(ResultType::MessageFatal);
|
const int fatals = m_summary.value(ResultType::MessageFatal);
|
||||||
QString txt = Tr::tr("%1 failures detected in %2.").arg(failed).arg(match.captured(3));
|
QString txt = Tr::tr("%1 failures detected in %2.").arg(failed).arg(match.captured(3));
|
||||||
int passed = qMax(0, m_testCaseCount - failed);
|
const int passed = qMax(0, m_testCaseCount - failed);
|
||||||
if (m_testCaseCount != -1)
|
if (m_testCaseCount != -1)
|
||||||
txt.append(' ').append(Tr::tr("%1 tests passed.").arg(passed));
|
txt.append(' ').append(Tr::tr("%1 tests passed.").arg(passed));
|
||||||
result->setDescription(txt);
|
result.setDescription(txt);
|
||||||
result->setResult(ResultType::MessageInfo);
|
result.setResult(ResultType::MessageInfo);
|
||||||
reportResult(TestResultPtr(result));
|
reportResult(result);
|
||||||
if (m_reportLevel == ReportLevel::Confirm) { // for the final summary
|
if (m_reportLevel == ReportLevel::Confirm) { // for the final summary
|
||||||
m_summary[ResultType::Pass] += passed;
|
m_summary[ResultType::Pass] += passed;
|
||||||
m_summary[ResultType::Fail] += failed - fatals;
|
m_summary[ResultType::Fail] += failed - fatals;
|
||||||
@@ -346,13 +351,13 @@ void BoostTestOutputReader::processOutputLine(const QByteArray &outputLine)
|
|||||||
if (line == noErrors) {
|
if (line == noErrors) {
|
||||||
if (m_result != ResultType::Invalid)
|
if (m_result != ResultType::Invalid)
|
||||||
sendCompleteInformation();
|
sendCompleteInformation();
|
||||||
BoostTestResult *result = new BoostTestResult(id(), {}, m_projectFile);
|
BoostTestResult result(id(), {}, m_projectFile);
|
||||||
QString txt = Tr::tr("No errors detected.");
|
QString txt = Tr::tr("No errors detected.");
|
||||||
if (m_testCaseCount != -1)
|
if (m_testCaseCount != -1)
|
||||||
txt.append(' ').append(Tr::tr("%1 tests passed.").arg(m_testCaseCount));
|
txt.append(' ').append(Tr::tr("%1 tests passed.").arg(m_testCaseCount));
|
||||||
result->setDescription(txt);
|
result.setDescription(txt);
|
||||||
result->setResult(ResultType::MessageInfo);
|
result.setResult(ResultType::MessageInfo);
|
||||||
reportResult(TestResultPtr(result));
|
reportResult(result);
|
||||||
if (m_reportLevel == ReportLevel::Confirm) // for the final summary
|
if (m_reportLevel == ReportLevel::Confirm) // for the final summary
|
||||||
m_summary.insert(ResultType::Pass, m_testCaseCount);
|
m_summary.insert(ResultType::Pass, m_testCaseCount);
|
||||||
return;
|
return;
|
||||||
@@ -372,16 +377,15 @@ void BoostTestOutputReader::processStdError(const QByteArray &outputLine)
|
|||||||
emit newOutputLineAvailable(outputLine, OutputChannel::StdErr);
|
emit newOutputLineAvailable(outputLine, OutputChannel::StdErr);
|
||||||
}
|
}
|
||||||
|
|
||||||
TestResultPtr BoostTestOutputReader::createDefaultResult() const
|
TestResult BoostTestOutputReader::createDefaultResult() const
|
||||||
{
|
{
|
||||||
return TestResultPtr(new BoostTestResult(id(), m_currentModule, m_projectFile,
|
return BoostTestResult(id(), m_currentModule, m_projectFile, m_currentTest, m_currentSuite);
|
||||||
m_currentTest, m_currentSuite));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BoostTestOutputReader::onDone() {
|
void BoostTestOutputReader::onDone(int exitCode)
|
||||||
int exitCode = m_testApplication->exitCode();
|
{
|
||||||
if (m_reportLevel == ReportLevel::No && m_testCaseCount != -1) {
|
if (m_reportLevel == ReportLevel::No && m_testCaseCount != -1) {
|
||||||
int reportedFailsAndSkips = m_summary[ResultType::Fail] + m_summary[ResultType::Skip];
|
const int reportedFailsAndSkips = m_summary[ResultType::Fail] + m_summary[ResultType::Skip];
|
||||||
m_summary.insert(ResultType::Pass, m_testCaseCount - reportedFailsAndSkips);
|
m_summary.insert(ResultType::Pass, m_testCaseCount - reportedFailsAndSkips);
|
||||||
}
|
}
|
||||||
// boost::exit_success (0), boost::exit_test_failure (201)
|
// boost::exit_success (0), boost::exit_test_failure (201)
|
||||||
@@ -416,11 +420,11 @@ void BoostTestOutputReader::onDone() {
|
|||||||
|
|
||||||
void BoostTestOutputReader::reportNoOutputFinish(const QString &description, ResultType type)
|
void BoostTestOutputReader::reportNoOutputFinish(const QString &description, ResultType type)
|
||||||
{
|
{
|
||||||
BoostTestResult *result = new BoostTestResult(id(), m_currentModule, m_projectFile,
|
BoostTestResult result(id(), m_currentModule, m_projectFile,
|
||||||
Tr::tr("Running tests without output."));
|
Tr::tr("Running tests without output."));
|
||||||
result->setDescription(description);
|
result.setDescription(description);
|
||||||
result->setResult(type);
|
result.setResult(type);
|
||||||
reportResult(TestResultPtr(result));
|
reportResult(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -15,16 +15,16 @@ class BoostTestOutputReader : public TestOutputReader
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
BoostTestOutputReader(const QFutureInterface<TestResultPtr> &futureInterface,
|
BoostTestOutputReader(const QFutureInterface<TestResult> &futureInterface,
|
||||||
Utils::QtcProcess *testApplication, const Utils::FilePath &buildDirectory,
|
Utils::QtcProcess *testApplication, const Utils::FilePath &buildDirectory,
|
||||||
const Utils::FilePath &projectFile, LogLevel log, ReportLevel report);
|
const Utils::FilePath &projectFile, LogLevel log, ReportLevel report);
|
||||||
protected:
|
protected:
|
||||||
void processOutputLine(const QByteArray &outputLine) override;
|
void processOutputLine(const QByteArray &outputLine) override;
|
||||||
void processStdError(const QByteArray &outputLine) override;
|
void processStdError(const QByteArray &outputLine) override;
|
||||||
TestResultPtr createDefaultResult() const override;
|
TestResult createDefaultResult() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void onDone();
|
void onDone(int exitCode);
|
||||||
void sendCompleteInformation();
|
void sendCompleteInformation();
|
||||||
void handleMessageMatch(const QRegularExpressionMatch &match);
|
void handleMessageMatch(const QRegularExpressionMatch &match);
|
||||||
void reportNoOutputFinish(const QString &description, ResultType type);
|
void reportNoOutputFinish(const QString &description, ResultType type);
|
||||||
|
@@ -78,8 +78,8 @@ static bool hasBoostTestMacros(const CPlusPlus::Document::Ptr &doc)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BoostTestParseResult *createParseResult(const QString &name, const Utils::FilePath &filePath,
|
static BoostTestParseResult *createParseResult(const QString &name, const FilePath &filePath,
|
||||||
const Utils::FilePath &projectFile,
|
const FilePath &projectFile,
|
||||||
ITestFramework *framework,
|
ITestFramework *framework,
|
||||||
TestTreeItem::Type type, const BoostTestInfo &info)
|
TestTreeItem::Type type, const BoostTestInfo &info)
|
||||||
{
|
{
|
||||||
@@ -97,7 +97,7 @@ static BoostTestParseResult *createParseResult(const QString &name, const Utils:
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool BoostTestParser::processDocument(QFutureInterface<TestParseResultPtr> &futureInterface,
|
bool BoostTestParser::processDocument(QFutureInterface<TestParseResultPtr> &futureInterface,
|
||||||
const Utils::FilePath &fileName)
|
const FilePath &fileName)
|
||||||
{
|
{
|
||||||
CPlusPlus::Document::Ptr doc = document(fileName);
|
CPlusPlus::Document::Ptr doc = document(fileName);
|
||||||
if (doc.isNull() || !includesBoostTest(doc, m_cppSnapshot) || !hasBoostTestMacros(doc))
|
if (doc.isNull() || !includesBoostTest(doc, m_cppSnapshot) || !hasBoostTestMacros(doc))
|
||||||
@@ -109,7 +109,7 @@ bool BoostTestParser::processDocument(QFutureInterface<TestParseResultPtr> &futu
|
|||||||
if (projectParts.isEmpty()) // happens if shutting down while parsing
|
if (projectParts.isEmpty()) // happens if shutting down while parsing
|
||||||
return false;
|
return false;
|
||||||
const CppEditor::ProjectPart::ConstPtr projectPart = projectParts.first();
|
const CppEditor::ProjectPart::ConstPtr projectPart = projectParts.first();
|
||||||
const auto projectFile = Utils::FilePath::fromString(projectPart->projectFile);
|
const auto projectFile = FilePath::fromString(projectPart->projectFile);
|
||||||
const QByteArray &fileContent = getFileContent(fileName);
|
const QByteArray &fileContent = getFileContent(fileName);
|
||||||
|
|
||||||
BoostCodeParser codeParser(fileContent, projectPart->languageFeatures, doc, m_cppSnapshot);
|
BoostCodeParser codeParser(fileContent, projectPart->languageFeatures, doc, m_cppSnapshot);
|
||||||
|
@@ -81,7 +81,7 @@ BoostTestSettings::BoostTestSettings()
|
|||||||
memLeaks.setToolTip(Tr::tr("Enable memory leak detection."));
|
memLeaks.setToolTip(Tr::tr("Enable memory leak detection."));
|
||||||
}
|
}
|
||||||
|
|
||||||
BoostTestSettingsPage::BoostTestSettingsPage(BoostTestSettings *settings, Utils::Id settingsId)
|
BoostTestSettingsPage::BoostTestSettingsPage(BoostTestSettings *settings, Id settingsId)
|
||||||
{
|
{
|
||||||
setId(settingsId);
|
setId(settingsId);
|
||||||
setCategory(Constants::AUTOTEST_SETTINGS_CATEGORY);
|
setCategory(Constants::AUTOTEST_SETTINGS_CATEGORY);
|
||||||
@@ -120,7 +120,7 @@ QString BoostTestSettings::logLevelToOption(const LogLevel logLevel)
|
|||||||
case LogLevel::Nothing: return QString("nothing");
|
case LogLevel::Nothing: return QString("nothing");
|
||||||
case LogLevel::Warning: return QString("warning");
|
case LogLevel::Warning: return QString("warning");
|
||||||
}
|
}
|
||||||
return QString();
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
QString BoostTestSettings::reportLevelToOption(const ReportLevel reportLevel)
|
QString BoostTestSettings::reportLevelToOption(const ReportLevel reportLevel)
|
||||||
@@ -131,7 +131,7 @@ QString BoostTestSettings::reportLevelToOption(const ReportLevel reportLevel)
|
|||||||
case ReportLevel::Detailed: return QString("detailed");
|
case ReportLevel::Detailed: return QString("detailed");
|
||||||
case ReportLevel::No: return QString("no");
|
case ReportLevel::No: return QString("no");
|
||||||
}
|
}
|
||||||
return QString();
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
|
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
namespace Autotest {
|
namespace Autotest {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
@@ -123,7 +125,7 @@ bool BoostTestTreeItem::modify(const TestParseResult *result)
|
|||||||
|
|
||||||
TestTreeItem *BoostTestTreeItem::createParentGroupNode() const
|
TestTreeItem *BoostTestTreeItem::createParentGroupNode() const
|
||||||
{
|
{
|
||||||
const Utils::FilePath &absPath = filePath().absolutePath();
|
const FilePath &absPath = filePath().absolutePath();
|
||||||
return new BoostTestTreeItem(framework(), absPath.baseName(), absPath, TestTreeItem::GroupNode);
|
return new BoostTestTreeItem(framework(), absPath.baseName(), absPath, TestTreeItem::GroupNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,7 +166,7 @@ QList<ITestConfiguration *> BoostTestTreeItem::getAllTestConfigurations() const
|
|||||||
};
|
};
|
||||||
|
|
||||||
// we only need the unique project files (and number of test cases for the progress indicator)
|
// we only need the unique project files (and number of test cases for the progress indicator)
|
||||||
QHash<Utils::FilePath, BoostTestCases> testsPerProjectfile;
|
QHash<FilePath, BoostTestCases> testsPerProjectfile;
|
||||||
forAllChildItems([&testsPerProjectfile](TestTreeItem *item){
|
forAllChildItems([&testsPerProjectfile](TestTreeItem *item){
|
||||||
if (item->type() != TestSuite)
|
if (item->type() != TestSuite)
|
||||||
return;
|
return;
|
||||||
@@ -207,7 +209,7 @@ QList<ITestConfiguration *> BoostTestTreeItem::getTestConfigurations(
|
|||||||
QSet<QString> internalTargets;
|
QSet<QString> internalTargets;
|
||||||
};
|
};
|
||||||
|
|
||||||
QHash<Utils::FilePath, BoostTestCases> testCasesForProjectFile;
|
QHash<FilePath, BoostTestCases> testCasesForProjectFile;
|
||||||
forAllChildren([&testCasesForProjectFile, &predicate](TreeItem *it){
|
forAllChildren([&testCasesForProjectFile, &predicate](TreeItem *it){
|
||||||
auto item = static_cast<BoostTestTreeItem *>(it);
|
auto item = static_cast<BoostTestTreeItem *>(it);
|
||||||
if (item->type() != TestCase)
|
if (item->type() != TestCase)
|
||||||
@@ -346,10 +348,10 @@ bool BoostTestTreeItem::enabled() const
|
|||||||
|
|
||||||
TestTreeItem *BoostTestTreeItem::findChildByNameStateAndFile(const QString &name,
|
TestTreeItem *BoostTestTreeItem::findChildByNameStateAndFile(const QString &name,
|
||||||
BoostTestTreeItem::TestStates state,
|
BoostTestTreeItem::TestStates state,
|
||||||
const Utils::FilePath &proFile) const
|
const FilePath &proFile) const
|
||||||
{
|
{
|
||||||
return static_cast<TestTreeItem *>(
|
return static_cast<TestTreeItem *>(
|
||||||
findAnyChild([name, state, proFile](const Utils::TreeItem *other){
|
findAnyChild([name, state, proFile](const TreeItem *other){
|
||||||
const BoostTestTreeItem *boostItem = static_cast<const BoostTestTreeItem *>(other);
|
const BoostTestTreeItem *boostItem = static_cast<const BoostTestTreeItem *>(other);
|
||||||
return boostItem->proFile() == proFile && boostItem->fullName() == name
|
return boostItem->proFile() == proFile && boostItem->fullName() == name
|
||||||
&& boostItem->state() == state;
|
&& boostItem->state() == state;
|
||||||
|
@@ -27,8 +27,8 @@ public:
|
|||||||
Q_DECLARE_FLAGS(TestStates, TestState)
|
Q_DECLARE_FLAGS(TestStates, TestState)
|
||||||
|
|
||||||
explicit BoostTestTreeItem(ITestFramework *framework,
|
explicit BoostTestTreeItem(ITestFramework *framework,
|
||||||
const QString &name = QString(),
|
const QString &name = {},
|
||||||
const Utils::FilePath &filePath = Utils::FilePath(),
|
const Utils::FilePath &filePath = {},
|
||||||
Type type = Root)
|
Type type = Root)
|
||||||
: TestTreeItem(framework, name, filePath, type)
|
: TestTreeItem(framework, name, filePath, type)
|
||||||
{}
|
{}
|
||||||
|
@@ -11,11 +11,13 @@
|
|||||||
|
|
||||||
#include <utils/stringutils.h>
|
#include <utils/stringutils.h>
|
||||||
|
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
namespace Autotest {
|
namespace Autotest {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
TestOutputReader *CatchConfiguration::createOutputReader(const QFutureInterface<TestResultPtr> &fi,
|
TestOutputReader *CatchConfiguration::createOutputReader(const QFutureInterface<TestResult> &fi,
|
||||||
Utils::QtcProcess *app) const
|
QtcProcess *app) const
|
||||||
{
|
{
|
||||||
return new CatchOutputReader(fi, app, buildDirectory(), projectFile());
|
return new CatchOutputReader(fi, app, buildDirectory(), projectFile());
|
||||||
}
|
}
|
||||||
@@ -115,7 +117,7 @@ QStringList CatchConfiguration::argumentsForTestRunner(QStringList *omitted) con
|
|||||||
return arguments;
|
return arguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
Utils::Environment CatchConfiguration::filteredEnvironment(const Utils::Environment &original) const
|
Environment CatchConfiguration::filteredEnvironment(const Environment &original) const
|
||||||
{
|
{
|
||||||
return original;
|
return original;
|
||||||
}
|
}
|
||||||
|
@@ -12,7 +12,7 @@ class CatchConfiguration : public DebuggableTestConfiguration
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CatchConfiguration(ITestFramework *framework) : DebuggableTestConfiguration(framework) {}
|
CatchConfiguration(ITestFramework *framework) : DebuggableTestConfiguration(framework) {}
|
||||||
TestOutputReader *createOutputReader(const QFutureInterface<TestResultPtr> &fi,
|
TestOutputReader *createOutputReader(const QFutureInterface<TestResult> &fi,
|
||||||
Utils::QtcProcess *app) const override;
|
Utils::QtcProcess *app) const override;
|
||||||
QStringList argumentsForTestRunner(QStringList *omitted = nullptr) const override;
|
QStringList argumentsForTestRunner(QStringList *omitted = nullptr) const override;
|
||||||
Utils::Environment filteredEnvironment(const Utils::Environment &original) const override;
|
Utils::Environment filteredEnvironment(const Utils::Environment &original) const override;
|
||||||
|
@@ -32,9 +32,7 @@ ITestParser *CatchFramework::createTestParser()
|
|||||||
|
|
||||||
ITestTreeItem *CatchFramework::createRootNode()
|
ITestTreeItem *CatchFramework::createRootNode()
|
||||||
{
|
{
|
||||||
return new CatchTreeItem(this,
|
return new CatchTreeItem(this, displayName(), {}, ITestTreeItem::Root);
|
||||||
displayName(),
|
|
||||||
Utils::FilePath(), ITestTreeItem::Root);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -9,6 +9,8 @@
|
|||||||
#include <utils/fileutils.h>
|
#include <utils/fileutils.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
namespace Autotest {
|
namespace Autotest {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
@@ -29,10 +31,10 @@ namespace CatchXml {
|
|||||||
const char TestCaseResultElement[] = "OverallResult";
|
const char TestCaseResultElement[] = "OverallResult";
|
||||||
}
|
}
|
||||||
|
|
||||||
CatchOutputReader::CatchOutputReader(const QFutureInterface<TestResultPtr> &futureInterface,
|
CatchOutputReader::CatchOutputReader(const QFutureInterface<TestResult> &futureInterface,
|
||||||
Utils::QtcProcess *testApplication,
|
QtcProcess *testApplication,
|
||||||
const Utils::FilePath &buildDirectory,
|
const FilePath &buildDirectory,
|
||||||
const Utils::FilePath &projectFile)
|
const FilePath &projectFile)
|
||||||
: TestOutputReader (futureInterface, testApplication, buildDirectory)
|
: TestOutputReader (futureInterface, testApplication, buildDirectory)
|
||||||
, m_projectFile(projectFile)
|
, m_projectFile(projectFile)
|
||||||
{
|
{
|
||||||
@@ -169,22 +171,17 @@ void CatchOutputReader::processOutputLine(const QByteArray &outputLineWithNewLin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TestResultPtr CatchOutputReader::createDefaultResult() const
|
TestResult CatchOutputReader::createDefaultResult() const
|
||||||
{
|
{
|
||||||
CatchResult *result = nullptr;
|
if (m_testCaseInfo.size() == 0)
|
||||||
if (m_testCaseInfo.size() > 0) {
|
return CatchResult(id(), {}, m_sectionDepth);
|
||||||
result = new CatchResult(id(), m_testCaseInfo.first().name, m_sectionDepth);
|
CatchResult result = CatchResult(id(), m_testCaseInfo.first().name, m_sectionDepth);
|
||||||
result->setDescription(m_testCaseInfo.last().name);
|
result.setDescription(m_testCaseInfo.last().name);
|
||||||
result->setLine(m_testCaseInfo.last().line);
|
result.setLine(m_testCaseInfo.last().line);
|
||||||
const QString givenPath = m_testCaseInfo.last().filename;
|
const QString givenPath = m_testCaseInfo.last().filename;
|
||||||
if (!givenPath.isEmpty()) {
|
if (!givenPath.isEmpty())
|
||||||
result->setFileName(constructSourceFilePath(m_buildDir, givenPath));
|
result.setFileName(constructSourceFilePath(m_buildDir, givenPath));
|
||||||
}
|
return result;
|
||||||
} else {
|
|
||||||
result = new CatchResult(id(), {}, m_sectionDepth);
|
|
||||||
}
|
|
||||||
|
|
||||||
return TestResultPtr(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CatchOutputReader::recordTestInformation(const QXmlStreamAttributes &attributes)
|
void CatchOutputReader::recordTestInformation(const QXmlStreamAttributes &attributes)
|
||||||
@@ -242,37 +239,38 @@ void CatchOutputReader::recordBenchmarkDetails(
|
|||||||
|
|
||||||
void CatchOutputReader::sendResult(const ResultType result)
|
void CatchOutputReader::sendResult(const ResultType result)
|
||||||
{
|
{
|
||||||
TestResultPtr catchResult = createDefaultResult();
|
TestResult catchResult = createDefaultResult();
|
||||||
catchResult->setResult(result);
|
catchResult.setResult(result);
|
||||||
|
|
||||||
if (result == ResultType::TestStart && m_testCaseInfo.size() > 0) {
|
if (result == ResultType::TestStart && m_testCaseInfo.size() > 0) {
|
||||||
catchResult->setDescription(Tr::tr("Executing %1 \"%2\"").arg(testOutputNodeToString().toLower())
|
catchResult.setDescription(Tr::tr("Executing %1 \"%2\"")
|
||||||
.arg(catchResult->description()));
|
.arg(testOutputNodeToString().toLower(), catchResult.description()));
|
||||||
} else if (result == ResultType::Pass || result == ResultType::UnexpectedPass) {
|
} else if (result == ResultType::Pass || result == ResultType::UnexpectedPass) {
|
||||||
if (result == ResultType::UnexpectedPass)
|
if (result == ResultType::UnexpectedPass)
|
||||||
++m_xpassCount;
|
++m_xpassCount;
|
||||||
|
|
||||||
if (m_currentExpression.isEmpty()) {
|
if (m_currentExpression.isEmpty()) {
|
||||||
catchResult->setDescription(Tr::tr("%1 \"%2\" passed").arg(testOutputNodeToString())
|
catchResult.setDescription(Tr::tr("%1 \"%2\" passed")
|
||||||
.arg(catchResult->description()));
|
.arg(testOutputNodeToString(), catchResult.description()));
|
||||||
} else {
|
} else {
|
||||||
catchResult->setDescription(Tr::tr("Expression passed")
|
catchResult.setDescription(Tr::tr("Expression passed")
|
||||||
.append('\n').append(m_currentExpression));
|
.append('\n').append(m_currentExpression));
|
||||||
}
|
}
|
||||||
m_reportedSectionResult = true;
|
m_reportedSectionResult = true;
|
||||||
m_reportedResult = true;
|
m_reportedResult = true;
|
||||||
} else if (result == ResultType::Fail || result == ResultType::ExpectedFail) {
|
} else if (result == ResultType::Fail || result == ResultType::ExpectedFail) {
|
||||||
catchResult->setDescription(Tr::tr("Expression failed: %1").arg(m_currentExpression.trimmed()));
|
catchResult.setDescription(Tr::tr("Expression failed: %1")
|
||||||
|
.arg(m_currentExpression.trimmed()));
|
||||||
if (!m_reportedSectionResult)
|
if (!m_reportedSectionResult)
|
||||||
m_reportedSectionResult = true;
|
m_reportedSectionResult = true;
|
||||||
m_reportedResult = true;
|
m_reportedResult = true;
|
||||||
} else if (result == ResultType::TestEnd) {
|
} else if (result == ResultType::TestEnd) {
|
||||||
catchResult->setDescription(Tr::tr("Finished executing %1 \"%2\"").arg(testOutputNodeToString().toLower())
|
catchResult.setDescription(Tr::tr("Finished executing %1 \"%2\"")
|
||||||
.arg(catchResult->description()));
|
.arg(testOutputNodeToString().toLower(), catchResult.description()));
|
||||||
} else if (result == ResultType::Benchmark || result == ResultType::MessageFatal) {
|
} else if (result == ResultType::Benchmark || result == ResultType::MessageFatal) {
|
||||||
catchResult->setDescription(m_currentExpression);
|
catchResult.setDescription(m_currentExpression);
|
||||||
} else if (result == ResultType::MessageWarn || result == ResultType::MessageInfo) {
|
} else if (result == ResultType::MessageWarn || result == ResultType::MessageInfo) {
|
||||||
catchResult->setDescription(m_currentExpression.trimmed());
|
catchResult.setDescription(m_currentExpression.trimmed());
|
||||||
}
|
}
|
||||||
|
|
||||||
reportResult(catchResult);
|
reportResult(catchResult);
|
||||||
@@ -319,8 +317,7 @@ QString CatchOutputReader::testOutputNodeToString() const
|
|||||||
case SectionNode:
|
case SectionNode:
|
||||||
return QStringLiteral("Section");
|
return QStringLiteral("Section");
|
||||||
}
|
}
|
||||||
|
return {};
|
||||||
return QString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -14,13 +14,13 @@ namespace Internal {
|
|||||||
class CatchOutputReader : public TestOutputReader
|
class CatchOutputReader : public TestOutputReader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CatchOutputReader(const QFutureInterface<TestResultPtr> &futureInterface,
|
CatchOutputReader(const QFutureInterface<TestResult> &futureInterface,
|
||||||
Utils::QtcProcess *testApplication, const Utils::FilePath &buildDirectory,
|
Utils::QtcProcess *testApplication, const Utils::FilePath &buildDirectory,
|
||||||
const Utils::FilePath &projectFile);
|
const Utils::FilePath &projectFile);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void processOutputLine(const QByteArray &outputLineWithNewLine) override;
|
void processOutputLine(const QByteArray &outputLineWithNewLine) override;
|
||||||
TestResultPtr createDefaultResult() const override;
|
TestResult createDefaultResult() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum TestOutputNodeType {
|
enum TestOutputNodeType {
|
||||||
|
@@ -92,7 +92,7 @@ static bool hasCatchNames(const CPlusPlus::Document::Ptr &document)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool CatchTestParser::processDocument(QFutureInterface<TestParseResultPtr> &futureInterface,
|
bool CatchTestParser::processDocument(QFutureInterface<TestParseResultPtr> &futureInterface,
|
||||||
const Utils::FilePath &fileName)
|
const FilePath &fileName)
|
||||||
{
|
{
|
||||||
CPlusPlus::Document::Ptr doc = document(fileName);
|
CPlusPlus::Document::Ptr doc = document(fileName);
|
||||||
if (doc.isNull() || !includesCatchHeader(doc, m_cppSnapshot))
|
if (doc.isNull() || !includesCatchHeader(doc, m_cppSnapshot))
|
||||||
@@ -117,9 +117,9 @@ bool CatchTestParser::processDocument(QFutureInterface<TestParseResultPtr> &futu
|
|||||||
const QList<CppEditor::ProjectPart::ConstPtr> projectParts = modelManager->projectPart(fileName);
|
const QList<CppEditor::ProjectPart::ConstPtr> projectParts = modelManager->projectPart(fileName);
|
||||||
if (projectParts.isEmpty()) // happens if shutting down while parsing
|
if (projectParts.isEmpty()) // happens if shutting down while parsing
|
||||||
return false;
|
return false;
|
||||||
Utils::FilePath proFile;
|
FilePath proFile;
|
||||||
const CppEditor::ProjectPart::ConstPtr projectPart = projectParts.first();
|
const CppEditor::ProjectPart::ConstPtr projectPart = projectParts.first();
|
||||||
proFile = Utils::FilePath::fromString(projectPart->projectFile);
|
proFile = FilePath::fromString(projectPart->projectFile);
|
||||||
|
|
||||||
CatchCodeParser codeParser(fileContent, projectPart->languageFeatures);
|
CatchCodeParser codeParser(fileContent, projectPart->languageFeatures);
|
||||||
const CatchTestCodeLocationList foundTests = codeParser.findTests();
|
const CatchTestCodeLocationList foundTests = codeParser.findTests();
|
||||||
|
@@ -114,7 +114,7 @@ CatchTestSettings::CatchTestSettings()
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
CatchTestSettingsPage::CatchTestSettingsPage(CatchTestSettings *settings, Utils::Id settingsId)
|
CatchTestSettingsPage::CatchTestSettingsPage(CatchTestSettings *settings, Id settingsId)
|
||||||
{
|
{
|
||||||
setId(settingsId);
|
setId(settingsId);
|
||||||
setCategory(Constants::AUTOTEST_SETTINGS_CATEGORY);
|
setCategory(Constants::AUTOTEST_SETTINGS_CATEGORY);
|
||||||
|
@@ -14,6 +14,8 @@
|
|||||||
#include <projectexplorer/session.h>
|
#include <projectexplorer/session.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
namespace Autotest {
|
namespace Autotest {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
@@ -72,7 +74,7 @@ TestTreeItem *CatchTreeItem::find(const TestParseResult *result)
|
|||||||
switch (type()) {
|
switch (type()) {
|
||||||
case Root:
|
case Root:
|
||||||
if (result->framework->grouping()) {
|
if (result->framework->grouping()) {
|
||||||
const Utils::FilePath path = result->fileName.absolutePath();
|
const FilePath path = result->fileName.absolutePath();
|
||||||
for (int row = 0; row < childCount(); ++row) {
|
for (int row = 0; row < childCount(); ++row) {
|
||||||
TestTreeItem *group = childItem(row);
|
TestTreeItem *group = childItem(row);
|
||||||
if (group->filePath() != path)
|
if (group->filePath() != path)
|
||||||
@@ -123,7 +125,7 @@ bool CatchTreeItem::modify(const TestParseResult *result)
|
|||||||
|
|
||||||
TestTreeItem *CatchTreeItem::createParentGroupNode() const
|
TestTreeItem *CatchTreeItem::createParentGroupNode() const
|
||||||
{
|
{
|
||||||
const Utils::FilePath absPath = filePath().absolutePath();
|
const FilePath absPath = filePath().absolutePath();
|
||||||
return new CatchTreeItem(framework(), absPath.baseName(), absPath, TestTreeItem::GroupNode);
|
return new CatchTreeItem(framework(), absPath.baseName(), absPath, TestTreeItem::GroupNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -172,7 +174,7 @@ struct CatchTestCases
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void collectTestInfo(const TestTreeItem *item,
|
static void collectTestInfo(const TestTreeItem *item,
|
||||||
QHash<Utils::FilePath, CatchTestCases> &testCasesForProfile,
|
QHash<FilePath, CatchTestCases> &testCasesForProfile,
|
||||||
bool ignoreCheckState)
|
bool ignoreCheckState)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(item, return);
|
QTC_ASSERT(item, return);
|
||||||
@@ -189,7 +191,7 @@ static void collectTestInfo(const TestTreeItem *item,
|
|||||||
QTC_ASSERT(childCount != 0, return);
|
QTC_ASSERT(childCount != 0, return);
|
||||||
QTC_ASSERT(item->type() == TestTreeItem::TestSuite, return);
|
QTC_ASSERT(item->type() == TestTreeItem::TestSuite, return);
|
||||||
if (ignoreCheckState || item->checked() == Qt::Checked) {
|
if (ignoreCheckState || item->checked() == Qt::Checked) {
|
||||||
const Utils::FilePath &projectFile = item->childItem(0)->proFile();
|
const FilePath &projectFile = item->childItem(0)->proFile();
|
||||||
item->forAllChildItems([&testCasesForProfile, &projectFile](TestTreeItem *it) {
|
item->forAllChildItems([&testCasesForProfile, &projectFile](TestTreeItem *it) {
|
||||||
CatchTreeItem *current = static_cast<CatchTreeItem *>(it);
|
CatchTreeItem *current = static_cast<CatchTreeItem *>(it);
|
||||||
testCasesForProfile[projectFile].names.append(current->testCasesString());
|
testCasesForProfile[projectFile].names.append(current->testCasesString());
|
||||||
@@ -210,7 +212,7 @@ static void collectTestInfo(const TestTreeItem *item,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void collectFailedTestInfo(const CatchTreeItem *item,
|
static void collectFailedTestInfo(const CatchTreeItem *item,
|
||||||
QHash<Utils::FilePath, CatchTestCases> &testCasesForProfile)
|
QHash<FilePath, CatchTestCases> &testCasesForProfile)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(item, return);
|
QTC_ASSERT(item, return);
|
||||||
QTC_ASSERT(item->type() == TestTreeItem::Root, return);
|
QTC_ASSERT(item->type() == TestTreeItem::Root, return);
|
||||||
@@ -246,7 +248,7 @@ QList<ITestConfiguration *> CatchTreeItem::getFailedTestConfigurations() const
|
|||||||
if (!project || type() != Root)
|
if (!project || type() != Root)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
QHash<Utils::FilePath, CatchTestCases> testCasesForProFile;
|
QHash<FilePath, CatchTestCases> testCasesForProFile;
|
||||||
collectFailedTestInfo(this, testCasesForProFile);
|
collectFailedTestInfo(this, testCasesForProFile);
|
||||||
|
|
||||||
for (auto it = testCasesForProFile.begin(), end = testCasesForProFile.end(); it != end; ++it) {
|
for (auto it = testCasesForProFile.begin(), end = testCasesForProFile.end(); it != end; ++it) {
|
||||||
@@ -263,7 +265,7 @@ QList<ITestConfiguration *> CatchTreeItem::getFailedTestConfigurations() const
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<ITestConfiguration *> CatchTreeItem::getTestConfigurationsForFile(const Utils::FilePath &fileName) const
|
QList<ITestConfiguration *> CatchTreeItem::getTestConfigurationsForFile(const FilePath &fileName) const
|
||||||
{
|
{
|
||||||
QList<ITestConfiguration *> result;
|
QList<ITestConfiguration *> result;
|
||||||
const auto cppMM = CppEditor::CppModelManager::instance();
|
const auto cppMM = CppEditor::CppModelManager::instance();
|
||||||
@@ -316,7 +318,7 @@ QList<ITestConfiguration *> CatchTreeItem::getTestConfigurations(bool ignoreChec
|
|||||||
if (!project || type() != Root)
|
if (!project || type() != Root)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
QHash<Utils::FilePath, CatchTestCases> testCasesForProfile;
|
QHash<FilePath, CatchTestCases> testCasesForProfile;
|
||||||
for (int row = 0, end = childCount(); row < end; ++row)
|
for (int row = 0, end = childCount(); row < end; ++row)
|
||||||
collectTestInfo(childItem(row), testCasesForProfile, ignoreCheckState);
|
collectTestInfo(childItem(row), testCasesForProfile, ignoreCheckState);
|
||||||
|
|
||||||
|
@@ -20,8 +20,8 @@ public:
|
|||||||
Q_FLAGS(TestState)
|
Q_FLAGS(TestState)
|
||||||
Q_DECLARE_FLAGS(TestStates, TestState)
|
Q_DECLARE_FLAGS(TestStates, TestState)
|
||||||
|
|
||||||
explicit CatchTreeItem(ITestFramework *testFramework, const QString &name = QString(),
|
explicit CatchTreeItem(ITestFramework *testFramework, const QString &name = {},
|
||||||
const Utils::FilePath &filePath = Utils::FilePath(), Type type = Root)
|
const Utils::FilePath &filePath = {}, Type type = Root)
|
||||||
: TestTreeItem(testFramework, name, filePath, type) {}
|
: TestTreeItem(testFramework, name, filePath, type) {}
|
||||||
|
|
||||||
void setStates(CatchTreeItem::TestStates state) { m_state = state; }
|
void setStates(CatchTreeItem::TestStates state) { m_state = state; }
|
||||||
|
@@ -13,7 +13,7 @@ CTestConfiguration::CTestConfiguration(ITestBase *testBase)
|
|||||||
setDisplayName("CTest");
|
setDisplayName("CTest");
|
||||||
}
|
}
|
||||||
|
|
||||||
TestOutputReader *CTestConfiguration::createOutputReader(const QFutureInterface<TestResultPtr> &fi,
|
TestOutputReader *CTestConfiguration::createOutputReader(const QFutureInterface<TestResult> &fi,
|
||||||
Utils::QtcProcess *app) const
|
Utils::QtcProcess *app) const
|
||||||
{
|
{
|
||||||
return new CTestOutputReader(fi, app, workingDirectory());
|
return new CTestOutputReader(fi, app, workingDirectory());
|
||||||
|
@@ -13,7 +13,7 @@ class CTestConfiguration final : public Autotest::TestToolConfiguration
|
|||||||
public:
|
public:
|
||||||
explicit CTestConfiguration(ITestBase *testBase);
|
explicit CTestConfiguration(ITestBase *testBase);
|
||||||
|
|
||||||
TestOutputReader *createOutputReader(const QFutureInterface<TestResultPtr> &fi,
|
TestOutputReader *createOutputReader(const QFutureInterface<TestResult> &fi,
|
||||||
Utils::QtcProcess *app) const final;
|
Utils::QtcProcess *app) const final;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -52,9 +52,9 @@ public:
|
|||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
CTestOutputReader::CTestOutputReader(const QFutureInterface<TestResultPtr> &futureInterface,
|
CTestOutputReader::CTestOutputReader(const QFutureInterface<TestResult> &futureInterface,
|
||||||
Utils::QtcProcess *testApplication,
|
QtcProcess *testApplication,
|
||||||
const Utils::FilePath &buildDirectory)
|
const FilePath &buildDirectory)
|
||||||
: TestOutputReader(futureInterface, testApplication, buildDirectory)
|
: TestOutputReader(futureInterface, testApplication, buildDirectory)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -91,9 +91,9 @@ void CTestOutputReader::processOutputLine(const QByteArray &outputLine)
|
|||||||
if (!m_testName.isEmpty()) // possible?
|
if (!m_testName.isEmpty()) // possible?
|
||||||
sendCompleteInformation();
|
sendCompleteInformation();
|
||||||
m_project = match.captured(1);
|
m_project = match.captured(1);
|
||||||
TestResultPtr testResult = createDefaultResult();
|
TestResult testResult = createDefaultResult();
|
||||||
testResult->setResult(ResultType::TestStart);
|
testResult.setResult(ResultType::TestStart);
|
||||||
testResult->setDescription(Tr::tr("Running tests for %1").arg(m_project));
|
testResult.setDescription(Tr::tr("Running tests for %1").arg(m_project));
|
||||||
reportResult(testResult);
|
reportResult(testResult);
|
||||||
} else if (ExactMatch match = testCase1.match(line)) {
|
} else if (ExactMatch match = testCase1.match(line)) {
|
||||||
int current = match.captured("current").toInt();
|
int current = match.captured("current").toInt();
|
||||||
@@ -125,9 +125,9 @@ void CTestOutputReader::processOutputLine(const QByteArray &outputLine)
|
|||||||
} else if (ExactMatch match = summary.match(line)) {
|
} else if (ExactMatch match = summary.match(line)) {
|
||||||
if (!m_testName.isEmpty())
|
if (!m_testName.isEmpty())
|
||||||
sendCompleteInformation();
|
sendCompleteInformation();
|
||||||
TestResultPtr testResult = createDefaultResult();
|
TestResult testResult = createDefaultResult();
|
||||||
testResult->setResult(ResultType::MessageInfo);
|
testResult.setResult(ResultType::MessageInfo);
|
||||||
testResult->setDescription(match.captured());
|
testResult.setDescription(match.captured());
|
||||||
reportResult(testResult);
|
reportResult(testResult);
|
||||||
int failed = match.captured(1).toInt();
|
int failed = match.captured(1).toInt();
|
||||||
int testCount = match.captured(2).toInt();
|
int testCount = match.captured(2).toInt();
|
||||||
@@ -136,9 +136,9 @@ void CTestOutputReader::processOutputLine(const QByteArray &outputLine)
|
|||||||
} else if (ExactMatch match = summaryTime.match(line)) {
|
} else if (ExactMatch match = summaryTime.match(line)) {
|
||||||
if (!m_testName.isEmpty()) // possible?
|
if (!m_testName.isEmpty()) // possible?
|
||||||
sendCompleteInformation();
|
sendCompleteInformation();
|
||||||
TestResultPtr testResult = createDefaultResult();
|
TestResult testResult = createDefaultResult();
|
||||||
testResult->setResult(ResultType::TestEnd);
|
testResult.setResult(ResultType::TestEnd);
|
||||||
testResult->setDescription(match.captured());
|
testResult.setDescription(match.captured());
|
||||||
reportResult(testResult);
|
reportResult(testResult);
|
||||||
} else if (ExactMatch match = testCrash.match(line)) {
|
} else if (ExactMatch match = testCrash.match(line)) {
|
||||||
m_description = match.captured();
|
m_description = match.captured();
|
||||||
@@ -156,9 +156,9 @@ void CTestOutputReader::processOutputLine(const QByteArray &outputLine)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TestResultPtr CTestOutputReader::createDefaultResult() const
|
TestResult CTestOutputReader::createDefaultResult() const
|
||||||
{
|
{
|
||||||
return TestResultPtr(new CTestResult(id(), m_project, m_testName));
|
return CTestResult(id(), m_project, m_testName);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTestOutputReader::sendCompleteInformation()
|
void CTestOutputReader::sendCompleteInformation()
|
||||||
@@ -168,10 +168,9 @@ void CTestOutputReader::sendCompleteInformation()
|
|||||||
QTC_CHECK(m_currentTestNo == -1 && m_testName.isEmpty());
|
QTC_CHECK(m_currentTestNo == -1 && m_testName.isEmpty());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
TestResult testResult = createDefaultResult();
|
||||||
TestResultPtr testResult = createDefaultResult();
|
testResult.setResult(m_result);
|
||||||
testResult->setResult(m_result);
|
testResult.setDescription(m_description);
|
||||||
testResult->setDescription(m_description);
|
|
||||||
reportResult(testResult);
|
reportResult(testResult);
|
||||||
m_testName.clear();
|
m_testName.clear();
|
||||||
m_description.clear();
|
m_description.clear();
|
||||||
|
@@ -13,12 +13,12 @@ namespace Internal {
|
|||||||
class CTestOutputReader final : public Autotest::TestOutputReader
|
class CTestOutputReader final : public Autotest::TestOutputReader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CTestOutputReader(const QFutureInterface<TestResultPtr> &futureInterface,
|
CTestOutputReader(const QFutureInterface<TestResult> &futureInterface,
|
||||||
Utils::QtcProcess *testApplication, const Utils::FilePath &buildDirectory);
|
Utils::QtcProcess *testApplication, const Utils::FilePath &buildDirectory);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void processOutputLine(const QByteArray &outputLineWithNewLine) final;
|
void processOutputLine(const QByteArray &outputLineWithNewLine) final;
|
||||||
TestResultPtr createDefaultResult() const final;
|
TestResult createDefaultResult() const final;
|
||||||
private:
|
private:
|
||||||
void sendCompleteInformation();
|
void sendCompleteInformation();
|
||||||
int m_currentTestNo = -1;
|
int m_currentTestNo = -1;
|
||||||
|
@@ -36,9 +36,7 @@ QString CTestTool::displayName() const
|
|||||||
|
|
||||||
ITestTreeItem *CTestTool::createRootNode()
|
ITestTreeItem *CTestTool::createRootNode()
|
||||||
{
|
{
|
||||||
return new CTestTreeItem(this,
|
return new CTestTreeItem(this, displayName(), {}, ITestTreeItem::Root);
|
||||||
displayName(),
|
|
||||||
Utils::FilePath(), ITestTreeItem::Root);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -20,11 +20,13 @@
|
|||||||
#include <utils/link.h>
|
#include <utils/link.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
namespace Autotest {
|
namespace Autotest {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
CTestTreeItem::CTestTreeItem(ITestBase *testBase, const QString &name,
|
CTestTreeItem::CTestTreeItem(ITestBase *testBase, const QString &name,
|
||||||
const Utils::FilePath &filepath, Type type)
|
const FilePath &filepath, Type type)
|
||||||
: ITestTreeItem(testBase, name, filepath, type)
|
: ITestTreeItem(testBase, name, filepath, type)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -69,7 +71,7 @@ QVariant CTestTreeItem::data(int column, int role) const
|
|||||||
return checked();
|
return checked();
|
||||||
if (role == LinkRole) {
|
if (role == LinkRole) {
|
||||||
QVariant itemLink;
|
QVariant itemLink;
|
||||||
itemLink.setValue(Utils::Link(filePath(), line()));
|
itemLink.setValue(Link(filePath(), line()));
|
||||||
return itemLink;
|
return itemLink;
|
||||||
}
|
}
|
||||||
return ITestTreeItem::data(column, role);
|
return ITestTreeItem::data(column, role);
|
||||||
@@ -89,7 +91,7 @@ QList<ITestConfiguration *> CTestTreeItem::testConfigurationsFor(const QStringLi
|
|||||||
QStringList options{"--timeout", QString::number(AutotestPlugin::settings()->timeout / 1000)};
|
QStringList options{"--timeout", QString::number(AutotestPlugin::settings()->timeout / 1000)};
|
||||||
auto ctestSettings = static_cast<CTestSettings *>(testBase()->testSettings());
|
auto ctestSettings = static_cast<CTestSettings *>(testBase()->testSettings());
|
||||||
options << ctestSettings->activeSettingsAsOptions();
|
options << ctestSettings->activeSettingsAsOptions();
|
||||||
Utils::CommandLine command = buildSystem->commandLineForTests(selected, options);
|
CommandLine command = buildSystem->commandLineForTests(selected, options);
|
||||||
if (command.executable().isEmpty())
|
if (command.executable().isEmpty())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
@@ -97,12 +99,12 @@ QList<ITestConfiguration *> CTestTreeItem::testConfigurationsFor(const QStringLi
|
|||||||
config->setProject(project);
|
config->setProject(project);
|
||||||
config->setCommandLine(command);
|
config->setCommandLine(command);
|
||||||
const ProjectExplorer::RunConfiguration *runConfig = target->activeRunConfiguration();
|
const ProjectExplorer::RunConfiguration *runConfig = target->activeRunConfiguration();
|
||||||
Utils::Environment env = Utils::Environment::systemEnvironment();
|
Environment env = Environment::systemEnvironment();
|
||||||
if (QTC_GUARD(runConfig)) {
|
if (QTC_GUARD(runConfig)) {
|
||||||
if (auto envAspect = runConfig->aspect<ProjectExplorer::EnvironmentAspect>())
|
if (auto envAspect = runConfig->aspect<ProjectExplorer::EnvironmentAspect>())
|
||||||
env = envAspect->environment();
|
env = envAspect->environment();
|
||||||
}
|
}
|
||||||
if (Utils::HostOsInfo::isWindowsHost()) {
|
if (HostOsInfo::isWindowsHost()) {
|
||||||
env.set("QT_FORCE_STDERR_LOGGING", "1");
|
env.set("QT_FORCE_STDERR_LOGGING", "1");
|
||||||
env.set("QT_LOGGING_TO_CONSOLE", "1");
|
env.set("QT_LOGGING_TO_CONSOLE", "1");
|
||||||
}
|
}
|
||||||
|
@@ -12,11 +12,13 @@
|
|||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
#include <utils/stringutils.h>
|
#include <utils/stringutils.h>
|
||||||
|
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
namespace Autotest {
|
namespace Autotest {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
TestOutputReader *GTestConfiguration::createOutputReader(const QFutureInterface<TestResultPtr> &fi,
|
TestOutputReader *GTestConfiguration::createOutputReader(const QFutureInterface<TestResult> &fi,
|
||||||
Utils::QtcProcess *app) const
|
QtcProcess *app) const
|
||||||
{
|
{
|
||||||
return new GTestOutputReader(fi, app, buildDirectory(), projectFile());
|
return new GTestOutputReader(fi, app, buildDirectory(), projectFile());
|
||||||
}
|
}
|
||||||
@@ -88,13 +90,13 @@ QStringList GTestConfiguration::argumentsForTestRunner(QStringList *omitted) con
|
|||||||
return arguments;
|
return arguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
Utils::Environment GTestConfiguration::filteredEnvironment(const Utils::Environment &original) const
|
Environment GTestConfiguration::filteredEnvironment(const Environment &original) const
|
||||||
{
|
{
|
||||||
const QStringList interfering{"GTEST_FILTER", "GTEST_ALSO_RUN_DISABLED_TESTS",
|
const QStringList interfering{"GTEST_FILTER", "GTEST_ALSO_RUN_DISABLED_TESTS",
|
||||||
"GTEST_REPEAT", "GTEST_SHUFFLE", "GTEST_RANDOM_SEED",
|
"GTEST_REPEAT", "GTEST_SHUFFLE", "GTEST_RANDOM_SEED",
|
||||||
"GTEST_OUTPUT", "GTEST_BREAK_ON_FAILURE", "GTEST_PRINT_TIME",
|
"GTEST_OUTPUT", "GTEST_BREAK_ON_FAILURE", "GTEST_PRINT_TIME",
|
||||||
"GTEST_CATCH_EXCEPTIONS"};
|
"GTEST_CATCH_EXCEPTIONS"};
|
||||||
Utils::Environment result = original;
|
Environment result = original;
|
||||||
if (!result.hasKey("GTEST_COLOR"))
|
if (!result.hasKey("GTEST_COLOR"))
|
||||||
result.set("GTEST_COLOR", "1"); // use colored output by default
|
result.set("GTEST_COLOR", "1"); // use colored output by default
|
||||||
for (const QString &key : interfering)
|
for (const QString &key : interfering)
|
||||||
|
@@ -14,7 +14,7 @@ public:
|
|||||||
explicit GTestConfiguration(ITestFramework *framework)
|
explicit GTestConfiguration(ITestFramework *framework)
|
||||||
: DebuggableTestConfiguration(framework) {}
|
: DebuggableTestConfiguration(framework) {}
|
||||||
|
|
||||||
TestOutputReader *createOutputReader(const QFutureInterface<TestResultPtr> &fi,
|
TestOutputReader *createOutputReader(const QFutureInterface<TestResult> &fi,
|
||||||
Utils::QtcProcess *app) const override;
|
Utils::QtcProcess *app) const override;
|
||||||
QStringList argumentsForTestRunner(QStringList *omitted = nullptr) const override;
|
QStringList argumentsForTestRunner(QStringList *omitted = nullptr) const override;
|
||||||
Utils::Environment filteredEnvironment(const Utils::Environment &original) const override;
|
Utils::Environment filteredEnvironment(const Utils::Environment &original) const override;
|
||||||
|
@@ -25,10 +25,7 @@ ITestParser *GTestFramework::createTestParser()
|
|||||||
|
|
||||||
ITestTreeItem *GTestFramework::createRootNode()
|
ITestTreeItem *GTestFramework::createRootNode()
|
||||||
{
|
{
|
||||||
return new GTestTreeItem(
|
return new GTestTreeItem(this, displayName(), {}, ITestTreeItem::Root);
|
||||||
this,
|
|
||||||
displayName(),
|
|
||||||
Utils::FilePath(), ITestTreeItem::Root);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *GTestFramework::name() const
|
const char *GTestFramework::name() const
|
||||||
|
@@ -12,25 +12,27 @@
|
|||||||
|
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
|
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
namespace Autotest {
|
namespace Autotest {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
GTestOutputReader::GTestOutputReader(const QFutureInterface<TestResultPtr> &futureInterface,
|
GTestOutputReader::GTestOutputReader(const QFutureInterface<TestResult> &futureInterface,
|
||||||
Utils::QtcProcess *testApplication,
|
QtcProcess *testApplication,
|
||||||
const Utils::FilePath &buildDirectory,
|
const FilePath &buildDirectory,
|
||||||
const Utils::FilePath &projectFile)
|
const FilePath &projectFile)
|
||||||
: TestOutputReader(futureInterface, testApplication, buildDirectory)
|
: TestOutputReader(futureInterface, testApplication, buildDirectory)
|
||||||
, m_projectFile(projectFile)
|
, m_projectFile(projectFile)
|
||||||
{
|
{
|
||||||
if (m_testApplication) {
|
if (testApplication) {
|
||||||
connect(m_testApplication, &Utils::QtcProcess::done, this, [this] {
|
connect(testApplication, &QtcProcess::done, this, [this, testApplication] {
|
||||||
const int exitCode = m_testApplication->exitCode();
|
const int exitCode = testApplication->exitCode();
|
||||||
if (exitCode == 1 && !m_description.isEmpty()) {
|
if (exitCode == 1 && !m_description.isEmpty()) {
|
||||||
createAndReportResult(Tr::tr("Running tests failed.\n %1\nExecutable: %2")
|
createAndReportResult(Tr::tr("Running tests failed.\n %1\nExecutable: %2")
|
||||||
.arg(m_description).arg(id()), ResultType::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 (HostOsInfo::isWindowsHost() && exitCode == 3)
|
||||||
reportCrash();
|
reportCrash();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -70,9 +72,9 @@ void GTestOutputReader::processOutputLine(const QByteArray &outputLine)
|
|||||||
m_description = line;
|
m_description = line;
|
||||||
if (m_iteration > 1)
|
if (m_iteration > 1)
|
||||||
m_description.append(' ' + Tr::tr("(iteration %1)").arg(m_iteration));
|
m_description.append(' ' + Tr::tr("(iteration %1)").arg(m_iteration));
|
||||||
TestResultPtr testResult = TestResultPtr(new GTestResult(id(), {}, m_projectFile));
|
GTestResult testResult(id(), {}, m_projectFile);
|
||||||
testResult->setResult(ResultType::MessageInternal);
|
testResult.setResult(ResultType::MessageInternal);
|
||||||
testResult->setDescription(m_description);
|
testResult.setDescription(m_description);
|
||||||
reportResult(testResult);
|
reportResult(testResult);
|
||||||
m_description.clear();
|
m_description.clear();
|
||||||
} else if (ExactMatch match = disabledTests.match(line)) {
|
} else if (ExactMatch match = disabledTests.match(line)) {
|
||||||
@@ -83,66 +85,66 @@ void GTestOutputReader::processOutputLine(const QByteArray &outputLine)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ExactMatch match = testEnds.match(line)) {
|
if (ExactMatch match = testEnds.match(line)) {
|
||||||
TestResultPtr testResult = createDefaultResult();
|
TestResult testResult = createDefaultResult();
|
||||||
testResult->setResult(ResultType::TestEnd);
|
testResult.setResult(ResultType::TestEnd);
|
||||||
testResult->setDescription(Tr::tr("Test execution took %1").arg(match.captured(2)));
|
testResult.setDescription(Tr::tr("Test execution took %1").arg(match.captured(2)));
|
||||||
reportResult(testResult);
|
reportResult(testResult);
|
||||||
m_currentTestSuite.clear();
|
m_currentTestSuite.clear();
|
||||||
m_currentTestCase.clear();
|
m_currentTestCase.clear();
|
||||||
} else if (ExactMatch match = newTestStarts.match(line)) {
|
} else if (ExactMatch match = newTestStarts.match(line)) {
|
||||||
setCurrentTestSuite(match.captured(1));
|
setCurrentTestSuite(match.captured(1));
|
||||||
TestResultPtr testResult = createDefaultResult();
|
TestResult testResult = createDefaultResult();
|
||||||
testResult->setResult(ResultType::TestStart);
|
testResult.setResult(ResultType::TestStart);
|
||||||
if (m_iteration > 1) {
|
if (m_iteration > 1) {
|
||||||
testResult->setDescription(Tr::tr("Repeating test suite %1 (iteration %2)")
|
testResult.setDescription(Tr::tr("Repeating test suite %1 (iteration %2)")
|
||||||
.arg(m_currentTestSuite).arg(m_iteration));
|
.arg(m_currentTestSuite).arg(m_iteration));
|
||||||
} else {
|
} else {
|
||||||
testResult->setDescription(Tr::tr("Executing test suite %1").arg(m_currentTestSuite));
|
testResult.setDescription(Tr::tr("Executing test suite %1").arg(m_currentTestSuite));
|
||||||
}
|
}
|
||||||
reportResult(testResult);
|
reportResult(testResult);
|
||||||
} else if (ExactMatch match = newTestSetStarts.match(line)) {
|
} else if (ExactMatch match = newTestSetStarts.match(line)) {
|
||||||
m_testSetStarted = true;
|
m_testSetStarted = true;
|
||||||
setCurrentTestCase(match.captured(1));
|
setCurrentTestCase(match.captured(1));
|
||||||
TestResultPtr testResult = TestResultPtr(new GTestResult({}, {}, m_projectFile));
|
GTestResult testResult("internal", {}, m_projectFile);
|
||||||
testResult->setResult(ResultType::MessageCurrentTest);
|
testResult.setResult(ResultType::MessageCurrentTest);
|
||||||
testResult->setDescription(Tr::tr("Entering test case %1").arg(m_currentTestCase));
|
testResult.setDescription(Tr::tr("Entering test case %1").arg(m_currentTestCase));
|
||||||
reportResult(testResult);
|
reportResult(testResult);
|
||||||
m_description.clear();
|
m_description.clear();
|
||||||
} else if (ExactMatch match = testSetSuccess.match(line)) {
|
} else if (ExactMatch match = testSetSuccess.match(line)) {
|
||||||
m_testSetStarted = false;
|
m_testSetStarted = false;
|
||||||
TestResultPtr testResult = createDefaultResult();
|
TestResult testResult = createDefaultResult();
|
||||||
testResult->setResult(ResultType::Pass);
|
testResult.setResult(ResultType::Pass);
|
||||||
testResult->setDescription(m_description);
|
testResult.setDescription(m_description);
|
||||||
reportResult(testResult);
|
reportResult(testResult);
|
||||||
m_description.clear();
|
m_description.clear();
|
||||||
testResult = createDefaultResult();
|
testResult = createDefaultResult();
|
||||||
testResult->setResult(ResultType::MessageInternal);
|
testResult.setResult(ResultType::MessageInternal);
|
||||||
testResult->setDescription(Tr::tr("Execution took %1.").arg(match.captured(2)));
|
testResult.setDescription(Tr::tr("Execution took %1.").arg(match.captured(2)));
|
||||||
reportResult(testResult);
|
reportResult(testResult);
|
||||||
m_futureInterface.setProgressValue(m_futureInterface.progressValue() + 1);
|
m_futureInterface.setProgressValue(m_futureInterface.progressValue() + 1);
|
||||||
} else if (ExactMatch match = testSetFail.match(line)) {
|
} else if (ExactMatch match = testSetFail.match(line)) {
|
||||||
m_testSetStarted = false;
|
m_testSetStarted = false;
|
||||||
TestResultPtr testResult = createDefaultResult();
|
TestResult testResult = createDefaultResult();
|
||||||
testResult->setResult(ResultType::Fail);
|
testResult.setResult(ResultType::Fail);
|
||||||
m_description.chop(1);
|
m_description.chop(1);
|
||||||
handleDescriptionAndReportResult(testResult);
|
handleDescriptionAndReportResult(testResult);
|
||||||
testResult = createDefaultResult();
|
testResult = createDefaultResult();
|
||||||
testResult->setResult(ResultType::MessageInternal);
|
testResult.setResult(ResultType::MessageInternal);
|
||||||
testResult->setDescription(Tr::tr("Execution took %1.").arg(match.captured(2)));
|
testResult.setDescription(Tr::tr("Execution took %1.").arg(match.captured(2)));
|
||||||
reportResult(testResult);
|
reportResult(testResult);
|
||||||
m_futureInterface.setProgressValue(m_futureInterface.progressValue() + 1);
|
m_futureInterface.setProgressValue(m_futureInterface.progressValue() + 1);
|
||||||
} else if (ExactMatch match = testSetSkipped.match(line)) {
|
} else if (ExactMatch match = testSetSkipped.match(line)) {
|
||||||
if (!m_testSetStarted) // ignore SKIPPED at summary
|
if (!m_testSetStarted) // ignore SKIPPED at summary
|
||||||
return;
|
return;
|
||||||
m_testSetStarted = false;
|
m_testSetStarted = false;
|
||||||
TestResultPtr testResult = createDefaultResult();
|
TestResult testResult = createDefaultResult();
|
||||||
testResult->setResult(ResultType::Skip);
|
testResult.setResult(ResultType::Skip);
|
||||||
m_description.chop(1);
|
m_description.chop(1);
|
||||||
m_description.prepend(match.captured(1) + '\n');
|
m_description.prepend(match.captured(1) + '\n');
|
||||||
handleDescriptionAndReportResult(testResult);
|
handleDescriptionAndReportResult(testResult);
|
||||||
testResult = createDefaultResult();
|
testResult = createDefaultResult();
|
||||||
testResult->setResult(ResultType::MessageInternal);
|
testResult.setResult(ResultType::MessageInternal);
|
||||||
testResult->setDescription(Tr::tr("Execution took %1.").arg(match.captured(2)));
|
testResult.setDescription(Tr::tr("Execution took %1.").arg(match.captured(2)));
|
||||||
reportResult(testResult);
|
reportResult(testResult);
|
||||||
} else if (ExactMatch match = logging.match(line)) {
|
} else if (ExactMatch match = logging.match(line)) {
|
||||||
const QString severity = match.captured(1).trimmed();
|
const QString severity = match.captured(1).trimmed();
|
||||||
@@ -153,13 +155,13 @@ void GTestOutputReader::processOutputLine(const QByteArray &outputLine)
|
|||||||
case 'E': type = ResultType::MessageError; break; // ERROR
|
case 'E': type = ResultType::MessageError; break; // ERROR
|
||||||
case 'F': type = ResultType::MessageFatal; break; // FATAL
|
case 'F': type = ResultType::MessageFatal; break; // FATAL
|
||||||
}
|
}
|
||||||
TestResultPtr testResult = createDefaultResult();
|
TestResult testResult = createDefaultResult();
|
||||||
testResult->setResult(type);
|
testResult.setResult(type);
|
||||||
testResult->setLine(match.captured(3).toInt());
|
testResult.setLine(match.captured(3).toInt());
|
||||||
const Utils::FilePath file = constructSourceFilePath(m_buildDir, match.captured(2));
|
const FilePath file = constructSourceFilePath(m_buildDir, match.captured(2));
|
||||||
if (file.exists())
|
if (file.exists())
|
||||||
testResult->setFileName(file);
|
testResult.setFileName(file);
|
||||||
testResult->setDescription(match.captured(4));
|
testResult.setDescription(match.captured(4));
|
||||||
reportResult(testResult);
|
reportResult(testResult);
|
||||||
} else if (ExactMatch match = testDeath.match(line)) {
|
} else if (ExactMatch match = testDeath.match(line)) {
|
||||||
m_description.append(line);
|
m_description.append(line);
|
||||||
@@ -175,19 +177,15 @@ void GTestOutputReader::processStdError(const QByteArray &outputLine)
|
|||||||
emit newOutputLineAvailable(outputLine, OutputChannel::StdErr);
|
emit newOutputLineAvailable(outputLine, OutputChannel::StdErr);
|
||||||
}
|
}
|
||||||
|
|
||||||
TestResultPtr GTestOutputReader::createDefaultResult() const
|
TestResult GTestOutputReader::createDefaultResult() const
|
||||||
{
|
{
|
||||||
GTestResult *result = new GTestResult(id(), m_currentTestSuite, m_projectFile,
|
GTestResult result(id(), m_currentTestSuite, m_projectFile, m_currentTestCase, m_iteration);
|
||||||
m_currentTestCase, m_iteration);
|
const ITestTreeItem *testItem = result.findTestTreeItem();
|
||||||
|
|
||||||
const ITestTreeItem *testItem = result->findTestTreeItem();
|
|
||||||
|
|
||||||
if (testItem && testItem->line()) {
|
if (testItem && testItem->line()) {
|
||||||
result->setFileName(testItem->filePath());
|
result.setFileName(testItem->filePath());
|
||||||
result->setLine(testItem->line());
|
result.setLine(testItem->line());
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
return TestResultPtr(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GTestOutputReader::setCurrentTestCase(const QString &testCase)
|
void GTestOutputReader::setCurrentTestCase(const QString &testCase)
|
||||||
@@ -200,13 +198,13 @@ void GTestOutputReader::setCurrentTestSuite(const QString &testSuite)
|
|||||||
m_currentTestSuite = testSuite;
|
m_currentTestSuite = testSuite;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GTestOutputReader::handleDescriptionAndReportResult(TestResultPtr testResult)
|
void GTestOutputReader::handleDescriptionAndReportResult(const TestResult &testResult)
|
||||||
{
|
{
|
||||||
static const QRegularExpression failureLocation("^(.*):(\\d+): Failure$");
|
static const QRegularExpression failureLocation("^(.*):(\\d+): Failure$");
|
||||||
static const QRegularExpression skipOrErrorLocation("^(.*)\\((\\d+)\\): (Skipped|error:.*)$");
|
static const QRegularExpression skipOrErrorLocation("^(.*)\\((\\d+)\\): (Skipped|error:.*)$");
|
||||||
|
|
||||||
QStringList resultDescription;
|
QStringList resultDescription;
|
||||||
|
TestResult result = testResult;
|
||||||
for (const QString &output : m_description.split('\n')) {
|
for (const QString &output : m_description.split('\n')) {
|
||||||
QRegularExpressionMatch innerMatch = failureLocation.match(output);
|
QRegularExpressionMatch innerMatch = failureLocation.match(output);
|
||||||
if (!innerMatch.hasMatch()) {
|
if (!innerMatch.hasMatch()) {
|
||||||
@@ -216,20 +214,20 @@ void GTestOutputReader::handleDescriptionAndReportResult(TestResultPtr testResul
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
testResult->setDescription(resultDescription.join('\n'));
|
result.setDescription(resultDescription.join('\n'));
|
||||||
reportResult(testResult);
|
reportResult(testResult);
|
||||||
resultDescription.clear();
|
resultDescription.clear();
|
||||||
|
|
||||||
testResult = createDefaultResult();
|
result = createDefaultResult();
|
||||||
testResult->setResult(ResultType::MessageLocation);
|
result.setResult(ResultType::MessageLocation);
|
||||||
testResult->setLine(innerMatch.captured(2).toInt());
|
result.setLine(innerMatch.captured(2).toInt());
|
||||||
const Utils::FilePath file = constructSourceFilePath(m_buildDir, innerMatch.captured(1));
|
const FilePath file = constructSourceFilePath(m_buildDir, innerMatch.captured(1));
|
||||||
if (file.exists())
|
if (file.exists())
|
||||||
testResult->setFileName(file);
|
result.setFileName(file);
|
||||||
resultDescription << output;
|
resultDescription << output;
|
||||||
}
|
}
|
||||||
testResult->setDescription(resultDescription.join('\n'));
|
result.setDescription(resultDescription.join('\n'));
|
||||||
reportResult(testResult);
|
reportResult(result);
|
||||||
m_description.clear();
|
m_description.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -11,18 +11,18 @@ namespace Internal {
|
|||||||
class GTestOutputReader : public TestOutputReader
|
class GTestOutputReader : public TestOutputReader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GTestOutputReader(const QFutureInterface<TestResultPtr> &futureInterface,
|
GTestOutputReader(const QFutureInterface<TestResult> &futureInterface,
|
||||||
Utils::QtcProcess *testApplication, const Utils::FilePath &buildDirectory,
|
Utils::QtcProcess *testApplication, const Utils::FilePath &buildDirectory,
|
||||||
const Utils::FilePath &projectFile);
|
const Utils::FilePath &projectFile);
|
||||||
protected:
|
protected:
|
||||||
void processOutputLine(const QByteArray &outputLine) override;
|
void processOutputLine(const QByteArray &outputLine) override;
|
||||||
void processStdError(const QByteArray &outputLine) override;
|
void processStdError(const QByteArray &outputLine) override;
|
||||||
TestResultPtr createDefaultResult() const override;
|
TestResult createDefaultResult() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setCurrentTestCase(const QString &testCase);
|
void setCurrentTestCase(const QString &testCase);
|
||||||
void setCurrentTestSuite(const QString &testSuite);
|
void setCurrentTestSuite(const QString &testSuite);
|
||||||
void handleDescriptionAndReportResult(TestResultPtr testResult);
|
void handleDescriptionAndReportResult(const TestResult &testResult);
|
||||||
|
|
||||||
Utils::FilePath m_projectFile;
|
Utils::FilePath m_projectFile;
|
||||||
QString m_currentTestSuite;
|
QString m_currentTestSuite;
|
||||||
|
@@ -71,7 +71,7 @@ static bool hasGTestNames(const CPlusPlus::Document::Ptr &document)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool GTestParser::processDocument(QFutureInterface<TestParseResultPtr> &futureInterface,
|
bool GTestParser::processDocument(QFutureInterface<TestParseResultPtr> &futureInterface,
|
||||||
const Utils::FilePath &fileName)
|
const FilePath &fileName)
|
||||||
{
|
{
|
||||||
CPlusPlus::Document::Ptr doc = document(fileName);
|
CPlusPlus::Document::Ptr doc = document(fileName);
|
||||||
if (doc.isNull() || !includesGTest(doc, m_cppSnapshot))
|
if (doc.isNull() || !includesGTest(doc, m_cppSnapshot))
|
||||||
@@ -93,10 +93,10 @@ bool GTestParser::processDocument(QFutureInterface<TestParseResultPtr> &futureIn
|
|||||||
visitor.accept(ast);
|
visitor.accept(ast);
|
||||||
|
|
||||||
const QMap<GTestCaseSpec, GTestCodeLocationList> result = visitor.gtestFunctions();
|
const QMap<GTestCaseSpec, GTestCodeLocationList> result = visitor.gtestFunctions();
|
||||||
Utils::FilePath proFile;
|
FilePath proFile;
|
||||||
const QList<CppEditor::ProjectPart::ConstPtr> &ppList = modelManager->projectPart(filePath);
|
const QList<CppEditor::ProjectPart::ConstPtr> &ppList = modelManager->projectPart(filePath);
|
||||||
if (!ppList.isEmpty())
|
if (!ppList.isEmpty())
|
||||||
proFile = Utils::FilePath::fromString(ppList.first()->projectFile);
|
proFile = FilePath::fromString(ppList.first()->projectFile);
|
||||||
else
|
else
|
||||||
return false; // happens if shutting down while parsing
|
return false; // happens if shutting down while parsing
|
||||||
|
|
||||||
|
@@ -30,7 +30,7 @@ GTestSettings::GTestSettings()
|
|||||||
|
|
||||||
registerAspect(&seed);
|
registerAspect(&seed);
|
||||||
seed.setSettingsKey("Seed");
|
seed.setSettingsKey("Seed");
|
||||||
seed.setSpecialValueText(QString());
|
seed.setSpecialValueText({});
|
||||||
seed.setEnabled(false);
|
seed.setEnabled(false);
|
||||||
seed.setLabelText(Tr::tr("Seed:"));
|
seed.setLabelText(Tr::tr("Seed:"));
|
||||||
seed.setToolTip(Tr::tr("A seed of 0 generates a seed based on the current timestamp."));
|
seed.setToolTip(Tr::tr("A seed of 0 generates a seed based on the current timestamp."));
|
||||||
@@ -106,7 +106,7 @@ GTestSettings::GTestSettings()
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
GTestSettingsPage::GTestSettingsPage(GTestSettings *settings, Utils::Id settingsId)
|
GTestSettingsPage::GTestSettingsPage(GTestSettings *settings, Id settingsId)
|
||||||
{
|
{
|
||||||
setId(settingsId);
|
setId(settingsId);
|
||||||
setCategory(Constants::AUTOTEST_SETTINGS_CATEGORY);
|
setCategory(Constants::AUTOTEST_SETTINGS_CATEGORY);
|
||||||
|
@@ -20,6 +20,8 @@
|
|||||||
|
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
|
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
namespace Autotest {
|
namespace Autotest {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
@@ -110,8 +112,8 @@ QVariant GTestTreeItem::data(int column, int role) const
|
|||||||
case Qt::DecorationRole:
|
case Qt::DecorationRole:
|
||||||
if (type() == GroupNode
|
if (type() == GroupNode
|
||||||
&& GTestFramework::groupMode() == GTest::Constants::GTestFilter) {
|
&& GTestFramework::groupMode() == GTest::Constants::GTestFilter) {
|
||||||
static const QIcon filterIcon = Utils::Icon({{":/utils/images/filtericon.png",
|
static const QIcon filterIcon = Icon({{":/utils/images/filtericon.png",
|
||||||
Utils::Theme::PanelTextColorMid}}).icon();
|
Theme::PanelTextColorMid}}).icon();
|
||||||
return filterIcon;
|
return filterIcon;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -195,7 +197,7 @@ struct GTestCases
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void collectTestInfo(const GTestTreeItem *item,
|
static void collectTestInfo(const GTestTreeItem *item,
|
||||||
QHash<Utils::FilePath, GTestCases> &testCasesForProFile,
|
QHash<FilePath, GTestCases> &testCasesForProFile,
|
||||||
bool ignoreCheckState)
|
bool ignoreCheckState)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(item, return);
|
QTC_ASSERT(item, return);
|
||||||
@@ -210,7 +212,7 @@ static void collectTestInfo(const GTestTreeItem *item,
|
|||||||
QTC_ASSERT(childCount != 0, return);
|
QTC_ASSERT(childCount != 0, return);
|
||||||
QTC_ASSERT(item->type() == TestTreeItem::TestSuite, return);
|
QTC_ASSERT(item->type() == TestTreeItem::TestSuite, return);
|
||||||
if (ignoreCheckState || item->checked() == Qt::Checked) {
|
if (ignoreCheckState || item->checked() == Qt::Checked) {
|
||||||
const Utils::FilePath &projectFile = item->childItem(0)->proFile();
|
const FilePath &projectFile = item->childItem(0)->proFile();
|
||||||
testCasesForProFile[projectFile].filters.append(
|
testCasesForProFile[projectFile].filters.append(
|
||||||
gtestFilter(item->state()).arg(item->name()).arg('*'));
|
gtestFilter(item->state()).arg(item->name()).arg('*'));
|
||||||
testCasesForProFile[projectFile].testSetCount += childCount - 1;
|
testCasesForProFile[projectFile].testSetCount += childCount - 1;
|
||||||
@@ -229,7 +231,7 @@ static void collectTestInfo(const GTestTreeItem *item,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void collectFailedTestInfo(const GTestTreeItem *item,
|
static void collectFailedTestInfo(const GTestTreeItem *item,
|
||||||
QHash<Utils::FilePath, GTestCases> &testCasesForProfile)
|
QHash<FilePath, GTestCases> &testCasesForProfile)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(item, return);
|
QTC_ASSERT(item, return);
|
||||||
QTC_ASSERT(item->type() == TestTreeItem::Root, return);
|
QTC_ASSERT(item->type() == TestTreeItem::Root, return);
|
||||||
@@ -254,7 +256,7 @@ QList<ITestConfiguration *> GTestTreeItem::getTestConfigurations(bool ignoreChec
|
|||||||
if (!project || type() != Root)
|
if (!project || type() != Root)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
QHash<Utils::FilePath, GTestCases> testCasesForProFile;
|
QHash<FilePath, GTestCases> testCasesForProFile;
|
||||||
for (int row = 0, count = childCount(); row < count; ++row) {
|
for (int row = 0, count = childCount(); row < count; ++row) {
|
||||||
auto child = static_cast<const GTestTreeItem *>(childAt(row));
|
auto child = static_cast<const GTestTreeItem *>(childAt(row));
|
||||||
collectTestInfo(child, testCasesForProFile, ignoreCheckState);
|
collectTestInfo(child, testCasesForProFile, ignoreCheckState);
|
||||||
@@ -293,7 +295,7 @@ QList<ITestConfiguration *> GTestTreeItem::getFailedTestConfigurations() const
|
|||||||
if (!project || type() != Root)
|
if (!project || type() != Root)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
QHash<Utils::FilePath, GTestCases> testCasesForProFile;
|
QHash<FilePath, GTestCases> testCasesForProFile;
|
||||||
collectFailedTestInfo(this, testCasesForProFile);
|
collectFailedTestInfo(this, testCasesForProFile);
|
||||||
|
|
||||||
for (auto it = testCasesForProFile.begin(), end = testCasesForProFile.end(); it != end; ++it) {
|
for (auto it = testCasesForProFile.begin(), end = testCasesForProFile.end(); it != end; ++it) {
|
||||||
@@ -311,14 +313,14 @@ QList<ITestConfiguration *> GTestTreeItem::getFailedTestConfigurations() const
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<ITestConfiguration *> GTestTreeItem::getTestConfigurationsForFile(const Utils::FilePath &fileName) const
|
QList<ITestConfiguration *> GTestTreeItem::getTestConfigurationsForFile(const FilePath &fileName) const
|
||||||
{
|
{
|
||||||
QList<ITestConfiguration *> result;
|
QList<ITestConfiguration *> result;
|
||||||
ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject();
|
ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject();
|
||||||
if (!project || type() != Root)
|
if (!project || type() != Root)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
QHash<Utils::FilePath, GTestCases> testCases;
|
QHash<FilePath, GTestCases> testCases;
|
||||||
forAllChildItems([&testCases, &fileName](TestTreeItem *node) {
|
forAllChildItems([&testCases, &fileName](TestTreeItem *node) {
|
||||||
if (node->type() == Type::TestCase && node->filePath() == fileName) {
|
if (node->type() == Type::TestCase && node->filePath() == fileName) {
|
||||||
QTC_ASSERT(node->parentItem(), return);
|
QTC_ASSERT(node->parentItem(), return);
|
||||||
@@ -358,7 +360,7 @@ TestTreeItem *GTestTreeItem::find(const TestParseResult *result)
|
|||||||
case Root:
|
case Root:
|
||||||
if (result->framework->grouping()) {
|
if (result->framework->grouping()) {
|
||||||
if (GTestFramework::groupMode() == GTest::Constants::Directory) {
|
if (GTestFramework::groupMode() == GTest::Constants::Directory) {
|
||||||
const Utils::FilePath base = parseResult->fileName.absolutePath();
|
const FilePath base = parseResult->fileName.absolutePath();
|
||||||
for (int row = 0; row < childCount(); ++row) {
|
for (int row = 0; row < childCount(); ++row) {
|
||||||
GTestTreeItem *group = static_cast<GTestTreeItem *>(childAt(row));
|
GTestTreeItem *group = static_cast<GTestTreeItem *>(childAt(row));
|
||||||
if (group->filePath() != base.absoluteFilePath())
|
if (group->filePath() != base.absoluteFilePath())
|
||||||
@@ -442,7 +444,7 @@ bool GTestTreeItem::modify(const TestParseResult *result)
|
|||||||
TestTreeItem *GTestTreeItem::createParentGroupNode() const
|
TestTreeItem *GTestTreeItem::createParentGroupNode() const
|
||||||
{
|
{
|
||||||
if (GTestFramework::groupMode() == GTest::Constants::Directory) {
|
if (GTestFramework::groupMode() == GTest::Constants::Directory) {
|
||||||
const Utils::FilePath &absPath = filePath().absolutePath();
|
const FilePath &absPath = filePath().absolutePath();
|
||||||
return new GTestTreeItem(framework(), absPath.baseName(), absPath, TestTreeItem::GroupNode);
|
return new GTestTreeItem(framework(), absPath.baseName(), absPath, TestTreeItem::GroupNode);
|
||||||
} else { // GTestFilter
|
} else { // GTestFilter
|
||||||
QTC_ASSERT(childCount(), return nullptr); // paranoia
|
QTC_ASSERT(childCount(), return nullptr); // paranoia
|
||||||
@@ -453,7 +455,7 @@ TestTreeItem *GTestTreeItem::createParentGroupNode() const
|
|||||||
matchesFilter(activeFilter, fullTestName) ? matchingString() : notMatchingString();
|
matchesFilter(activeFilter, fullTestName) ? matchingString() : notMatchingString();
|
||||||
// FIXME activeFilter is not a FilePath
|
// FIXME activeFilter is not a FilePath
|
||||||
auto groupNode = new GTestTreeItem(framework(), groupNodeName,
|
auto groupNode = new GTestTreeItem(framework(), groupNodeName,
|
||||||
Utils::FilePath::fromString(activeFilter),
|
FilePath::fromString(activeFilter),
|
||||||
TestTreeItem::GroupNode);
|
TestTreeItem::GroupNode);
|
||||||
if (groupNodeName == notMatchingString())
|
if (groupNodeName == notMatchingString())
|
||||||
groupNode->setData(0, Qt::Unchecked, Qt::CheckStateRole);
|
groupNode->setData(0, Qt::Unchecked, Qt::CheckStateRole);
|
||||||
@@ -475,7 +477,7 @@ bool GTestTreeItem::modifyTestSetContent(const GTestParseResult *result)
|
|||||||
|
|
||||||
TestTreeItem *GTestTreeItem::findChildByNameStateAndFile(const QString &name,
|
TestTreeItem *GTestTreeItem::findChildByNameStateAndFile(const QString &name,
|
||||||
GTestTreeItem::TestStates state,
|
GTestTreeItem::TestStates state,
|
||||||
const Utils::FilePath &proFile) const
|
const FilePath &proFile) const
|
||||||
{
|
{
|
||||||
return findFirstLevelChildItem([name, state, proFile](const TestTreeItem *other) {
|
return findFirstLevelChildItem([name, state, proFile](const TestTreeItem *other) {
|
||||||
const GTestTreeItem *gtestItem = static_cast<const GTestTreeItem *>(other);
|
const GTestTreeItem *gtestItem = static_cast<const GTestTreeItem *>(other);
|
||||||
@@ -504,13 +506,13 @@ QSet<QString> internalTargets(const TestTreeItem &item)
|
|||||||
const auto projectInfo = cppMM->projectInfo(ProjectExplorer::SessionManager::startupProject());
|
const auto projectInfo = cppMM->projectInfo(ProjectExplorer::SessionManager::startupProject());
|
||||||
if (!projectInfo)
|
if (!projectInfo)
|
||||||
return {};
|
return {};
|
||||||
const Utils::FilePath filePath = item.filePath();
|
const FilePath filePath = item.filePath();
|
||||||
const QVector<CppEditor::ProjectPart::ConstPtr> projectParts = projectInfo->projectParts();
|
const QVector<CppEditor::ProjectPart::ConstPtr> projectParts = projectInfo->projectParts();
|
||||||
if (projectParts.isEmpty())
|
if (projectParts.isEmpty())
|
||||||
return cppMM->dependingInternalTargets(item.filePath());
|
return cppMM->dependingInternalTargets(item.filePath());
|
||||||
for (const CppEditor::ProjectPart::ConstPtr &projectPart : projectParts) {
|
for (const CppEditor::ProjectPart::ConstPtr &projectPart : projectParts) {
|
||||||
if (Utils::FilePath::fromString(projectPart->projectFile) == item.proFile()
|
if (FilePath::fromString(projectPart->projectFile) == item.proFile()
|
||||||
&& Utils::anyOf(projectPart->files, [&filePath] (const CppEditor::ProjectFile &pf) {
|
&& Utils::anyOf(projectPart->files, [&filePath](const CppEditor::ProjectFile &pf) {
|
||||||
return pf.path == filePath;
|
return pf.path == filePath;
|
||||||
})) {
|
})) {
|
||||||
result.insert(projectPart->buildSystemTarget);
|
result.insert(projectPart->buildSystemTarget);
|
||||||
|
@@ -24,10 +24,8 @@ public:
|
|||||||
Q_FLAGS(TestState)
|
Q_FLAGS(TestState)
|
||||||
Q_DECLARE_FLAGS(TestStates, TestState)
|
Q_DECLARE_FLAGS(TestStates, TestState)
|
||||||
|
|
||||||
explicit GTestTreeItem(ITestFramework *testFramework,
|
explicit GTestTreeItem(ITestFramework *testFramework, const QString &name = {},
|
||||||
const QString &name = QString(),
|
const Utils::FilePath &filePath = {}, Type type = Root)
|
||||||
const Utils::FilePath &filePath = Utils::FilePath(),
|
|
||||||
Type type = Root)
|
|
||||||
: TestTreeItem(testFramework, name, filePath, type), m_state(Enabled)
|
: TestTreeItem(testFramework, name, filePath, type), m_state(Enabled)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
@@ -8,6 +8,8 @@
|
|||||||
#include "testtreeitem.h"
|
#include "testtreeitem.h"
|
||||||
#include "testtreemodel.h"
|
#include "testtreemodel.h"
|
||||||
|
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
namespace Autotest {
|
namespace Autotest {
|
||||||
|
|
||||||
ITestBase::ITestBase(bool activeByDefault, const ITestBase::TestBaseType type)
|
ITestBase::ITestBase(bool activeByDefault, const ITestBase::TestBaseType type)
|
||||||
@@ -15,15 +17,15 @@ ITestBase::ITestBase(bool activeByDefault, const ITestBase::TestBaseType type)
|
|||||||
, m_type(type)
|
, m_type(type)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Utils::Id ITestBase::settingsId() const
|
Id ITestBase::settingsId() const
|
||||||
{
|
{
|
||||||
return Utils::Id(Constants::SETTINGSPAGE_PREFIX)
|
return Id(Constants::SETTINGSPAGE_PREFIX)
|
||||||
.withSuffix(QString("%1.%2").arg(priority()).arg(QLatin1String(name())));
|
.withSuffix(QString("%1.%2").arg(priority()).arg(QLatin1String(name())));
|
||||||
}
|
}
|
||||||
|
|
||||||
Utils::Id ITestBase::id() const
|
Id ITestBase::id() const
|
||||||
{
|
{
|
||||||
return Utils::Id(Constants::FRAMEWORK_PREFIX).withSuffix(name());
|
return Id(Constants::FRAMEWORK_PREFIX).withSuffix(name());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ITestBase::resetRootNode()
|
void ITestBase::resetRootNode()
|
||||||
|
@@ -72,7 +72,7 @@ public:
|
|||||||
bool grouping() const { return m_grouping; }
|
bool grouping() const { return m_grouping; }
|
||||||
void setGrouping(bool group) { m_grouping = group; }
|
void setGrouping(bool group) { m_grouping = group; }
|
||||||
// framework specific tool tip to be displayed on the general settings page
|
// framework specific tool tip to be displayed on the general settings page
|
||||||
virtual QString groupingToolTip() const { return QString(); }
|
virtual QString groupingToolTip() const { return {}; }
|
||||||
|
|
||||||
ITestFramework *asFramework() final { return this; }
|
ITestFramework *asFramework() final { return this; }
|
||||||
|
|
||||||
|
@@ -24,7 +24,7 @@ CppParser::CppParser(ITestFramework *framework)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void CppParser::init(const Utils::FilePaths &filesToParse, bool fullParse)
|
void CppParser::init(const FilePaths &filesToParse, bool fullParse)
|
||||||
{
|
{
|
||||||
Q_UNUSED(filesToParse)
|
Q_UNUSED(filesToParse)
|
||||||
Q_UNUSED(fullParse)
|
Q_UNUSED(fullParse)
|
||||||
@@ -32,7 +32,7 @@ void CppParser::init(const Utils::FilePaths &filesToParse, bool fullParse)
|
|||||||
m_workingCopy = CppEditor::CppModelManager::instance()->workingCopy();
|
m_workingCopy = CppEditor::CppModelManager::instance()->workingCopy();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CppParser::selectedForBuilding(const Utils::FilePath &fileName)
|
bool CppParser::selectedForBuilding(const FilePath &fileName)
|
||||||
{
|
{
|
||||||
QList<CppEditor::ProjectPart::ConstPtr> projParts =
|
QList<CppEditor::ProjectPart::ConstPtr> projParts =
|
||||||
CppEditor::CppModelManager::instance()->projectPart(fileName);
|
CppEditor::CppModelManager::instance()->projectPart(fileName);
|
||||||
@@ -40,7 +40,7 @@ bool CppParser::selectedForBuilding(const Utils::FilePath &fileName)
|
|||||||
return !projParts.isEmpty() && projParts.at(0)->selectedForBuilding;
|
return !projParts.isEmpty() && projParts.at(0)->selectedForBuilding;
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray CppParser::getFileContent(const Utils::FilePath &filePath) const
|
QByteArray CppParser::getFileContent(const FilePath &filePath) const
|
||||||
{
|
{
|
||||||
QByteArray fileContent;
|
QByteArray fileContent;
|
||||||
if (m_workingCopy.contains(filePath)) {
|
if (m_workingCopy.contains(filePath)) {
|
||||||
@@ -48,8 +48,8 @@ QByteArray CppParser::getFileContent(const Utils::FilePath &filePath) const
|
|||||||
} else {
|
} else {
|
||||||
QString error;
|
QString error;
|
||||||
const QTextCodec *codec = Core::EditorManager::defaultTextCodec();
|
const QTextCodec *codec = Core::EditorManager::defaultTextCodec();
|
||||||
if (Utils::TextFileFormat::readFileUTF8(filePath, codec, &fileContent, &error)
|
if (TextFileFormat::readFileUTF8(filePath, codec, &fileContent, &error)
|
||||||
!= Utils::TextFileFormat::ReadSuccess) {
|
!= TextFileFormat::ReadSuccess) {
|
||||||
qDebug() << "Failed to read file" << filePath << ":" << error;
|
qDebug() << "Failed to read file" << filePath << ":" << error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -58,7 +58,7 @@ QByteArray CppParser::getFileContent(const Utils::FilePath &filePath) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool precompiledHeaderContains(const CPlusPlus::Snapshot &snapshot,
|
bool precompiledHeaderContains(const CPlusPlus::Snapshot &snapshot,
|
||||||
const Utils::FilePath &filePath,
|
const FilePath &filePath,
|
||||||
const QString &cacheString,
|
const QString &cacheString,
|
||||||
const std::function<bool(const FilePath &)> &checker)
|
const std::function<bool(const FilePath &)> &checker)
|
||||||
{
|
{
|
||||||
@@ -82,7 +82,7 @@ bool precompiledHeaderContains(const CPlusPlus::Snapshot &snapshot,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool CppParser::precompiledHeaderContains(const CPlusPlus::Snapshot &snapshot,
|
bool CppParser::precompiledHeaderContains(const CPlusPlus::Snapshot &snapshot,
|
||||||
const Utils::FilePath &filePath,
|
const FilePath &filePath,
|
||||||
const QString &headerFilePath)
|
const QString &headerFilePath)
|
||||||
{
|
{
|
||||||
return Autotest::precompiledHeaderContains(snapshot,
|
return Autotest::precompiledHeaderContains(snapshot,
|
||||||
@@ -94,7 +94,7 @@ bool CppParser::precompiledHeaderContains(const CPlusPlus::Snapshot &snapshot,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool CppParser::precompiledHeaderContains(const CPlusPlus::Snapshot &snapshot,
|
bool CppParser::precompiledHeaderContains(const CPlusPlus::Snapshot &snapshot,
|
||||||
const Utils::FilePath &filePath,
|
const FilePath &filePath,
|
||||||
const QRegularExpression &headerFileRegex)
|
const QRegularExpression &headerFileRegex)
|
||||||
{
|
{
|
||||||
return Autotest::precompiledHeaderContains(snapshot,
|
return Autotest::precompiledHeaderContains(snapshot,
|
||||||
@@ -113,7 +113,7 @@ void CppParser::release()
|
|||||||
s_pchLookupCache.clear();
|
s_pchLookupCache.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
CPlusPlus::Document::Ptr CppParser::document(const Utils::FilePath &fileName)
|
CPlusPlus::Document::Ptr CppParser::document(const FilePath &fileName)
|
||||||
{
|
{
|
||||||
return selectedForBuilding(fileName) ? m_cppSnapshot.document(fileName) : nullptr;
|
return selectedForBuilding(fileName) ? m_cppSnapshot.document(fileName) : nullptr;
|
||||||
}
|
}
|
||||||
|
@@ -14,6 +14,8 @@
|
|||||||
#include <QByteArrayList>
|
#include <QByteArrayList>
|
||||||
#include <QSet>
|
#include <QSet>
|
||||||
|
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
namespace Autotest {
|
namespace Autotest {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
namespace QTestUtils {
|
namespace QTestUtils {
|
||||||
@@ -25,10 +27,9 @@ bool isQTestMacro(const QByteArray ¯o)
|
|||||||
return valid.contains(macro);
|
return valid.contains(macro);
|
||||||
}
|
}
|
||||||
|
|
||||||
QHash<Utils::FilePath, TestCases> testCaseNamesForFiles(ITestFramework *framework,
|
QHash<FilePath, TestCases> testCaseNamesForFiles(ITestFramework *framework, const FilePaths &files)
|
||||||
const Utils::FilePaths &files)
|
|
||||||
{
|
{
|
||||||
QHash<Utils::FilePath, TestCases> result;
|
QHash<FilePath, TestCases> result;
|
||||||
TestTreeItem *rootNode = framework->rootNode();
|
TestTreeItem *rootNode = framework->rootNode();
|
||||||
QTC_ASSERT(rootNode, return result);
|
QTC_ASSERT(rootNode, return result);
|
||||||
|
|
||||||
@@ -48,18 +49,17 @@ QHash<Utils::FilePath, TestCases> testCaseNamesForFiles(ITestFramework *framewor
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
QMultiHash<Utils::FilePath, Utils::FilePath> alternativeFiles(ITestFramework *framework,
|
QMultiHash<FilePath, FilePath> alternativeFiles(ITestFramework *framework, const FilePaths &files)
|
||||||
const Utils::FilePaths &files)
|
|
||||||
{
|
{
|
||||||
QMultiHash<Utils::FilePath, Utils::FilePath> result;
|
QMultiHash<FilePath, FilePath> result;
|
||||||
TestTreeItem *rootNode = framework->rootNode();
|
TestTreeItem *rootNode = framework->rootNode();
|
||||||
QTC_ASSERT(rootNode, return result);
|
QTC_ASSERT(rootNode, return result);
|
||||||
|
|
||||||
rootNode->forFirstLevelChildren([&result, &files](ITestTreeItem *child) {
|
rootNode->forFirstLevelChildren([&result, &files](ITestTreeItem *child) {
|
||||||
const Utils::FilePath &baseFilePath = child->filePath();
|
const FilePath &baseFilePath = child->filePath();
|
||||||
for (int childRow = 0, count = child->childCount(); childRow < count; ++childRow) {
|
for (int childRow = 0, count = child->childCount(); childRow < count; ++childRow) {
|
||||||
auto grandChild = static_cast<const QtTestTreeItem *>(child->childAt(childRow));
|
auto grandChild = static_cast<const QtTestTreeItem *>(child->childAt(childRow));
|
||||||
const Utils::FilePath &filePath = grandChild->filePath();
|
const FilePath &filePath = grandChild->filePath();
|
||||||
if (grandChild->inherited() && baseFilePath != filePath && files.contains(filePath)) {
|
if (grandChild->inherited() && baseFilePath != filePath && files.contains(filePath)) {
|
||||||
if (!result.contains(filePath, baseFilePath))
|
if (!result.contains(filePath, baseFilePath))
|
||||||
result.insert(filePath, baseFilePath);
|
result.insert(filePath, baseFilePath);
|
||||||
@@ -128,10 +128,10 @@ QStringList filterInterfering(const QStringList &provided, QStringList *omitted,
|
|||||||
return allowed;
|
return allowed;
|
||||||
}
|
}
|
||||||
|
|
||||||
Utils::Environment prepareBasicEnvironment(const Utils::Environment &env)
|
Environment prepareBasicEnvironment(const Environment &env)
|
||||||
{
|
{
|
||||||
Utils::Environment result(env);
|
Environment result(env);
|
||||||
if (Utils::HostOsInfo::isWindowsHost()) {
|
if (HostOsInfo::isWindowsHost()) {
|
||||||
result.set("QT_FORCE_STDERR_LOGGING", "1");
|
result.set("QT_FORCE_STDERR_LOGGING", "1");
|
||||||
result.set("QT_LOGGING_TO_CONSOLE", "1");
|
result.set("QT_LOGGING_TO_CONSOLE", "1");
|
||||||
}
|
}
|
||||||
|
@@ -13,6 +13,8 @@
|
|||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
#include <utils/stringutils.h>
|
#include <utils/stringutils.h>
|
||||||
|
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
namespace Autotest {
|
namespace Autotest {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
@@ -26,8 +28,8 @@ static QStringList quoteIfNeeded(const QStringList &testCases, bool debugMode)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
TestOutputReader *QtTestConfiguration::createOutputReader(const QFutureInterface<TestResultPtr> &fi,
|
TestOutputReader *QtTestConfiguration::createOutputReader(const QFutureInterface<TestResult> &fi,
|
||||||
Utils::QtcProcess *app) const
|
QtcProcess *app) const
|
||||||
{
|
{
|
||||||
auto qtSettings = static_cast<QtTestSettings *>(framework()->testSettings());
|
auto qtSettings = static_cast<QtTestSettings *>(framework()->testSettings());
|
||||||
const QtTestOutputReader::OutputMode mode = qtSettings && qtSettings->useXMLOutput.value()
|
const QtTestOutputReader::OutputMode mode = qtSettings && qtSettings->useXMLOutput.value()
|
||||||
@@ -71,7 +73,7 @@ QStringList QtTestConfiguration::argumentsForTestRunner(QStringList *omitted) co
|
|||||||
return arguments;
|
return arguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
Utils::Environment QtTestConfiguration::filteredEnvironment(const Utils::Environment &original) const
|
Environment QtTestConfiguration::filteredEnvironment(const Environment &original) const
|
||||||
{
|
{
|
||||||
return QTestUtils::prepareBasicEnvironment(original);
|
return QTestUtils::prepareBasicEnvironment(original);
|
||||||
}
|
}
|
||||||
|
@@ -13,7 +13,7 @@ class QtTestConfiguration : public DebuggableTestConfiguration
|
|||||||
public:
|
public:
|
||||||
explicit QtTestConfiguration(ITestFramework *framework)
|
explicit QtTestConfiguration(ITestFramework *framework)
|
||||||
: DebuggableTestConfiguration(framework) {}
|
: DebuggableTestConfiguration(framework) {}
|
||||||
TestOutputReader *createOutputReader(const QFutureInterface<TestResultPtr> &fi,
|
TestOutputReader *createOutputReader(const QFutureInterface<TestResult> &fi,
|
||||||
Utils::QtcProcess *app) const override;
|
Utils::QtcProcess *app) const override;
|
||||||
QStringList argumentsForTestRunner(QStringList *omitted = nullptr) const override;
|
QStringList argumentsForTestRunner(QStringList *omitted = nullptr) const override;
|
||||||
Utils::Environment filteredEnvironment(const Utils::Environment &original) const override;
|
Utils::Environment filteredEnvironment(const Utils::Environment &original) const override;
|
||||||
|
@@ -18,10 +18,7 @@ ITestParser *QtTestFramework::createTestParser()
|
|||||||
|
|
||||||
ITestTreeItem *QtTestFramework::createRootNode()
|
ITestTreeItem *QtTestFramework::createRootNode()
|
||||||
{
|
{
|
||||||
return new QtTestTreeItem(
|
return new QtTestTreeItem(this, displayName(), {}, ITestTreeItem::Root);
|
||||||
this,
|
|
||||||
displayName(),
|
|
||||||
Utils::FilePath(), ITestTreeItem::Root);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *QtTestFramework::name() const
|
const char *QtTestFramework::name() const
|
||||||
|
@@ -14,6 +14,8 @@
|
|||||||
|
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
|
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
namespace Autotest {
|
namespace Autotest {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
@@ -103,10 +105,10 @@ static QString constructBenchmarkInformation(const QString &metric, double value
|
|||||||
.arg(iterations);
|
.arg(iterations);
|
||||||
}
|
}
|
||||||
|
|
||||||
QtTestOutputReader::QtTestOutputReader(const QFutureInterface<TestResultPtr> &futureInterface,
|
QtTestOutputReader::QtTestOutputReader(const QFutureInterface<TestResult> &futureInterface,
|
||||||
Utils::QtcProcess *testApplication,
|
QtcProcess *testApplication,
|
||||||
const Utils::FilePath &buildDirectory,
|
const FilePath &buildDirectory,
|
||||||
const Utils::FilePath &projectFile,
|
const FilePath &projectFile,
|
||||||
OutputMode mode, TestType type)
|
OutputMode mode, TestType type)
|
||||||
: TestOutputReader(futureInterface, testApplication, buildDirectory)
|
: TestOutputReader(futureInterface, testApplication, buildDirectory)
|
||||||
, m_projectFile(projectFile)
|
, m_projectFile(projectFile)
|
||||||
@@ -130,11 +132,9 @@ void QtTestOutputReader::processOutputLine(const QByteArray &outputLine)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TestResultPtr QtTestOutputReader::createDefaultResult() const
|
TestResult QtTestOutputReader::createDefaultResult() const
|
||||||
{
|
{
|
||||||
QtTestResult *result = new QtTestResult(id(), m_className, m_projectFile, m_testType,
|
return QtTestResult(id(), m_className, m_projectFile, m_testType, m_testCase, m_dataTag);
|
||||||
m_testCase, m_dataTag);
|
|
||||||
return TestResultPtr(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static QString trQtVersion(const QString &version)
|
static QString trQtVersion(const QString &version)
|
||||||
@@ -455,73 +455,75 @@ void QtTestOutputReader::processSummaryFinishOutput()
|
|||||||
|
|
||||||
void QtTestOutputReader::sendCompleteInformation()
|
void QtTestOutputReader::sendCompleteInformation()
|
||||||
{
|
{
|
||||||
TestResultPtr testResult = createDefaultResult();
|
TestResult testResult = createDefaultResult();
|
||||||
testResult->setResult(m_result);
|
testResult.setResult(m_result);
|
||||||
|
|
||||||
if (m_lineNumber) {
|
if (m_lineNumber) {
|
||||||
testResult->setFileName(m_file);
|
testResult.setFileName(m_file);
|
||||||
testResult->setLine(m_lineNumber);
|
testResult.setLine(m_lineNumber);
|
||||||
} else {
|
} else {
|
||||||
const ITestTreeItem *testItem = testResult->findTestTreeItem();
|
const ITestTreeItem *testItem = testResult.findTestTreeItem();
|
||||||
if (testItem && testItem->line()) {
|
if (testItem && testItem->line()) {
|
||||||
testResult->setFileName(testItem->filePath());
|
testResult.setFileName(testItem->filePath());
|
||||||
testResult->setLine(testItem->line());
|
testResult.setLine(testItem->line());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
testResult->setDescription(m_description);
|
testResult.setDescription(m_description);
|
||||||
reportResult(testResult);
|
reportResult(testResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtTestOutputReader::sendMessageCurrentTest()
|
void QtTestOutputReader::sendMessageCurrentTest()
|
||||||
{
|
{
|
||||||
QtTestResult *testResult = new QtTestResult({}, {}, m_projectFile, m_testType);
|
QtTestResult result("internal", {}, m_projectFile, m_testType);
|
||||||
testResult->setResult(ResultType::MessageCurrentTest);
|
result.setResult(ResultType::MessageCurrentTest);
|
||||||
testResult->setDescription(Tr::tr("Entering test function %1::%2").arg(m_className, m_testCase));
|
result.setDescription(Tr::tr("Entering test function %1::%2").arg(m_className, m_testCase));
|
||||||
reportResult(TestResultPtr(testResult));
|
reportResult(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtTestOutputReader::sendStartMessage(bool isFunction)
|
void QtTestOutputReader::sendStartMessage(bool isFunction)
|
||||||
{
|
{
|
||||||
TestResultPtr testResult = createDefaultResult();
|
TestResult result = createDefaultResult();
|
||||||
testResult->setResult(ResultType::TestStart);
|
result.setResult(ResultType::TestStart);
|
||||||
testResult->setDescription(isFunction ? Tr::tr("Executing test function %1").arg(m_testCase)
|
result.setDescription(isFunction ? Tr::tr("Executing test function %1").arg(m_testCase)
|
||||||
: Tr::tr("Executing test case %1").arg(m_className));
|
: Tr::tr("Executing test case %1").arg(m_className));
|
||||||
const ITestTreeItem *testItem = testResult->findTestTreeItem();
|
const ITestTreeItem *testItem = result.findTestTreeItem();
|
||||||
if (testItem && testItem->line()) {
|
if (testItem && testItem->line()) {
|
||||||
testResult->setFileName(testItem->filePath());
|
result.setFileName(testItem->filePath());
|
||||||
testResult->setLine(testItem->line());
|
result.setLine(testItem->line());
|
||||||
}
|
}
|
||||||
reportResult(testResult);
|
reportResult(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtTestOutputReader::sendFinishMessage(bool isFunction)
|
void QtTestOutputReader::sendFinishMessage(bool isFunction)
|
||||||
{
|
{
|
||||||
TestResultPtr testResult = createDefaultResult();
|
TestResult result = createDefaultResult();
|
||||||
testResult->setResult(ResultType::TestEnd);
|
result.setResult(ResultType::TestEnd);
|
||||||
if (!m_duration.isEmpty()) {
|
if (!m_duration.isEmpty()) {
|
||||||
testResult->setDescription(isFunction ? Tr::tr("Execution took %1 ms.").arg(m_duration)
|
result.setDescription(isFunction ? Tr::tr("Execution took %1 ms.").arg(m_duration)
|
||||||
: Tr::tr("Test execution took %1 ms.").arg(m_duration));
|
: Tr::tr("Test execution took %1 ms.").arg(m_duration));
|
||||||
} else {
|
} else {
|
||||||
testResult->setDescription(isFunction ? Tr::tr("Test function finished.")
|
result.setDescription(isFunction ? Tr::tr("Test function finished.")
|
||||||
: Tr::tr("Test finished."));
|
: Tr::tr("Test finished."));
|
||||||
}
|
}
|
||||||
reportResult(testResult);
|
reportResult(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtTestOutputReader::handleAndSendConfigMessage(const QRegularExpressionMatch &config)
|
void QtTestOutputReader::handleAndSendConfigMessage(const QRegularExpressionMatch &config)
|
||||||
{
|
{
|
||||||
TestResultPtr testResult = createDefaultResult();
|
TestResult result = createDefaultResult();
|
||||||
testResult->setResult(ResultType::MessageInternal);
|
result.setResult(ResultType::MessageInternal);
|
||||||
testResult->setDescription(trQtVersion(config.captured(3)));
|
result.setDescription(trQtVersion(config.captured(3)));
|
||||||
reportResult(testResult);
|
reportResult(result);
|
||||||
testResult = createDefaultResult();
|
|
||||||
testResult->setResult(ResultType::MessageInternal);
|
result = createDefaultResult();
|
||||||
testResult->setDescription(trQtBuild(config.captured(2)));
|
result.setResult(ResultType::MessageInternal);
|
||||||
reportResult(testResult);
|
result.setDescription(trQtBuild(config.captured(2)));
|
||||||
testResult = createDefaultResult();
|
reportResult(result);
|
||||||
testResult->setResult(ResultType::MessageInternal);
|
|
||||||
testResult->setDescription(trQtestVersion(config.captured(1)));
|
result = createDefaultResult();
|
||||||
reportResult(testResult);
|
result.setResult(ResultType::MessageInternal);
|
||||||
|
result.setDescription(trQtestVersion(config.captured(1)));
|
||||||
|
reportResult(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -22,12 +22,12 @@ public:
|
|||||||
PlainText
|
PlainText
|
||||||
};
|
};
|
||||||
|
|
||||||
QtTestOutputReader(const QFutureInterface<TestResultPtr> &futureInterface,
|
QtTestOutputReader(const QFutureInterface<TestResult> &futureInterface,
|
||||||
Utils::QtcProcess *testApplication, const Utils::FilePath &buildDirectory,
|
Utils::QtcProcess *testApplication, const Utils::FilePath &buildDirectory,
|
||||||
const Utils::FilePath &projectFile, OutputMode mode, TestType type);
|
const Utils::FilePath &projectFile, OutputMode mode, TestType type);
|
||||||
protected:
|
protected:
|
||||||
void processOutputLine(const QByteArray &outputLine) override;
|
void processOutputLine(const QByteArray &outputLine) override;
|
||||||
TestResultPtr createDefaultResult() const override;
|
TestResult createDefaultResult() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void processXMLOutput(const QByteArray &outputLine);
|
void processXMLOutput(const QByteArray &outputLine);
|
||||||
|
@@ -36,8 +36,7 @@ TestTreeItem *QtTestParseResult::createTestTreeItem() const
|
|||||||
|
|
||||||
static bool includesQtTest(const CPlusPlus::Document::Ptr &doc, const CPlusPlus::Snapshot &snapshot)
|
static bool includesQtTest(const CPlusPlus::Document::Ptr &doc, const CPlusPlus::Snapshot &snapshot)
|
||||||
{
|
{
|
||||||
static QStringList expectedHeaderPrefixes
|
static QStringList expectedHeaderPrefixes = HostOsInfo::isMacHost()
|
||||||
= Utils::HostOsInfo::isMacHost()
|
|
||||||
? QStringList({"QtTest.framework/Headers", "QtTest"}) : QStringList({"QtTest"});
|
? QStringList({"QtTest.framework/Headers", "QtTest"}) : QStringList({"QtTest"});
|
||||||
|
|
||||||
const QList<CPlusPlus::Document::Include> includes = doc->resolvedIncludes();
|
const QList<CPlusPlus::Document::Include> includes = doc->resolvedIncludes();
|
||||||
@@ -71,7 +70,7 @@ static bool includesQtTest(const CPlusPlus::Document::Ptr &doc, const CPlusPlus:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool qtTestLibDefined(const Utils::FilePath &fileName)
|
static bool qtTestLibDefined(const FilePath &fileName)
|
||||||
{
|
{
|
||||||
const QList<CppEditor::ProjectPart::ConstPtr> parts =
|
const QList<CppEditor::ProjectPart::ConstPtr> parts =
|
||||||
CppEditor::CppModelManager::instance()->projectPart(fileName);
|
CppEditor::CppModelManager::instance()->projectPart(fileName);
|
||||||
@@ -84,7 +83,7 @@ static bool qtTestLibDefined(const Utils::FilePath &fileName)
|
|||||||
}
|
}
|
||||||
|
|
||||||
TestCases QtTestParser::testCases(const CppEditor::CppModelManager *modelManager,
|
TestCases QtTestParser::testCases(const CppEditor::CppModelManager *modelManager,
|
||||||
const Utils::FilePath &filePath) const
|
const FilePath &filePath) const
|
||||||
{
|
{
|
||||||
const QByteArray &fileContent = getFileContent(filePath);
|
const QByteArray &fileContent = getFileContent(filePath);
|
||||||
CPlusPlus::Document::Ptr document = modelManager->document(filePath);
|
CPlusPlus::Document::Ptr document = modelManager->document(filePath);
|
||||||
@@ -141,7 +140,7 @@ TestCases QtTestParser::testCases(const CppEditor::CppModelManager *modelManager
|
|||||||
static CPlusPlus::Document::Ptr declaringDocument(CPlusPlus::Document::Ptr doc,
|
static CPlusPlus::Document::Ptr declaringDocument(CPlusPlus::Document::Ptr doc,
|
||||||
const CPlusPlus::Snapshot &snapshot,
|
const CPlusPlus::Snapshot &snapshot,
|
||||||
const QString &testCaseName,
|
const QString &testCaseName,
|
||||||
const Utils::FilePaths &alternativeFiles = {},
|
const FilePaths &alternativeFiles = {},
|
||||||
int *line = nullptr,
|
int *line = nullptr,
|
||||||
int *column = nullptr)
|
int *column = nullptr)
|
||||||
{
|
{
|
||||||
@@ -153,7 +152,7 @@ static CPlusPlus::Document::Ptr declaringDocument(CPlusPlus::Document::Ptr doc,
|
|||||||
doc->globalNamespace());
|
doc->globalNamespace());
|
||||||
// fallback for inherited functions
|
// fallback for inherited functions
|
||||||
if (lookupItems.size() == 0 && !alternativeFiles.isEmpty()) {
|
if (lookupItems.size() == 0 && !alternativeFiles.isEmpty()) {
|
||||||
for (const Utils::FilePath &alternativeFile : alternativeFiles) {
|
for (const FilePath &alternativeFile : alternativeFiles) {
|
||||||
if (snapshot.contains(alternativeFile)) {
|
if (snapshot.contains(alternativeFile)) {
|
||||||
CPlusPlus::Document::Ptr document = snapshot.document(alternativeFile);
|
CPlusPlus::Document::Ptr document = snapshot.document(alternativeFile);
|
||||||
CPlusPlus::TypeOfExpression typeOfExpr; // we need a new one with no bindings
|
CPlusPlus::TypeOfExpression typeOfExpr; // we need a new one with no bindings
|
||||||
@@ -179,10 +178,10 @@ static CPlusPlus::Document::Ptr declaringDocument(CPlusPlus::Document::Ptr doc,
|
|||||||
return declaringDoc;
|
return declaringDoc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QSet<Utils::FilePath> filesWithDataFunctionDefinitions(
|
static QSet<FilePath> filesWithDataFunctionDefinitions(
|
||||||
const QMap<QString, QtTestCodeLocationAndType> &testFunctions)
|
const QMap<QString, QtTestCodeLocationAndType> &testFunctions)
|
||||||
{
|
{
|
||||||
QSet<Utils::FilePath> result;
|
QSet<FilePath> result;
|
||||||
QMap<QString, QtTestCodeLocationAndType>::ConstIterator it = testFunctions.begin();
|
QMap<QString, QtTestCodeLocationAndType>::ConstIterator it = testFunctions.begin();
|
||||||
const QMap<QString, QtTestCodeLocationAndType>::ConstIterator end = testFunctions.end();
|
const QMap<QString, QtTestCodeLocationAndType>::ConstIterator end = testFunctions.end();
|
||||||
|
|
||||||
@@ -195,7 +194,7 @@ static QSet<Utils::FilePath> filesWithDataFunctionDefinitions(
|
|||||||
}
|
}
|
||||||
|
|
||||||
QHash<QString, QtTestCodeLocationList> QtTestParser::checkForDataTags(
|
QHash<QString, QtTestCodeLocationList> QtTestParser::checkForDataTags(
|
||||||
const Utils::FilePath &fileName) const
|
const FilePath &fileName) const
|
||||||
{
|
{
|
||||||
const QByteArray fileContent = getFileContent(fileName);
|
const QByteArray fileContent = getFileContent(fileName);
|
||||||
CPlusPlus::Document::Ptr document = m_cppSnapshot.preprocessedDocument(fileContent, fileName);
|
CPlusPlus::Document::Ptr document = m_cppSnapshot.preprocessedDocument(fileContent, fileName);
|
||||||
@@ -289,12 +288,12 @@ static QtTestCodeLocationList tagLocationsFor(const QtTestParseResult *func,
|
|||||||
static bool isQObject(const CPlusPlus::Document::Ptr &declaringDoc)
|
static bool isQObject(const CPlusPlus::Document::Ptr &declaringDoc)
|
||||||
{
|
{
|
||||||
const FilePath file = declaringDoc->filePath();
|
const FilePath file = declaringDoc->filePath();
|
||||||
return (Utils::HostOsInfo::isMacHost() && file.endsWith("QtCore.framework/Headers/qobject.h"))
|
return (HostOsInfo::isMacHost() && file.endsWith("QtCore.framework/Headers/qobject.h"))
|
||||||
|| file.endsWith("QtCore/qobject.h") || file.endsWith("kernel/qobject.h");
|
|| file.endsWith("QtCore/qobject.h") || file.endsWith("kernel/qobject.h");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QtTestParser::processDocument(QFutureInterface<TestParseResultPtr> &futureInterface,
|
bool QtTestParser::processDocument(QFutureInterface<TestParseResultPtr> &futureInterface,
|
||||||
const Utils::FilePath &fileName)
|
const FilePath &fileName)
|
||||||
{
|
{
|
||||||
CPlusPlus::Document::Ptr doc = document(fileName);
|
CPlusPlus::Document::Ptr doc = document(fileName);
|
||||||
if (doc.isNull())
|
if (doc.isNull())
|
||||||
@@ -359,8 +358,8 @@ std::optional<bool> QtTestParser::fillTestCaseData(
|
|||||||
if (data.testFunctions.isEmpty() && testCaseName == "QObject" && isQObject(declaringDoc))
|
if (data.testFunctions.isEmpty() && testCaseName == "QObject" && isQObject(declaringDoc))
|
||||||
return true; // we did not handle it, but we do not expect any test defined there either
|
return true; // we did not handle it, but we do not expect any test defined there either
|
||||||
|
|
||||||
const QSet<Utils::FilePath> &files = filesWithDataFunctionDefinitions(data.testFunctions);
|
const QSet<FilePath> &files = filesWithDataFunctionDefinitions(data.testFunctions);
|
||||||
for (const Utils::FilePath &file : files)
|
for (const FilePath &file : files)
|
||||||
Utils::addToHash(&(data.dataTags), checkForDataTags(file));
|
Utils::addToHash(&(data.dataTags), checkForDataTags(file));
|
||||||
|
|
||||||
data.fileName = declaringDoc->filePath();
|
data.fileName = declaringDoc->filePath();
|
||||||
@@ -378,7 +377,7 @@ QtTestParseResult *QtTestParser::createParseResult(
|
|||||||
parseResult->displayName = testCaseName;
|
parseResult->displayName = testCaseName;
|
||||||
parseResult->line = data.line;
|
parseResult->line = data.line;
|
||||||
parseResult->column = data.column;
|
parseResult->column = data.column;
|
||||||
parseResult->proFile = Utils::FilePath::fromString(projectFile);
|
parseResult->proFile = FilePath::fromString(projectFile);
|
||||||
parseResult->setRunsMultipleTestcases(data.multipleTestCases);
|
parseResult->setRunsMultipleTestcases(data.multipleTestCases);
|
||||||
QMap<QString, QtTestCodeLocationAndType>::ConstIterator it = data.testFunctions.begin();
|
QMap<QString, QtTestCodeLocationAndType>::ConstIterator it = data.testFunctions.begin();
|
||||||
const QMap<QString, QtTestCodeLocationAndType>::ConstIterator end = data.testFunctions.end();
|
const QMap<QString, QtTestCodeLocationAndType>::ConstIterator end = data.testFunctions.end();
|
||||||
@@ -414,7 +413,7 @@ QtTestParseResult *QtTestParser::createParseResult(
|
|||||||
return parseResult;
|
return parseResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtTestParser::init(const Utils::FilePaths &filesToParse, bool fullParse)
|
void QtTestParser::init(const FilePaths &filesToParse, bool fullParse)
|
||||||
{
|
{
|
||||||
if (!fullParse) { // in a full parse cached information might lead to wrong results
|
if (!fullParse) { // in a full parse cached information might lead to wrong results
|
||||||
m_testCases = QTestUtils::testCaseNamesForFiles(framework(), filesToParse);
|
m_testCases = QTestUtils::testCaseNamesForFiles(framework(), filesToParse);
|
||||||
|
@@ -86,7 +86,7 @@ QString QtTestSettings::metricsTypeToOption(const MetricsType type)
|
|||||||
{
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case MetricsType::Walltime:
|
case MetricsType::Walltime:
|
||||||
return QString();
|
return {};
|
||||||
case MetricsType::TickCounter:
|
case MetricsType::TickCounter:
|
||||||
return QString("-tickcounter");
|
return QString("-tickcounter");
|
||||||
case MetricsType::EventCounter:
|
case MetricsType::EventCounter:
|
||||||
@@ -96,7 +96,7 @@ QString QtTestSettings::metricsTypeToOption(const MetricsType type)
|
|||||||
case MetricsType::Perf:
|
case MetricsType::Perf:
|
||||||
return QString("-perf");
|
return QString("-perf");
|
||||||
}
|
}
|
||||||
return QString();
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
QtTestSettingsPage::QtTestSettingsPage(QtTestSettings *settings, Id settingsId)
|
QtTestSettingsPage::QtTestSettingsPage(QtTestSettings *settings, Id settingsId)
|
||||||
|
@@ -12,11 +12,13 @@
|
|||||||
#include <projectexplorer/session.h>
|
#include <projectexplorer/session.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
namespace Autotest {
|
namespace Autotest {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
QtTestTreeItem::QtTestTreeItem(ITestFramework *testFramework, const QString &name,
|
QtTestTreeItem::QtTestTreeItem(ITestFramework *testFramework, const QString &name,
|
||||||
const Utils::FilePath &filePath, TestTreeItem::Type type)
|
const FilePath &filePath, TestTreeItem::Type type)
|
||||||
: TestTreeItem(testFramework, name, filePath, type)
|
: TestTreeItem(testFramework, name, filePath, type)
|
||||||
{
|
{
|
||||||
if (type == TestDataTag)
|
if (type == TestDataTag)
|
||||||
@@ -286,7 +288,7 @@ QList<ITestConfiguration *> QtTestTreeItem::getFailedTestConfigurations() const
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<ITestConfiguration *> QtTestTreeItem::getTestConfigurationsForFile(const Utils::FilePath &fileName) const
|
QList<ITestConfiguration *> QtTestTreeItem::getTestConfigurationsForFile(const FilePath &fileName) const
|
||||||
{
|
{
|
||||||
QList<ITestConfiguration *> result;
|
QList<ITestConfiguration *> result;
|
||||||
|
|
||||||
@@ -321,7 +323,7 @@ TestTreeItem *QtTestTreeItem::find(const TestParseResult *result)
|
|||||||
switch (type()) {
|
switch (type()) {
|
||||||
case Root:
|
case Root:
|
||||||
if (result->framework->grouping()) {
|
if (result->framework->grouping()) {
|
||||||
const Utils::FilePath path = result->fileName.absolutePath();
|
const FilePath path = result->fileName.absolutePath();
|
||||||
for (int row = 0; row < childCount(); ++row) {
|
for (int row = 0; row < childCount(); ++row) {
|
||||||
TestTreeItem *group = childItem(row);
|
TestTreeItem *group = childItem(row);
|
||||||
if (group->filePath() != path)
|
if (group->filePath() != path)
|
||||||
@@ -394,7 +396,7 @@ bool QtTestTreeItem::modify(const TestParseResult *result)
|
|||||||
|
|
||||||
TestTreeItem *QtTestTreeItem::createParentGroupNode() const
|
TestTreeItem *QtTestTreeItem::createParentGroupNode() const
|
||||||
{
|
{
|
||||||
const Utils::FilePath &absPath = filePath().absolutePath();
|
const FilePath &absPath = filePath().absolutePath();
|
||||||
return new QtTestTreeItem(framework(), absPath.baseName(), absPath, TestTreeItem::GroupNode);
|
return new QtTestTreeItem(framework(), absPath.baseName(), absPath, TestTreeItem::GroupNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -403,7 +405,7 @@ bool QtTestTreeItem::isGroupable() const
|
|||||||
return type() == TestCase;
|
return type() == TestCase;
|
||||||
}
|
}
|
||||||
|
|
||||||
TestTreeItem *QtTestTreeItem::findChildByFileNameAndType(const Utils::FilePath &file,
|
TestTreeItem *QtTestTreeItem::findChildByFileNameAndType(const FilePath &file,
|
||||||
const QString &name, Type type) const
|
const QString &name, Type type) const
|
||||||
{
|
{
|
||||||
return findFirstLevelChildItem([file, name, type](const TestTreeItem *other) {
|
return findFirstLevelChildItem([file, name, type](const TestTreeItem *other) {
|
||||||
|
@@ -11,8 +11,8 @@ namespace Internal {
|
|||||||
class QtTestTreeItem : public TestTreeItem
|
class QtTestTreeItem : public TestTreeItem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit QtTestTreeItem(ITestFramework *framework, const QString &name = QString(),
|
explicit QtTestTreeItem(ITestFramework *framework, const QString &name = {},
|
||||||
const Utils::FilePath &filePath = Utils::FilePath(), Type type = Root);
|
const Utils::FilePath &filePath = {}, Type type = Root);
|
||||||
|
|
||||||
TestTreeItem *copyWithoutChildren() override;
|
TestTreeItem *copyWithoutChildren() override;
|
||||||
QVariant data(int column, int role) const override;
|
QVariant data(int column, int role) const override;
|
||||||
|
@@ -12,6 +12,7 @@
|
|||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
using namespace CPlusPlus;
|
using namespace CPlusPlus;
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
namespace Autotest {
|
namespace Autotest {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
@@ -36,7 +37,7 @@ bool TestVisitor::visit(Class *symbol)
|
|||||||
Symbol *member = symbol->memberAt(i);
|
Symbol *member = symbol->memberAt(i);
|
||||||
Type *type = member->type().type();
|
Type *type = member->type().type();
|
||||||
|
|
||||||
const QString className = o.prettyName(CPlusPlus::LookupContext::fullyQualifiedName(
|
const QString className = o.prettyName(LookupContext::fullyQualifiedName(
|
||||||
member->enclosingClass()));
|
member->enclosingClass()));
|
||||||
if (className != m_className)
|
if (className != m_className)
|
||||||
continue;
|
continue;
|
||||||
@@ -51,12 +52,12 @@ bool TestVisitor::visit(Class *symbol)
|
|||||||
Function *functionDefinition = m_symbolFinder.findMatchingDefinition(
|
Function *functionDefinition = m_symbolFinder.findMatchingDefinition(
|
||||||
func, m_snapshot, true);
|
func, m_snapshot, true);
|
||||||
if (functionDefinition && functionDefinition->fileId()) {
|
if (functionDefinition && functionDefinition->fileId()) {
|
||||||
locationAndType.m_filePath = Utils::FilePath::fromString(
|
locationAndType.m_filePath = FilePath::fromString(
|
||||||
QString::fromUtf8(functionDefinition->fileName()));
|
QString::fromUtf8(functionDefinition->fileName()));
|
||||||
locationAndType.m_line = functionDefinition->line();
|
locationAndType.m_line = functionDefinition->line();
|
||||||
locationAndType.m_column = functionDefinition->column() - 1;
|
locationAndType.m_column = functionDefinition->column() - 1;
|
||||||
} else { // if we cannot find the definition use declaration as fallback
|
} else { // if we cannot find the definition use declaration as fallback
|
||||||
locationAndType.m_filePath = Utils::FilePath::fromString(
|
locationAndType.m_filePath = FilePath::fromString(
|
||||||
QString::fromUtf8(member->fileName()));
|
QString::fromUtf8(member->fileName()));
|
||||||
locationAndType.m_line = member->line();
|
locationAndType.m_line = member->line();
|
||||||
locationAndType.m_column = member->column() - 1;
|
locationAndType.m_column = member->column() - 1;
|
||||||
@@ -74,7 +75,7 @@ bool TestVisitor::visit(Class *symbol)
|
|||||||
}
|
}
|
||||||
for (int counter = 0, end = symbol->baseClassCount(); counter < end; ++counter) {
|
for (int counter = 0, end = symbol->baseClassCount(); counter < end; ++counter) {
|
||||||
if (BaseClass *base = symbol->baseClassAt(counter)) {
|
if (BaseClass *base = symbol->baseClassAt(counter)) {
|
||||||
const QString &baseClassName = o.prettyName(CPlusPlus::LookupContext::fullyQualifiedName(base));
|
const QString &baseClassName = o.prettyName(LookupContext::fullyQualifiedName(base));
|
||||||
if (baseClassName != "QObject")
|
if (baseClassName != "QObject")
|
||||||
m_baseClasses.insert(baseClassName);
|
m_baseClasses.insert(baseClassName);
|
||||||
}
|
}
|
||||||
@@ -171,7 +172,7 @@ bool TestDataFunctionVisitor::visit(FunctionDefinitionAST *ast)
|
|||||||
|
|
||||||
LookupContext lc;
|
LookupContext lc;
|
||||||
const QString prettyName =
|
const QString prettyName =
|
||||||
m_overview.prettyName(CPlusPlus::LookupContext::fullyQualifiedName(ast->symbol));
|
m_overview.prettyName(LookupContext::fullyQualifiedName(ast->symbol));
|
||||||
// do not handle functions that aren't real test data functions
|
// do not handle functions that aren't real test data functions
|
||||||
if (!prettyName.endsWith("_data"))
|
if (!prettyName.endsWith("_data"))
|
||||||
return false;
|
return false;
|
||||||
@@ -189,7 +190,7 @@ QString TestDataFunctionVisitor::extractNameFromAST(StringLiteralAST *ast, bool
|
|||||||
auto token = m_currentDoc->translationUnit()->tokenAt(ast->literal_token);
|
auto token = m_currentDoc->translationUnit()->tokenAt(ast->literal_token);
|
||||||
if (!token.isStringLiteral()) {
|
if (!token.isStringLiteral()) {
|
||||||
*ok = false;
|
*ok = false;
|
||||||
return QString();
|
return {};
|
||||||
}
|
}
|
||||||
*ok = true;
|
*ok = true;
|
||||||
QString name = QString::fromUtf8(token.spell());
|
QString name = QString::fromUtf8(token.spell());
|
||||||
|
@@ -9,6 +9,8 @@
|
|||||||
|
|
||||||
#include <QByteArrayList>
|
#include <QByteArrayList>
|
||||||
|
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
namespace Autotest {
|
namespace Autotest {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
namespace QuickTestUtils {
|
namespace QuickTestUtils {
|
||||||
@@ -20,10 +22,9 @@ bool isQuickTestMacro(const QByteArray ¯o)
|
|||||||
return valid.contains(macro);
|
return valid.contains(macro);
|
||||||
}
|
}
|
||||||
|
|
||||||
QHash<Utils::FilePath, Utils::FilePath> proFilesForQmlFiles(ITestFramework *framework,
|
QHash<FilePath, FilePath> proFilesForQmlFiles(ITestFramework *framework, const FilePaths &files)
|
||||||
const Utils::FilePaths &files)
|
|
||||||
{
|
{
|
||||||
QHash<Utils::FilePath, Utils::FilePath> result;
|
QHash<FilePath, FilePath> result;
|
||||||
TestTreeItem *rootNode = framework->rootNode();
|
TestTreeItem *rootNode = framework->rootNode();
|
||||||
QTC_ASSERT(rootNode, return result);
|
QTC_ASSERT(rootNode, return result);
|
||||||
|
|
||||||
@@ -31,16 +32,16 @@ QHash<Utils::FilePath, Utils::FilePath> proFilesForQmlFiles(ITestFramework *fram
|
|||||||
return result;
|
return result;
|
||||||
|
|
||||||
rootNode->forFirstLevelChildItems([&result, &files](TestTreeItem *child) {
|
rootNode->forFirstLevelChildItems([&result, &files](TestTreeItem *child) {
|
||||||
const Utils::FilePath &file = child->filePath();
|
const FilePath &file = child->filePath();
|
||||||
if (!file.isEmpty() && files.contains(file)) {
|
if (!file.isEmpty() && files.contains(file)) {
|
||||||
const Utils::FilePath &proFile = child->proFile();
|
const FilePath &proFile = child->proFile();
|
||||||
if (!proFile.isEmpty())
|
if (!proFile.isEmpty())
|
||||||
result.insert(file, proFile);
|
result.insert(file, proFile);
|
||||||
}
|
}
|
||||||
child->forFirstLevelChildItems([&result, &files](TestTreeItem *grandChild) {
|
child->forFirstLevelChildItems([&result, &files](TestTreeItem *grandChild) {
|
||||||
const Utils::FilePath &file = grandChild->filePath();
|
const FilePath &file = grandChild->filePath();
|
||||||
if (!file.isEmpty() && files.contains(file)) {
|
if (!file.isEmpty() && files.contains(file)) {
|
||||||
const Utils::FilePath &proFile = grandChild->proFile();
|
const FilePath &proFile = grandChild->proFile();
|
||||||
if (!proFile.isEmpty())
|
if (!proFile.isEmpty())
|
||||||
result.insert(file, proFile);
|
result.insert(file, proFile);
|
||||||
}
|
}
|
||||||
|
@@ -12,6 +12,8 @@
|
|||||||
|
|
||||||
#include <utils/stringutils.h>
|
#include <utils/stringutils.h>
|
||||||
|
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
namespace Autotest {
|
namespace Autotest {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
@@ -22,7 +24,7 @@ QuickTestConfiguration::QuickTestConfiguration(ITestFramework *framework)
|
|||||||
}
|
}
|
||||||
|
|
||||||
TestOutputReader *QuickTestConfiguration::createOutputReader(
|
TestOutputReader *QuickTestConfiguration::createOutputReader(
|
||||||
const QFutureInterface<TestResultPtr> &fi, Utils::QtcProcess *app) const
|
const QFutureInterface<TestResult> &fi, QtcProcess *app) const
|
||||||
{
|
{
|
||||||
auto qtSettings = static_cast<QtTestSettings *>(framework()->testSettings());
|
auto qtSettings = static_cast<QtTestSettings *>(framework()->testSettings());
|
||||||
const QtTestOutputReader::OutputMode mode = qtSettings && qtSettings->useXMLOutput.value()
|
const QtTestOutputReader::OutputMode mode = qtSettings && qtSettings->useXMLOutput.value()
|
||||||
@@ -64,7 +66,7 @@ QStringList QuickTestConfiguration::argumentsForTestRunner(QStringList *omitted)
|
|||||||
return arguments;
|
return arguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
Utils::Environment QuickTestConfiguration::filteredEnvironment(const Utils::Environment &original) const
|
Environment QuickTestConfiguration::filteredEnvironment(const Environment &original) const
|
||||||
{
|
{
|
||||||
return QTestUtils::prepareBasicEnvironment(original);
|
return QTestUtils::prepareBasicEnvironment(original);
|
||||||
}
|
}
|
||||||
|
@@ -12,7 +12,7 @@ class QuickTestConfiguration : public DebuggableTestConfiguration
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit QuickTestConfiguration(ITestFramework *framework);
|
explicit QuickTestConfiguration(ITestFramework *framework);
|
||||||
TestOutputReader *createOutputReader(const QFutureInterface<TestResultPtr> &fi,
|
TestOutputReader *createOutputReader(const QFutureInterface<TestResult> &fi,
|
||||||
Utils::QtcProcess *app) const override;
|
Utils::QtcProcess *app) const override;
|
||||||
QStringList argumentsForTestRunner(QStringList *omitted = nullptr) const override;
|
QStringList argumentsForTestRunner(QStringList *omitted = nullptr) const override;
|
||||||
Utils::Environment filteredEnvironment(const Utils::Environment &original) const override;
|
Utils::Environment filteredEnvironment(const Utils::Environment &original) const override;
|
||||||
|
@@ -20,8 +20,7 @@ ITestParser *QuickTestFramework::createTestParser()
|
|||||||
|
|
||||||
ITestTreeItem *QuickTestFramework::createRootNode()
|
ITestTreeItem *QuickTestFramework::createRootNode()
|
||||||
{
|
{
|
||||||
return new QuickTestTreeItem(this, displayName(),
|
return new QuickTestTreeItem(this, displayName(), {}, ITestTreeItem::Root);
|
||||||
Utils::FilePath(), ITestTreeItem::Root);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *QuickTestFramework::name() const
|
const char *QuickTestFramework::name() const
|
||||||
|
@@ -43,8 +43,7 @@ TestTreeItem *QuickTestParseResult::createTestTreeItem() const
|
|||||||
static bool includesQtQuickTest(const CPlusPlus::Document::Ptr &doc,
|
static bool includesQtQuickTest(const CPlusPlus::Document::Ptr &doc,
|
||||||
const CPlusPlus::Snapshot &snapshot)
|
const CPlusPlus::Snapshot &snapshot)
|
||||||
{
|
{
|
||||||
static QStringList expectedHeaderPrefixes
|
static QStringList expectedHeaderPrefixes = HostOsInfo::isMacHost()
|
||||||
= Utils::HostOsInfo::isMacHost()
|
|
||||||
? QStringList({"QtQuickTest.framework/Headers", "QtQuickTest"})
|
? QStringList({"QtQuickTest.framework/Headers", "QtQuickTest"})
|
||||||
: QStringList({"QtQuickTest"});
|
: QStringList({"QtQuickTest"});
|
||||||
|
|
||||||
@@ -78,8 +77,7 @@ static bool includesQtQuickTest(const CPlusPlus::Document::Ptr &doc,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QString quickTestSrcDir(const CppEditor::CppModelManager *cppMM,
|
static QString quickTestSrcDir(const CppEditor::CppModelManager *cppMM, const FilePath &fileName)
|
||||||
const Utils::FilePath &fileName)
|
|
||||||
{
|
{
|
||||||
const QList<CppEditor::ProjectPart::ConstPtr> parts = cppMM->projectPart(fileName);
|
const QList<CppEditor::ProjectPart::ConstPtr> parts = cppMM->projectPart(fileName);
|
||||||
if (parts.size() > 0) {
|
if (parts.size() > 0) {
|
||||||
@@ -103,7 +101,7 @@ static QString quickTestSrcDir(const CppEditor::CppModelManager *cppMM,
|
|||||||
QString QuickTestParser::quickTestName(const CPlusPlus::Document::Ptr &doc) const
|
QString QuickTestParser::quickTestName(const CPlusPlus::Document::Ptr &doc) const
|
||||||
{
|
{
|
||||||
const QList<CPlusPlus::Document::MacroUse> macros = doc->macroUses();
|
const QList<CPlusPlus::Document::MacroUse> macros = doc->macroUses();
|
||||||
const Utils::FilePath filePath = doc->filePath();
|
const FilePath filePath = doc->filePath();
|
||||||
|
|
||||||
for (const CPlusPlus::Document::MacroUse ¯o : macros) {
|
for (const CPlusPlus::Document::MacroUse ¯o : macros) {
|
||||||
if (!macro.isFunctionLike() || macro.arguments().isEmpty())
|
if (!macro.isFunctionLike() || macro.arguments().isEmpty())
|
||||||
@@ -121,7 +119,7 @@ QString QuickTestParser::quickTestName(const CPlusPlus::Document::Ptr &doc) cons
|
|||||||
// check for using quick_test_main() directly
|
// check for using quick_test_main() directly
|
||||||
CPlusPlus::Document::Ptr document = m_cppSnapshot.preprocessedDocument(fileContent, filePath);
|
CPlusPlus::Document::Ptr document = m_cppSnapshot.preprocessedDocument(fileContent, filePath);
|
||||||
if (document.isNull())
|
if (document.isNull())
|
||||||
return QString();
|
return {};
|
||||||
document->check();
|
document->check();
|
||||||
CPlusPlus::AST *ast = document->translationUnit()->ast();
|
CPlusPlus::AST *ast = document->translationUnit()->ast();
|
||||||
QuickTestAstVisitor astVisitor(document, m_cppSnapshot);
|
QuickTestAstVisitor astVisitor(document, m_cppSnapshot);
|
||||||
@@ -130,8 +128,7 @@ QString QuickTestParser::quickTestName(const CPlusPlus::Document::Ptr &doc) cons
|
|||||||
return astVisitor.testBaseName();
|
return astVisitor.testBaseName();
|
||||||
|
|
||||||
// check for precompiled headers
|
// check for precompiled headers
|
||||||
static QStringList expectedHeaderPrefixes
|
static QStringList expectedHeaderPrefixes = HostOsInfo::isMacHost()
|
||||||
= Utils::HostOsInfo::isMacHost()
|
|
||||||
? QStringList({"QtQuickTest.framework/Headers", "QtQuickTest"})
|
? QStringList({"QtQuickTest.framework/Headers", "QtQuickTest"})
|
||||||
: QStringList({"QtQuickTest"});
|
: QStringList({"QtQuickTest"});
|
||||||
bool pchIncludes = false;
|
bool pchIncludes = false;
|
||||||
@@ -152,9 +149,9 @@ QString QuickTestParser::quickTestName(const CPlusPlus::Document::Ptr &doc) cons
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<Document::Ptr> QuickTestParser::scanDirectoryForQuickTestQmlFiles(const Utils::FilePath &srcDir)
|
QList<Document::Ptr> QuickTestParser::scanDirectoryForQuickTestQmlFiles(const FilePath &srcDir)
|
||||||
{
|
{
|
||||||
Utils::FilePaths dirs({srcDir});
|
FilePaths dirs({srcDir});
|
||||||
QStringList dirsStr({srcDir.toString()});
|
QStringList dirsStr({srcDir.toString()});
|
||||||
ModelManagerInterface *qmlJsMM = QmlJSTools::Internal::ModelManager::instance();
|
ModelManagerInterface *qmlJsMM = QmlJSTools::Internal::ModelManager::instance();
|
||||||
// make sure even files not listed in pro file are available inside the snapshot
|
// make sure even files not listed in pro file are available inside the snapshot
|
||||||
@@ -171,7 +168,7 @@ QList<Document::Ptr> QuickTestParser::scanDirectoryForQuickTestQmlFiles(const Ut
|
|||||||
QDirIterator::Subdirectories);
|
QDirIterator::Subdirectories);
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
it.next();
|
it.next();
|
||||||
auto subDir = Utils::FilePath::fromFileInfo(it.fileInfo()).canonicalPath();
|
auto subDir = FilePath::fromFileInfo(it.fileInfo()).canonicalPath();
|
||||||
dirs.append(subDir);
|
dirs.append(subDir);
|
||||||
dirsStr.append(subDir.toString());
|
dirsStr.append(subDir.toString());
|
||||||
}
|
}
|
||||||
@@ -182,10 +179,10 @@ QList<Document::Ptr> QuickTestParser::scanDirectoryForQuickTestQmlFiles(const Ut
|
|||||||
|
|
||||||
QList<Document::Ptr> foundDocs;
|
QList<Document::Ptr> foundDocs;
|
||||||
|
|
||||||
for (const Utils::FilePath &path : std::as_const(dirs)) {
|
for (const FilePath &path : std::as_const(dirs)) {
|
||||||
const QList<Document::Ptr> docs = snapshot.documentsInDirectory(path);
|
const QList<Document::Ptr> docs = snapshot.documentsInDirectory(path);
|
||||||
for (const Document::Ptr &doc : docs) {
|
for (const Document::Ptr &doc : docs) {
|
||||||
Utils::FilePath fi = doc->fileName();
|
const FilePath fi = doc->fileName();
|
||||||
//const QFileInfo fi(doc->fileName());
|
//const QFileInfo fi(doc->fileName());
|
||||||
// using working copy above might provide no more existing files
|
// using working copy above might provide no more existing files
|
||||||
if (!fi.exists())
|
if (!fi.exists())
|
||||||
@@ -202,7 +199,7 @@ QList<Document::Ptr> QuickTestParser::scanDirectoryForQuickTestQmlFiles(const Ut
|
|||||||
static bool checkQmlDocumentForQuickTestCode(QFutureInterface<TestParseResultPtr> &futureInterface,
|
static bool checkQmlDocumentForQuickTestCode(QFutureInterface<TestParseResultPtr> &futureInterface,
|
||||||
const Document::Ptr &qmlJSDoc,
|
const Document::Ptr &qmlJSDoc,
|
||||||
ITestFramework *framework,
|
ITestFramework *framework,
|
||||||
const Utils::FilePath &proFile = Utils::FilePath(),
|
const FilePath &proFile = {},
|
||||||
bool checkForDerivedTest = false)
|
bool checkForDerivedTest = false)
|
||||||
{
|
{
|
||||||
if (qmlJSDoc.isNull())
|
if (qmlJSDoc.isNull())
|
||||||
@@ -260,10 +257,9 @@ bool QuickTestParser::handleQtQuickTest(QFutureInterface<TestParseResultPtr> &fu
|
|||||||
if (ppList.isEmpty()) // happens if shutting down while parsing
|
if (ppList.isEmpty()) // happens if shutting down while parsing
|
||||||
return false;
|
return false;
|
||||||
const FilePath cppFileName = document->filePath();
|
const FilePath cppFileName = document->filePath();
|
||||||
const FilePath proFile = Utils::FilePath::fromString(ppList.at(0)->projectFile);
|
const FilePath proFile = FilePath::fromString(ppList.at(0)->projectFile);
|
||||||
m_mainCppFiles.insert(cppFileName, proFile);
|
m_mainCppFiles.insert(cppFileName, proFile);
|
||||||
const Utils::FilePath srcDir = Utils::FilePath::fromString(
|
const FilePath srcDir = FilePath::fromString(quickTestSrcDir(modelManager, cppFileName));
|
||||||
quickTestSrcDir(modelManager, cppFileName));
|
|
||||||
if (srcDir.isEmpty())
|
if (srcDir.isEmpty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -308,7 +304,7 @@ void QuickTestParser::handleDirectoryChanged(const QString &directory)
|
|||||||
if (timestampChanged) {
|
if (timestampChanged) {
|
||||||
m_watchedFiles[directory] = filesAndDates;
|
m_watchedFiles[directory] = filesAndDates;
|
||||||
PathsAndLanguages paths;
|
PathsAndLanguages paths;
|
||||||
paths.maybeInsert(Utils::FilePath::fromString(directory), Dialect::Qml);
|
paths.maybeInsert(FilePath::fromString(directory), Dialect::Qml);
|
||||||
QFutureInterface<void> future;
|
QFutureInterface<void> future;
|
||||||
ModelManagerInterface *qmlJsMM = ModelManagerInterface::instance();
|
ModelManagerInterface *qmlJsMM = ModelManagerInterface::instance();
|
||||||
ModelManagerInterface::importScan(future, ModelManagerInterface::workingCopy(), paths,
|
ModelManagerInterface::importScan(future, ModelManagerInterface::workingCopy(), paths,
|
||||||
@@ -342,14 +338,14 @@ QuickTestParser::QuickTestParser(ITestFramework *framework)
|
|||||||
this, &QuickTestParser::handleDirectoryChanged);
|
this, &QuickTestParser::handleDirectoryChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QuickTestParser::init(const Utils::FilePaths &filesToParse, bool fullParse)
|
void QuickTestParser::init(const FilePaths &filesToParse, bool fullParse)
|
||||||
{
|
{
|
||||||
m_qmlSnapshot = QmlJSTools::Internal::ModelManager::instance()->snapshot();
|
m_qmlSnapshot = QmlJSTools::Internal::ModelManager::instance()->snapshot();
|
||||||
if (!fullParse) {
|
if (!fullParse) {
|
||||||
// in a full parse we get the correct entry points by the respective main
|
// in a full parse we get the correct entry points by the respective main
|
||||||
m_proFilesForQmlFiles = QuickTestUtils::proFilesForQmlFiles(framework(), filesToParse);
|
m_proFilesForQmlFiles = QuickTestUtils::proFilesForQmlFiles(framework(), filesToParse);
|
||||||
// get rid of cached main cpp files that are going to get processed anyhow
|
// get rid of cached main cpp files that are going to get processed anyhow
|
||||||
for (const Utils::FilePath &file : filesToParse) {
|
for (const FilePath &file : filesToParse) {
|
||||||
if (m_mainCppFiles.contains(file)) {
|
if (m_mainCppFiles.contains(file)) {
|
||||||
m_mainCppFiles.remove(file);
|
m_mainCppFiles.remove(file);
|
||||||
if (m_mainCppFiles.isEmpty())
|
if (m_mainCppFiles.isEmpty())
|
||||||
@@ -375,10 +371,10 @@ void QuickTestParser::release()
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool QuickTestParser::processDocument(QFutureInterface<TestParseResultPtr> &futureInterface,
|
bool QuickTestParser::processDocument(QFutureInterface<TestParseResultPtr> &futureInterface,
|
||||||
const Utils::FilePath &fileName)
|
const FilePath &fileName)
|
||||||
{
|
{
|
||||||
if (fileName.endsWith(".qml")) {
|
if (fileName.endsWith(".qml")) {
|
||||||
const Utils::FilePath &proFile = m_proFilesForQmlFiles.value(fileName);
|
const FilePath &proFile = m_proFilesForQmlFiles.value(fileName);
|
||||||
if (proFile.isEmpty())
|
if (proFile.isEmpty())
|
||||||
return false;
|
return false;
|
||||||
Document::Ptr qmlJSDoc = m_qmlSnapshot.document(fileName);
|
Document::Ptr qmlJSDoc = m_qmlSnapshot.document(fileName);
|
||||||
@@ -396,9 +392,9 @@ bool QuickTestParser::processDocument(QFutureInterface<TestParseResultPtr> &futu
|
|||||||
return handleQtQuickTest(futureInterface, cppdoc, framework());
|
return handleQtQuickTest(futureInterface, cppdoc, framework());
|
||||||
}
|
}
|
||||||
|
|
||||||
Utils::FilePath QuickTestParser::projectFileForMainCppFile(const Utils::FilePath &fileName) const
|
FilePath QuickTestParser::projectFileForMainCppFile(const FilePath &fileName) const
|
||||||
{
|
{
|
||||||
return m_mainCppFiles.contains(fileName) ? m_mainCppFiles.value(fileName) : Utils::FilePath();
|
return m_mainCppFiles.contains(fileName) ? m_mainCppFiles.value(fileName) : FilePath();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -12,10 +12,12 @@
|
|||||||
#include <projectexplorer/session.h>
|
#include <projectexplorer/session.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
namespace Autotest {
|
namespace Autotest {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
static QSet<QString> internalTargets(const Utils::FilePath &proFile);
|
static QSet<QString> internalTargets(const FilePath &proFile);
|
||||||
|
|
||||||
TestTreeItem *QuickTestTreeItem::copyWithoutChildren()
|
TestTreeItem *QuickTestTreeItem::copyWithoutChildren()
|
||||||
{
|
{
|
||||||
@@ -149,8 +151,8 @@ static QList<ITestConfiguration *> testConfigurationsFor(
|
|||||||
if (!project || rootNode->type() != TestTreeItem::Root)
|
if (!project || rootNode->type() != TestTreeItem::Root)
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
QHash<Utils::FilePath, QuickTestConfiguration *> configurationForProFiles;
|
QHash<FilePath, QuickTestConfiguration *> configurationForProFiles;
|
||||||
rootNode->forSelectedChildren([&predicate, &configurationForProFiles](Utils::TreeItem *it) {
|
rootNode->forSelectedChildren([&predicate, &configurationForProFiles](TreeItem *it) {
|
||||||
auto treeItem = static_cast<TestTreeItem *>(it);
|
auto treeItem = static_cast<TestTreeItem *>(it);
|
||||||
if (treeItem->type() == TestTreeItem::Root || treeItem->type() == TestTreeItem::GroupNode)
|
if (treeItem->type() == TestTreeItem::Root || treeItem->type() == TestTreeItem::GroupNode)
|
||||||
return true;
|
return true;
|
||||||
@@ -208,12 +210,12 @@ QList<ITestConfiguration *> QuickTestTreeItem::getAllTestConfigurations() const
|
|||||||
if (!project || type() != Root)
|
if (!project || type() != Root)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
QHash<Utils::FilePath, Tests> testsForProfile;
|
QHash<FilePath, Tests> testsForProfile;
|
||||||
forFirstLevelChildItems([&testsForProfile](TestTreeItem *child) {
|
forFirstLevelChildItems([&testsForProfile](TestTreeItem *child) {
|
||||||
// unnamed Quick Tests must be handled separately
|
// unnamed Quick Tests must be handled separately
|
||||||
if (child->name().isEmpty()) {
|
if (child->name().isEmpty()) {
|
||||||
child->forFirstLevelChildItems([&testsForProfile](TestTreeItem *grandChild) {
|
child->forFirstLevelChildItems([&testsForProfile](TestTreeItem *grandChild) {
|
||||||
const Utils::FilePath &proFile = grandChild->proFile();
|
const FilePath &proFile = grandChild->proFile();
|
||||||
++(testsForProfile[proFile].testCount);
|
++(testsForProfile[proFile].testCount);
|
||||||
testsForProfile[proFile].internalTargets = internalTargets(grandChild->proFile());
|
testsForProfile[proFile].internalTargets = internalTargets(grandChild->proFile());
|
||||||
});
|
});
|
||||||
@@ -255,7 +257,7 @@ QList<ITestConfiguration *> QuickTestTreeItem::getFailedTestConfigurations() con
|
|||||||
}
|
}
|
||||||
|
|
||||||
QList<ITestConfiguration *> QuickTestTreeItem::getTestConfigurationsForFile(
|
QList<ITestConfiguration *> QuickTestTreeItem::getTestConfigurationsForFile(
|
||||||
const Utils::FilePath &fileName) const
|
const FilePath &fileName) const
|
||||||
{
|
{
|
||||||
return testConfigurationsFor(this, [&fileName](TestTreeItem *it) {
|
return testConfigurationsFor(this, [&fileName](TestTreeItem *it) {
|
||||||
return it->filePath() == fileName;
|
return it->filePath() == fileName;
|
||||||
@@ -271,7 +273,7 @@ TestTreeItem *QuickTestTreeItem::find(const TestParseResult *result)
|
|||||||
if (result->name.isEmpty())
|
if (result->name.isEmpty())
|
||||||
return unnamedQuickTests();
|
return unnamedQuickTests();
|
||||||
if (result->framework->grouping()) {
|
if (result->framework->grouping()) {
|
||||||
const Utils::FilePath path = result->fileName.absolutePath();
|
const FilePath path = result->fileName.absolutePath();
|
||||||
TestTreeItem *group = findFirstLevelChildItem([path](TestTreeItem *group) {
|
TestTreeItem *group = findFirstLevelChildItem([path](TestTreeItem *group) {
|
||||||
return group->filePath() == path;
|
return group->filePath() == path;
|
||||||
});
|
});
|
||||||
@@ -354,7 +356,7 @@ bool QuickTestTreeItem::removeOnSweepIfEmpty() const
|
|||||||
|
|
||||||
TestTreeItem *QuickTestTreeItem::createParentGroupNode() const
|
TestTreeItem *QuickTestTreeItem::createParentGroupNode() const
|
||||||
{
|
{
|
||||||
const Utils::FilePath &absPath = filePath().absolutePath();
|
const FilePath &absPath = filePath().absolutePath();
|
||||||
return new QuickTestTreeItem(framework(), absPath.baseName(), absPath, TestTreeItem::GroupNode);
|
return new QuickTestTreeItem(framework(), absPath.baseName(), absPath, TestTreeItem::GroupNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -363,7 +365,7 @@ bool QuickTestTreeItem::isGroupable() const
|
|||||||
return type() == TestCase && !name().isEmpty() && !filePath().isEmpty();
|
return type() == TestCase && !name().isEmpty() && !filePath().isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
QSet<QString> internalTargets(const Utils::FilePath &proFile)
|
QSet<QString> internalTargets(const FilePath &proFile)
|
||||||
{
|
{
|
||||||
QSet<QString> result;
|
QSet<QString> result;
|
||||||
const auto cppMM = CppEditor::CppModelManager::instance();
|
const auto cppMM = CppEditor::CppModelManager::instance();
|
||||||
@@ -379,11 +381,11 @@ QSet<QString> internalTargets(const Utils::FilePath &proFile)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QuickTestTreeItem::markForRemovalRecursively(const Utils::FilePath &filePath)
|
void QuickTestTreeItem::markForRemovalRecursively(const FilePath &filePath)
|
||||||
{
|
{
|
||||||
TestTreeItem::markForRemovalRecursively(filePath);
|
TestTreeItem::markForRemovalRecursively(filePath);
|
||||||
auto parser = static_cast<QuickTestParser *>(framework()->testParser());
|
auto parser = static_cast<QuickTestParser *>(framework()->testParser());
|
||||||
const Utils::FilePath proFile = parser->projectFileForMainCppFile(filePath);
|
const FilePath proFile = parser->projectFileForMainCppFile(filePath);
|
||||||
if (!proFile.isEmpty()) {
|
if (!proFile.isEmpty()) {
|
||||||
TestTreeItem *root = framework()->rootNode();
|
TestTreeItem *root = framework()->rootNode();
|
||||||
root->forAllChildItems([proFile](TestTreeItem *it) {
|
root->forAllChildItems([proFile](TestTreeItem *it) {
|
||||||
@@ -393,7 +395,7 @@ void QuickTestTreeItem::markForRemovalRecursively(const Utils::FilePath &filePat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TestTreeItem *QuickTestTreeItem::findChildByFileNameAndType(const Utils::FilePath &filePath,
|
TestTreeItem *QuickTestTreeItem::findChildByFileNameAndType(const FilePath &filePath,
|
||||||
const QString &name,
|
const QString &name,
|
||||||
TestTreeItem::Type tType)
|
TestTreeItem::Type tType)
|
||||||
|
|
||||||
@@ -404,7 +406,7 @@ TestTreeItem *QuickTestTreeItem::findChildByFileNameAndType(const Utils::FilePat
|
|||||||
}
|
}
|
||||||
|
|
||||||
TestTreeItem *QuickTestTreeItem::findChildByNameFileAndLine(const QString &name,
|
TestTreeItem *QuickTestTreeItem::findChildByNameFileAndLine(const QString &name,
|
||||||
const Utils::FilePath &filePath,
|
const FilePath &filePath,
|
||||||
int line)
|
int line)
|
||||||
{
|
{
|
||||||
return findFirstLevelChildItem([name, filePath, line](const TestTreeItem *other) {
|
return findFirstLevelChildItem([name, filePath, line](const TestTreeItem *other) {
|
||||||
|
@@ -11,10 +11,8 @@ namespace Internal {
|
|||||||
class QuickTestTreeItem : public TestTreeItem
|
class QuickTestTreeItem : public TestTreeItem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit QuickTestTreeItem(ITestFramework *testFramework,
|
explicit QuickTestTreeItem(ITestFramework *testFramework, const QString &name = {},
|
||||||
const QString &name = QString(),
|
const Utils::FilePath &filePath = {}, Type type = Root)
|
||||||
const Utils::FilePath &filePath = Utils::FilePath(),
|
|
||||||
Type type = Root)
|
|
||||||
: TestTreeItem(testFramework, name, filePath, type)
|
: TestTreeItem(testFramework, name, filePath, type)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
@@ -26,6 +26,8 @@
|
|||||||
#include <QFutureInterface>
|
#include <QFutureInterface>
|
||||||
#include <QLoggingCategory>
|
#include <QLoggingCategory>
|
||||||
|
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
namespace Autotest {
|
namespace Autotest {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
@@ -146,12 +148,12 @@ void TestCodeParser::updateTestTree(const QSet<ITestParser *> &parsers)
|
|||||||
[](const ITestParser *lhs, const ITestParser *rhs) {
|
[](const ITestParser *lhs, const ITestParser *rhs) {
|
||||||
return lhs->framework()->priority() < rhs->framework()->priority();
|
return lhs->framework()->priority() < rhs->framework()->priority();
|
||||||
});
|
});
|
||||||
scanForTests(Utils::FilePaths(), sortedParsers);
|
scanForTests({}, sortedParsers);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****** threaded parsing stuff *******/
|
/****** threaded parsing stuff *******/
|
||||||
|
|
||||||
void TestCodeParser::onDocumentUpdated(const Utils::FilePath &fileName, bool isQmlFile)
|
void TestCodeParser::onDocumentUpdated(const FilePath &fileName, bool isQmlFile)
|
||||||
{
|
{
|
||||||
if (isProjectParsing() || m_codeModelParsing || m_postponedUpdateType == UpdateType::FullUpdate)
|
if (isProjectParsing() || m_codeModelParsing || m_postponedUpdateType == UpdateType::FullUpdate)
|
||||||
return;
|
return;
|
||||||
@@ -163,7 +165,7 @@ void TestCodeParser::onDocumentUpdated(const Utils::FilePath &fileName, bool isQ
|
|||||||
if (!isQmlFile && !project->isKnownFile(fileName))
|
if (!isQmlFile && !project->isKnownFile(fileName))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
scanForTests(Utils::FilePaths{fileName});
|
scanForTests({fileName});
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestCodeParser::onCppDocumentUpdated(const CPlusPlus::Document::Ptr &document)
|
void TestCodeParser::onCppDocumentUpdated(const CPlusPlus::Document::Ptr &document)
|
||||||
@@ -174,7 +176,7 @@ void TestCodeParser::onCppDocumentUpdated(const CPlusPlus::Document::Ptr &docume
|
|||||||
void TestCodeParser::onQmlDocumentUpdated(const QmlJS::Document::Ptr &document)
|
void TestCodeParser::onQmlDocumentUpdated(const QmlJS::Document::Ptr &document)
|
||||||
{
|
{
|
||||||
static const QStringList ignoredSuffixes{ "qbs", "ui.qml" };
|
static const QStringList ignoredSuffixes{ "qbs", "ui.qml" };
|
||||||
const Utils::FilePath fileName = document->fileName();
|
const FilePath fileName = document->fileName();
|
||||||
if (!ignoredSuffixes.contains(fileName.suffix()))
|
if (!ignoredSuffixes.contains(fileName.suffix()))
|
||||||
onDocumentUpdated(fileName, true);
|
onDocumentUpdated(fileName, true);
|
||||||
}
|
}
|
||||||
@@ -211,7 +213,7 @@ void TestCodeParser::aboutToShutdown()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TestCodeParser::postponed(const Utils::FilePaths &fileList)
|
bool TestCodeParser::postponed(const FilePaths &fileList)
|
||||||
{
|
{
|
||||||
switch (m_parserState) {
|
switch (m_parserState) {
|
||||||
case Idle:
|
case Idle:
|
||||||
@@ -253,7 +255,7 @@ bool TestCodeParser::postponed(const Utils::FilePaths &fileList)
|
|||||||
if (m_postponedUpdateType == UpdateType::FullUpdate)
|
if (m_postponedUpdateType == UpdateType::FullUpdate)
|
||||||
return true;
|
return true;
|
||||||
// partial parse triggered, postpone or add current files to already postponed partial
|
// partial parse triggered, postpone or add current files to already postponed partial
|
||||||
for (const Utils::FilePath &file : fileList)
|
for (const FilePath &file : fileList)
|
||||||
m_postponedFiles.insert(file);
|
m_postponedFiles.insert(file);
|
||||||
m_postponedUpdateType = UpdateType::PartialUpdate;
|
m_postponedUpdateType = UpdateType::PartialUpdate;
|
||||||
}
|
}
|
||||||
@@ -266,7 +268,7 @@ bool TestCodeParser::postponed(const Utils::FilePaths &fileList)
|
|||||||
|
|
||||||
static void parseFileForTests(const QList<ITestParser *> &parsers,
|
static void parseFileForTests(const QList<ITestParser *> &parsers,
|
||||||
QFutureInterface<TestParseResultPtr> &futureInterface,
|
QFutureInterface<TestParseResultPtr> &futureInterface,
|
||||||
const Utils::FilePath &fileName)
|
const FilePath &fileName)
|
||||||
{
|
{
|
||||||
for (ITestParser *parser : parsers) {
|
for (ITestParser *parser : parsers) {
|
||||||
if (futureInterface.isCanceled())
|
if (futureInterface.isCanceled())
|
||||||
@@ -276,8 +278,7 @@ static void parseFileForTests(const QList<ITestParser *> &parsers,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestCodeParser::scanForTests(const Utils::FilePaths &fileList,
|
void TestCodeParser::scanForTests(const FilePaths &fileList, const QList<ITestParser *> &parsers)
|
||||||
const QList<ITestParser *> &parsers)
|
|
||||||
{
|
{
|
||||||
if (m_parserState == Shutdown || m_testCodeParsers.isEmpty())
|
if (m_parserState == Shutdown || m_testCodeParsers.isEmpty())
|
||||||
return;
|
return;
|
||||||
@@ -292,7 +293,7 @@ void TestCodeParser::scanForTests(const Utils::FilePaths &fileList,
|
|||||||
Project *project = SessionManager::startupProject();
|
Project *project = SessionManager::startupProject();
|
||||||
if (!project)
|
if (!project)
|
||||||
return;
|
return;
|
||||||
Utils::FilePaths list;
|
FilePaths list;
|
||||||
if (isFullParse) {
|
if (isFullParse) {
|
||||||
list = project->files(Project::SourceFiles);
|
list = project->files(Project::SourceFiles);
|
||||||
if (list.isEmpty()) {
|
if (list.isEmpty()) {
|
||||||
@@ -318,7 +319,7 @@ void TestCodeParser::scanForTests(const Utils::FilePaths &fileList,
|
|||||||
TestTreeModel::instance()->updateCheckStateCache();
|
TestTreeModel::instance()->updateCheckStateCache();
|
||||||
if (isFullParse) {
|
if (isFullParse) {
|
||||||
// remove qml files as they will be found automatically by the referencing cpp file
|
// remove qml files as they will be found automatically by the referencing cpp file
|
||||||
list = Utils::filtered(list, [](const Utils::FilePath &fn) {
|
list = Utils::filtered(list, [](const FilePath &fn) {
|
||||||
return !fn.endsWith(".qml");
|
return !fn.endsWith(".qml");
|
||||||
});
|
});
|
||||||
if (!parsers.isEmpty()) {
|
if (!parsers.isEmpty()) {
|
||||||
@@ -330,11 +331,11 @@ void TestCodeParser::scanForTests(const Utils::FilePaths &fileList,
|
|||||||
}
|
}
|
||||||
} else if (!parsers.isEmpty()) {
|
} else if (!parsers.isEmpty()) {
|
||||||
for (ITestParser *parser: parsers) {
|
for (ITestParser *parser: parsers) {
|
||||||
for (const Utils::FilePath &filePath : std::as_const(list))
|
for (const FilePath &filePath : std::as_const(list))
|
||||||
parser->framework()->rootNode()->markForRemovalRecursively(filePath);
|
parser->framework()->rootNode()->markForRemovalRecursively(filePath);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (const Utils::FilePath &filePath : std::as_const(list))
|
for (const FilePath &filePath : std::as_const(list))
|
||||||
emit requestRemoval(filePath);
|
emit requestRemoval(filePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -353,8 +354,8 @@ void TestCodeParser::scanForTests(const Utils::FilePaths &fileList,
|
|||||||
}
|
}
|
||||||
// We are only interested in files that have been either parsed by the c++ parser,
|
// We are only interested in files that have been either parsed by the c++ parser,
|
||||||
// or have an extension that one of the parsers is specifically interested in.
|
// or have an extension that one of the parsers is specifically interested in.
|
||||||
const Utils::FilePaths filteredList
|
const FilePaths filteredList
|
||||||
= Utils::filtered(list, [&extensions, &cppSnapshot](const Utils::FilePath &fn) {
|
= Utils::filtered(list, [&extensions, &cppSnapshot](const FilePath &fn) {
|
||||||
const bool isSupportedExtension = Utils::anyOf(extensions, [&fn](const QString &ext) {
|
const bool isSupportedExtension = Utils::anyOf(extensions, [&fn](const QString &ext) {
|
||||||
return fn.suffix() == ext;
|
return fn.suffix() == ext;
|
||||||
});
|
});
|
||||||
@@ -366,12 +367,11 @@ void TestCodeParser::scanForTests(const Utils::FilePaths &fileList,
|
|||||||
qCDebug(LOG) << "Starting scan of" << filteredList.size() << "(" << list.size() << ")"
|
qCDebug(LOG) << "Starting scan of" << filteredList.size() << "(" << list.size() << ")"
|
||||||
<< "files with" << codeParsers.size() << "parsers";
|
<< "files with" << codeParsers.size() << "parsers";
|
||||||
|
|
||||||
QFuture<TestParseResultPtr> future = Utils::map(
|
QFuture<TestParseResultPtr> future = Utils::map(filteredList,
|
||||||
filteredList,
|
[codeParsers](QFutureInterface<TestParseResultPtr> &fi, const FilePath &file) {
|
||||||
[codeParsers](QFutureInterface<TestParseResultPtr> &fi, const Utils::FilePath &file) {
|
|
||||||
parseFileForTests(codeParsers, fi, file);
|
parseFileForTests(codeParsers, fi, file);
|
||||||
},
|
},
|
||||||
Utils::MapReduceOption::Unordered,
|
MapReduceOption::Unordered,
|
||||||
m_threadPool,
|
m_threadPool,
|
||||||
QThread::LowestPriority);
|
QThread::LowestPriority);
|
||||||
m_futureWatcher.setFuture(future);
|
m_futureWatcher.setFuture(future);
|
||||||
@@ -381,7 +381,7 @@ void TestCodeParser::scanForTests(const Utils::FilePaths &fileList,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestCodeParser::onTaskStarted(Utils::Id type)
|
void TestCodeParser::onTaskStarted(Id type)
|
||||||
{
|
{
|
||||||
if (type == CppEditor::Constants::TASK_INDEX) {
|
if (type == CppEditor::Constants::TASK_INDEX) {
|
||||||
m_codeModelParsing = true;
|
m_codeModelParsing = true;
|
||||||
@@ -395,7 +395,7 @@ void TestCodeParser::onTaskStarted(Utils::Id type)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestCodeParser::onAllTasksFinished(Utils::Id type)
|
void TestCodeParser::onAllTasksFinished(Id type)
|
||||||
{
|
{
|
||||||
// if we cancel parsing ensure that progress animation is canceled as well
|
// if we cancel parsing ensure that progress animation is canceled as well
|
||||||
if (type == Constants::TASK_PARSE && m_parsingHasFailed)
|
if (type == Constants::TASK_PARSE && m_parsingHasFailed)
|
||||||
|
@@ -61,7 +61,7 @@ FilePath ITestConfiguration::executableFilePath() const
|
|||||||
if (!hasExecutable())
|
if (!hasExecutable())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
const Environment env = m_runnable.environment.isValid()
|
const Environment env = m_runnable.environment.hasChanges()
|
||||||
? m_runnable.environment : Environment::systemEnvironment();
|
? m_runnable.environment : Environment::systemEnvironment();
|
||||||
return env.searchInPath(m_runnable.command.executable().path());
|
return env.searchInPath(m_runnable.command.executable().path());
|
||||||
}
|
}
|
||||||
|
@@ -26,8 +26,6 @@ class TestOutputReader;
|
|||||||
class TestResult;
|
class TestResult;
|
||||||
enum class TestRunMode;
|
enum class TestRunMode;
|
||||||
|
|
||||||
using TestResultPtr = QSharedPointer<TestResult>;
|
|
||||||
|
|
||||||
class ITestConfiguration
|
class ITestConfiguration
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -40,8 +38,9 @@ public:
|
|||||||
Utils::FilePath workingDirectory() const;
|
Utils::FilePath workingDirectory() const;
|
||||||
bool hasExecutable() const;
|
bool hasExecutable() const;
|
||||||
Utils::FilePath executableFilePath() const;
|
Utils::FilePath executableFilePath() const;
|
||||||
|
virtual Utils::FilePath testExecutable() const { return executableFilePath(); };
|
||||||
|
|
||||||
virtual TestOutputReader *createOutputReader(const QFutureInterface<TestResultPtr> &fi,
|
virtual TestOutputReader *createOutputReader(const QFutureInterface<TestResult> &fi,
|
||||||
Utils::QtcProcess *app) const = 0;
|
Utils::QtcProcess *app) const = 0;
|
||||||
virtual Utils::Environment filteredEnvironment(const Utils::Environment &original) const;
|
virtual Utils::Environment filteredEnvironment(const Utils::Environment &original) const;
|
||||||
|
|
||||||
@@ -126,6 +125,7 @@ public:
|
|||||||
explicit TestToolConfiguration(ITestBase *testBase) : ITestConfiguration(testBase) {}
|
explicit TestToolConfiguration(ITestBase *testBase) : ITestConfiguration(testBase) {}
|
||||||
Utils::CommandLine commandLine() const { return m_commandLine; }
|
Utils::CommandLine commandLine() const { return m_commandLine; }
|
||||||
void setCommandLine(const Utils::CommandLine &cmdline) { m_commandLine = cmdline; }
|
void setCommandLine(const Utils::CommandLine &cmdline) { m_commandLine = cmdline; }
|
||||||
|
virtual Utils::FilePath testExecutable() const override { return m_commandLine.executable(); };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Utils::CommandLine m_commandLine;
|
Utils::CommandLine m_commandLine;
|
||||||
|
@@ -32,6 +32,8 @@
|
|||||||
#include <QToolButton>
|
#include <QToolButton>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
namespace Autotest {
|
namespace Autotest {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
@@ -48,10 +50,8 @@ TestNavigationWidget::TestNavigationWidget(QWidget *parent) :
|
|||||||
m_view->setItemDelegate(new TestTreeItemDelegate(this));
|
m_view->setItemDelegate(new TestTreeItemDelegate(this));
|
||||||
|
|
||||||
QPalette pal;
|
QPalette pal;
|
||||||
pal.setColor(QPalette::Window,
|
pal.setColor(QPalette::Window, creatorTheme()->color(Theme::InfoBarBackground));
|
||||||
Utils::creatorTheme()->color(Utils::Theme::InfoBarBackground));
|
pal.setColor(QPalette::WindowText, creatorTheme()->color(Theme::InfoBarText));
|
||||||
pal.setColor(QPalette::WindowText,
|
|
||||||
Utils::creatorTheme()->color(Utils::Theme::InfoBarText));
|
|
||||||
m_missingFrameworksWidget = new QFrame;
|
m_missingFrameworksWidget = new QFrame;
|
||||||
m_missingFrameworksWidget->setPalette(pal);
|
m_missingFrameworksWidget->setPalette(pal);
|
||||||
m_missingFrameworksWidget->setAutoFillBackground(true);
|
m_missingFrameworksWidget->setAutoFillBackground(true);
|
||||||
@@ -70,7 +70,7 @@ TestNavigationWidget::TestNavigationWidget(QWidget *parent) :
|
|||||||
|
|
||||||
connect(m_view, &TestTreeView::activated, this, &TestNavigationWidget::onItemActivated);
|
connect(m_view, &TestTreeView::activated, this, &TestNavigationWidget::onItemActivated);
|
||||||
|
|
||||||
m_progressIndicator = new Utils::ProgressIndicator(Utils::ProgressIndicatorSize::Medium, this);
|
m_progressIndicator = new ProgressIndicator(ProgressIndicatorSize::Medium, this);
|
||||||
m_progressIndicator->attachToWidget(m_view);
|
m_progressIndicator->attachToWidget(m_view);
|
||||||
m_progressIndicator->hide();
|
m_progressIndicator->hide();
|
||||||
|
|
||||||
@@ -94,8 +94,7 @@ TestNavigationWidget::TestNavigationWidget(QWidget *parent) :
|
|||||||
});
|
});
|
||||||
connect(m_model, &TestTreeModel::testTreeModelChanged,
|
connect(m_model, &TestTreeModel::testTreeModelChanged,
|
||||||
this, &TestNavigationWidget::reapplyCachedExpandedState);
|
this, &TestNavigationWidget::reapplyCachedExpandedState);
|
||||||
connect(m_progressTimer, &QTimer::timeout,
|
connect(m_progressTimer, &QTimer::timeout, m_progressIndicator, &ProgressIndicator::show);
|
||||||
m_progressIndicator, &Utils::ProgressIndicator::show);
|
|
||||||
connect(m_view, &TestTreeView::expanded, this, &TestNavigationWidget::updateExpandedStateCache);
|
connect(m_view, &TestTreeView::expanded, this, &TestNavigationWidget::updateExpandedStateCache);
|
||||||
connect(m_view, &TestTreeView::collapsed, this, &TestNavigationWidget::updateExpandedStateCache);
|
connect(m_view, &TestTreeView::collapsed, this, &TestNavigationWidget::updateExpandedStateCache);
|
||||||
}
|
}
|
||||||
@@ -233,8 +232,8 @@ void TestNavigationWidget::updateExpandedStateCache()
|
|||||||
{
|
{
|
||||||
m_expandedStateCache.evolve(ITestBase::Framework);
|
m_expandedStateCache.evolve(ITestBase::Framework);
|
||||||
|
|
||||||
for (Utils::TreeItem *rootNode : *m_model->rootItem()) {
|
for (TreeItem *rootNode : *m_model->rootItem()) {
|
||||||
rootNode->forAllChildren([this](Utils::TreeItem *child) {
|
rootNode->forAllChildren([this](TreeItem *child) {
|
||||||
m_expandedStateCache.insert(static_cast<ITestTreeItem *>(child),
|
m_expandedStateCache.insert(static_cast<ITestTreeItem *>(child),
|
||||||
m_view->isExpanded(child->index()));
|
m_view->isExpanded(child->index()));
|
||||||
});
|
});
|
||||||
@@ -243,7 +242,7 @@ void TestNavigationWidget::updateExpandedStateCache()
|
|||||||
|
|
||||||
void TestNavigationWidget::onItemActivated(const QModelIndex &index)
|
void TestNavigationWidget::onItemActivated(const QModelIndex &index)
|
||||||
{
|
{
|
||||||
const Utils::Link link = index.data(LinkRole).value<Utils::Link>();
|
const Link link = index.data(LinkRole).value<Link>();
|
||||||
if (link.hasValidTarget())
|
if (link.hasValidTarget())
|
||||||
Core::EditorManager::openEditorAt(link);
|
Core::EditorManager::openEditorAt(link);
|
||||||
}
|
}
|
||||||
|
@@ -16,20 +16,19 @@
|
|||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
|
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
namespace Autotest {
|
namespace Autotest {
|
||||||
|
|
||||||
Utils::FilePath TestOutputReader::constructSourceFilePath(const Utils::FilePath &path,
|
FilePath TestOutputReader::constructSourceFilePath(const FilePath &path, const QString &file)
|
||||||
const QString &file)
|
|
||||||
{
|
{
|
||||||
const Utils::FilePath filePath = path.resolvePath(file);
|
const FilePath filePath = path.resolvePath(file);
|
||||||
return filePath.isReadableFile() ? filePath : Utils::FilePath();
|
return filePath.isReadableFile() ? filePath : FilePath();
|
||||||
}
|
}
|
||||||
|
|
||||||
TestOutputReader::TestOutputReader(const QFutureInterface<TestResultPtr> &futureInterface,
|
TestOutputReader::TestOutputReader(const QFutureInterface<TestResult> &futureInterface,
|
||||||
Utils::QtcProcess *testApplication,
|
QtcProcess *testApplication, const FilePath &buildDirectory)
|
||||||
const Utils::FilePath &buildDirectory)
|
|
||||||
: m_futureInterface(futureInterface)
|
: m_futureInterface(futureInterface)
|
||||||
, m_testApplication(testApplication)
|
|
||||||
, m_buildDir(buildDirectory)
|
, m_buildDir(buildDirectory)
|
||||||
, m_id(testApplication ? testApplication->commandLine().executable().toUserOutput() : QString())
|
, m_id(testApplication ? testApplication->commandLine().executable().toUserOutput() : QString())
|
||||||
{
|
{
|
||||||
@@ -41,11 +40,11 @@ TestOutputReader::TestOutputReader(const QFutureInterface<TestResultPtr> &future
|
|||||||
return line;
|
return line;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (m_testApplication) {
|
if (testApplication) {
|
||||||
m_testApplication->setStdOutLineCallback([this, &chopLineBreak](const QString &line) {
|
testApplication->setStdOutLineCallback([this, &chopLineBreak](const QString &line) {
|
||||||
processStdOutput(chopLineBreak(line.toUtf8()));
|
processStdOutput(chopLineBreak(line.toUtf8()));
|
||||||
});
|
});
|
||||||
m_testApplication->setStdErrLineCallback([this, &chopLineBreak](const QString &line) {
|
testApplication->setStdErrLineCallback([this, &chopLineBreak](const QString &line) {
|
||||||
processStdError(chopLineBreak(line.toUtf8()));
|
processStdError(chopLineBreak(line.toUtf8()));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -53,7 +52,7 @@ TestOutputReader::TestOutputReader(const QFutureInterface<TestResultPtr> &future
|
|||||||
|
|
||||||
TestOutputReader::~TestOutputReader()
|
TestOutputReader::~TestOutputReader()
|
||||||
{
|
{
|
||||||
if (m_sanitizerResult)
|
if (m_sanitizerResult.isValid())
|
||||||
sendAndResetSanitizerResult();
|
sendAndResetSanitizerResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,17 +70,17 @@ void TestOutputReader::processStdError(const QByteArray &outputLine)
|
|||||||
|
|
||||||
void TestOutputReader::reportCrash()
|
void TestOutputReader::reportCrash()
|
||||||
{
|
{
|
||||||
TestResultPtr result = createDefaultResult();
|
TestResult result = createDefaultResult();
|
||||||
result->setDescription(Tr::tr("Test executable crashed."));
|
result.setDescription(Tr::tr("Test executable crashed."));
|
||||||
result->setResult(ResultType::MessageFatal);
|
result.setResult(ResultType::MessageFatal);
|
||||||
m_futureInterface.reportResult(result);
|
emit newResult(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestOutputReader::createAndReportResult(const QString &message, ResultType type)
|
void TestOutputReader::createAndReportResult(const QString &message, ResultType type)
|
||||||
{
|
{
|
||||||
TestResultPtr result = createDefaultResult();
|
TestResult result = createDefaultResult();
|
||||||
result->setDescription(message);
|
result.setDescription(message);
|
||||||
result->setResult(type);
|
result.setResult(type);
|
||||||
reportResult(result);
|
reportResult(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,11 +104,11 @@ QString TestOutputReader::removeCommandlineColors(const QString &original)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestOutputReader::reportResult(const TestResultPtr &result)
|
void TestOutputReader::reportResult(const TestResult &result)
|
||||||
{
|
{
|
||||||
if (m_sanitizerResult)
|
if (m_sanitizerResult.isValid())
|
||||||
sendAndResetSanitizerResult();
|
sendAndResetSanitizerResult();
|
||||||
m_futureInterface.reportResult(result);
|
emit newResult(result);
|
||||||
m_hadValidOutput = true;
|
m_hadValidOutput = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,7 +140,7 @@ void TestOutputReader::checkForSanitizerOutput(const QByteArray &line)
|
|||||||
mode = SanitizerOutputMode::Ubsan;
|
mode = SanitizerOutputMode::Ubsan;
|
||||||
}
|
}
|
||||||
if (mode != SanitizerOutputMode::None) {
|
if (mode != SanitizerOutputMode::None) {
|
||||||
if (m_sanitizerResult) // we have a result that has not been reported yet
|
if (m_sanitizerResult.isValid()) // we have a result that has not been reported yet
|
||||||
sendAndResetSanitizerResult();
|
sendAndResetSanitizerResult();
|
||||||
|
|
||||||
m_sanitizerOutputMode = mode;
|
m_sanitizerOutputMode = mode;
|
||||||
@@ -149,34 +148,34 @@ void TestOutputReader::checkForSanitizerOutput(const QByteArray &line)
|
|||||||
m_sanitizerLines.append("Sanitizer Issue");
|
m_sanitizerLines.append("Sanitizer Issue");
|
||||||
m_sanitizerLines.append(lineStr);
|
m_sanitizerLines.append(lineStr);
|
||||||
if (m_sanitizerOutputMode == SanitizerOutputMode::Ubsan) {
|
if (m_sanitizerOutputMode == SanitizerOutputMode::Ubsan) {
|
||||||
const Utils::FilePath path = constructSourceFilePath(m_buildDir, match.captured(1));
|
const FilePath path = constructSourceFilePath(m_buildDir, match.captured(1));
|
||||||
// path may be empty if not existing - so, provide at least what we have
|
// path may be empty if not existing - so, provide at least what we have
|
||||||
m_sanitizerResult->setFileName(
|
m_sanitizerResult.setFileName(
|
||||||
path.exists() ? path : Utils::FilePath::fromString(match.captured(1)));
|
path.exists() ? path : FilePath::fromString(match.captured(1)));
|
||||||
m_sanitizerResult->setLine(match.captured(2).toInt());
|
m_sanitizerResult.setLine(match.captured(2).toInt());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestOutputReader::sendAndResetSanitizerResult()
|
void TestOutputReader::sendAndResetSanitizerResult()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(m_sanitizerResult, return);
|
QTC_ASSERT(m_sanitizerResult.isValid(), return);
|
||||||
m_sanitizerResult->setDescription(m_sanitizerLines.join('\n'));
|
m_sanitizerResult.setDescription(m_sanitizerLines.join('\n'));
|
||||||
m_sanitizerResult->setResult(m_sanitizerOutputMode == SanitizerOutputMode::Ubsan
|
m_sanitizerResult.setResult(m_sanitizerOutputMode == SanitizerOutputMode::Ubsan
|
||||||
? ResultType::Fail : ResultType::MessageFatal);
|
? ResultType::Fail : ResultType::MessageFatal);
|
||||||
|
|
||||||
if (m_sanitizerResult->fileName().isEmpty()) {
|
if (m_sanitizerResult.fileName().isEmpty()) {
|
||||||
const ITestTreeItem *testItem = m_sanitizerResult->findTestTreeItem();
|
const ITestTreeItem *testItem = m_sanitizerResult.findTestTreeItem();
|
||||||
if (testItem && testItem->line()) {
|
if (testItem && testItem->line()) {
|
||||||
m_sanitizerResult->setFileName(testItem->filePath());
|
m_sanitizerResult.setFileName(testItem->filePath());
|
||||||
m_sanitizerResult->setLine(testItem->line());
|
m_sanitizerResult.setLine(testItem->line());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_futureInterface.reportResult(m_sanitizerResult);
|
emit newResult(m_sanitizerResult);
|
||||||
m_hadValidOutput = true;
|
m_hadValidOutput = true;
|
||||||
m_sanitizerLines.clear();
|
m_sanitizerLines.clear();
|
||||||
m_sanitizerResult.reset();
|
m_sanitizerResult = {};
|
||||||
m_sanitizerOutputMode = SanitizerOutputMode::None;
|
m_sanitizerOutputMode = SanitizerOutputMode::None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -17,7 +17,7 @@ class TestOutputReader : public QObject
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
TestOutputReader(const QFutureInterface<TestResultPtr> &futureInterface,
|
TestOutputReader(const QFutureInterface<TestResult> &futureInterface,
|
||||||
Utils::QtcProcess *testApplication, const Utils::FilePath &buildDirectory);
|
Utils::QtcProcess *testApplication, const Utils::FilePath &buildDirectory);
|
||||||
virtual ~TestOutputReader();
|
virtual ~TestOutputReader();
|
||||||
void processStdOutput(const QByteArray &outputLine);
|
void processStdOutput(const QByteArray &outputLine);
|
||||||
@@ -33,6 +33,7 @@ public:
|
|||||||
|
|
||||||
void resetCommandlineColor();
|
void resetCommandlineColor();
|
||||||
signals:
|
signals:
|
||||||
|
void newResult(const TestResult &result);
|
||||||
void newOutputLineAvailable(const QByteArray &outputLine, OutputChannel channel);
|
void newOutputLineAvailable(const QByteArray &outputLine, OutputChannel channel);
|
||||||
protected:
|
protected:
|
||||||
static Utils::FilePath constructSourceFilePath(const Utils::FilePath &base,
|
static Utils::FilePath constructSourceFilePath(const Utils::FilePath &base,
|
||||||
@@ -40,20 +41,19 @@ protected:
|
|||||||
|
|
||||||
QString removeCommandlineColors(const QString &original);
|
QString removeCommandlineColors(const QString &original);
|
||||||
virtual void processOutputLine(const QByteArray &outputLine) = 0;
|
virtual void processOutputLine(const QByteArray &outputLine) = 0;
|
||||||
virtual TestResultPtr createDefaultResult() const = 0;
|
virtual TestResult createDefaultResult() const = 0;
|
||||||
void checkForSanitizerOutput(const QByteArray &line);
|
void checkForSanitizerOutput(const QByteArray &line);
|
||||||
void sendAndResetSanitizerResult();
|
void sendAndResetSanitizerResult();
|
||||||
|
|
||||||
void reportResult(const TestResultPtr &result);
|
void reportResult(const TestResult &result);
|
||||||
QFutureInterface<TestResultPtr> m_futureInterface;
|
QFutureInterface<TestResult> m_futureInterface;
|
||||||
Utils::QtcProcess *m_testApplication; // not owned
|
|
||||||
Utils::FilePath m_buildDir;
|
Utils::FilePath m_buildDir;
|
||||||
QString m_id;
|
QString m_id;
|
||||||
QHash<ResultType, int> m_summary;
|
QHash<ResultType, int> m_summary;
|
||||||
int m_disabled = -1;
|
int m_disabled = -1;
|
||||||
private:
|
private:
|
||||||
enum class SanitizerOutputMode { None, Asan, Ubsan};
|
enum class SanitizerOutputMode { None, Asan, Ubsan};
|
||||||
TestResultPtr m_sanitizerResult;
|
TestResult m_sanitizerResult;
|
||||||
QStringList m_sanitizerLines;
|
QStringList m_sanitizerLines;
|
||||||
SanitizerOutputMode m_sanitizerOutputMode = SanitizerOutputMode::None;
|
SanitizerOutputMode m_sanitizerOutputMode = SanitizerOutputMode::None;
|
||||||
bool m_hadValidOutput = false;
|
bool m_hadValidOutput = false;
|
||||||
|
@@ -12,6 +12,8 @@
|
|||||||
|
|
||||||
#include <QLoggingCategory>
|
#include <QLoggingCategory>
|
||||||
|
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
namespace Autotest {
|
namespace Autotest {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
@@ -43,7 +45,7 @@ void TestProjectSettings::setUseGlobalSettings(bool useGlobal)
|
|||||||
m_useGlobalSettings = useGlobal;
|
m_useGlobalSettings = useGlobal;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestProjectSettings::activateFramework(const Utils::Id &id, bool activate)
|
void TestProjectSettings::activateFramework(const Id &id, bool activate)
|
||||||
{
|
{
|
||||||
ITestFramework *framework = TestFrameworkManager::frameworkForId(id);
|
ITestFramework *framework = TestFrameworkManager::frameworkForId(id);
|
||||||
m_activeTestFrameworks[framework] = activate;
|
m_activeTestFrameworks[framework] = activate;
|
||||||
@@ -51,7 +53,7 @@ void TestProjectSettings::activateFramework(const Utils::Id &id, bool activate)
|
|||||||
framework->resetRootNode();
|
framework->resetRootNode();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestProjectSettings::activateTestTool(const Utils::Id &id, bool activate)
|
void TestProjectSettings::activateTestTool(const Id &id, bool activate)
|
||||||
{
|
{
|
||||||
ITestTool *testTool = TestFrameworkManager::testToolForId(id);
|
ITestTool *testTool = TestFrameworkManager::testToolForId(id);
|
||||||
m_activeTestTools[testTool] = activate;
|
m_activeTestTools[testTool] = activate;
|
||||||
@@ -74,12 +76,12 @@ void TestProjectSettings::load()
|
|||||||
if (activeFrameworks.isValid()) {
|
if (activeFrameworks.isValid()) {
|
||||||
const QMap<QString, QVariant> frameworksMap = activeFrameworks.toMap();
|
const QMap<QString, QVariant> frameworksMap = activeFrameworks.toMap();
|
||||||
for (ITestFramework *framework : registeredFrameworks) {
|
for (ITestFramework *framework : registeredFrameworks) {
|
||||||
const Utils::Id id = framework->id();
|
const Id id = framework->id();
|
||||||
bool active = frameworksMap.value(id.toString(), framework->active()).toBool();
|
bool active = frameworksMap.value(id.toString(), framework->active()).toBool();
|
||||||
m_activeTestFrameworks.insert(framework, active);
|
m_activeTestFrameworks.insert(framework, active);
|
||||||
}
|
}
|
||||||
for (ITestTool *testTool : registeredTestTools) {
|
for (ITestTool *testTool : registeredTestTools) {
|
||||||
const Utils::Id id = testTool->id();
|
const Id id = testTool->id();
|
||||||
bool active = frameworksMap.value(id.toString(), testTool->active()).toBool();
|
bool active = frameworksMap.value(id.toString(), testTool->active()).toBool();
|
||||||
m_activeTestTools.insert(testTool, active);
|
m_activeTestTools.insert(testTool, active);
|
||||||
}
|
}
|
||||||
|
@@ -6,6 +6,8 @@
|
|||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
#include <utils/theme/theme.h>
|
#include <utils/theme/theme.h>
|
||||||
|
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
namespace Autotest {
|
namespace Autotest {
|
||||||
|
|
||||||
TestResult::TestResult(const QString &id, const QString &name, const ResultHooks &hooks)
|
TestResult::TestResult(const QString &id, const QString &name, const ResultHooks &hooks)
|
||||||
@@ -15,6 +17,11 @@ TestResult::TestResult(const QString &id, const QString &name, const ResultHooks
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TestResult::isValid() const
|
||||||
|
{
|
||||||
|
return !m_id.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
const QString TestResult::outputString(bool selected) const
|
const QString TestResult::outputString(bool selected) const
|
||||||
{
|
{
|
||||||
if (m_hooks.outputString)
|
if (m_hooks.outputString)
|
||||||
@@ -113,10 +120,10 @@ QString TestResult::resultToString(const ResultType type)
|
|||||||
return QString("BXFAIL");
|
return QString("BXFAIL");
|
||||||
case ResultType::MessageLocation:
|
case ResultType::MessageLocation:
|
||||||
case ResultType::Application:
|
case ResultType::Application:
|
||||||
return QString();
|
return {};
|
||||||
default:
|
default:
|
||||||
if (type >= ResultType::INTERNAL_MESSAGES_BEGIN && type <= ResultType::INTERNAL_MESSAGES_END)
|
if (type >= ResultType::INTERNAL_MESSAGES_BEGIN && type <= ResultType::INTERNAL_MESSAGES_END)
|
||||||
return QString();
|
return {};
|
||||||
return QString("UNKNOWN");
|
return QString("UNKNOWN");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -126,64 +133,60 @@ QColor TestResult::colorForType(const ResultType type)
|
|||||||
if (type >= ResultType::INTERNAL_MESSAGES_BEGIN && type <= ResultType::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();
|
const Theme *theme = creatorTheme();
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ResultType::Pass:
|
case ResultType::Pass:
|
||||||
return creatorTheme->color(Utils::Theme::OutputPanes_TestPassTextColor);
|
return theme->color(Theme::OutputPanes_TestPassTextColor);
|
||||||
case ResultType::Fail:
|
case ResultType::Fail:
|
||||||
return creatorTheme->color(Utils::Theme::OutputPanes_TestFailTextColor);
|
return theme->color(Theme::OutputPanes_TestFailTextColor);
|
||||||
case ResultType::ExpectedFail:
|
case ResultType::ExpectedFail:
|
||||||
return creatorTheme->color(Utils::Theme::OutputPanes_TestXFailTextColor);
|
return theme->color(Theme::OutputPanes_TestXFailTextColor);
|
||||||
case ResultType::UnexpectedPass:
|
case ResultType::UnexpectedPass:
|
||||||
return creatorTheme->color(Utils::Theme::OutputPanes_TestXPassTextColor);
|
return theme->color(Theme::OutputPanes_TestXPassTextColor);
|
||||||
case ResultType::Skip:
|
case ResultType::Skip:
|
||||||
return creatorTheme->color(Utils::Theme::OutputPanes_TestSkipTextColor);
|
return theme->color(Theme::OutputPanes_TestSkipTextColor);
|
||||||
case ResultType::MessageDebug:
|
case ResultType::MessageDebug:
|
||||||
case ResultType::MessageInfo:
|
case ResultType::MessageInfo:
|
||||||
return creatorTheme->color(Utils::Theme::OutputPanes_TestDebugTextColor);
|
return theme->color(Theme::OutputPanes_TestDebugTextColor);
|
||||||
case ResultType::MessageWarn:
|
case ResultType::MessageWarn:
|
||||||
return creatorTheme->color(Utils::Theme::OutputPanes_TestWarnTextColor);
|
return theme->color(Theme::OutputPanes_TestWarnTextColor);
|
||||||
case ResultType::MessageFatal:
|
case ResultType::MessageFatal:
|
||||||
case ResultType::MessageSystem:
|
case ResultType::MessageSystem:
|
||||||
case ResultType::MessageError:
|
case ResultType::MessageError:
|
||||||
return creatorTheme->color(Utils::Theme::OutputPanes_TestFatalTextColor);
|
return theme->color(Theme::OutputPanes_TestFatalTextColor);
|
||||||
case ResultType::BlacklistedPass:
|
case ResultType::BlacklistedPass:
|
||||||
case ResultType::BlacklistedFail:
|
case ResultType::BlacklistedFail:
|
||||||
case ResultType::BlacklistedXPass:
|
case ResultType::BlacklistedXPass:
|
||||||
case ResultType::BlacklistedXFail:
|
case ResultType::BlacklistedXFail:
|
||||||
default:
|
default:
|
||||||
return creatorTheme->color(Utils::Theme::OutputPanes_StdOutTextColor);
|
return theme->color(Theme::OutputPanes_StdOutTextColor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TestResult::isDirectParentOf(const TestResult *other, bool *needsIntermediate) const
|
bool TestResult::isDirectParentOf(const TestResult &other, bool *needsIntermediate) const
|
||||||
{
|
{
|
||||||
QTC_ASSERT(other, return false);
|
QTC_ASSERT(other.isValid(), return false);
|
||||||
const bool ret = !m_id.isEmpty() && m_id == other->m_id && m_name == other->m_name;
|
const bool ret = !m_id.isEmpty() && m_id == other.m_id && m_name == other.m_name;
|
||||||
if (!ret)
|
if (!ret)
|
||||||
return false;
|
return false;
|
||||||
if (m_hooks.directParent)
|
if (m_hooks.directParent)
|
||||||
return m_hooks.directParent(*this, *other, needsIntermediate);
|
return m_hooks.directParent(*this, other, needsIntermediate);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TestResult::isIntermediateFor(const TestResult *other) const
|
bool TestResult::isIntermediateFor(const TestResult &other) const
|
||||||
{
|
{
|
||||||
QTC_ASSERT(other, return false);
|
QTC_ASSERT(other.isValid(), return false);
|
||||||
if (m_hooks.intermediate)
|
if (m_hooks.intermediate)
|
||||||
return m_hooks.intermediate(*this, *other);
|
return m_hooks.intermediate(*this, other);
|
||||||
return !m_id.isEmpty() && m_id == other->m_id && m_name == other->m_name;
|
return !m_id.isEmpty() && m_id == other.m_id && m_name == other.m_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
TestResult *TestResult::createIntermediateResult() const
|
TestResult TestResult::intermediateResult() const
|
||||||
{
|
{
|
||||||
if (m_hooks.createResult) {
|
if (m_hooks.createResult)
|
||||||
TestResult *newResult = new TestResult;
|
return m_hooks.createResult(*this);
|
||||||
*newResult = m_hooks.createResult(*this);
|
return {m_id, m_name};
|
||||||
return newResult;
|
|
||||||
}
|
|
||||||
TestResult *intermediate = new TestResult(m_id, m_name);
|
|
||||||
return intermediate;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Autotest
|
} // namespace Autotest
|
||||||
|
@@ -5,12 +5,9 @@
|
|||||||
|
|
||||||
#include "autotestconstants.h"
|
#include "autotestconstants.h"
|
||||||
|
|
||||||
#include <utils/fileutils.h>
|
#include <utils/filepath.h>
|
||||||
|
|
||||||
#include <QColor>
|
#include <QColor>
|
||||||
#include <QMetaType>
|
|
||||||
#include <QSharedPointer>
|
|
||||||
#include <QString>
|
|
||||||
|
|
||||||
namespace Autotest {
|
namespace Autotest {
|
||||||
|
|
||||||
@@ -82,6 +79,7 @@ public:
|
|||||||
TestResult(const QString &id, const QString &name, const ResultHooks &hooks = {});
|
TestResult(const QString &id, const QString &name, const ResultHooks &hooks = {});
|
||||||
virtual ~TestResult() {}
|
virtual ~TestResult() {}
|
||||||
|
|
||||||
|
bool isValid() const;
|
||||||
const QString outputString(bool selected) const;
|
const QString outputString(bool selected) const;
|
||||||
const ITestTreeItem *findTestTreeItem() const;
|
const ITestTreeItem *findTestTreeItem() const;
|
||||||
|
|
||||||
@@ -103,9 +101,9 @@ public:
|
|||||||
static QString resultToString(const ResultType type);
|
static QString resultToString(const ResultType type);
|
||||||
static QColor colorForType(const ResultType type);
|
static QColor colorForType(const ResultType type);
|
||||||
|
|
||||||
bool isDirectParentOf(const TestResult *other, bool *needsIntermediate) const;
|
bool isDirectParentOf(const TestResult &other, bool *needsIntermediate) const;
|
||||||
bool isIntermediateFor(const TestResult *other) const;
|
bool isIntermediateFor(const TestResult &other) const;
|
||||||
TestResult *createIntermediateResult() const;
|
TestResult intermediateResult() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString m_id;
|
QString m_id;
|
||||||
@@ -117,8 +115,6 @@ private:
|
|||||||
ResultHooks m_hooks;
|
ResultHooks m_hooks;
|
||||||
};
|
};
|
||||||
|
|
||||||
using TestResultPtr = QSharedPointer<TestResult>;
|
|
||||||
|
|
||||||
} // namespace Autotest
|
} // namespace Autotest
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(Autotest::TestResult)
|
Q_DECLARE_METATYPE(Autotest::TestResult)
|
||||||
|
@@ -50,9 +50,9 @@ void TestResultDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op
|
|||||||
painter->fillRect(opt.rect, background);
|
painter->fillRect(opt.rect, background);
|
||||||
painter->setPen(foreground);
|
painter->setPen(foreground);
|
||||||
|
|
||||||
LayoutPositions positions(opt, resultFilterModel);
|
const LayoutPositions positions(opt, resultFilterModel);
|
||||||
const TestResult *testResult = resultFilterModel->testResult(index);
|
const TestResult testResult = resultFilterModel->testResult(index);
|
||||||
QTC_ASSERT(testResult, painter->restore();return);
|
QTC_ASSERT(testResult.isValid(), painter->restore(); return);
|
||||||
|
|
||||||
const QWidget *widget = dynamic_cast<const QWidget*>(painter->device());
|
const QWidget *widget = dynamic_cast<const QWidget*>(painter->device());
|
||||||
QWindow *window = widget ? widget->window()->windowHandle() : nullptr;
|
QWindow *window = widget ? widget->window()->windowHandle() : nullptr;
|
||||||
@@ -69,15 +69,15 @@ void TestResultDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op
|
|||||||
painter->drawText(positions.typeAreaLeft(), positions.top() + fm.ascent(), typeStr);
|
painter->drawText(positions.typeAreaLeft(), positions.top() + fm.ascent(), typeStr);
|
||||||
} else {
|
} else {
|
||||||
QPen tmp = painter->pen();
|
QPen tmp = painter->pen();
|
||||||
if (testResult->result() == ResultType::TestStart)
|
if (testResult.result() == ResultType::TestStart)
|
||||||
painter->setPen(opt.palette.mid().color());
|
painter->setPen(opt.palette.mid().color());
|
||||||
else
|
else
|
||||||
painter->setPen(TestResult::colorForType(testResult->result()));
|
painter->setPen(TestResult::colorForType(testResult.result()));
|
||||||
painter->drawText(positions.typeAreaLeft(), positions.top() + fm.ascent(), typeStr);
|
painter->drawText(positions.typeAreaLeft(), positions.top() + fm.ascent(), typeStr);
|
||||||
painter->setPen(tmp);
|
painter->setPen(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString output = testResult->outputString(selected);
|
QString output = testResult.outputString(selected);
|
||||||
|
|
||||||
if (selected) {
|
if (selected) {
|
||||||
limitTextOutput(output);
|
limitTextOutput(output);
|
||||||
@@ -92,12 +92,12 @@ void TestResultDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op
|
|||||||
fm.elidedText(output.left(2000), Qt::ElideRight, positions.textAreaWidth()));
|
fm.elidedText(output.left(2000), Qt::ElideRight, positions.textAreaWidth()));
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString file = testResult->fileName().fileName();
|
const QString file = testResult.fileName().fileName();
|
||||||
painter->setClipRect(positions.fileArea());
|
painter->setClipRect(positions.fileArea());
|
||||||
painter->drawText(positions.fileAreaLeft(), positions.top() + fm.ascent(), file);
|
painter->drawText(positions.fileAreaLeft(), positions.top() + fm.ascent(), file);
|
||||||
|
|
||||||
if (testResult->line()) {
|
if (testResult.line()) {
|
||||||
QString line = QString::number(testResult->line());
|
QString line = QString::number(testResult.line());
|
||||||
painter->setClipRect(positions.lineArea());
|
painter->setClipRect(positions.lineArea());
|
||||||
painter->drawText(positions.lineAreaLeft(), positions.top() + fm.ascent(), line);
|
painter->drawText(positions.lineAreaLeft(), positions.top() + fm.ascent(), line);
|
||||||
}
|
}
|
||||||
@@ -129,9 +129,9 @@ QSize TestResultDelegate::sizeHint(const QStyleOptionViewItem &option, const QMo
|
|||||||
s.setWidth(opt.rect.width() - indentation);
|
s.setWidth(opt.rect.width() - indentation);
|
||||||
|
|
||||||
if (selected) {
|
if (selected) {
|
||||||
const TestResult *testResult = resultFilterModel->testResult(index);
|
const TestResult testResult = resultFilterModel->testResult(index);
|
||||||
QTC_ASSERT(testResult, return QSize());
|
QTC_ASSERT(testResult.isValid(), return {});
|
||||||
QString output = testResult->outputString(selected);
|
QString output = testResult.outputString(selected);
|
||||||
limitTextOutput(output);
|
limitTextOutput(output);
|
||||||
output.replace('\n', QChar::LineSeparator);
|
output.replace('\n', QChar::LineSeparator);
|
||||||
recalculateTextLayout(index, output, opt.font, positions.textAreaWidth() - indentation);
|
recalculateTextLayout(index, output, opt.font, positions.textAreaWidth() - indentation);
|
||||||
|
@@ -16,12 +16,14 @@
|
|||||||
#include <QFontMetrics>
|
#include <QFontMetrics>
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
|
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
namespace Autotest {
|
namespace Autotest {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
/********************************* TestResultItem ******************************************/
|
/********************************* TestResultItem ******************************************/
|
||||||
|
|
||||||
TestResultItem::TestResultItem(const TestResultPtr &testResult)
|
TestResultItem::TestResultItem(const TestResult &testResult)
|
||||||
: m_testResult(testResult)
|
: m_testResult(testResult)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -71,9 +73,9 @@ QVariant TestResultItem::data(int column, int role) const
|
|||||||
{
|
{
|
||||||
switch (role) {
|
switch (role) {
|
||||||
case Qt::DecorationRole: {
|
case Qt::DecorationRole: {
|
||||||
if (!m_testResult)
|
if (!m_testResult.isValid())
|
||||||
return QVariant();
|
return {};
|
||||||
const ResultType result = m_testResult->result();
|
const ResultType result = m_testResult.result();
|
||||||
if (result == ResultType::MessageLocation && parent())
|
if (result == ResultType::MessageLocation && parent())
|
||||||
return parent()->data(column, role);
|
return parent()->data(column, role);
|
||||||
if (result == ResultType::TestStart)
|
if (result == ResultType::TestStart)
|
||||||
@@ -81,17 +83,16 @@ QVariant TestResultItem::data(int column, int role) const
|
|||||||
return testResultIcon(result);
|
return testResultIcon(result);
|
||||||
}
|
}
|
||||||
case Qt::DisplayRole:
|
case Qt::DisplayRole:
|
||||||
return m_testResult ? m_testResult->outputString(true) : QVariant();
|
return m_testResult.isValid() ? m_testResult.outputString(true) : QVariant();
|
||||||
default:
|
default:
|
||||||
return Utils::TreeItem::data(column, role);
|
return TreeItem::data(column, role);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestResultItem::updateDescription(const QString &description)
|
void TestResultItem::updateDescription(const QString &description)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(m_testResult, return);
|
QTC_ASSERT(m_testResult.isValid(), return);
|
||||||
|
m_testResult.setDescription(description);
|
||||||
m_testResult->setDescription(description);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isSignificant(ResultType type)
|
static bool isSignificant(ResultType type)
|
||||||
@@ -117,7 +118,7 @@ void TestResultItem::updateResult(bool &changed, ResultType addedChildType,
|
|||||||
const std::optional<SummaryEvaluation> &summary)
|
const std::optional<SummaryEvaluation> &summary)
|
||||||
{
|
{
|
||||||
changed = false;
|
changed = false;
|
||||||
if (m_testResult->result() != ResultType::TestStart)
|
if (m_testResult.result() != ResultType::TestStart)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!isSignificant(addedChildType) || (addedChildType == ResultType::TestStart && !summary))
|
if (!isSignificant(addedChildType) || (addedChildType == ResultType::TestStart && !summary))
|
||||||
@@ -165,13 +166,13 @@ void TestResultItem::updateResult(bool &changed, ResultType addedChildType,
|
|||||||
TestResultItem *TestResultItem::intermediateFor(const TestResultItem *item) const
|
TestResultItem *TestResultItem::intermediateFor(const TestResultItem *item) const
|
||||||
{
|
{
|
||||||
QTC_ASSERT(item, return nullptr);
|
QTC_ASSERT(item, return nullptr);
|
||||||
const TestResult *otherResult = item->testResult();
|
const TestResult otherResult = item->testResult();
|
||||||
for (int row = childCount() - 1; row >= 0; --row) {
|
for (int row = childCount() - 1; row >= 0; --row) {
|
||||||
TestResultItem *child = childAt(row);
|
TestResultItem *child = childAt(row);
|
||||||
const TestResult *testResult = child->testResult();
|
const TestResult testResult = child->testResult();
|
||||||
if (testResult->result() != ResultType::TestStart)
|
if (testResult.result() != ResultType::TestStart)
|
||||||
continue;
|
continue;
|
||||||
if (testResult->isIntermediateFor(otherResult))
|
if (testResult.isIntermediateFor(otherResult))
|
||||||
return child;
|
return child;
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -179,9 +180,9 @@ TestResultItem *TestResultItem::intermediateFor(const TestResultItem *item) cons
|
|||||||
|
|
||||||
TestResultItem *TestResultItem::createAndAddIntermediateFor(const TestResultItem *child)
|
TestResultItem *TestResultItem::createAndAddIntermediateFor(const TestResultItem *child)
|
||||||
{
|
{
|
||||||
TestResultPtr result(child->testResult()->createIntermediateResult());
|
TestResult result = child->testResult().intermediateResult();
|
||||||
QTC_ASSERT(!result.isNull(), return nullptr);
|
QTC_ASSERT(result.isValid(), return nullptr);
|
||||||
result->setResult(ResultType::TestStart);
|
result.setResult(ResultType::TestStart);
|
||||||
TestResultItem *intermediate = new TestResultItem(result);
|
TestResultItem *intermediate = new TestResultItem(result);
|
||||||
appendChild(intermediate);
|
appendChild(intermediate);
|
||||||
return intermediate;
|
return intermediate;
|
||||||
@@ -189,17 +190,17 @@ TestResultItem *TestResultItem::createAndAddIntermediateFor(const TestResultItem
|
|||||||
|
|
||||||
QString TestResultItem::resultString() const
|
QString TestResultItem::resultString() const
|
||||||
{
|
{
|
||||||
if (testResult()->result() != ResultType::TestStart)
|
if (testResult().result() != ResultType::TestStart)
|
||||||
return TestResult::resultToString(testResult()->result());
|
return TestResult::resultToString(testResult().result());
|
||||||
if (!m_summaryResult)
|
if (!m_summaryResult)
|
||||||
return QString();
|
return {};
|
||||||
return m_summaryResult->failed ? QString("FAIL") : QString("PASS");
|
return m_summaryResult->failed ? QString("FAIL") : QString("PASS");
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************* TestResultModel *****************************************/
|
/********************************* TestResultModel *****************************************/
|
||||||
|
|
||||||
TestResultModel::TestResultModel(QObject *parent)
|
TestResultModel::TestResultModel(QObject *parent)
|
||||||
: Utils::TreeModel<TestResultItem>(new TestResultItem(TestResultPtr()), parent)
|
: TreeModel<TestResultItem>(new TestResultItem({}), parent)
|
||||||
{
|
{
|
||||||
connect(TestRunner::instance(), &TestRunner::reportSummary,
|
connect(TestRunner::instance(), &TestRunner::reportSummary,
|
||||||
this, [this](const QString &id, const QHash<ResultType, int> &summary){
|
this, [this](const QString &id, const QHash<ResultType, int> &summary){
|
||||||
@@ -210,12 +211,12 @@ TestResultModel::TestResultModel(QObject *parent)
|
|||||||
void TestResultModel::updateParent(const TestResultItem *item)
|
void TestResultModel::updateParent(const TestResultItem *item)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(item, return);
|
QTC_ASSERT(item, return);
|
||||||
QTC_ASSERT(item->testResult(), return);
|
QTC_ASSERT(item->testResult().isValid(), return);
|
||||||
TestResultItem *parentItem = item->parent();
|
TestResultItem *parentItem = item->parent();
|
||||||
if (parentItem == rootItem()) // do not update invisible root item
|
if (parentItem == rootItem()) // do not update invisible root item
|
||||||
return;
|
return;
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
parentItem->updateResult(changed, item->testResult()->result(), item->summaryResult());
|
parentItem->updateResult(changed, item->testResult().result(), item->summaryResult());
|
||||||
if (!changed)
|
if (!changed)
|
||||||
return;
|
return;
|
||||||
emit dataChanged(parentItem->index(), parentItem->index());
|
emit dataChanged(parentItem->index(), parentItem->index());
|
||||||
@@ -232,16 +233,16 @@ static bool isFailed(ResultType type)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestResultModel::addTestResult(const TestResultPtr &testResult, bool autoExpand)
|
void TestResultModel::addTestResult(const TestResult &testResult, bool autoExpand)
|
||||||
{
|
{
|
||||||
const int lastRow = rootItem()->childCount() - 1;
|
const int lastRow = rootItem()->childCount() - 1;
|
||||||
if (testResult->result() == ResultType::MessageCurrentTest) {
|
if (testResult.result() == ResultType::MessageCurrentTest) {
|
||||||
// MessageCurrentTest should always be the last top level item
|
// MessageCurrentTest should always be the last top level item
|
||||||
if (lastRow >= 0) {
|
if (lastRow >= 0) {
|
||||||
TestResultItem *current = rootItem()->childAt(lastRow);
|
TestResultItem *current = rootItem()->childAt(lastRow);
|
||||||
const TestResult *result = current->testResult();
|
const TestResult result = current->testResult();
|
||||||
if (result && result->result() == ResultType::MessageCurrentTest) {
|
if (result.isValid() && result.result() == ResultType::MessageCurrentTest) {
|
||||||
current->updateDescription(testResult->description());
|
current->updateDescription(testResult.description());
|
||||||
emit dataChanged(current->index(), current->index());
|
emit dataChanged(current->index(), current->index());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -251,22 +252,22 @@ void TestResultModel::addTestResult(const TestResultPtr &testResult, bool autoEx
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_testResultCount[testResult->id()][testResult->result()]++;
|
m_testResultCount[testResult.id()][testResult.result()]++;
|
||||||
|
|
||||||
TestResultItem *newItem = new TestResultItem(testResult);
|
TestResultItem *newItem = new TestResultItem(testResult);
|
||||||
TestResultItem *root = nullptr;
|
TestResultItem *root = nullptr;
|
||||||
if (AutotestPlugin::settings()->displayApplication) {
|
if (AutotestPlugin::settings()->displayApplication) {
|
||||||
const QString application = testResult->id();
|
const QString application = testResult.id();
|
||||||
if (!application.isEmpty()) {
|
if (!application.isEmpty()) {
|
||||||
root = rootItem()->findFirstLevelChild([&application](TestResultItem *child) {
|
root = rootItem()->findFirstLevelChild([&application](TestResultItem *child) {
|
||||||
QTC_ASSERT(child, return false);
|
QTC_ASSERT(child, return false);
|
||||||
return child->testResult()->id() == application;
|
return child->testResult().id() == application;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!root) {
|
if (!root) {
|
||||||
TestResult *tmpAppResult = new TestResult(application, application);
|
TestResult tmpAppResult(application, application);
|
||||||
tmpAppResult->setResult(ResultType::Application);
|
tmpAppResult.setResult(ResultType::Application);
|
||||||
root = new TestResultItem(TestResultPtr(tmpAppResult));
|
root = new TestResultItem(tmpAppResult);
|
||||||
if (lastRow >= 0)
|
if (lastRow >= 0)
|
||||||
rootItem()->insertChild(lastRow, root);
|
rootItem()->insertChild(lastRow, root);
|
||||||
else
|
else
|
||||||
@@ -276,20 +277,20 @@ void TestResultModel::addTestResult(const TestResultPtr &testResult, bool autoEx
|
|||||||
}
|
}
|
||||||
|
|
||||||
TestResultItem *parentItem = findParentItemFor(newItem, root);
|
TestResultItem *parentItem = findParentItemFor(newItem, root);
|
||||||
addFileName(testResult->fileName().fileName()); // ensure we calculate the results pane correctly
|
addFileName(testResult.fileName().fileName()); // ensure we calculate the results pane correctly
|
||||||
if (parentItem) {
|
if (parentItem) {
|
||||||
parentItem->appendChild(newItem);
|
parentItem->appendChild(newItem);
|
||||||
if (autoExpand) {
|
if (autoExpand) {
|
||||||
parentItem->expand();
|
parentItem->expand();
|
||||||
newItem->expand();
|
newItem->expand();
|
||||||
newItem->forAllChildren([](Utils::TreeItem *it) { it->expand(); });
|
newItem->forAllChildren([](TreeItem *it) { it->expand(); });
|
||||||
}
|
}
|
||||||
updateParent(newItem);
|
updateParent(newItem);
|
||||||
} else {
|
} else {
|
||||||
if (lastRow >= 0) {
|
if (lastRow >= 0) {
|
||||||
TestResultItem *current = rootItem()->childAt(lastRow);
|
TestResultItem *current = rootItem()->childAt(lastRow);
|
||||||
const TestResult *result = current->testResult();
|
const TestResult result = current->testResult();
|
||||||
if (result && result->result() == ResultType::MessageCurrentTest) {
|
if (result.isValid() && result.result() == ResultType::MessageCurrentTest) {
|
||||||
rootItem()->insertChild(current->index().row(), newItem);
|
rootItem()->insertChild(current->index().row(), newItem);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -298,8 +299,8 @@ void TestResultModel::addTestResult(const TestResultPtr &testResult, bool autoEx
|
|||||||
rootItem()->appendChild(newItem);
|
rootItem()->appendChild(newItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isFailed(testResult->result())) {
|
if (isFailed(testResult.result())) {
|
||||||
if (const ITestTreeItem *it = testResult->findTestTreeItem()) {
|
if (const ITestTreeItem *it = testResult.findTestTreeItem()) {
|
||||||
TestTreeModel *model = TestTreeModel::instance();
|
TestTreeModel *model = TestTreeModel::instance();
|
||||||
model->setData(model->indexForItem(it), true, FailedRole);
|
model->setData(model->indexForItem(it), true, FailedRole);
|
||||||
}
|
}
|
||||||
@@ -309,7 +310,7 @@ void TestResultModel::addTestResult(const TestResultPtr &testResult, bool autoEx
|
|||||||
void TestResultModel::removeCurrentTestMessage()
|
void TestResultModel::removeCurrentTestMessage()
|
||||||
{
|
{
|
||||||
TestResultItem *currentMessageItem = rootItem()->findFirstLevelChild([](TestResultItem *it) {
|
TestResultItem *currentMessageItem = rootItem()->findFirstLevelChild([](TestResultItem *it) {
|
||||||
return (it->testResult()->result() == ResultType::MessageCurrentTest);
|
return (it->testResult().result() == ResultType::MessageCurrentTest);
|
||||||
});
|
});
|
||||||
if (currentMessageItem)
|
if (currentMessageItem)
|
||||||
destroyItem(currentMessageItem);
|
destroyItem(currentMessageItem);
|
||||||
@@ -326,12 +327,11 @@ void TestResultModel::clearTestResults()
|
|||||||
m_widthOfLineNumber = 0;
|
m_widthOfLineNumber = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const TestResult *TestResultModel::testResult(const QModelIndex &idx)
|
TestResult TestResultModel::testResult(const QModelIndex &idx)
|
||||||
{
|
{
|
||||||
if (idx.isValid())
|
if (idx.isValid())
|
||||||
return itemForIndex(idx)->testResult();
|
return itemForIndex(idx)->testResult();
|
||||||
|
return {};
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestResultModel::recalculateMaxWidthOfFileName(const QFont &font)
|
void TestResultModel::recalculateMaxWidthOfFileName(const QFont &font)
|
||||||
@@ -383,15 +383,15 @@ TestResultItem *TestResultModel::findParentItemFor(const TestResultItem *item,
|
|||||||
{
|
{
|
||||||
QTC_ASSERT(item, return nullptr);
|
QTC_ASSERT(item, return nullptr);
|
||||||
TestResultItem *root = startItem ? const_cast<TestResultItem *>(startItem) : nullptr;
|
TestResultItem *root = startItem ? const_cast<TestResultItem *>(startItem) : nullptr;
|
||||||
const TestResult *result = item->testResult();
|
const TestResult result = item->testResult();
|
||||||
const QString &name = result->name();
|
const QString &name = result.name();
|
||||||
const QString &id = result->id();
|
const QString &id = result.id();
|
||||||
|
|
||||||
if (root == nullptr && !name.isEmpty()) {
|
if (root == nullptr && !name.isEmpty()) {
|
||||||
for (int row = rootItem()->childCount() - 1; row >= 0; --row) {
|
for (int row = rootItem()->childCount() - 1; row >= 0; --row) {
|
||||||
TestResultItem *tmp = rootItem()->childAt(row);
|
TestResultItem *tmp = rootItem()->childAt(row);
|
||||||
auto tmpTestResult = tmp->testResult();
|
const TestResult tmpTestResult = tmp->testResult();
|
||||||
if (tmpTestResult->id() == id && tmpTestResult->name() == name) {
|
if (tmpTestResult.id() == id && tmpTestResult.name() == name) {
|
||||||
root = tmp;
|
root = tmp;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -401,9 +401,9 @@ TestResultItem *TestResultModel::findParentItemFor(const TestResultItem *item,
|
|||||||
return root;
|
return root;
|
||||||
|
|
||||||
bool needsIntermediate = false;
|
bool needsIntermediate = false;
|
||||||
auto predicate = [result, &needsIntermediate](Utils::TreeItem *it) {
|
auto predicate = [result, &needsIntermediate](TreeItem *it) {
|
||||||
TestResultItem *currentItem = static_cast<TestResultItem *>(it);
|
TestResultItem *currentItem = static_cast<TestResultItem *>(it);
|
||||||
return currentItem->testResult()->isDirectParentOf(result, &needsIntermediate);
|
return currentItem->testResult().isDirectParentOf(result, &needsIntermediate);
|
||||||
};
|
};
|
||||||
TestResultItem *parent = root->reverseFindAnyChild(predicate);
|
TestResultItem *parent = root->reverseFindAnyChild(predicate);
|
||||||
if (parent) {
|
if (parent) {
|
||||||
@@ -480,7 +480,7 @@ bool TestResultFilterModel::hasResults()
|
|||||||
return rowCount(QModelIndex());
|
return rowCount(QModelIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
const TestResult *TestResultFilterModel::testResult(const QModelIndex &index) const
|
TestResult TestResultFilterModel::testResult(const QModelIndex &index) const
|
||||||
{
|
{
|
||||||
return m_sourceModel->testResult(mapToSource(index));
|
return m_sourceModel->testResult(mapToSource(index));
|
||||||
}
|
}
|
||||||
@@ -495,7 +495,7 @@ bool TestResultFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &s
|
|||||||
QModelIndex index = m_sourceModel->index(sourceRow, 0, sourceParent);
|
QModelIndex index = m_sourceModel->index(sourceRow, 0, sourceParent);
|
||||||
if (!index.isValid())
|
if (!index.isValid())
|
||||||
return false;
|
return false;
|
||||||
ResultType resultType = m_sourceModel->testResult(index)->result();
|
const ResultType resultType = m_sourceModel->testResult(index).result();
|
||||||
if (resultType == ResultType::TestStart) {
|
if (resultType == ResultType::TestStart) {
|
||||||
TestResultItem *item = m_sourceModel->itemForIndex(index);
|
TestResultItem *item = m_sourceModel->itemForIndex(index);
|
||||||
QTC_ASSERT(item, return false);
|
QTC_ASSERT(item, return false);
|
||||||
@@ -511,7 +511,7 @@ bool TestResultFilterModel::acceptTestCaseResult(const QModelIndex &srcIndex) co
|
|||||||
for (int row = 0, count = m_sourceModel->rowCount(srcIndex); row < count; ++row) {
|
for (int row = 0, count = m_sourceModel->rowCount(srcIndex); row < count; ++row) {
|
||||||
const QModelIndex &child = m_sourceModel->index(row, 0, srcIndex);
|
const QModelIndex &child = m_sourceModel->index(row, 0, srcIndex);
|
||||||
TestResultItem *item = m_sourceModel->itemForIndex(child);
|
TestResultItem *item = m_sourceModel->itemForIndex(child);
|
||||||
ResultType type = item->testResult()->result();
|
const ResultType type = item->testResult().result();
|
||||||
|
|
||||||
if (type == ResultType::TestStart) {
|
if (type == ResultType::TestStart) {
|
||||||
if (!item->summaryResult())
|
if (!item->summaryResult())
|
||||||
|
@@ -20,9 +20,9 @@ namespace Internal {
|
|||||||
class TestResultItem : public Utils::TypedTreeItem<TestResultItem, TestResultItem>
|
class TestResultItem : public Utils::TypedTreeItem<TestResultItem, TestResultItem>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit TestResultItem(const TestResultPtr &testResult);
|
explicit TestResultItem(const TestResult &testResult);
|
||||||
QVariant data(int column, int role) const override;
|
QVariant data(int column, int role) const override;
|
||||||
const TestResult *testResult() const { return m_testResult.data(); }
|
TestResult testResult() const { return m_testResult; }
|
||||||
void updateDescription(const QString &description);
|
void updateDescription(const QString &description);
|
||||||
|
|
||||||
struct SummaryEvaluation
|
struct SummaryEvaluation
|
||||||
@@ -45,7 +45,7 @@ public:
|
|||||||
std::optional<SummaryEvaluation> summaryResult() const { return m_summaryResult; }
|
std::optional<SummaryEvaluation> summaryResult() const { return m_summaryResult; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TestResultPtr m_testResult;
|
TestResult m_testResult;
|
||||||
std::optional<SummaryEvaluation> m_summaryResult;
|
std::optional<SummaryEvaluation> m_summaryResult;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -54,11 +54,11 @@ class TestResultModel : public Utils::TreeModel<TestResultItem>
|
|||||||
public:
|
public:
|
||||||
explicit TestResultModel(QObject *parent = nullptr);
|
explicit TestResultModel(QObject *parent = nullptr);
|
||||||
|
|
||||||
void addTestResult(const TestResultPtr &testResult, bool autoExpand = false);
|
void addTestResult(const TestResult &testResult, bool autoExpand = false);
|
||||||
void removeCurrentTestMessage();
|
void removeCurrentTestMessage();
|
||||||
void clearTestResults();
|
void clearTestResults();
|
||||||
|
|
||||||
const TestResult *testResult(const QModelIndex &idx);
|
TestResult testResult(const QModelIndex &idx);
|
||||||
|
|
||||||
int maxWidthOfFileName(const QFont &font);
|
int maxWidthOfFileName(const QFont &font);
|
||||||
int maxWidthOfLineNumber(const QFont &font);
|
int maxWidthOfLineNumber(const QFont &font);
|
||||||
@@ -92,7 +92,7 @@ public:
|
|||||||
void toggleTestResultType(ResultType type);
|
void toggleTestResultType(ResultType type);
|
||||||
void clearTestResults();
|
void clearTestResults();
|
||||||
bool hasResults();
|
bool hasResults();
|
||||||
const TestResult *testResult(const QModelIndex &index) const;
|
TestResult testResult(const QModelIndex &index) const;
|
||||||
TestResultItem *itemForIndex(const QModelIndex &index) const;
|
TestResultItem *itemForIndex(const QModelIndex &index) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@@ -56,7 +56,7 @@ namespace Autotest {
|
|||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
ResultsTreeView::ResultsTreeView(QWidget *parent)
|
ResultsTreeView::ResultsTreeView(QWidget *parent)
|
||||||
: Utils::TreeView(parent)
|
: TreeView(parent)
|
||||||
{
|
{
|
||||||
setAttribute(Qt::WA_MacShowFocusRect, false);
|
setAttribute(Qt::WA_MacShowFocusRect, false);
|
||||||
setFrameStyle(NoFrame);
|
setFrameStyle(NoFrame);
|
||||||
@@ -84,10 +84,8 @@ TestResultsPane::TestResultsPane(QObject *parent) :
|
|||||||
visualOutputWidget->setLayout(outputLayout);
|
visualOutputWidget->setLayout(outputLayout);
|
||||||
|
|
||||||
QPalette pal;
|
QPalette pal;
|
||||||
pal.setColor(QPalette::Window,
|
pal.setColor(QPalette::Window, creatorTheme()->color(Theme::InfoBarBackground));
|
||||||
Utils::creatorTheme()->color(Utils::Theme::InfoBarBackground));
|
pal.setColor(QPalette::WindowText, creatorTheme()->color(Theme::InfoBarText));
|
||||||
pal.setColor(QPalette::WindowText,
|
|
||||||
Utils::creatorTheme()->color(Utils::Theme::InfoBarText));
|
|
||||||
m_summaryWidget = new QFrame;
|
m_summaryWidget = new QFrame;
|
||||||
m_summaryWidget->setPalette(pal);
|
m_summaryWidget->setPalette(pal);
|
||||||
m_summaryWidget->setAutoFillBackground(true);
|
m_summaryWidget->setAutoFillBackground(true);
|
||||||
@@ -130,10 +128,10 @@ TestResultsPane::TestResultsPane(QObject *parent) :
|
|||||||
|
|
||||||
createToolButtons();
|
createToolButtons();
|
||||||
|
|
||||||
connect(m_treeView, &Utils::TreeView::activated, this, &TestResultsPane::onItemActivated);
|
connect(m_treeView, &TreeView::activated, this, &TestResultsPane::onItemActivated);
|
||||||
connect(m_treeView->selectionModel(), &QItemSelectionModel::currentChanged,
|
connect(m_treeView->selectionModel(), &QItemSelectionModel::currentChanged,
|
||||||
trd, &TestResultDelegate::currentChanged);
|
trd, &TestResultDelegate::currentChanged);
|
||||||
connect(m_treeView, &Utils::TreeView::customContextMenuRequested,
|
connect(m_treeView, &TreeView::customContextMenuRequested,
|
||||||
this, &TestResultsPane::onCustomContextMenuRequested);
|
this, &TestResultsPane::onCustomContextMenuRequested);
|
||||||
connect(m_treeView, &ResultsTreeView::copyShortcutTriggered, this, [this] {
|
connect(m_treeView, &ResultsTreeView::copyShortcutTriggered, this, [this] {
|
||||||
onCopyItemTriggered(getTestResult(m_treeView->currentIndex()));
|
onCopyItemTriggered(getTestResult(m_treeView->currentIndex()));
|
||||||
@@ -167,25 +165,21 @@ void TestResultsPane::createToolButtons()
|
|||||||
});
|
});
|
||||||
|
|
||||||
m_runAll = new QToolButton(m_treeView);
|
m_runAll = new QToolButton(m_treeView);
|
||||||
m_runAll->setDefaultAction(
|
m_runAll->setDefaultAction(ProxyAction::proxyActionWithIcon(
|
||||||
Utils::ProxyAction::proxyActionWithIcon(
|
|
||||||
ActionManager::command(Constants::ACTION_RUN_ALL_ID)->action(),
|
ActionManager::command(Constants::ACTION_RUN_ALL_ID)->action(),
|
||||||
Utils::Icons::RUN_SMALL_TOOLBAR.icon()));
|
Utils::Icons::RUN_SMALL_TOOLBAR.icon()));
|
||||||
|
|
||||||
m_runSelected = new QToolButton(m_treeView);
|
m_runSelected = new QToolButton(m_treeView);
|
||||||
m_runSelected->setDefaultAction(
|
m_runSelected->setDefaultAction(ProxyAction::proxyActionWithIcon(
|
||||||
Utils::ProxyAction::proxyActionWithIcon(
|
|
||||||
ActionManager::command(Constants::ACTION_RUN_SELECTED_ID)->action(),
|
ActionManager::command(Constants::ACTION_RUN_SELECTED_ID)->action(),
|
||||||
Utils::Icons::RUN_SELECTED_TOOLBAR.icon()));
|
Utils::Icons::RUN_SELECTED_TOOLBAR.icon()));
|
||||||
|
|
||||||
m_runFailed = new QToolButton(m_treeView);
|
m_runFailed = new QToolButton(m_treeView);
|
||||||
m_runFailed->setDefaultAction(
|
m_runFailed->setDefaultAction(ProxyAction::proxyActionWithIcon(
|
||||||
Utils::ProxyAction::proxyActionWithIcon(
|
|
||||||
ActionManager::command(Constants::ACTION_RUN_FAILED_ID)->action(),
|
ActionManager::command(Constants::ACTION_RUN_FAILED_ID)->action(),
|
||||||
Icons::RUN_FAILED_TOOLBAR.icon()));
|
Icons::RUN_FAILED_TOOLBAR.icon()));
|
||||||
m_runFile = new QToolButton(m_treeView);
|
m_runFile = new QToolButton(m_treeView);
|
||||||
m_runFile->setDefaultAction(
|
m_runFile->setDefaultAction(ProxyAction::proxyActionWithIcon(
|
||||||
Utils::ProxyAction::proxyActionWithIcon(
|
|
||||||
ActionManager::command(Constants::ACTION_RUN_FILE_ID)->action(),
|
ActionManager::command(Constants::ACTION_RUN_FILE_ID)->action(),
|
||||||
Utils::Icons::RUN_FILE_TOOLBAR.icon()));
|
Utils::Icons::RUN_FILE_TOOLBAR.icon()));
|
||||||
|
|
||||||
@@ -228,7 +222,7 @@ TestResultsPane::~TestResultsPane()
|
|||||||
s_instance = nullptr;
|
s_instance = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestResultsPane::addTestResult(const TestResultPtr &result)
|
void TestResultsPane::addTestResult(const TestResult &result)
|
||||||
{
|
{
|
||||||
const QScrollBar *scrollBar = m_treeView->verticalScrollBar();
|
const QScrollBar *scrollBar = m_treeView->verticalScrollBar();
|
||||||
m_atEnd = scrollBar ? scrollBar->value() == scrollBar->maximum() : true;
|
m_atEnd = scrollBar ? scrollBar->value() == scrollBar->maximum() : true;
|
||||||
@@ -248,22 +242,22 @@ static void checkAndFineTuneColors(QTextCharFormat *format)
|
|||||||
const QColor bgColor = format->background().color();
|
const QColor bgColor = format->background().color();
|
||||||
QColor fgColor = format->foreground().color();
|
QColor fgColor = format->foreground().color();
|
||||||
|
|
||||||
if (Utils::StyleHelper::isReadableOn(bgColor, fgColor))
|
if (StyleHelper::isReadableOn(bgColor, fgColor))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int h, s, v;
|
int h, s, v;
|
||||||
fgColor.getHsv(&h, &s, &v);
|
fgColor.getHsv(&h, &s, &v);
|
||||||
// adjust the color value to ensure better readability
|
// adjust the color value to ensure better readability
|
||||||
if (Utils::StyleHelper::luminance(bgColor) < .5)
|
if (StyleHelper::luminance(bgColor) < .5)
|
||||||
v = v + 64;
|
v = v + 64;
|
||||||
else
|
else
|
||||||
v = v - 64;
|
v = v - 64;
|
||||||
|
|
||||||
fgColor.setHsv(h, s, v);
|
fgColor.setHsv(h, s, v);
|
||||||
if (!Utils::StyleHelper::isReadableOn(bgColor, fgColor)) {
|
if (!StyleHelper::isReadableOn(bgColor, fgColor)) {
|
||||||
s = (s + 128) % 255; // adjust the saturation to ensure better readability
|
s = (s + 128) % 255; // adjust the saturation to ensure better readability
|
||||||
fgColor.setHsv(h, s, v);
|
fgColor.setHsv(h, s, v);
|
||||||
if (!Utils::StyleHelper::isReadableOn(bgColor, fgColor))
|
if (!StyleHelper::isReadableOn(bgColor, fgColor))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -278,9 +272,9 @@ void TestResultsPane::addOutputLine(const QByteArray &outputLine, OutputChannel
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Utils::FormattedText formattedText
|
const FormattedText formattedText
|
||||||
= Utils::FormattedText{QString::fromUtf8(outputLine), m_defaultFormat};
|
= FormattedText{QString::fromUtf8(outputLine), m_defaultFormat};
|
||||||
const QList<Utils::FormattedText> formatted = channel == OutputChannel::StdOut
|
const QList<FormattedText> formatted = channel == OutputChannel::StdOut
|
||||||
? m_stdOutHandler.parseText(formattedText)
|
? m_stdOutHandler.parseText(formattedText)
|
||||||
: m_stdErrHandler.parseText(formattedText);
|
: m_stdErrHandler.parseText(formattedText);
|
||||||
|
|
||||||
@@ -332,9 +326,9 @@ void TestResultsPane::clearContents()
|
|||||||
connect(m_treeView->verticalScrollBar(), &QScrollBar::rangeChanged,
|
connect(m_treeView->verticalScrollBar(), &QScrollBar::rangeChanged,
|
||||||
this, &TestResultsPane::onScrollBarRangeChanged, Qt::UniqueConnection);
|
this, &TestResultsPane::onScrollBarRangeChanged, Qt::UniqueConnection);
|
||||||
m_textOutput->clear();
|
m_textOutput->clear();
|
||||||
m_defaultFormat.setBackground(Utils::creatorTheme()->palette().color(
|
m_defaultFormat.setBackground(creatorTheme()->palette().color(
|
||||||
m_textOutput->backgroundRole()));
|
m_textOutput->backgroundRole()));
|
||||||
m_defaultFormat.setForeground(Utils::creatorTheme()->palette().color(
|
m_defaultFormat.setForeground(creatorTheme()->palette().color(
|
||||||
m_textOutput->foregroundRole()));
|
m_textOutput->foregroundRole()));
|
||||||
|
|
||||||
// in case they had been forgotten to reset
|
// in case they had been forgotten to reset
|
||||||
@@ -402,7 +396,7 @@ void TestResultsPane::goToNext()
|
|||||||
|
|
||||||
// if we have no current or could not find a next one, use the first item of the whole tree
|
// if we have no current or could not find a next one, use the first item of the whole tree
|
||||||
if (!nextCurrentIndex.isValid()) {
|
if (!nextCurrentIndex.isValid()) {
|
||||||
Utils::TreeItem *rootItem = m_model->itemForIndex(QModelIndex());
|
TreeItem *rootItem = m_model->itemForIndex(QModelIndex());
|
||||||
// if the tree does not contain any item - don't do anything
|
// if the tree does not contain any item - don't do anything
|
||||||
if (!rootItem || !rootItem->childCount())
|
if (!rootItem || !rootItem->childCount())
|
||||||
return;
|
return;
|
||||||
@@ -457,9 +451,9 @@ void TestResultsPane::onItemActivated(const QModelIndex &index)
|
|||||||
if (!index.isValid())
|
if (!index.isValid())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const TestResult *testResult = m_filterModel->testResult(index);
|
const TestResult testResult = m_filterModel->testResult(index);
|
||||||
if (testResult && !testResult->fileName().isEmpty())
|
if (testResult.isValid() && !testResult.fileName().isEmpty())
|
||||||
EditorManager::openEditorAt(Utils::Link{testResult->fileName(), testResult->line(), 0});
|
EditorManager::openEditorAt(Link{testResult.fileName(), testResult.line(), 0});
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestResultsPane::onRunAllTriggered()
|
void TestResultsPane::onRunAllTriggered()
|
||||||
@@ -609,12 +603,12 @@ void TestResultsPane::onCustomContextMenuRequested(const QPoint &pos)
|
|||||||
{
|
{
|
||||||
const bool resultsAvailable = m_filterModel->hasResults();
|
const bool resultsAvailable = m_filterModel->hasResults();
|
||||||
const bool enabled = !m_testRunning && resultsAvailable;
|
const bool enabled = !m_testRunning && resultsAvailable;
|
||||||
const TestResult *clicked = getTestResult(m_treeView->indexAt(pos));
|
const TestResult clicked = getTestResult(m_treeView->indexAt(pos));
|
||||||
QMenu menu;
|
QMenu menu;
|
||||||
|
|
||||||
QAction *action = new QAction(Tr::tr("Copy"), &menu);
|
QAction *action = new QAction(Tr::tr("Copy"), &menu);
|
||||||
action->setShortcut(QKeySequence(QKeySequence::Copy));
|
action->setShortcut(QKeySequence(QKeySequence::Copy));
|
||||||
action->setEnabled(resultsAvailable && clicked);
|
action->setEnabled(resultsAvailable && clicked.isValid());
|
||||||
connect(action, &QAction::triggered, this, [this, clicked] {
|
connect(action, &QAction::triggered, this, [this, clicked] {
|
||||||
onCopyItemTriggered(clicked);
|
onCopyItemTriggered(clicked);
|
||||||
});
|
});
|
||||||
@@ -630,7 +624,7 @@ void TestResultsPane::onCustomContextMenuRequested(const QPoint &pos)
|
|||||||
connect(action, &QAction::triggered, this, &TestResultsPane::onSaveWholeTriggered);
|
connect(action, &QAction::triggered, this, &TestResultsPane::onSaveWholeTriggered);
|
||||||
menu.addAction(action);
|
menu.addAction(action);
|
||||||
|
|
||||||
const auto correlatingItem = (enabled && clicked) ? clicked->findTestTreeItem() : nullptr;
|
const auto correlatingItem = (enabled && clicked.isValid()) ? clicked.findTestTreeItem() : nullptr;
|
||||||
action = new QAction(Tr::tr("Run This Test"), &menu);
|
action = new QAction(Tr::tr("Run This Test"), &menu);
|
||||||
action->setEnabled(correlatingItem && correlatingItem->canProvideTestConfiguration());
|
action->setEnabled(correlatingItem && correlatingItem->canProvideTestConfiguration());
|
||||||
connect(action, &QAction::triggered, this, [this, clicked] {
|
connect(action, &QAction::triggered, this, [this, clicked] {
|
||||||
@@ -669,21 +663,19 @@ void TestResultsPane::onCustomContextMenuRequested(const QPoint &pos)
|
|||||||
menu.exec(m_treeView->mapToGlobal(pos));
|
menu.exec(m_treeView->mapToGlobal(pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
const TestResult *TestResultsPane::getTestResult(const QModelIndex &idx)
|
TestResult TestResultsPane::getTestResult(const QModelIndex &idx)
|
||||||
{
|
{
|
||||||
if (!idx.isValid())
|
if (!idx.isValid())
|
||||||
return nullptr;
|
return {};
|
||||||
|
const TestResult result = m_filterModel->testResult(idx);
|
||||||
const TestResult *result = m_filterModel->testResult(idx);
|
QTC_CHECK(result.isValid());
|
||||||
QTC_CHECK(result);
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestResultsPane::onCopyItemTriggered(const TestResult *result)
|
void TestResultsPane::onCopyItemTriggered(const TestResult &result)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(result, return);
|
QTC_ASSERT(result.isValid(), return);
|
||||||
setClipboardAndSelection(result->outputString(true));
|
setClipboardAndSelection(result.outputString(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestResultsPane::onCopyWholeTriggered()
|
void TestResultsPane::onCopyWholeTriggered()
|
||||||
@@ -705,12 +697,11 @@ void TestResultsPane::onSaveWholeTriggered()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestResultsPane::onRunThisTestTriggered(TestRunMode runMode, const TestResult *result)
|
void TestResultsPane::onRunThisTestTriggered(TestRunMode runMode, const TestResult &result)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(result, return);
|
QTC_ASSERT(result.isValid(), return);
|
||||||
|
|
||||||
const ITestTreeItem *item = result->findTestTreeItem();
|
|
||||||
|
|
||||||
|
const ITestTreeItem *item = result.findTestTreeItem();
|
||||||
if (item)
|
if (item)
|
||||||
TestRunner::instance()->runTest(runMode, item);
|
TestRunner::instance()->runTest(runMode, item);
|
||||||
}
|
}
|
||||||
@@ -729,11 +720,11 @@ QString TestResultsPane::getWholeOutput(const QModelIndex &parent)
|
|||||||
QString output;
|
QString output;
|
||||||
for (int row = 0, count = m_model->rowCount(parent); row < count; ++row) {
|
for (int row = 0, count = m_model->rowCount(parent); row < count; ++row) {
|
||||||
QModelIndex current = m_model->index(row, 0, parent);
|
QModelIndex current = m_model->index(row, 0, parent);
|
||||||
const TestResult *result = m_model->testResult(current);
|
const TestResult result = m_model->testResult(current);
|
||||||
QTC_ASSERT(result, continue);
|
QTC_ASSERT(result.isValid(), continue);
|
||||||
if (auto item = m_model->itemForIndex(current))
|
if (auto item = m_model->itemForIndex(current))
|
||||||
output.append(item->resultString()).append('\t');
|
output.append(item->resultString()).append('\t');
|
||||||
output.append(result->outputString(true)).append('\n');
|
output.append(result.outputString(true)).append('\n');
|
||||||
output.append(getWholeOutput(current));
|
output.append(getWholeOutput(current));
|
||||||
}
|
}
|
||||||
return output;
|
return output;
|
||||||
@@ -741,25 +732,25 @@ QString TestResultsPane::getWholeOutput(const QModelIndex &parent)
|
|||||||
|
|
||||||
void TestResultsPane::createMarks(const QModelIndex &parent)
|
void TestResultsPane::createMarks(const QModelIndex &parent)
|
||||||
{
|
{
|
||||||
const TestResult *parentResult = m_model->testResult(parent);
|
const TestResult parentResult = m_model->testResult(parent);
|
||||||
ResultType parentType = parentResult ? parentResult->result() : ResultType::Invalid;
|
const ResultType parentType = parentResult.isValid() ? parentResult.result() : ResultType::Invalid;
|
||||||
const QVector<ResultType> interested{ResultType::Fail, ResultType::UnexpectedPass};
|
const QVector<ResultType> interested{ResultType::Fail, ResultType::UnexpectedPass};
|
||||||
for (int row = 0, count = m_model->rowCount(parent); row < count; ++row) {
|
for (int row = 0, count = m_model->rowCount(parent); row < count; ++row) {
|
||||||
const QModelIndex index = m_model->index(row, 0, parent);
|
const QModelIndex index = m_model->index(row, 0, parent);
|
||||||
const TestResult *result = m_model->testResult(index);
|
const TestResult result = m_model->testResult(index);
|
||||||
QTC_ASSERT(result, continue);
|
QTC_ASSERT(result.isValid(), continue);
|
||||||
|
|
||||||
if (m_model->hasChildren(index))
|
if (m_model->hasChildren(index))
|
||||||
createMarks(index);
|
createMarks(index);
|
||||||
|
|
||||||
bool isLocationItem = result->result() == ResultType::MessageLocation;
|
bool isLocationItem = result.result() == ResultType::MessageLocation;
|
||||||
if (interested.contains(result->result())
|
if (interested.contains(result.result())
|
||||||
|| (isLocationItem && interested.contains(parentType))) {
|
|| (isLocationItem && interested.contains(parentType))) {
|
||||||
TestEditorMark *mark = new TestEditorMark(index, result->fileName(), result->line());
|
TestEditorMark *mark = new TestEditorMark(index, result.fileName(), result.line());
|
||||||
mark->setIcon(index.data(Qt::DecorationRole).value<QIcon>());
|
mark->setIcon(index.data(Qt::DecorationRole).value<QIcon>());
|
||||||
mark->setColor(Utils::Theme::OutputPanes_TestFailTextColor);
|
mark->setColor(Theme::OutputPanes_TestFailTextColor);
|
||||||
mark->setPriority(TextEditor::TextMark::NormalPriority);
|
mark->setPriority(TextEditor::TextMark::NormalPriority);
|
||||||
mark->setToolTip(result->description());
|
mark->setToolTip(result.description());
|
||||||
m_marks << mark;
|
m_marks << mark;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -72,7 +72,7 @@ public:
|
|||||||
void goToNext() override;
|
void goToNext() override;
|
||||||
void goToPrev() override;
|
void goToPrev() override;
|
||||||
|
|
||||||
void addTestResult(const TestResultPtr &result);
|
void addTestResult(const TestResult &result);
|
||||||
void addOutputLine(const QByteArray &outputLine, OutputChannel channel);
|
void addOutputLine(const QByteArray &outputLine, OutputChannel channel);
|
||||||
void showTestResult(const QModelIndex &index);
|
void showTestResult(const QModelIndex &index);
|
||||||
private:
|
private:
|
||||||
@@ -92,11 +92,11 @@ private:
|
|||||||
void onTestRunFinished();
|
void onTestRunFinished();
|
||||||
void onScrollBarRangeChanged(int, int max);
|
void onScrollBarRangeChanged(int, int max);
|
||||||
void onCustomContextMenuRequested(const QPoint &pos);
|
void onCustomContextMenuRequested(const QPoint &pos);
|
||||||
const TestResult *getTestResult(const QModelIndex &idx);
|
TestResult getTestResult(const QModelIndex &idx);
|
||||||
void onCopyItemTriggered(const TestResult *result);
|
void onCopyItemTriggered(const TestResult &result);
|
||||||
void onCopyWholeTriggered();
|
void onCopyWholeTriggered();
|
||||||
void onSaveWholeTriggered();
|
void onSaveWholeTriggered();
|
||||||
void onRunThisTestTriggered(TestRunMode runMode, const TestResult *result);
|
void onRunThisTestTriggered(TestRunMode runMode, const TestResult &result);
|
||||||
void toggleOutputStyle();
|
void toggleOutputStyle();
|
||||||
QString getWholeOutput(const QModelIndex &parent = QModelIndex());
|
QString getWholeOutput(const QModelIndex &parent = QModelIndex());
|
||||||
|
|
||||||
|
@@ -72,13 +72,11 @@ TestRunner::TestRunner()
|
|||||||
|
|
||||||
m_cancelTimer.setSingleShot(true);
|
m_cancelTimer.setSingleShot(true);
|
||||||
connect(&m_cancelTimer, &QTimer::timeout, this, [this] { cancelCurrent(Timeout); });
|
connect(&m_cancelTimer, &QTimer::timeout, this, [this] { cancelCurrent(Timeout); });
|
||||||
connect(&m_futureWatcher, &QFutureWatcher<TestResultPtr>::resultReadyAt,
|
connect(&m_futureWatcher, &QFutureWatcher<TestResult>::finished,
|
||||||
this, [this](int index) { emit testResultReady(m_futureWatcher.resultAt(index)); });
|
|
||||||
connect(&m_futureWatcher, &QFutureWatcher<TestResultPtr>::finished,
|
|
||||||
this, &TestRunner::onFinished);
|
this, &TestRunner::onFinished);
|
||||||
connect(this, &TestRunner::requestStopTestRun,
|
connect(this, &TestRunner::requestStopTestRun,
|
||||||
&m_futureWatcher, &QFutureWatcher<TestResultPtr>::cancel);
|
&m_futureWatcher, &QFutureWatcher<TestResult>::cancel);
|
||||||
connect(&m_futureWatcher, &QFutureWatcher<TestResultPtr>::canceled, this, [this] {
|
connect(&m_futureWatcher, &QFutureWatcher<TestResult>::canceled, this, [this] {
|
||||||
cancelCurrent(UserCanceled);
|
cancelCurrent(UserCanceled);
|
||||||
reportResult(ResultType::MessageFatal, Tr::tr("Test run canceled by user."));
|
reportResult(ResultType::MessageFatal, Tr::tr("Test run canceled by user."));
|
||||||
});
|
});
|
||||||
@@ -148,15 +146,10 @@ static QString constructOmittedVariablesDetailsString(const EnvironmentItems &di
|
|||||||
|
|
||||||
bool TestRunner::currentConfigValid()
|
bool TestRunner::currentConfigValid()
|
||||||
{
|
{
|
||||||
FilePath commandFilePath;
|
const FilePath commandFilePath = m_currentConfig->testExecutable();
|
||||||
if (m_currentConfig->testBase()->type() == ITestBase::Framework) {
|
if (!commandFilePath.isEmpty())
|
||||||
TestConfiguration *current = static_cast<TestConfiguration *>(m_currentConfig);
|
return true;
|
||||||
commandFilePath = current->executableFilePath();
|
|
||||||
} else {
|
|
||||||
TestToolConfiguration *current = static_cast<TestToolConfiguration *>(m_currentConfig);
|
|
||||||
commandFilePath = current->commandLine().executable();
|
|
||||||
}
|
|
||||||
if (commandFilePath.isEmpty()) {
|
|
||||||
reportResult(ResultType::MessageFatal,
|
reportResult(ResultType::MessageFatal,
|
||||||
Tr::tr("Executable path is empty. (%1)").arg(m_currentConfig->displayName()));
|
Tr::tr("Executable path is empty. (%1)").arg(m_currentConfig->displayName()));
|
||||||
delete m_currentConfig;
|
delete m_currentConfig;
|
||||||
@@ -169,21 +162,6 @@ bool TestRunner::currentConfigValid()
|
|||||||
onProcessDone();
|
onProcessDone();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TestRunner::setUpProcess()
|
|
||||||
{
|
|
||||||
QTC_ASSERT(m_currentConfig, return);
|
|
||||||
m_currentProcess = new QtcProcess;
|
|
||||||
if (m_currentConfig->testBase()->type() == ITestBase::Framework) {
|
|
||||||
TestConfiguration *current = static_cast<TestConfiguration *>(m_currentConfig);
|
|
||||||
m_currentProcess->setCommand({current->executableFilePath(), {}});
|
|
||||||
} else {
|
|
||||||
TestToolConfiguration *current = static_cast<TestToolConfiguration *>(m_currentConfig);
|
|
||||||
m_currentProcess->setCommand({current->commandLine().executable(), {}});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestRunner::setUpProcessEnv()
|
void TestRunner::setUpProcessEnv()
|
||||||
@@ -234,12 +212,13 @@ void TestRunner::scheduleNext()
|
|||||||
if (!m_currentConfig->project())
|
if (!m_currentConfig->project())
|
||||||
onProcessDone();
|
onProcessDone();
|
||||||
|
|
||||||
setUpProcess();
|
m_currentProcess = new QtcProcess;
|
||||||
QTC_ASSERT(m_currentProcess, onProcessDone(); return);
|
m_currentProcess->setCommand({m_currentConfig->testExecutable(), {}});
|
||||||
|
|
||||||
QTC_ASSERT(!m_currentOutputReader, delete m_currentOutputReader);
|
QTC_ASSERT(!m_currentOutputReader, delete m_currentOutputReader);
|
||||||
m_currentOutputReader = m_currentConfig->createOutputReader(*m_fakeFutureInterface, m_currentProcess);
|
m_currentOutputReader = m_currentConfig->createOutputReader(*m_fakeFutureInterface, m_currentProcess);
|
||||||
QTC_ASSERT(m_currentOutputReader, onProcessDone(); return);
|
QTC_ASSERT(m_currentOutputReader, onProcessDone(); return);
|
||||||
|
connect(m_currentOutputReader, &TestOutputReader::newResult, this, &TestRunner::testResultReady);
|
||||||
connect(m_currentOutputReader, &TestOutputReader::newOutputLineAvailable,
|
connect(m_currentOutputReader, &TestOutputReader::newOutputLineAvailable,
|
||||||
TestResultsPane::instance(), &TestResultsPane::addOutputLine);
|
TestResultsPane::instance(), &TestResultsPane::addOutputLine);
|
||||||
|
|
||||||
@@ -537,8 +516,8 @@ void TestRunner::runTestsHelper()
|
|||||||
int testCaseCount = precheckTestConfigurations();
|
int testCaseCount = precheckTestConfigurations();
|
||||||
|
|
||||||
// Fake future interface - destruction will be handled by QFuture/QFutureWatcher
|
// Fake future interface - destruction will be handled by QFuture/QFutureWatcher
|
||||||
m_fakeFutureInterface = new QFutureInterface<TestResultPtr>(QFutureInterfaceBase::Running);
|
m_fakeFutureInterface = new QFutureInterface<TestResult>(QFutureInterfaceBase::Running);
|
||||||
QFuture<TestResultPtr> future = m_fakeFutureInterface->future();
|
QFuture<TestResult> future = m_fakeFutureInterface->future();
|
||||||
m_fakeFutureInterface->setProgressRange(0, testCaseCount);
|
m_fakeFutureInterface->setProgressRange(0, testCaseCount);
|
||||||
m_fakeFutureInterface->setProgressValue(0);
|
m_fakeFutureInterface->setProgressValue(0);
|
||||||
m_futureWatcher.setFuture(future);
|
m_futureWatcher.setFuture(future);
|
||||||
@@ -648,12 +627,13 @@ void TestRunner::debugTests()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// We need a fake QFuture for the results. TODO: replace with QtConcurrent::run
|
// We need a fake QFuture for the results. TODO: replace with QtConcurrent::run
|
||||||
QFutureInterface<TestResultPtr> *futureInterface
|
QFutureInterface<TestResult> *futureInterface
|
||||||
= new QFutureInterface<TestResultPtr>(QFutureInterfaceBase::Running);
|
= new QFutureInterface<TestResult>(QFutureInterfaceBase::Running);
|
||||||
m_futureWatcher.setFuture(futureInterface->future());
|
m_futureWatcher.setFuture(futureInterface->future());
|
||||||
|
|
||||||
if (useOutputProcessor) {
|
if (useOutputProcessor) {
|
||||||
TestOutputReader *outputreader = config->createOutputReader(*futureInterface, nullptr);
|
TestOutputReader *outputreader = config->createOutputReader(*futureInterface, nullptr);
|
||||||
|
connect(outputreader, &TestOutputReader::newResult, this, &TestRunner::testResultReady);
|
||||||
outputreader->setId(inferior.command.executable().toString());
|
outputreader->setId(inferior.command.executable().toString());
|
||||||
connect(outputreader, &TestOutputReader::newOutputLineAvailable,
|
connect(outputreader, &TestOutputReader::newOutputLineAvailable,
|
||||||
TestResultsPane::instance(), &TestResultsPane::addOutputLine);
|
TestResultsPane::instance(), &TestResultsPane::addOutputLine);
|
||||||
@@ -804,9 +784,9 @@ void TestRunner::onFinished()
|
|||||||
|
|
||||||
void TestRunner::reportResult(ResultType type, const QString &description)
|
void TestRunner::reportResult(ResultType type, const QString &description)
|
||||||
{
|
{
|
||||||
TestResultPtr result(new TestResult);
|
TestResult result("internal", {});
|
||||||
result->setResult(type);
|
result.setResult(type);
|
||||||
result->setDescription(description);
|
result.setDescription(description);
|
||||||
emit testResultReady(result);
|
emit testResultReady(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -50,7 +50,7 @@ signals:
|
|||||||
void testRunStarted();
|
void testRunStarted();
|
||||||
void testRunFinished();
|
void testRunFinished();
|
||||||
void requestStopTestRun();
|
void requestStopTestRun();
|
||||||
void testResultReady(const TestResultPtr &result);
|
void testResultReady(const TestResult &result);
|
||||||
void hadDisabledTests(int disabled);
|
void hadDisabledTests(int disabled);
|
||||||
void reportSummary(const QString &id, const QHash<ResultType, int> &summary);
|
void reportSummary(const QString &id, const QHash<ResultType, int> &summary);
|
||||||
|
|
||||||
@@ -62,7 +62,6 @@ private:
|
|||||||
|
|
||||||
int precheckTestConfigurations();
|
int precheckTestConfigurations();
|
||||||
bool currentConfigValid();
|
bool currentConfigValid();
|
||||||
void setUpProcess();
|
|
||||||
void setUpProcessEnv();
|
void setUpProcessEnv();
|
||||||
void scheduleNext();
|
void scheduleNext();
|
||||||
void cancelCurrent(CancelReason reason);
|
void cancelCurrent(CancelReason reason);
|
||||||
@@ -76,8 +75,8 @@ private:
|
|||||||
bool postponeTestRunWithEmptyExecutable(ProjectExplorer::Project *project);
|
bool postponeTestRunWithEmptyExecutable(ProjectExplorer::Project *project);
|
||||||
void onBuildSystemUpdated();
|
void onBuildSystemUpdated();
|
||||||
|
|
||||||
QFutureWatcher<TestResultPtr> m_futureWatcher;
|
QFutureWatcher<TestResult> m_futureWatcher;
|
||||||
QFutureInterface<TestResultPtr> *m_fakeFutureInterface = nullptr;
|
QFutureInterface<TestResult> *m_fakeFutureInterface = nullptr;
|
||||||
QList<ITestConfiguration *> m_selectedTests;
|
QList<ITestConfiguration *> m_selectedTests;
|
||||||
bool m_executingTests = false;
|
bool m_executingTests = false;
|
||||||
bool m_canceled = false;
|
bool m_canceled = false;
|
||||||
|
@@ -29,6 +29,8 @@
|
|||||||
#include <QTreeWidget>
|
#include <QTreeWidget>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
namespace Autotest {
|
namespace Autotest {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
@@ -41,8 +43,8 @@ public:
|
|||||||
TestSettings settings() const;
|
TestSettings settings() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void populateFrameworksListWidget(const QHash<Utils::Id, bool> &frameworks,
|
void populateFrameworksListWidget(const QHash<Id, bool> &frameworks,
|
||||||
const QHash<Utils::Id, bool> &testTools);
|
const QHash<Id, bool> &testTools);
|
||||||
void testSettings(TestSettings &settings) const;
|
void testSettings(TestSettings &settings) const;
|
||||||
void testToolsSettings(TestSettings &settings) const;
|
void testToolsSettings(TestSettings &settings) const;
|
||||||
void onFrameworkItemChanged();
|
void onFrameworkItemChanged();
|
||||||
@@ -61,7 +63,7 @@ private:
|
|||||||
QComboBox *m_runAfterBuildCB;
|
QComboBox *m_runAfterBuildCB;
|
||||||
QSpinBox *m_timeoutSpin;
|
QSpinBox *m_timeoutSpin;
|
||||||
QTreeWidget *m_frameworkTreeWidget;
|
QTreeWidget *m_frameworkTreeWidget;
|
||||||
Utils::InfoLabel *m_frameworksWarn;
|
InfoLabel *m_frameworksWarn;
|
||||||
};
|
};
|
||||||
|
|
||||||
TestSettingsWidget::TestSettingsWidget(QWidget *parent)
|
TestSettingsWidget::TestSettingsWidget(QWidget *parent)
|
||||||
@@ -146,12 +148,12 @@ TestSettingsWidget::TestSettingsWidget(QWidget *parent)
|
|||||||
item->setText(1, Tr::tr("Group"));
|
item->setText(1, Tr::tr("Group"));
|
||||||
item->setToolTip(1, Tr::tr("Enables grouping of test cases."));
|
item->setToolTip(1, Tr::tr("Enables grouping of test cases."));
|
||||||
|
|
||||||
m_frameworksWarn = new Utils::InfoLabel;
|
m_frameworksWarn = new InfoLabel;
|
||||||
m_frameworksWarn->setVisible(false);
|
m_frameworksWarn->setVisible(false);
|
||||||
m_frameworksWarn->setElideMode(Qt::ElideNone);
|
m_frameworksWarn->setElideMode(Qt::ElideNone);
|
||||||
m_frameworksWarn->setType(Utils::InfoLabel::Warning);
|
m_frameworksWarn->setType(InfoLabel::Warning);
|
||||||
|
|
||||||
using namespace Utils::Layouting;
|
using namespace Layouting;
|
||||||
|
|
||||||
PushButton resetChoicesButton {
|
PushButton resetChoicesButton {
|
||||||
text(Tr::tr("Reset Cached Choices")),
|
text(Tr::tr("Reset Cached Choices")),
|
||||||
@@ -249,13 +251,13 @@ enum TestBaseInfo
|
|||||||
BaseType
|
BaseType
|
||||||
};
|
};
|
||||||
|
|
||||||
void TestSettingsWidget::populateFrameworksListWidget(const QHash<Utils::Id, bool> &frameworks,
|
void TestSettingsWidget::populateFrameworksListWidget(const QHash<Id, bool> &frameworks,
|
||||||
const QHash<Utils::Id, bool> &testTools)
|
const QHash<Id, bool> &testTools)
|
||||||
{
|
{
|
||||||
const TestFrameworks ®istered = TestFrameworkManager::registeredFrameworks();
|
const TestFrameworks ®istered = TestFrameworkManager::registeredFrameworks();
|
||||||
m_frameworkTreeWidget->clear();
|
m_frameworkTreeWidget->clear();
|
||||||
for (const ITestFramework *framework : registered) {
|
for (const ITestFramework *framework : registered) {
|
||||||
const Utils::Id id = framework->id();
|
const Id id = framework->id();
|
||||||
auto item = new QTreeWidgetItem(m_frameworkTreeWidget, {framework->displayName()});
|
auto item = new QTreeWidgetItem(m_frameworkTreeWidget, {framework->displayName()});
|
||||||
item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable);
|
item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable);
|
||||||
item->setCheckState(0, frameworks.value(id) ? Qt::Checked : Qt::Unchecked);
|
item->setCheckState(0, frameworks.value(id) ? Qt::Checked : Qt::Unchecked);
|
||||||
@@ -272,7 +274,7 @@ void TestSettingsWidget::populateFrameworksListWidget(const QHash<Utils::Id, boo
|
|||||||
// ...and now the test tools
|
// ...and now the test tools
|
||||||
const TestTools ®isteredTools = TestFrameworkManager::registeredTestTools();
|
const TestTools ®isteredTools = TestFrameworkManager::registeredTestTools();
|
||||||
for (const ITestTool *testTool : registeredTools) {
|
for (const ITestTool *testTool : registeredTools) {
|
||||||
const Utils::Id id = testTool->id();
|
const Id id = testTool->id();
|
||||||
auto item = new QTreeWidgetItem(m_frameworkTreeWidget, {testTool->displayName()});
|
auto item = new QTreeWidgetItem(m_frameworkTreeWidget, {testTool->displayName()});
|
||||||
item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable);
|
item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable);
|
||||||
item->setCheckState(0, testTools.value(id) ? Qt::Checked : Qt::Unchecked);
|
item->setCheckState(0, testTools.value(id) ? Qt::Checked : Qt::Unchecked);
|
||||||
@@ -289,7 +291,7 @@ void TestSettingsWidget::testSettings(TestSettings &settings) const
|
|||||||
QTC_ASSERT(itemCount <= model->rowCount(), return);
|
QTC_ASSERT(itemCount <= model->rowCount(), return);
|
||||||
for (int row = 0; row < itemCount; ++row) {
|
for (int row = 0; row < itemCount; ++row) {
|
||||||
QModelIndex idx = model->index(row, 0);
|
QModelIndex idx = model->index(row, 0);
|
||||||
const Utils::Id id = Utils::Id::fromSetting(idx.data(BaseId));
|
const Id id = Id::fromSetting(idx.data(BaseId));
|
||||||
settings.frameworks.insert(id, idx.data(Qt::CheckStateRole) == Qt::Checked);
|
settings.frameworks.insert(id, idx.data(Qt::CheckStateRole) == Qt::Checked);
|
||||||
idx = model->index(row, 1);
|
idx = model->index(row, 1);
|
||||||
settings.frameworksGrouping.insert(id, idx.data(Qt::CheckStateRole) == Qt::Checked);
|
settings.frameworksGrouping.insert(id, idx.data(Qt::CheckStateRole) == Qt::Checked);
|
||||||
@@ -306,7 +308,7 @@ void TestSettingsWidget::testToolsSettings(TestSettings &settings) const
|
|||||||
QTC_ASSERT(row <= end, return);
|
QTC_ASSERT(row <= end, return);
|
||||||
for ( ; row < end; ++row) {
|
for ( ; row < end; ++row) {
|
||||||
const QModelIndex idx = model->index(row, 0);
|
const QModelIndex idx = model->index(row, 0);
|
||||||
const Utils::Id id = Utils::Id::fromSetting(idx.data(BaseId));
|
const Id id = Id::fromSetting(idx.data(BaseId));
|
||||||
settings.tools.insert(id, idx.data(Qt::CheckStateRole) == Qt::Checked);
|
settings.tools.insert(id, idx.data(Qt::CheckStateRole) == Qt::Checked);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -365,8 +367,8 @@ void TestSettingsPage::apply()
|
|||||||
if (!m_widget) // page was not shown at all
|
if (!m_widget) // page was not shown at all
|
||||||
return;
|
return;
|
||||||
const TestSettings newSettings = m_widget->settings();
|
const TestSettings newSettings = m_widget->settings();
|
||||||
const QList<Utils::Id> changedIds = Utils::filtered(newSettings.frameworksGrouping.keys(),
|
const QList<Id> changedIds = Utils::filtered(newSettings.frameworksGrouping.keys(),
|
||||||
[newSettings, this](const Utils::Id &id) {
|
[newSettings, this](const Id &id) {
|
||||||
return newSettings.frameworksGrouping[id] != m_settings->frameworksGrouping[id];
|
return newSettings.frameworksGrouping[id] != m_settings->frameworksGrouping[id];
|
||||||
});
|
});
|
||||||
*m_settings = newSettings;
|
*m_settings = newSettings;
|
||||||
|
@@ -14,16 +14,18 @@
|
|||||||
|
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
|
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
namespace Autotest {
|
namespace Autotest {
|
||||||
|
|
||||||
static QIcon testTreeIcon(TestTreeItem::Type type)
|
static QIcon testTreeIcon(TestTreeItem::Type type)
|
||||||
{
|
{
|
||||||
static QIcon icons[] = {
|
static QIcon icons[] = {
|
||||||
QIcon(),
|
QIcon(),
|
||||||
Utils::Icons::OPENFILE.icon(),
|
Icons::OPENFILE.icon(),
|
||||||
QIcon(":/autotest/images/suite.png"),
|
QIcon(":/autotest/images/suite.png"),
|
||||||
Utils::CodeModelIcon::iconForType(Utils::CodeModelIcon::Class),
|
CodeModelIcon::iconForType(CodeModelIcon::Class),
|
||||||
Utils::CodeModelIcon::iconForType(Utils::CodeModelIcon::SlotPrivate),
|
CodeModelIcon::iconForType(CodeModelIcon::SlotPrivate),
|
||||||
QIcon(":/autotest/images/data.png")
|
QIcon(":/autotest/images/data.png")
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -33,7 +35,7 @@ static QIcon testTreeIcon(TestTreeItem::Type type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ITestTreeItem::ITestTreeItem(ITestBase *testBase, const QString &name,
|
ITestTreeItem::ITestTreeItem(ITestBase *testBase, const QString &name,
|
||||||
const Utils::FilePath &filePath, Type type)
|
const FilePath &filePath, Type type)
|
||||||
: m_testBase(testBase)
|
: m_testBase(testBase)
|
||||||
, m_name(name)
|
, m_name(name)
|
||||||
, m_filePath(filePath)
|
, m_filePath(filePath)
|
||||||
@@ -115,8 +117,8 @@ bool ITestTreeItem::lessThan(const ITestTreeItem *other, ITestTreeItem::SortMode
|
|||||||
Qt::CaseInsensitive) > 0;
|
Qt::CaseInsensitive) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Utils::Link &leftLink = data(0, LinkRole).value<Utils::Link>();
|
const Link &leftLink = data(0, LinkRole).value<Link>();
|
||||||
const Utils::Link &rightLink = other->data(0, LinkRole).value<Utils::Link>();
|
const Link &rightLink = other->data(0, LinkRole).value<Link>();
|
||||||
const int comparison = leftLink.targetFilePath.toString().compare(
|
const int comparison = leftLink.targetFilePath.toString().compare(
|
||||||
rightLink.targetFilePath.toString(), Qt::CaseInsensitive);
|
rightLink.targetFilePath.toString(), Qt::CaseInsensitive);
|
||||||
if (comparison == 0) {
|
if (comparison == 0) {
|
||||||
@@ -144,7 +146,7 @@ ITestConfiguration *ITestTreeItem::asConfiguration(TestRunMode mode) const
|
|||||||
/****************************** TestTreeItem ********************************************/
|
/****************************** TestTreeItem ********************************************/
|
||||||
|
|
||||||
TestTreeItem::TestTreeItem(ITestFramework *testFramework, const QString &name,
|
TestTreeItem::TestTreeItem(ITestFramework *testFramework, const QString &name,
|
||||||
const Utils::FilePath &filePath, Type type)
|
const FilePath &filePath, Type type)
|
||||||
: ITestTreeItem(testFramework, name, filePath, type)
|
: ITestTreeItem(testFramework, name, filePath, type)
|
||||||
{
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
@@ -168,7 +170,7 @@ QVariant TestTreeItem::data(int column, int role) const
|
|||||||
return QVariant();
|
return QVariant();
|
||||||
QVariant itemLink;
|
QVariant itemLink;
|
||||||
itemLink.setValue(
|
itemLink.setValue(
|
||||||
Utils::Link(filePath(), line(), int(m_column)));
|
Link(filePath(), line(), int(m_column)));
|
||||||
return itemLink;
|
return itemLink;
|
||||||
}
|
}
|
||||||
return ITestTreeItem::data(column, role);
|
return ITestTreeItem::data(column, role);
|
||||||
@@ -222,7 +224,7 @@ void TestTreeItem::markForRemovalRecursively(bool mark)
|
|||||||
childItem(row)->markForRemovalRecursively(mark);
|
childItem(row)->markForRemovalRecursively(mark);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestTreeItem::markForRemovalRecursively(const Utils::FilePath &filepath)
|
void TestTreeItem::markForRemovalRecursively(const FilePath &filepath)
|
||||||
{
|
{
|
||||||
bool mark = filePath() == filepath;
|
bool mark = filePath() == filepath;
|
||||||
forFirstLevelChildItems([&mark, &filepath](TestTreeItem *child) {
|
forFirstLevelChildItems([&mark, &filepath](TestTreeItem *child) {
|
||||||
@@ -249,20 +251,20 @@ TestTreeItem *TestTreeItem::findChildByName(const QString &name)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
TestTreeItem *TestTreeItem::findChildByFile(const Utils::FilePath &filePath)
|
TestTreeItem *TestTreeItem::findChildByFile(const FilePath &filePath)
|
||||||
{
|
{
|
||||||
return findFirstLevelChildItem([filePath](const TestTreeItem *other) {
|
return findFirstLevelChildItem([filePath](const TestTreeItem *other) {
|
||||||
return other->filePath() == filePath;
|
return other->filePath() == filePath;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
TestTreeItem *TestTreeItem::findChildByFileAndType(const Utils::FilePath &filePath, Type tType)
|
TestTreeItem *TestTreeItem::findChildByFileAndType(const FilePath &filePath, Type tType)
|
||||||
{
|
{
|
||||||
return findFirstLevelChildItem([filePath, tType](const TestTreeItem *other) {
|
return findFirstLevelChildItem([filePath, tType](const TestTreeItem *other) {
|
||||||
return other->type() == tType && other->filePath() == filePath;
|
return other->type() == tType && other->filePath() == filePath;
|
||||||
});}
|
});}
|
||||||
|
|
||||||
TestTreeItem *TestTreeItem::findChildByNameAndFile(const QString &name, const Utils::FilePath &filePath)
|
TestTreeItem *TestTreeItem::findChildByNameAndFile(const QString &name, const FilePath &filePath)
|
||||||
{
|
{
|
||||||
return findFirstLevelChildItem([name, filePath](const TestTreeItem *other) {
|
return findFirstLevelChildItem([name, filePath](const TestTreeItem *other) {
|
||||||
return other->filePath() == filePath && other->name() == name;
|
return other->filePath() == filePath && other->name() == name;
|
||||||
@@ -280,7 +282,7 @@ ITestConfiguration *TestTreeItem::asConfiguration(TestRunMode mode) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<ITestConfiguration *> TestTreeItem::getTestConfigurationsForFile(const Utils::FilePath &) const
|
QList<ITestConfiguration *> TestTreeItem::getTestConfigurationsForFile(const FilePath &) const
|
||||||
{
|
{
|
||||||
return QList<ITestConfiguration *>();
|
return QList<ITestConfiguration *>();
|
||||||
}
|
}
|
||||||
@@ -342,7 +344,7 @@ void TestTreeItem::copyBasicDataFrom(const TestTreeItem *other)
|
|||||||
m_status = other->m_status;
|
m_status = other->m_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool TestTreeItem::modifyFilePath(const Utils::FilePath &filepath)
|
inline bool TestTreeItem::modifyFilePath(const FilePath &filepath)
|
||||||
{
|
{
|
||||||
if (filePath() != filepath) {
|
if (filePath() != filepath) {
|
||||||
setFilePath(filepath);
|
setFilePath(filepath);
|
||||||
|
@@ -51,8 +51,8 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
explicit ITestTreeItem(ITestBase *testBase,
|
explicit ITestTreeItem(ITestBase *testBase,
|
||||||
const QString &name = QString(),
|
const QString &name = {},
|
||||||
const Utils::FilePath &filePath = Utils::FilePath(),
|
const Utils::FilePath &filePath = {},
|
||||||
Type type = Root);
|
Type type = Root);
|
||||||
|
|
||||||
virtual QVariant data(int column, int role) const override;
|
virtual QVariant data(int column, int role) const override;
|
||||||
@@ -97,8 +97,8 @@ class TestTreeItem : public ITestTreeItem
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit TestTreeItem(ITestFramework *testFramework,
|
explicit TestTreeItem(ITestFramework *testFramework,
|
||||||
const QString &name = QString(),
|
const QString &name = {},
|
||||||
const Utils::FilePath &filePath = Utils::FilePath(),
|
const Utils::FilePath &filePath = {},
|
||||||
Type type = Root);
|
Type type = Root);
|
||||||
|
|
||||||
virtual TestTreeItem *copyWithoutChildren() = 0;
|
virtual TestTreeItem *copyWithoutChildren() = 0;
|
||||||
|
@@ -20,8 +20,9 @@
|
|||||||
#include <utils/fileutils.h>
|
#include <utils/fileutils.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
using namespace ProjectExplorer;
|
|
||||||
using namespace Autotest::Internal;
|
using namespace Autotest::Internal;
|
||||||
|
using namespace ProjectExplorer;
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
namespace Autotest {
|
namespace Autotest {
|
||||||
|
|
||||||
@@ -95,8 +96,7 @@ void TestTreeModel::setupParsingConnections()
|
|||||||
m_parser, &TestCodeParser::onCppDocumentUpdated, Qt::QueuedConnection);
|
m_parser, &TestCodeParser::onCppDocumentUpdated, Qt::QueuedConnection);
|
||||||
connect(cppMM, &CppEditor::CppModelManager::aboutToRemoveFiles,
|
connect(cppMM, &CppEditor::CppModelManager::aboutToRemoveFiles,
|
||||||
this, [this](const QStringList &files) {
|
this, [this](const QStringList &files) {
|
||||||
const Utils::FilePaths filesToRemove
|
const FilePaths filesToRemove = FileUtils::toFilePathList(files);
|
||||||
= Utils::FileUtils::toFilePathList(files);
|
|
||||||
removeFiles(filesToRemove);
|
removeFiles(filesToRemove);
|
||||||
}, Qt::QueuedConnection);
|
}, Qt::QueuedConnection);
|
||||||
connect(cppMM, &CppEditor::CppModelManager::projectPartsUpdated,
|
connect(cppMM, &CppEditor::CppModelManager::projectPartsUpdated,
|
||||||
@@ -125,7 +125,7 @@ bool TestTreeModel::setData(const QModelIndex &index, const QVariant &value, int
|
|||||||
Qt::CheckState checked = item->checked();
|
Qt::CheckState checked = item->checked();
|
||||||
if (item->hasChildren() && checked != Qt::PartiallyChecked) {
|
if (item->hasChildren() && checked != Qt::PartiallyChecked) {
|
||||||
// handle the new checkstate for children as well...
|
// handle the new checkstate for children as well...
|
||||||
for (Utils::TreeItem *child : *item) {
|
for (TreeItem *child : *item) {
|
||||||
const QModelIndex &idx = indexForItem(child);
|
const QModelIndex &idx = indexForItem(child);
|
||||||
setData(idx, checked ? Qt::Checked : Qt::Unchecked, Qt::CheckStateRole);
|
setData(idx, checked ? Qt::Checked : Qt::Unchecked, Qt::CheckStateRole);
|
||||||
}
|
}
|
||||||
@@ -155,7 +155,7 @@ Qt::ItemFlags TestTreeModel::flags(const QModelIndex &index) const
|
|||||||
|
|
||||||
bool TestTreeModel::hasTests() const
|
bool TestTreeModel::hasTests() const
|
||||||
{
|
{
|
||||||
for (Utils::TreeItem *frameworkRoot : *rootItem()) {
|
for (TreeItem *frameworkRoot : *rootItem()) {
|
||||||
if (frameworkRoot->hasChildren())
|
if (frameworkRoot->hasChildren())
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -189,7 +189,7 @@ QList<ITestConfiguration *> TestTreeModel::getFailedTests() const
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<ITestConfiguration *> TestTreeModel::getTestsForFile(const Utils::FilePath &fileName) const
|
QList<ITestConfiguration *> TestTreeModel::getTestsForFile(const FilePath &fileName) const
|
||||||
{
|
{
|
||||||
QList<ITestConfiguration *> result;
|
QList<ITestConfiguration *> result;
|
||||||
forItemsAtLevel<1>([&result, &fileName](ITestTreeItem *testRoot) {
|
forItemsAtLevel<1>([&result, &fileName](ITestTreeItem *testRoot) {
|
||||||
@@ -316,10 +316,10 @@ void TestTreeModel::synchronizeTestFrameworks()
|
|||||||
|
|
||||||
const auto sortedParsers = Utils::transform(sorted, &ITestFramework::testParser);
|
const auto sortedParsers = Utils::transform(sorted, &ITestFramework::testParser);
|
||||||
// pre-check to avoid further processing when frameworks are unchanged
|
// pre-check to avoid further processing when frameworks are unchanged
|
||||||
Utils::TreeItem *invisibleRoot = rootItem();
|
TreeItem *invisibleRoot = rootItem();
|
||||||
QSet<ITestParser *> newlyAdded;
|
QSet<ITestParser *> newlyAdded;
|
||||||
QList<ITestTreeItem *> oldFrameworkRoots;
|
QList<ITestTreeItem *> oldFrameworkRoots;
|
||||||
for (Utils::TreeItem *oldFrameworkRoot : *invisibleRoot)
|
for (TreeItem *oldFrameworkRoot : *invisibleRoot)
|
||||||
oldFrameworkRoots.append(static_cast<ITestTreeItem *>(oldFrameworkRoot));
|
oldFrameworkRoots.append(static_cast<ITestTreeItem *>(oldFrameworkRoot));
|
||||||
|
|
||||||
for (ITestTreeItem *oldFrameworkRoot : oldFrameworkRoots)
|
for (ITestTreeItem *oldFrameworkRoot : oldFrameworkRoots)
|
||||||
@@ -362,10 +362,10 @@ void TestTreeModel::synchronizeTestTools()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// pre-check to avoid further processing when test tools are unchanged
|
// pre-check to avoid further processing when test tools are unchanged
|
||||||
Utils::TreeItem *invisibleRoot = rootItem();
|
TreeItem *invisibleRoot = rootItem();
|
||||||
QSet<ITestTool *> newlyAdded;
|
QSet<ITestTool *> newlyAdded;
|
||||||
QList<ITestTreeItem *> oldFrameworkRoots;
|
QList<ITestTreeItem *> oldFrameworkRoots;
|
||||||
for (Utils::TreeItem *oldFrameworkRoot : *invisibleRoot) {
|
for (TreeItem *oldFrameworkRoot : *invisibleRoot) {
|
||||||
auto item = static_cast<ITestTreeItem *>(oldFrameworkRoot);
|
auto item = static_cast<ITestTreeItem *>(oldFrameworkRoot);
|
||||||
if (item->testBase()->type() == ITestBase::Tool)
|
if (item->testBase()->type() == ITestBase::Tool)
|
||||||
oldFrameworkRoots.append(item);
|
oldFrameworkRoots.append(item);
|
||||||
@@ -416,9 +416,9 @@ void TestTreeModel::filterAndInsert(TestTreeItem *item, TestTreeItem *root, bool
|
|||||||
insertItemInParent(filtered, root, groupingEnabled);
|
insertItemInParent(filtered, root, groupingEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestTreeModel::rebuild(const QList<Utils::Id> &frameworkIds)
|
void TestTreeModel::rebuild(const QList<Id> &frameworkIds)
|
||||||
{
|
{
|
||||||
for (const Utils::Id &id : frameworkIds) {
|
for (const Id &id : frameworkIds) {
|
||||||
ITestFramework *framework = TestFrameworkManager::frameworkForId(id);
|
ITestFramework *framework = TestFrameworkManager::frameworkForId(id);
|
||||||
TestTreeItem *frameworkRoot = framework->rootNode();
|
TestTreeItem *frameworkRoot = framework->rootNode();
|
||||||
const bool groupingEnabled = framework->grouping();
|
const bool groupingEnabled = framework->grouping();
|
||||||
@@ -456,7 +456,7 @@ void TestTreeModel::updateCheckStateCache()
|
|||||||
|
|
||||||
bool TestTreeModel::hasFailedTests() const
|
bool TestTreeModel::hasFailedTests() const
|
||||||
{
|
{
|
||||||
auto failedItem = rootItem()->findAnyChild([](Utils::TreeItem *it) {
|
auto failedItem = rootItem()->findAnyChild([](TreeItem *it) {
|
||||||
return it->data(0, FailedRole).toBool();
|
return it->data(0, FailedRole).toBool();
|
||||||
});
|
});
|
||||||
return failedItem != nullptr;
|
return failedItem != nullptr;
|
||||||
@@ -464,17 +464,17 @@ bool TestTreeModel::hasFailedTests() const
|
|||||||
|
|
||||||
void TestTreeModel::clearFailedMarks()
|
void TestTreeModel::clearFailedMarks()
|
||||||
{
|
{
|
||||||
for (Utils::TreeItem *rootNode : *rootItem()) {
|
for (TreeItem *rootNode : *rootItem()) {
|
||||||
rootNode->forAllChildren([](Utils::TreeItem *child) {
|
rootNode->forAllChildren([](TreeItem *child) {
|
||||||
child->setData(0, false, FailedRole);
|
child->setData(0, false, FailedRole);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
m_failedStateCache.clear();
|
m_failedStateCache.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestTreeModel::removeFiles(const Utils::FilePaths &files)
|
void TestTreeModel::removeFiles(const FilePaths &files)
|
||||||
{
|
{
|
||||||
for (const Utils::FilePath &file : files)
|
for (const FilePath &file : files)
|
||||||
markForRemoval(file);
|
markForRemoval(file);
|
||||||
sweep();
|
sweep();
|
||||||
}
|
}
|
||||||
@@ -488,7 +488,7 @@ void TestTreeModel::markAllFrameworkItemsForRemoval()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestTreeModel::markForRemoval(const Utils::FilePath &filePath)
|
void TestTreeModel::markForRemoval(const FilePath &filePath)
|
||||||
{
|
{
|
||||||
if (filePath.isEmpty())
|
if (filePath.isEmpty())
|
||||||
return;
|
return;
|
||||||
@@ -558,7 +558,7 @@ static void applyParentCheckState(ITestTreeItem *parent, ITestTreeItem *newItem)
|
|||||||
const Qt::CheckState checkState = parent->checked() == Qt::Unchecked ? Qt::Unchecked
|
const Qt::CheckState checkState = parent->checked() == Qt::Unchecked ? Qt::Unchecked
|
||||||
: Qt::Checked;
|
: Qt::Checked;
|
||||||
newItem->setData(0, checkState, Qt::CheckStateRole);
|
newItem->setData(0, checkState, Qt::CheckStateRole);
|
||||||
newItem->forAllChildren([checkState](Utils::TreeItem *it) {
|
newItem->forAllChildren([checkState](TreeItem *it) {
|
||||||
it->setData(0, checkState, Qt::CheckStateRole);
|
it->setData(0, checkState, Qt::CheckStateRole);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -752,25 +752,25 @@ void TestTreeModel::removeAllTestToolItems()
|
|||||||
// we're inside tests - so use some internal knowledge to make testing easier
|
// we're inside tests - so use some internal knowledge to make testing easier
|
||||||
static TestTreeItem *qtRootNode()
|
static TestTreeItem *qtRootNode()
|
||||||
{
|
{
|
||||||
auto id = Utils::Id(Constants::FRAMEWORK_PREFIX).withSuffix("QtTest");
|
const Id id = Id(Constants::FRAMEWORK_PREFIX).withSuffix("QtTest");
|
||||||
return TestFrameworkManager::frameworkForId(id)->rootNode();
|
return TestFrameworkManager::frameworkForId(id)->rootNode();
|
||||||
}
|
}
|
||||||
|
|
||||||
static TestTreeItem *quickRootNode()
|
static TestTreeItem *quickRootNode()
|
||||||
{
|
{
|
||||||
auto id = Utils::Id(Constants::FRAMEWORK_PREFIX).withSuffix("QtQuickTest");
|
const Id id = Id(Constants::FRAMEWORK_PREFIX).withSuffix("QtQuickTest");
|
||||||
return TestFrameworkManager::frameworkForId(id)->rootNode();
|
return TestFrameworkManager::frameworkForId(id)->rootNode();
|
||||||
}
|
}
|
||||||
|
|
||||||
static TestTreeItem *gtestRootNode()
|
static TestTreeItem *gtestRootNode()
|
||||||
{
|
{
|
||||||
auto id = Utils::Id(Constants::FRAMEWORK_PREFIX).withSuffix("GTest");
|
const Id id = Id(Constants::FRAMEWORK_PREFIX).withSuffix("GTest");
|
||||||
return TestFrameworkManager::frameworkForId(id)->rootNode();
|
return TestFrameworkManager::frameworkForId(id)->rootNode();
|
||||||
}
|
}
|
||||||
|
|
||||||
static TestTreeItem *boostTestRootNode()
|
static TestTreeItem *boostTestRootNode()
|
||||||
{
|
{
|
||||||
auto id = Utils::Id(Constants::FRAMEWORK_PREFIX).withSuffix("Boost");
|
const Id id = Id(Constants::FRAMEWORK_PREFIX).withSuffix("Boost");
|
||||||
return TestFrameworkManager::frameworkForId(id)->rootNode();
|
return TestFrameworkManager::frameworkForId(id)->rootNode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -11,7 +11,6 @@
|
|||||||
#include <projectexplorer/runconfigurationaspects.h>
|
#include <projectexplorer/runconfigurationaspects.h>
|
||||||
#include <projectexplorer/target.h>
|
#include <projectexplorer/target.h>
|
||||||
|
|
||||||
#include <remotelinux/abstractremotelinuxdeployservice.h>
|
|
||||||
#include <remotelinux/abstractremotelinuxdeploystep.h>
|
#include <remotelinux/abstractremotelinuxdeploystep.h>
|
||||||
|
|
||||||
#include <utils/commandline.h>
|
#include <utils/commandline.h>
|
||||||
|
@@ -100,20 +100,6 @@ void registerFlashAction(QObject *parentForAction)
|
|||||||
toolsContainer->addAction(flashCommand, flashActionId);
|
toolsContainer->addAction(flashCommand, flashActionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
class QdbQtVersionFactory : public QtSupport::QtVersionFactory
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
QdbQtVersionFactory()
|
|
||||||
{
|
|
||||||
setQtVersionCreator([] { return new QdbQtVersion; });
|
|
||||||
setSupportedType("Qdb.EmbeddedLinuxQt");
|
|
||||||
setPriority(99);
|
|
||||||
setRestrictionChecker([](const SetupData &setup) {
|
|
||||||
return setup.platforms.contains("boot2qt");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class Step>
|
template <class Step>
|
||||||
class QdbDeployStepFactory : public ProjectExplorer::BuildStepFactory
|
class QdbDeployStepFactory : public ProjectExplorer::BuildStepFactory
|
||||||
{
|
{
|
||||||
|
@@ -6,17 +6,32 @@
|
|||||||
#include "qdbconstants.h"
|
#include "qdbconstants.h"
|
||||||
#include "qdbtr.h"
|
#include "qdbtr.h"
|
||||||
|
|
||||||
|
#include <qtsupport/baseqtversion.h>
|
||||||
|
#include <qtsupport/qtsupporttr.h>
|
||||||
|
|
||||||
namespace Qdb::Internal {
|
namespace Qdb::Internal {
|
||||||
|
|
||||||
QString QdbQtVersion::description() const
|
class QdbQtVersion : public QtSupport::QtVersion
|
||||||
{
|
|
||||||
return Tr::tr("Boot2Qt", "Qt version is used for Boot2Qt development");
|
|
||||||
}
|
|
||||||
|
|
||||||
QSet<Utils::Id> QdbQtVersion::targetDeviceTypes() const
|
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
QString description() const final
|
||||||
|
{
|
||||||
|
return QtSupport::Tr::tr("Boot2Qt", "Qt version is used for Boot2Qt development");
|
||||||
|
}
|
||||||
|
QSet<Utils::Id> targetDeviceTypes() const final
|
||||||
|
{
|
||||||
return {Utils::Id(Constants::QdbLinuxOsType)};
|
return {Utils::Id(Constants::QdbLinuxOsType)};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
QdbQtVersionFactory::QdbQtVersionFactory()
|
||||||
|
{
|
||||||
|
setQtVersionCreator([] { return new QdbQtVersion; });
|
||||||
|
setSupportedType("Qdb.EmbeddedLinuxQt");
|
||||||
|
setPriority(99);
|
||||||
|
setRestrictionChecker([](const SetupData &setup) {
|
||||||
|
return setup.platforms.contains("boot2qt");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
} // Qdb::Internal
|
} // Qdb::Internal
|
||||||
|
@@ -3,18 +3,14 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <qtsupport/baseqtversion.h>
|
#include <qtsupport/qtversionfactory.h>
|
||||||
|
|
||||||
namespace Qdb::Internal {
|
namespace Qdb::Internal {
|
||||||
|
|
||||||
class QdbQtVersion : public QtSupport::QtVersion
|
class QdbQtVersionFactory : public QtSupport::QtVersionFactory
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QdbQtVersion() = default;
|
QdbQtVersionFactory();
|
||||||
~QdbQtVersion() = default;
|
|
||||||
|
|
||||||
QString description() const final;
|
|
||||||
QSet<Utils::Id> targetDeviceTypes() const final;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // Qdb::Internal
|
} // Qdb::Internal
|
||||||
|
@@ -11,7 +11,6 @@
|
|||||||
#include <projectexplorer/projectexplorerconstants.h>
|
#include <projectexplorer/projectexplorerconstants.h>
|
||||||
#include <projectexplorer/target.h>
|
#include <projectexplorer/target.h>
|
||||||
|
|
||||||
#include <remotelinux/abstractremotelinuxdeployservice.h>
|
|
||||||
#include <remotelinux/abstractremotelinuxdeploystep.h>
|
#include <remotelinux/abstractremotelinuxdeploystep.h>
|
||||||
|
|
||||||
#include <utils/qtcprocess.h>
|
#include <utils/qtcprocess.h>
|
||||||
|
@@ -292,7 +292,7 @@ public:
|
|||||||
|
|
||||||
void findUsages(TextDocument *document, const QTextCursor &cursor,
|
void findUsages(TextDocument *document, const QTextCursor &cursor,
|
||||||
const QString &searchTerm, const std::optional<QString> &replacement,
|
const QString &searchTerm, const std::optional<QString> &replacement,
|
||||||
bool categorize);
|
const std::function<void()> &callback, bool categorize);
|
||||||
|
|
||||||
void handleDeclDefSwitchReplies();
|
void handleDeclDefSwitchReplies();
|
||||||
|
|
||||||
@@ -509,7 +509,8 @@ void ClangdClient::closeExtraFile(const Utils::FilePath &filePath)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ClangdClient::findUsages(TextDocument *document, const QTextCursor &cursor,
|
void ClangdClient::findUsages(TextDocument *document, const QTextCursor &cursor,
|
||||||
const std::optional<QString> &replacement)
|
const std::optional<QString> &replacement,
|
||||||
|
const std::function<void()> &renameCallback)
|
||||||
{
|
{
|
||||||
// Quick check: Are we even on anything searchable?
|
// Quick check: Are we even on anything searchable?
|
||||||
const QTextCursor adjustedCursor = d->adjustedCursor(cursor, document);
|
const QTextCursor adjustedCursor = d->adjustedCursor(cursor, document);
|
||||||
@@ -519,7 +520,7 @@ void ClangdClient::findUsages(TextDocument *document, const QTextCursor &cursor,
|
|||||||
|
|
||||||
if (replacement && versionNumber() >= QVersionNumber(16)
|
if (replacement && versionNumber() >= QVersionNumber(16)
|
||||||
&& Utils::qtcEnvironmentVariable("QTC_CLANGD_RENAMING") != "0") {
|
&& Utils::qtcEnvironmentVariable("QTC_CLANGD_RENAMING") != "0") {
|
||||||
symbolSupport().renameSymbol(document, adjustedCursor, *replacement,
|
symbolSupport().renameSymbol(document, adjustedCursor, *replacement, renameCallback,
|
||||||
CppEditor::preferLowerCaseFileNames());
|
CppEditor::preferLowerCaseFileNames());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -530,19 +531,20 @@ void ClangdClient::findUsages(TextDocument *document, const QTextCursor &cursor,
|
|||||||
if (searchTerm != "operator" && Utils::allOf(searchTerm, [](const QChar &c) {
|
if (searchTerm != "operator" && Utils::allOf(searchTerm, [](const QChar &c) {
|
||||||
return c.isLetterOrNumber() || c == '_';
|
return c.isLetterOrNumber() || c == '_';
|
||||||
})) {
|
})) {
|
||||||
d->findUsages(document, adjustedCursor, searchTerm, replacement, categorize);
|
d->findUsages(document, adjustedCursor, searchTerm, replacement, renameCallback, categorize);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise get the proper spelling of the search term from clang, so we can put it into the
|
// Otherwise get the proper spelling of the search term from clang, so we can put it into the
|
||||||
// search widget.
|
// search widget.
|
||||||
const auto symbolInfoHandler = [this, doc = QPointer(document), adjustedCursor, replacement, categorize]
|
const auto symbolInfoHandler = [this, doc = QPointer(document), adjustedCursor, replacement,
|
||||||
|
renameCallback, categorize]
|
||||||
(const QString &name, const QString &, const MessageId &) {
|
(const QString &name, const QString &, const MessageId &) {
|
||||||
if (!doc)
|
if (!doc)
|
||||||
return;
|
return;
|
||||||
if (name.isEmpty())
|
if (name.isEmpty())
|
||||||
return;
|
return;
|
||||||
d->findUsages(doc.data(), adjustedCursor, name, replacement, categorize);
|
d->findUsages(doc.data(), adjustedCursor, name, replacement, renameCallback, categorize);
|
||||||
};
|
};
|
||||||
requestSymbolInfo(document->filePath(), Range(adjustedCursor).start(), symbolInfoHandler);
|
requestSymbolInfo(document->filePath(), Range(adjustedCursor).start(), symbolInfoHandler);
|
||||||
}
|
}
|
||||||
@@ -704,10 +706,11 @@ CppEditor::ClangdSettings::Data ClangdClient::settingsData() const { return d->s
|
|||||||
|
|
||||||
void ClangdClient::Private::findUsages(TextDocument *document,
|
void ClangdClient::Private::findUsages(TextDocument *document,
|
||||||
const QTextCursor &cursor, const QString &searchTerm,
|
const QTextCursor &cursor, const QString &searchTerm,
|
||||||
const std::optional<QString> &replacement, bool categorize)
|
const std::optional<QString> &replacement, const std::function<void()> &renameCallback,
|
||||||
|
bool categorize)
|
||||||
{
|
{
|
||||||
const auto findRefs = new ClangdFindReferences(q, document, cursor, searchTerm, replacement,
|
const auto findRefs = new ClangdFindReferences(q, document, cursor, searchTerm, replacement,
|
||||||
categorize);
|
renameCallback, categorize);
|
||||||
if (isTesting) {
|
if (isTesting) {
|
||||||
connect(findRefs, &ClangdFindReferences::foundReferences,
|
connect(findRefs, &ClangdFindReferences::foundReferences,
|
||||||
q, &ClangdClient::foundReferences);
|
q, &ClangdClient::foundReferences);
|
||||||
|
@@ -54,7 +54,8 @@ public:
|
|||||||
void closeExtraFile(const Utils::FilePath &filePath);
|
void closeExtraFile(const Utils::FilePath &filePath);
|
||||||
|
|
||||||
void findUsages(TextEditor::TextDocument *document, const QTextCursor &cursor,
|
void findUsages(TextEditor::TextDocument *document, const QTextCursor &cursor,
|
||||||
const std::optional<QString> &replacement);
|
const std::optional<QString> &replacement,
|
||||||
|
const std::function<void()> &renameCallback);
|
||||||
void checkUnused(const Utils::Link &link, Core::SearchResult *search,
|
void checkUnused(const Utils::Link &link, Core::SearchResult *search,
|
||||||
const Utils::LinkHandler &callback);
|
const Utils::LinkHandler &callback);
|
||||||
void followSymbol(TextEditor::TextDocument *document,
|
void followSymbol(TextEditor::TextDocument *document,
|
||||||
|
@@ -109,7 +109,8 @@ public:
|
|||||||
|
|
||||||
ClangdFindReferences::ClangdFindReferences(ClangdClient *client, TextDocument *document,
|
ClangdFindReferences::ClangdFindReferences(ClangdClient *client, TextDocument *document,
|
||||||
const QTextCursor &cursor, const QString &searchTerm,
|
const QTextCursor &cursor, const QString &searchTerm,
|
||||||
const std::optional<QString> &replacement, bool categorize)
|
const std::optional<QString> &replacement, const std::function<void()> &callback,
|
||||||
|
bool categorize)
|
||||||
: QObject(client), d(new ClangdFindReferences::Private(this))
|
: QObject(client), d(new ClangdFindReferences::Private(this))
|
||||||
{
|
{
|
||||||
d->categorize = categorize;
|
d->categorize = categorize;
|
||||||
@@ -130,6 +131,7 @@ ClangdFindReferences::ClangdFindReferences(ClangdClient *client, TextDocument *d
|
|||||||
replacement ? SearchResultWindow::SearchAndReplace : SearchResultWindow::SearchOnly,
|
replacement ? SearchResultWindow::SearchAndReplace : SearchResultWindow::SearchOnly,
|
||||||
SearchResultWindow::PreserveCaseDisabled,
|
SearchResultWindow::PreserveCaseDisabled,
|
||||||
"CppEditor");
|
"CppEditor");
|
||||||
|
d->search->makeNonInteractive(callback);
|
||||||
if (categorize)
|
if (categorize)
|
||||||
d->search->setFilter(new CppSearchResultFilter);
|
d->search->setFilter(new CppSearchResultFilter);
|
||||||
if (d->replacementData) {
|
if (d->replacementData) {
|
||||||
@@ -150,6 +152,7 @@ ClangdFindReferences::ClangdFindReferences(ClangdClient *client, TextDocument *d
|
|||||||
connect(d->search, &SearchResult::activated, [](const SearchResultItem& item) {
|
connect(d->search, &SearchResult::activated, [](const SearchResultItem& item) {
|
||||||
EditorManager::openEditorAtSearchResult(item);
|
EditorManager::openEditorAtSearchResult(item);
|
||||||
});
|
});
|
||||||
|
if (d->search->isInteractive())
|
||||||
SearchResultWindow::instance()->popup(IOutputPane::ModeSwitch | IOutputPane::WithFocus);
|
SearchResultWindow::instance()->popup(IOutputPane::ModeSwitch | IOutputPane::WithFocus);
|
||||||
|
|
||||||
const std::optional<MessageId> requestId = client->symbolSupport().findUsages(
|
const std::optional<MessageId> requestId = client->symbolSupport().findUsages(
|
||||||
|
@@ -27,7 +27,9 @@ class ClangdFindReferences : public QObject
|
|||||||
public:
|
public:
|
||||||
ClangdFindReferences(ClangdClient *client, TextEditor::TextDocument *document,
|
ClangdFindReferences(ClangdClient *client, TextEditor::TextDocument *document,
|
||||||
const QTextCursor &cursor, const QString &searchTerm,
|
const QTextCursor &cursor, const QString &searchTerm,
|
||||||
const std::optional<QString> &replacement, bool categorize);
|
const std::optional<QString> &replacement,
|
||||||
|
const std::function<void()> &callback,
|
||||||
|
bool categorize);
|
||||||
ClangdFindReferences(ClangdClient *client, const Utils::Link &link, Core::SearchResult *search,
|
ClangdFindReferences(ClangdClient *client, const Utils::Link &link, Core::SearchResult *search,
|
||||||
const Utils::LinkHandler &callback);
|
const Utils::LinkHandler &callback);
|
||||||
~ClangdFindReferences();
|
~ClangdFindReferences();
|
||||||
|
@@ -313,16 +313,17 @@ void ClangModelManagerSupport::startLocalRenaming(const CppEditor::CursorInEdito
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ClangModelManagerSupport::globalRename(const CppEditor::CursorInEditor &cursor,
|
void ClangModelManagerSupport::globalRename(const CppEditor::CursorInEditor &cursor,
|
||||||
const QString &replacement)
|
const QString &replacement,
|
||||||
|
const std::function<void()> &callback)
|
||||||
{
|
{
|
||||||
if (ClangdClient * const client = clientForFile(cursor.filePath());
|
if (ClangdClient * const client = clientForFile(cursor.filePath());
|
||||||
client && client->isFullyIndexed()) {
|
client && client->isFullyIndexed()) {
|
||||||
QTC_ASSERT(client->documentOpen(cursor.textDocument()),
|
QTC_ASSERT(client->documentOpen(cursor.textDocument()),
|
||||||
client->openDocument(cursor.textDocument()));
|
client->openDocument(cursor.textDocument()));
|
||||||
client->findUsages(cursor.textDocument(), cursor.cursor(), replacement);
|
client->findUsages(cursor.textDocument(), cursor.cursor(), replacement, callback);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
CppModelManager::globalRename(cursor, replacement, CppModelManager::Backend::Builtin);
|
CppModelManager::globalRename(cursor, replacement, callback, CppModelManager::Backend::Builtin);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClangModelManagerSupport::findUsages(const CppEditor::CursorInEditor &cursor) const
|
void ClangModelManagerSupport::findUsages(const CppEditor::CursorInEditor &cursor) const
|
||||||
@@ -331,7 +332,7 @@ void ClangModelManagerSupport::findUsages(const CppEditor::CursorInEditor &curso
|
|||||||
client && client->isFullyIndexed()) {
|
client && client->isFullyIndexed()) {
|
||||||
QTC_ASSERT(client->documentOpen(cursor.textDocument()),
|
QTC_ASSERT(client->documentOpen(cursor.textDocument()),
|
||||||
client->openDocument(cursor.textDocument()));
|
client->openDocument(cursor.textDocument()));
|
||||||
client->findUsages(cursor.textDocument(), cursor.cursor(), {});
|
client->findUsages(cursor.textDocument(), cursor.cursor(), {}, {});
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@@ -60,7 +60,8 @@ private:
|
|||||||
void startLocalRenaming(const CppEditor::CursorInEditor &data,
|
void startLocalRenaming(const CppEditor::CursorInEditor &data,
|
||||||
const CppEditor::ProjectPart *projectPart,
|
const CppEditor::ProjectPart *projectPart,
|
||||||
CppEditor::RenameCallback &&renameSymbolsCallback) override;
|
CppEditor::RenameCallback &&renameSymbolsCallback) override;
|
||||||
void globalRename(const CppEditor::CursorInEditor &cursor, const QString &replacement) override;
|
void globalRename(const CppEditor::CursorInEditor &cursor, const QString &replacement,
|
||||||
|
const std::function<void()> &callback) override;
|
||||||
void findUsages(const CppEditor::CursorInEditor &cursor) const override;
|
void findUsages(const CppEditor::CursorInEditor &cursor) const override;
|
||||||
void switchHeaderSource(const Utils::FilePath &filePath, bool inNextSplit) override;
|
void switchHeaderSource(const Utils::FilePath &filePath, bool inNextSplit) override;
|
||||||
void checkUnused(const Utils::Link &link, Core::SearchResult *search,
|
void checkUnused(const Utils::Link &link, Core::SearchResult *search,
|
||||||
|
@@ -294,7 +294,7 @@ void ClangdTestFindReferences::test()
|
|||||||
QVERIFY(doc);
|
QVERIFY(doc);
|
||||||
QTextCursor cursor(doc->document());
|
QTextCursor cursor(doc->document());
|
||||||
cursor.setPosition(pos);
|
cursor.setPosition(pos);
|
||||||
client()->findUsages(doc, cursor, {});
|
client()->findUsages(doc, cursor, {}, {});
|
||||||
QVERIFY(waitForSignalOrTimeout(client(), &ClangdClient::findUsagesDone, timeOutInMs()));
|
QVERIFY(waitForSignalOrTimeout(client(), &ClangdClient::findUsagesDone, timeOutInMs()));
|
||||||
|
|
||||||
QCOMPARE(m_actualResults.size(), expectedResults.size());
|
QCOMPARE(m_actualResults.size(), expectedResults.size());
|
||||||
|
@@ -146,7 +146,7 @@ static Environment projectBuildEnvironment(Project *project)
|
|||||||
if (BuildConfiguration *buildConfig = target->activeBuildConfiguration())
|
if (BuildConfiguration *buildConfig = target->activeBuildConfiguration())
|
||||||
env = buildConfig->environment();
|
env = buildConfig->environment();
|
||||||
}
|
}
|
||||||
if (!env.isValid())
|
if (!env.hasChanges())
|
||||||
env = Environment::systemEnvironment();
|
env = Environment::systemEnvironment();
|
||||||
return env;
|
return env;
|
||||||
}
|
}
|
||||||
|
@@ -1401,4 +1401,9 @@ void CMakeBuildSystem::runGenerator(Id id)
|
|||||||
proc->start();
|
proc->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ExtraCompiler *CMakeBuildSystem::findExtraCompiler(const ExtraCompilerFilter &filter) const
|
||||||
|
{
|
||||||
|
return Utils::findOrDefault(m_extraCompilers, filter);
|
||||||
|
}
|
||||||
|
|
||||||
} // CMakeProjectManager::Internal
|
} // CMakeProjectManager::Internal
|
||||||
|
@@ -122,6 +122,8 @@ signals:
|
|||||||
private:
|
private:
|
||||||
QList<QPair<Utils::Id, QString>> generators() const override;
|
QList<QPair<Utils::Id, QString>> generators() const override;
|
||||||
void runGenerator(Utils::Id id) override;
|
void runGenerator(Utils::Id id) override;
|
||||||
|
ProjectExplorer::ExtraCompiler *findExtraCompiler(
|
||||||
|
const ExtraCompilerFilter &filter) const override;
|
||||||
|
|
||||||
enum ForceEnabledChanged { False, True };
|
enum ForceEnabledChanged { False, True };
|
||||||
void clearError(ForceEnabledChanged fec = ForceEnabledChanged::False);
|
void clearError(ForceEnabledChanged fec = ForceEnabledChanged::False);
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user