AutoTest: Introduce ITestConfiguration

Preparation for an additional simpler test configuration
which needs to have the same common base.

Change-Id: I1800ed5d7301f1aea99eba6ef588a204697bd569
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Christian Stenger
2020-10-13 11:37:37 +02:00
parent 55298cc211
commit 239a59c596
34 changed files with 373 additions and 310 deletions

View File

@@ -329,7 +329,7 @@ void AutotestPluginPrivate::onRunSelectedTriggered()
void AutotestPluginPrivate::onRunFailedTriggered()
{
const QList<TestConfiguration *> failed = m_testTreeModel.getFailedTests();
const QList<ITestConfiguration *> failed = m_testTreeModel.getFailedTests();
if (failed.isEmpty()) // the framework might not be able to provide them
return;
m_testRunner.setSelectedTests(failed);
@@ -346,7 +346,7 @@ void AutotestPluginPrivate::onRunFileTriggered()
if (fileName.isEmpty())
return;
const QList<TestConfiguration *> tests = m_testTreeModel.getTestsForFile(fileName);
const QList<ITestConfiguration *> tests = m_testTreeModel.getTestsForFile(fileName);
if (tests.isEmpty())
return;
@@ -354,12 +354,12 @@ void AutotestPluginPrivate::onRunFileTriggered()
m_testRunner.prepareToRunTests(TestRunMode::Run);
}
static QList<TestConfiguration *> testItemsToTestConfigurations(const QList<TestTreeItem *> &items,
static QList<ITestConfiguration *> testItemsToTestConfigurations(const QList<TestTreeItem *> &items,
TestRunMode mode)
{
QList<TestConfiguration *> configs;
QList<ITestConfiguration *> configs;
for (const TestTreeItem * item : items) {
if (TestConfiguration *currentConfig = item->asConfiguration(mode))
if (ITestConfiguration *currentConfig = item->asConfiguration(mode))
configs << currentConfig;
}
return configs;
@@ -385,7 +385,7 @@ void AutotestPluginPrivate::onRunUnderCursorTriggered(TestRunMode mode)
return it->line() == line && it->filePath() == filePath;
});
const QList<TestConfiguration *> testsToRun = testItemsToTestConfigurations(
const QList<ITestConfiguration *> testsToRun = testItemsToTestConfigurations(
filteredItems.size() == 1 ? filteredItems : testsItems, mode);
if (testsToRun.isEmpty()) {

View File

@@ -108,7 +108,7 @@ void BoostTestOutputReader::sendCompleteInformation()
if (m_lineNumber) {
result->setLine(m_lineNumber);
result->setFileName(m_fileName);
} else if (const TestTreeItem *it = result->findTestTreeItem()) {
} else if (const ITestTreeItem *it = result->findTestTreeItem()) {
result->setLine(it->line());
result->setFileName(it->filePath());
}

View File

@@ -90,7 +90,7 @@ bool BoostTestResult::isDirectParentOf(const TestResult *other, bool *needsInter
return false;
}
const TestTreeItem *BoostTestResult::findTestTreeItem() const
const ITestTreeItem *BoostTestResult::findTestTreeItem() const
{
auto id = Utils::Id(Constants::FRAMEWORK_PREFIX).withSuffix(BoostTest::Constants::FRAMEWORK_NAME);
ITestFramework *framework = TestFrameworkManager::frameworkForId(id);
@@ -102,7 +102,7 @@ const TestTreeItem *BoostTestResult::findTestTreeItem() const
const auto foundItem = rootNode->findAnyChild([this](const Utils::TreeItem *item) {
return matches(static_cast<const BoostTestTreeItem *>(item));
});
return static_cast<const TestTreeItem *>(foundItem);
return static_cast<const ITestTreeItem *>(foundItem);
}
bool BoostTestResult::matches(const BoostTestTreeItem *item) const

View File

@@ -39,7 +39,7 @@ public:
const QString outputString(bool selected) const override;
bool isDirectParentOf(const TestResult *other, bool *needsIntermediate) const override;
const TestTreeItem * findTestTreeItem() const override;
const ITestTreeItem * findTestTreeItem() const override;
void setTestSuite(const QString &testSuite) { m_testSuite = testSuite; }
void setTestCase(const QString &testCase) { m_testCase = testCase; }
private:

View File

@@ -174,9 +174,9 @@ static QString handleSpecialFunctionNames(const QString &name)
return result;
}
QList<TestConfiguration *> BoostTestTreeItem::getAllTestConfigurations() const
QList<ITestConfiguration *> BoostTestTreeItem::getAllTestConfigurations() const
{
QList<TestConfiguration *> result;
QList<ITestConfiguration *> result;
ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject();
if (!project || type() != Root)
return result;
@@ -216,10 +216,10 @@ QList<TestConfiguration *> BoostTestTreeItem::getAllTestConfigurations() const
return result;
}
QList<TestConfiguration *> BoostTestTreeItem::getTestConfigurations(
QList<ITestConfiguration *> BoostTestTreeItem::getTestConfigurations(
std::function<bool(BoostTestTreeItem *)> predicate) const
{
QList<TestConfiguration *> result;
QList<ITestConfiguration *> result;
ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject();
if (!project || type() != Root)
return result;
@@ -263,21 +263,21 @@ QList<TestConfiguration *> BoostTestTreeItem::getTestConfigurations(
return result;
}
QList<TestConfiguration *> BoostTestTreeItem::getSelectedTestConfigurations() const
QList<ITestConfiguration *> BoostTestTreeItem::getSelectedTestConfigurations() const
{
return getTestConfigurations([](BoostTestTreeItem *it) {
return it->checked() == Qt::Checked;
});
}
QList<TestConfiguration *> BoostTestTreeItem::getFailedTestConfigurations() const
QList<ITestConfiguration *> BoostTestTreeItem::getFailedTestConfigurations() const
{
return getTestConfigurations([](BoostTestTreeItem *it) {
return it->data(0, FailedRole).toBool();
});
}
TestConfiguration *BoostTestTreeItem::testConfiguration() const
ITestConfiguration *BoostTestTreeItem::testConfiguration() const
{
ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject();
QTC_ASSERT(project, return nullptr);
@@ -320,7 +320,7 @@ TestConfiguration *BoostTestTreeItem::testConfiguration() const
return nullptr;
}
TestConfiguration *BoostTestTreeItem::debugConfiguration() const
ITestConfiguration *BoostTestTreeItem::debugConfiguration() const
{
BoostTestConfiguration *config = static_cast<BoostTestConfiguration *>(testConfiguration());
if (config)

View File

@@ -69,13 +69,13 @@ public:
void setState(TestState state) { m_state |= state; }
TestStates state() const { return m_state; }
QList<TestConfiguration *> getAllTestConfigurations() const override;
QList<TestConfiguration *> getSelectedTestConfigurations() const override;
QList<TestConfiguration *> getFailedTestConfigurations() const override;
QList<ITestConfiguration *> getAllTestConfigurations() const override;
QList<ITestConfiguration *> getSelectedTestConfigurations() const override;
QList<ITestConfiguration *> getFailedTestConfigurations() const override;
bool canProvideTestConfiguration() const override { return type() != Root; }
bool canProvideDebugConfiguration() const override { return canProvideTestConfiguration(); }
TestConfiguration *testConfiguration() const override;
TestConfiguration *debugConfiguration() const override;
ITestConfiguration *testConfiguration() const override;
ITestConfiguration *debugConfiguration() const override;
private:
QString nameSuffix() const;
@@ -84,7 +84,7 @@ private:
BoostTestTreeItem::TestStates state,
const QString &proFile) const;
QString prependWithParentsSuitePaths(const QString &testName) const;
QList<TestConfiguration *> getTestConfigurations(
QList<ITestConfiguration *> getTestConfigurations(
std::function<bool(BoostTestTreeItem *)> predicate) const;
bool modifyTestContent(const BoostTestParseResult *result);
TestStates m_state = Enabled;

View File

@@ -63,7 +63,7 @@ bool CatchResult::isDirectParentOf(const TestResult *other, bool *needsIntermedi
return name() == catchOther->name();
}
const TestTreeItem *CatchResult::findTestTreeItem() const
const ITestTreeItem *CatchResult::findTestTreeItem() const
{
auto id = Utils::Id(Constants::FRAMEWORK_PREFIX).withSuffix("Catch");
ITestFramework *framework = TestFrameworkManager::frameworkForId(id);
@@ -82,7 +82,7 @@ const TestTreeItem *CatchResult::findTestTreeItem() const
return parameterized ? tcName.startsWith(treeItem->name() + " - ")
: tcName == treeItem->name();
});
return static_cast<const TestTreeItem *>(item);
return static_cast<const ITestTreeItem *>(item);
}
} // namespace Internal

View File

@@ -35,7 +35,7 @@ public:
CatchResult(const QString &id, const QString &name);
bool isDirectParentOf(const TestResult *other, bool *needsIntermediate) const override;
const TestTreeItem *findTestTreeItem() const override;
const ITestTreeItem *findTestTreeItem() const override;
void setSectionDepth(int depth) { m_sectionDepth = depth; }
int sectionDepth() const { return m_sectionDepth; }

View File

@@ -153,7 +153,7 @@ bool CatchTreeItem::canProvideDebugConfiguration() const
return canProvideTestConfiguration();
}
TestConfiguration *CatchTreeItem::testConfiguration() const
ITestConfiguration *CatchTreeItem::testConfiguration() const
{
ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject();
QTC_ASSERT(project, return nullptr);
@@ -171,7 +171,7 @@ TestConfiguration *CatchTreeItem::testConfiguration() const
return config;
}
TestConfiguration *CatchTreeItem::debugConfiguration() const
ITestConfiguration *CatchTreeItem::debugConfiguration() const
{
CatchConfiguration *config = static_cast<CatchConfiguration *>(testConfiguration());
if (config)
@@ -240,19 +240,19 @@ static void collectFailedTestInfo(const CatchTreeItem *item,
});
}
QList<TestConfiguration *> CatchTreeItem::getAllTestConfigurations() const
QList<ITestConfiguration *> CatchTreeItem::getAllTestConfigurations() const
{
return getTestConfigurations(true);
}
QList<TestConfiguration *> CatchTreeItem::getSelectedTestConfigurations() const
QList<ITestConfiguration *> CatchTreeItem::getSelectedTestConfigurations() const
{
return getTestConfigurations(false);
}
QList<TestConfiguration *> CatchTreeItem::getFailedTestConfigurations() const
QList<ITestConfiguration *> CatchTreeItem::getFailedTestConfigurations() const
{
QList<TestConfiguration *> result;
QList<ITestConfiguration *> result;
ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject();
if (!project || type() != Root)
return result;
@@ -274,9 +274,9 @@ QList<TestConfiguration *> CatchTreeItem::getFailedTestConfigurations() const
return result;
}
QList<TestConfiguration *> CatchTreeItem::getTestConfigurationsForFile(const Utils::FilePath &fileName) const
QList<ITestConfiguration *> CatchTreeItem::getTestConfigurationsForFile(const Utils::FilePath &fileName) const
{
QList<TestConfiguration *> result;
QList<ITestConfiguration *> result;
ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject();
if (!project || type() != Root)
return result;
@@ -318,9 +318,9 @@ QString CatchTreeItem::stateSuffix() const
return types.isEmpty() ? QString() : QString(" [" + types.join(", ") + ']');
}
QList<TestConfiguration *> CatchTreeItem::getTestConfigurations(bool ignoreCheckState) const
QList<ITestConfiguration *> CatchTreeItem::getTestConfigurations(bool ignoreCheckState) const
{
QList<TestConfiguration *> result;
QList<ITestConfiguration *> result;
ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject();
if (!project || type() != Root)
return result;

View File

@@ -59,16 +59,16 @@ public:
bool canProvideTestConfiguration() const override;
bool canProvideDebugConfiguration() const override;
TestConfiguration *testConfiguration() const override;
TestConfiguration *debugConfiguration() const override;
QList<TestConfiguration *> getAllTestConfigurations() const override;
QList<TestConfiguration *> getSelectedTestConfigurations() const override;
QList<TestConfiguration *> getFailedTestConfigurations() const override;
QList<TestConfiguration *> getTestConfigurationsForFile(const Utils::FilePath &fileName) const override;
ITestConfiguration *testConfiguration() const override;
ITestConfiguration *debugConfiguration() const override;
QList<ITestConfiguration *> getAllTestConfigurations() const override;
QList<ITestConfiguration *> getSelectedTestConfigurations() const override;
QList<ITestConfiguration *> getFailedTestConfigurations() const override;
QList<ITestConfiguration *> getTestConfigurationsForFile(const Utils::FilePath &fileName) const override;
private:
QString stateSuffix() const;
QList<TestConfiguration *> getTestConfigurations(bool ignoreCheckState) const;
QList<ITestConfiguration *> getTestConfigurations(bool ignoreCheckState) const;
TestStates m_state = Normal;
};

View File

@@ -202,11 +202,11 @@ TestResultPtr GTestOutputReader::createDefaultResult() const
result->setTestCaseName(m_currentTestCase);
result->setIteration(m_iteration);
const TestTreeItem *testItem = result->findTestTreeItem();
const ITestTreeItem *testItem = result->findTestTreeItem();
if (testItem && testItem->line()) {
result->setFileName(testItem->filePath());
result->setLine(static_cast<int>(testItem->line()));
result->setLine(testItem->line());
}
return TestResultPtr(result);

View File

@@ -94,7 +94,7 @@ static QString normalizeTestName(const QString &testname)
return normalizeName(nameWithoutTypeParam);
}
const TestTreeItem *GTestResult::findTestTreeItem() const
const ITestTreeItem *GTestResult::findTestTreeItem() const
{
auto id = Utils::Id(Constants::FRAMEWORK_PREFIX).withSuffix(GTest::Constants::FRAMEWORK_NAME);
ITestFramework *framework = TestFrameworkManager::frameworkForId(id);
@@ -107,7 +107,7 @@ const TestTreeItem *GTestResult::findTestTreeItem() const
const auto treeItem = static_cast<const TestTreeItem *>(item);
return treeItem && matches(treeItem);
});
return static_cast<const TestTreeItem *>(item);
return static_cast<const ITestTreeItem *>(item);
}
bool GTestResult::matches(const TestTreeItem *treeItem) const

View File

@@ -28,6 +28,9 @@
#include "../testresult.h"
namespace Autotest {
class TestTreeItem;
namespace Internal {
class GTestResult : public TestResult
@@ -39,7 +42,7 @@ public:
void setTestCaseName(const QString &testSetName) { m_testCaseName = testSetName; }
void setIteration(int iteration) { m_iteration = iteration; }
bool isDirectParentOf(const TestResult *other, bool *needsIntermediate) const override;
virtual const TestTreeItem *findTestTreeItem() const override;
virtual const ITestTreeItem *findTestTreeItem() const override;
private:
bool isTestSuite() const { return m_testCaseName.isEmpty(); }

View File

@@ -162,7 +162,7 @@ QVariant GTestTreeItem::data(int column, int role) const
return TestTreeItem::data(column, role);
}
TestConfiguration *GTestTreeItem::testConfiguration() const
ITestConfiguration *GTestTreeItem::testConfiguration() const
{
ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject();
QTC_ASSERT(project, return nullptr);
@@ -199,7 +199,7 @@ TestConfiguration *GTestTreeItem::testConfiguration() const
return config;
}
TestConfiguration *GTestTreeItem::debugConfiguration() const
ITestConfiguration *GTestTreeItem::debugConfiguration() const
{
GTestConfiguration *config = static_cast<GTestConfiguration *>(testConfiguration());
if (config)
@@ -267,9 +267,9 @@ static void collectFailedTestInfo(const GTestTreeItem *item,
});
}
QList<TestConfiguration *> GTestTreeItem::getTestConfigurations(bool ignoreCheckState) const
QList<ITestConfiguration *> GTestTreeItem::getTestConfigurations(bool ignoreCheckState) const
{
QList<TestConfiguration *> result;
QList<ITestConfiguration *> result;
ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject();
if (!project || type() != Root)
return result;
@@ -296,19 +296,19 @@ QList<TestConfiguration *> GTestTreeItem::getTestConfigurations(bool ignoreCheck
return result;
}
QList<TestConfiguration *> GTestTreeItem::getAllTestConfigurations() const
QList<ITestConfiguration *> GTestTreeItem::getAllTestConfigurations() const
{
return getTestConfigurations(true);
}
QList<TestConfiguration *> GTestTreeItem::getSelectedTestConfigurations() const
QList<ITestConfiguration *> GTestTreeItem::getSelectedTestConfigurations() const
{
return getTestConfigurations(false);
}
QList<TestConfiguration *> GTestTreeItem::getFailedTestConfigurations() const
QList<ITestConfiguration *> GTestTreeItem::getFailedTestConfigurations() const
{
QList<TestConfiguration *> result;
QList<ITestConfiguration *> result;
ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject();
if (!project || type() != Root)
return result;
@@ -331,9 +331,9 @@ QList<TestConfiguration *> GTestTreeItem::getFailedTestConfigurations() const
return result;
}
QList<TestConfiguration *> GTestTreeItem::getTestConfigurationsForFile(const Utils::FilePath &fileName) const
QList<ITestConfiguration *> GTestTreeItem::getTestConfigurationsForFile(const Utils::FilePath &fileName) const
{
QList<TestConfiguration *> result;
QList<ITestConfiguration *> result;
ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject();
if (!project || type() != Root)
return result;

View File

@@ -57,12 +57,12 @@ public:
QVariant data(int column, int role) const override;
bool canProvideTestConfiguration() const override { return type() != Root; }
bool canProvideDebugConfiguration() const override { return type() != Root; }
TestConfiguration *testConfiguration() const override;
TestConfiguration *debugConfiguration() const override;
QList<TestConfiguration *> getAllTestConfigurations() const override;
QList<TestConfiguration *> getSelectedTestConfigurations() const override;
QList<TestConfiguration *> getFailedTestConfigurations() const override;
QList<TestConfiguration *> getTestConfigurationsForFile(const Utils::FilePath &fileName) const override;
ITestConfiguration *testConfiguration() const override;
ITestConfiguration *debugConfiguration() const override;
QList<ITestConfiguration *> getAllTestConfigurations() const override;
QList<ITestConfiguration *> getSelectedTestConfigurations() const override;
QList<ITestConfiguration *> getFailedTestConfigurations() const override;
QList<ITestConfiguration *> getTestConfigurationsForFile(const Utils::FilePath &fileName) const override;
TestTreeItem *find(const TestParseResult *result) override;
TestTreeItem *findChild(const TestTreeItem *other) override;
bool modify(const TestParseResult *result) override;
@@ -82,7 +82,7 @@ public:
bool shouldBeAddedAfterFiltering() const override;
private:
bool modifyTestSetContent(const GTestParseResult *result);
QList<TestConfiguration *> getTestConfigurations(bool ignoreCheckState) const;
QList<ITestConfiguration *> getTestConfigurations(bool ignoreCheckState) const;
GTestTreeItem::TestStates m_state;
};

View File

@@ -479,10 +479,10 @@ void QtTestOutputReader::sendCompleteInformation()
testResult->setFileName(m_file);
testResult->setLine(m_lineNumber);
} else {
const TestTreeItem *testItem = testResult->findTestTreeItem();
const ITestTreeItem *testItem = testResult->findTestTreeItem();
if (testItem && testItem->line()) {
testResult->setFileName(testItem->filePath());
testResult->setLine(static_cast<int>(testItem->line()));
testResult->setLine(testItem->line());
}
}
testResult->setDescription(m_description);
@@ -503,10 +503,10 @@ void QtTestOutputReader::sendStartMessage(bool isFunction)
testResult->setResult(ResultType::TestStart);
testResult->setDescription(isFunction ? tr("Executing test function %1").arg(m_testCase)
: tr("Executing test case %1").arg(m_className));
const TestTreeItem *testItem = testResult->findTestTreeItem();
const ITestTreeItem *testItem = testResult->findTestTreeItem();
if (testItem && testItem->line()) {
testResult->setFileName(testItem->filePath());
testResult->setLine(static_cast<int>(testItem->line()));
testResult->setLine(testItem->line());
}
reportResult(testResult);
}

View File

@@ -124,12 +124,12 @@ TestResult *QtTestResult::createIntermediateResultFor(const TestResult *other)
const auto correspondingItem = intermediate->findTestTreeItem();
if (correspondingItem && correspondingItem->line()) {
intermediate->setFileName(correspondingItem->filePath());
intermediate->setLine(static_cast<int>(correspondingItem->line()));
intermediate->setLine(correspondingItem->line());
}
return intermediate;
}
const TestTreeItem *QtTestResult::findTestTreeItem() const
const ITestTreeItem *QtTestResult::findTestTreeItem() const
{
Utils::Id id;
if (m_type == TestType::QtTest)
@@ -145,7 +145,7 @@ const TestTreeItem *QtTestResult::findTestTreeItem() const
const TestTreeItem *treeItem = static_cast<const TestTreeItem *>(item);
return treeItem && matches(treeItem);
});
return static_cast<const TestTreeItem *>(item);
return static_cast<const ITestTreeItem *>(item);
}
bool QtTestResult::matches(const TestTreeItem *item) const

View File

@@ -29,6 +29,9 @@
#include "qttestconstants.h"
namespace Autotest {
class TestTreeItem;
namespace Internal {
class QtTestResult : public TestResult
@@ -44,7 +47,7 @@ public:
bool isDirectParentOf(const TestResult *other, bool *needsIntermediate) const override;
bool isIntermediateFor(const TestResult *other) const override;
TestResult *createIntermediateResultFor(const TestResult *other) override;
const TestTreeItem *findTestTreeItem() const override;
const ITestTreeItem *findTestTreeItem() const override;
private:
bool isTestCase() const { return m_function.isEmpty() && m_dataTag.isEmpty(); }
bool isTestFunction() const { return !m_function.isEmpty() && m_dataTag.isEmpty(); }

View File

@@ -107,7 +107,7 @@ bool QtTestTreeItem::canProvideDebugConfiguration() const
return canProvideTestConfiguration();
}
TestConfiguration *QtTestTreeItem::testConfiguration() const
ITestConfiguration *QtTestTreeItem::testConfiguration() const
{
ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject();
QTC_ASSERT(project, return nullptr);
@@ -149,7 +149,7 @@ TestConfiguration *QtTestTreeItem::testConfiguration() const
}
static void fillTestConfigurationsFromCheckState(const TestTreeItem *item,
QList<TestConfiguration *> &testConfigurations)
QList<ITestConfiguration *> &testConfigurations)
{
QTC_ASSERT(item, return);
if (item->type() == TestTreeItem::GroupNode) {
@@ -190,7 +190,7 @@ static void fillTestConfigurationsFromCheckState(const TestTreeItem *item,
}
}
static void collectFailedTestInfo(TestTreeItem *item, QList<TestConfiguration *> &testConfigs)
static void collectFailedTestInfo(TestTreeItem *item, QList<ITestConfiguration *> &testConfigs)
{
QTC_ASSERT(item, return);
if (item->type() == TestTreeItem::GroupNode) {
@@ -221,7 +221,7 @@ static void collectFailedTestInfo(TestTreeItem *item, QList<TestConfiguration *>
testConfigs << testConfig;
}
TestConfiguration *QtTestTreeItem::debugConfiguration() const
ITestConfiguration *QtTestTreeItem::debugConfiguration() const
{
QtTestConfiguration *config = static_cast<QtTestConfiguration *>(testConfiguration());
if (config)
@@ -229,9 +229,9 @@ TestConfiguration *QtTestTreeItem::debugConfiguration() const
return config;
}
QList<TestConfiguration *> QtTestTreeItem::getAllTestConfigurations() const
QList<ITestConfiguration *> QtTestTreeItem::getAllTestConfigurations() const
{
QList<TestConfiguration *> result;
QList<ITestConfiguration *> result;
ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject();
if (!project || type() != Root)
@@ -239,12 +239,12 @@ QList<TestConfiguration *> QtTestTreeItem::getAllTestConfigurations() const
forFirstLevelChildren([&result](ITestTreeItem *child) {
if (child->type() == TestCase) {
TestConfiguration *tc = child->testConfiguration();
ITestConfiguration *tc = child->testConfiguration();
QTC_ASSERT(tc, return);
result << tc;
} else if (child->type() == GroupNode) {
child->forFirstLevelChildren([&result](ITestTreeItem *groupChild) {
TestConfiguration *tc = groupChild->testConfiguration();
ITestConfiguration *tc = groupChild->testConfiguration();
QTC_ASSERT(tc, return);
result << tc;
});
@@ -253,9 +253,9 @@ QList<TestConfiguration *> QtTestTreeItem::getAllTestConfigurations() const
return result;
}
QList<TestConfiguration *> QtTestTreeItem::getSelectedTestConfigurations() const
QList<ITestConfiguration *> QtTestTreeItem::getSelectedTestConfigurations() const
{
QList<TestConfiguration *> result;
QList<ITestConfiguration *> result;
ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject();
if (!project || type() != Root)
return result;
@@ -266,18 +266,18 @@ QList<TestConfiguration *> QtTestTreeItem::getSelectedTestConfigurations() const
return result;
}
QList<TestConfiguration *> QtTestTreeItem::getFailedTestConfigurations() const
QList<ITestConfiguration *> QtTestTreeItem::getFailedTestConfigurations() const
{
QList<TestConfiguration *> result;
QList<ITestConfiguration *> result;
QTC_ASSERT(type() == TestTreeItem::Root, return result);
for (int row = 0, end = childCount(); row < end; ++row)
collectFailedTestInfo(childItem(row), result);
return result;
}
QList<TestConfiguration *> QtTestTreeItem::getTestConfigurationsForFile(const Utils::FilePath &fileName) const
QList<ITestConfiguration *> QtTestTreeItem::getTestConfigurationsForFile(const Utils::FilePath &fileName) const
{
QList<TestConfiguration *> result;
QList<ITestConfiguration *> result;
ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject();
if (!project || type() != Root)
@@ -295,7 +295,7 @@ QList<TestConfiguration *> QtTestTreeItem::getTestConfigurationsForFile(const Ut
});
for (auto it = testFunctions.cbegin(), end = testFunctions.cend(); it != end; ++it) {
TestConfiguration *tc = it.key()->testConfiguration();
TestConfiguration *tc = static_cast<TestConfiguration *>(it.key()->testConfiguration());
QTC_ASSERT(tc, continue);
tc->setTestCases(it.value());
result << tc;

View File

@@ -41,12 +41,12 @@ public:
Qt::ItemFlags flags(int column) const override;
bool canProvideTestConfiguration() const override;
bool canProvideDebugConfiguration() const override;
TestConfiguration *testConfiguration() const override;
TestConfiguration *debugConfiguration() const override;
QList<TestConfiguration *> getAllTestConfigurations() const override;
QList<TestConfiguration *> getSelectedTestConfigurations() const override;
QList<TestConfiguration *> getFailedTestConfigurations() const override;
QList<TestConfiguration *> getTestConfigurationsForFile(const Utils::FilePath &fileName) const override;
ITestConfiguration *testConfiguration() const override;
ITestConfiguration *debugConfiguration() const override;
QList<ITestConfiguration *> getAllTestConfigurations() const override;
QList<ITestConfiguration *> getSelectedTestConfigurations() const override;
QList<ITestConfiguration *> getFailedTestConfigurations() const override;
QList<ITestConfiguration *> getTestConfigurationsForFile(const Utils::FilePath &fileName) const override;
TestTreeItem *find(const TestParseResult *result) override;
TestTreeItem *findChild(const TestTreeItem *other) override;
bool modify(const TestParseResult *result) override;

View File

@@ -123,7 +123,7 @@ bool QuickTestTreeItem::canProvideDebugConfiguration() const
return canProvideTestConfiguration();
}
TestConfiguration *QuickTestTreeItem::testConfiguration() const
ITestConfiguration *QuickTestTreeItem::testConfiguration() const
{
ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject();
QTC_ASSERT(project, return nullptr);
@@ -160,7 +160,7 @@ TestConfiguration *QuickTestTreeItem::testConfiguration() const
return config;
}
static QList<TestConfiguration *> testConfigurationsFor(
static QList<ITestConfiguration *> testConfigurationsFor(
const TestTreeItem *rootNode, const std::function<bool(TestTreeItem *)> &predicate)
{
QTC_ASSERT(rootNode, return {});
@@ -197,10 +197,10 @@ static QList<TestConfiguration *> testConfigurationsFor(
return false;
});
return Utils::static_container_cast<TestConfiguration *>(configurationForProFiles.values());
return Utils::static_container_cast<ITestConfiguration *>(configurationForProFiles.values());
}
TestConfiguration *QuickTestTreeItem::debugConfiguration() const
ITestConfiguration *QuickTestTreeItem::debugConfiguration() const
{
QuickTestConfiguration *config = static_cast<QuickTestConfiguration *>(testConfiguration());
if (config)
@@ -219,9 +219,9 @@ static void addTestsForItem(Tests &tests, const TestTreeItem *item)
tests.internalTargets = item->internalTargets();
}
QList<TestConfiguration *> QuickTestTreeItem::getAllTestConfigurations() const
QList<ITestConfiguration *> QuickTestTreeItem::getAllTestConfigurations() const
{
QList<TestConfiguration *> result;
QList<ITestConfiguration *> result;
ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject();
if (!project || type() != Root)
@@ -259,21 +259,21 @@ QList<TestConfiguration *> QuickTestTreeItem::getAllTestConfigurations() const
return result;
}
QList<TestConfiguration *> QuickTestTreeItem::getSelectedTestConfigurations() const
QList<ITestConfiguration *> QuickTestTreeItem::getSelectedTestConfigurations() const
{
return testConfigurationsFor(this, [](TestTreeItem *it) {
return it->checked() == Qt::Checked && it->type() == TestTreeItem::TestFunction;
});
}
QList<TestConfiguration *> QuickTestTreeItem::getFailedTestConfigurations() const
QList<ITestConfiguration *> QuickTestTreeItem::getFailedTestConfigurations() const
{
return testConfigurationsFor(this, [](TestTreeItem *it) {
return it->data(0, FailedRole).toBool();
});
}
QList<TestConfiguration *> QuickTestTreeItem::getTestConfigurationsForFile(
QList<ITestConfiguration *> QuickTestTreeItem::getTestConfigurationsForFile(
const Utils::FilePath &fileName) const
{
const QString &file = fileName.toString();

View File

@@ -45,12 +45,12 @@ public:
Qt::ItemFlags flags(int column) const override;
bool canProvideTestConfiguration() const override;
bool canProvideDebugConfiguration() const override;
TestConfiguration *testConfiguration() const override;
TestConfiguration *debugConfiguration() const override;
QList<TestConfiguration *> getAllTestConfigurations() const override;
QList<TestConfiguration *> getSelectedTestConfigurations() const override;
QList<TestConfiguration *> getFailedTestConfigurations() const override;
QList<TestConfiguration *> getTestConfigurationsForFile(const Utils::FilePath &fileName) const override;
ITestConfiguration *testConfiguration() const override;
ITestConfiguration *debugConfiguration() const override;
QList<ITestConfiguration *> getAllTestConfigurations() const override;
QList<ITestConfiguration *> getSelectedTestConfigurations() const override;
QList<ITestConfiguration *> getFailedTestConfigurations() const override;
QList<ITestConfiguration *> getTestConfigurationsForFile(const Utils::FilePath &fileName) const override;
TestTreeItem *find(const TestParseResult *result) override;
TestTreeItem *findChild(const TestTreeItem *other) override;
bool modify(const TestParseResult *result) override;

View File

@@ -25,6 +25,7 @@
#include "testconfiguration.h"
#include "itestframework.h"
#include "testoutputreader.h"
#include "testrunconfiguration.h"
@@ -50,8 +51,59 @@ using namespace Utils;
namespace Autotest {
ITestConfiguration::ITestConfiguration(Autotest::ITestBase *testBase)
: m_testBase(testBase)
{
}
void ITestConfiguration::setWorkingDirectory(const QString &workingDirectory)
{
m_runnable.workingDirectory = workingDirectory;
}
QString ITestConfiguration::workingDirectory() const
{
if (!m_runnable.workingDirectory.isEmpty()) {
const QFileInfo info(m_runnable.workingDirectory);
if (info.isDir()) // ensure wanted working dir does exist
return info.absoluteFilePath();
}
const QString executable = executableFilePath();
return executable.isEmpty() ? executable : QFileInfo(executable).absolutePath();
}
bool ITestConfiguration::hasExecutable() const
{
return !m_runnable.executable.isEmpty();
}
QString ITestConfiguration::executableFilePath() const
{
if (!hasExecutable())
return QString();
QFileInfo commandFileInfo = m_runnable.executable.toFileInfo();
if (commandFileInfo.isExecutable() && commandFileInfo.path() != ".") {
return commandFileInfo.absoluteFilePath();
} else if (commandFileInfo.path() == "."){
QString fullCommandFileName = m_runnable.executable.toString();
// TODO: check if we can use searchInPath() from Utils::Environment
const QStringList &pathList = m_runnable.environment.toProcessEnvironment().value("PATH")
.split(Utils::HostOsInfo::pathListSeparator());
for (const QString &path : pathList) {
QString filePath(path + QDir::separator() + fullCommandFileName);
if (QFileInfo(filePath).isExecutable())
return commandFileInfo.absoluteFilePath();
}
}
return QString();
}
TestConfiguration::TestConfiguration(ITestFramework *framework)
: m_framework(framework)
: ITestConfiguration(framework)
{
}
@@ -77,17 +129,17 @@ void TestConfiguration::completeTestInformation(ProjectExplorer::RunConfiguratio
TestRunMode runMode)
{
QTC_ASSERT(rc, return);
QTC_ASSERT(m_project, return);
QTC_ASSERT(project(), return);
if (hasExecutable()) {
qCDebug(LOG) << "Executable has been set already - not completing configuration again.";
return;
}
Project *project = SessionManager::startupProject();
if (!project || project != m_project)
Project *startupProject = SessionManager::startupProject();
if (!startupProject || startupProject != project())
return;
Target *target = project->activeTarget();
Target *target = startupProject->activeTarget();
if (!target)
return;
@@ -95,7 +147,7 @@ void TestConfiguration::completeTestInformation(ProjectExplorer::RunConfiguratio
return;
m_runnable = rc->runnable();
m_displayName = rc->displayName();
setDisplayName(rc->displayName());
BuildTargetInfo targetInfo = rc->buildTargetInfo();
if (!targetInfo.targetFilePath.isEmpty())
@@ -104,7 +156,7 @@ void TestConfiguration::completeTestInformation(ProjectExplorer::RunConfiguratio
QString buildBase;
if (auto buildConfig = target->activeBuildConfiguration()) {
buildBase = buildConfig->buildDirectory().toString();
const QString projBase = m_project->projectDirectory().toString();
const QString projBase = startupProject->projectDirectory().toString();
if (m_projectFile.startsWith(projBase))
m_buildDir = QFileInfo(buildBase + m_projectFile.mid(projBase.length())).absolutePath();
}
@@ -116,7 +168,7 @@ void TestConfiguration::completeTestInformation(TestRunMode runMode)
{
QTC_ASSERT(!m_projectFile.isEmpty(), return);
QTC_ASSERT(!m_buildTargets.isEmpty(), return);
QTC_ASSERT(m_project, return);
QTC_ASSERT(project(), return);
if (m_origRunConfig) {
qCDebug(LOG) << "Using run configuration specified by user or found by first call";
@@ -129,13 +181,13 @@ void TestConfiguration::completeTestInformation(TestRunMode runMode)
}
qCDebug(LOG) << "Failed to complete - using 'normal' way.";
}
Project *project = SessionManager::startupProject();
if (!project || project != m_project) {
m_project = nullptr;
Project *startupProject = SessionManager::startupProject();
if (!startupProject || startupProject != project()) {
setProject(nullptr);
return;
}
Target *target = project->activeTarget();
Target *target = startupProject->activeTarget();
if (!target)
return;
qCDebug(LOG) << "ActiveTargetName\n " << target->displayName();
@@ -171,7 +223,7 @@ void TestConfiguration::completeTestInformation(TestRunMode runMode)
QString buildBase;
if (auto buildConfig = target->activeBuildConfiguration()) {
buildBase = buildConfig->buildDirectory().toString();
const QString projBase = project->projectDirectory().toString();
const QString projBase = startupProject->projectDirectory().toString();
if (m_projectFile.startsWith(projBase))
m_buildDir = QFileInfo(buildBase + m_projectFile.mid(projBase.length())).absolutePath();
}
@@ -211,7 +263,7 @@ void TestConfiguration::completeTestInformation(TestRunMode runMode)
m_origRunConfig = runConfig;
m_runnable = runnable;
m_runnable.executable = currentExecutable;
m_displayName = runConfig->displayName();
setDisplayName(runConfig->displayName());
if (runMode == TestRunMode::Debug || runMode == TestRunMode::DebugWithoutDeploy)
m_runConfig = new Internal::TestRunConfiguration(target, this);
break;
@@ -224,7 +276,7 @@ void TestConfiguration::completeTestInformation(TestRunMode runMode)
// before installation) to have at least something to execute
if (!hasExecutable() && !localExecutable.isEmpty())
m_runnable.executable = localExecutable;
if (m_displayName.isEmpty() && hasExecutable()) {
if (displayName().isEmpty() && hasExecutable()) {
qCDebug(LOG) << " Fallback";
// we failed to find a valid runconfiguration - but we've got the executable already
if (auto rc = target->activeRunConfiguration()) {
@@ -242,8 +294,8 @@ void TestConfiguration::completeTestInformation(TestRunMode runMode)
}
}
if (m_displayName.isEmpty()) // happens e.g. when deducing the TestConfiguration or error
m_displayName = (*buildSystemTargets.begin());
if (displayName().isEmpty()) // happens e.g. when deducing the TestConfiguration or error
setDisplayName(*buildSystemTargets.begin());
}
/**
@@ -258,12 +310,7 @@ void TestConfiguration::setTestCases(const QStringList &testCases)
{
m_testCases.clear();
m_testCases << testCases;
m_testCaseCount = m_testCases.size();
}
void TestConfiguration::setTestCaseCount(int count)
{
m_testCaseCount = count;
setTestCaseCount(m_testCases.size());
}
void TestConfiguration::setExecutableFile(const QString &executableFile)
@@ -276,31 +323,11 @@ void TestConfiguration::setProjectFile(const QString &projectFile)
m_projectFile = projectFile;
}
void TestConfiguration::setWorkingDirectory(const QString &workingDirectory)
{
m_runnable.workingDirectory = workingDirectory;
}
void TestConfiguration::setBuildDirectory(const QString &buildDirectory)
{
m_buildDir = buildDirectory;
}
void TestConfiguration::setDisplayName(const QString &displayName)
{
m_displayName = displayName;
}
void TestConfiguration::setEnvironment(const Utils::Environment &env)
{
m_runnable.environment = env;
}
void TestConfiguration::setProject(Project *project)
{
m_project = project;
}
void TestConfiguration::setInternalTarget(const QString &target)
{
m_buildTargets.clear();
@@ -317,54 +344,14 @@ void TestConfiguration::setOriginalRunConfiguration(RunConfiguration *runConfig)
m_origRunConfig = runConfig;
}
QString TestConfiguration::executableFilePath() const
{
if (!hasExecutable())
return QString();
QFileInfo commandFileInfo = m_runnable.executable.toFileInfo();
if (commandFileInfo.isExecutable() && commandFileInfo.path() != ".") {
return commandFileInfo.absoluteFilePath();
} else if (commandFileInfo.path() == "."){
QString fullCommandFileName = m_runnable.executable.toString();
// TODO: check if we can use searchInPath() from Utils::Environment
const QStringList &pathList = m_runnable.environment.toProcessEnvironment().value("PATH")
.split(Utils::HostOsInfo::pathListSeparator());
foreach (const QString &path, pathList) {
QString filePath(path + QDir::separator() + fullCommandFileName);
if (QFileInfo(filePath).isExecutable())
return commandFileInfo.absoluteFilePath();
}
}
return QString();
}
QString TestConfiguration::workingDirectory() const
{
if (!m_runnable.workingDirectory.isEmpty()) {
const QFileInfo info(m_runnable.workingDirectory);
if (info.isDir()) // ensure wanted working dir does exist
return info.absoluteFilePath();
}
const QString executable = executableFilePath();
return executable.isEmpty() ? executable : QFileInfo(executable).absolutePath();
}
bool DebuggableTestConfiguration::isDebugRunMode() const
{
return m_runMode == TestRunMode::Debug || m_runMode == TestRunMode::DebugWithoutDeploy;
}
bool TestConfiguration::hasExecutable() const
{
return !m_runnable.executable.isEmpty();
}
ITestFramework *TestConfiguration::framework() const
{
return m_framework;
return static_cast<ITestFramework *>(testBase());
}
} // namespace Autotest

View File

@@ -44,6 +44,7 @@ namespace Internal {
class TestRunConfiguration;
} // namespace Internal
class ITestBase;
class ITestFramework;
class TestOutputReader;
class TestResult;
@@ -51,66 +52,81 @@ enum class TestRunMode;
using TestResultPtr = QSharedPointer<TestResult>;
class TestConfiguration
class ITestConfiguration
{
public:
explicit ITestConfiguration(ITestBase *testBase);
virtual ~ITestConfiguration() = default;
void setEnvironment(const Utils::Environment &env) { m_runnable.environment = env; }
Utils::Environment environment() const { return m_runnable.environment; }
void setWorkingDirectory(const QString &workingDirectory);
QString workingDirectory() const;
bool hasExecutable() const;
QString executableFilePath() const;
virtual TestOutputReader *outputReader(const QFutureInterface<TestResultPtr> &fi,
QProcess *app) const = 0;
virtual Utils::Environment filteredEnvironment(const Utils::Environment &original) const = 0;
ITestBase *testBase() const { return m_testBase; }
void setProject(ProjectExplorer::Project *project) { m_project = project; }
void setDisplayName(const QString &displayName) { m_displayName = displayName; }
QString displayName() const { return m_displayName; }
void setTestCaseCount(int count) { m_testCaseCount = count; }
int testCaseCount() const { return m_testCaseCount; }
ProjectExplorer::Project *project() const { return m_project.data(); }
ProjectExplorer::Runnable runnable() const { return m_runnable; }
protected:
ProjectExplorer::Runnable m_runnable;
private:
ITestBase *m_testBase = nullptr;
QPointer<ProjectExplorer::Project> m_project;
QString m_displayName;
int m_testCaseCount = 0;
};
class TestConfiguration : public ITestConfiguration
{
public:
explicit TestConfiguration(ITestFramework *framework);
virtual ~TestConfiguration();
~TestConfiguration() override;
void completeTestInformation(TestRunMode runMode);
void completeTestInformation(ProjectExplorer::RunConfiguration *rc, TestRunMode runMode);
void setTestCases(const QStringList &testCases);
void setTestCaseCount(int count);
void setExecutableFile(const QString &executableFile);
void setProjectFile(const QString &projectFile);
void setWorkingDirectory(const QString &workingDirectory);
void setBuildDirectory(const QString &buildDirectory);
void setDisplayName(const QString &displayName);
void setEnvironment(const Utils::Environment &env);
void setProject(ProjectExplorer::Project *project);
void setInternalTarget(const QString &target);
void setInternalTargets(const QSet<QString> &targets);
void setOriginalRunConfiguration(ProjectExplorer::RunConfiguration *runConfig);
ITestFramework *framework() const;
QStringList testCases() const { return m_testCases; }
int testCaseCount() const { return m_testCaseCount; }
QString executableFilePath() const;
QString workingDirectory() const;
QString buildDirectory() const { return m_buildDir; }
QString projectFile() const { return m_projectFile; }
QString displayName() const { return m_displayName; }
Utils::Environment environment() const { return m_runnable.environment; }
ProjectExplorer::Project *project() const { return m_project.data(); }
QSet<QString> internalTargets() const { return m_buildTargets; }
ProjectExplorer::RunConfiguration *originalRunConfiguration() const { return m_origRunConfig; }
Internal::TestRunConfiguration *runConfiguration() const { return m_runConfig; }
bool hasExecutable() const;
bool isDeduced() const { return m_deducedConfiguration; }
QString runConfigDisplayName() const { return m_deducedConfiguration ? m_deducedFrom
: m_displayName; }
: displayName(); }
ProjectExplorer::Runnable runnable() const { return m_runnable; }
virtual TestOutputReader *outputReader(const QFutureInterface<TestResultPtr> &fi,
QProcess *app) const = 0;
virtual QStringList argumentsForTestRunner(QStringList *omitted = nullptr) const = 0;
virtual Utils::Environment filteredEnvironment(const Utils::Environment &original) const = 0;
private:
ITestFramework *m_framework;
QStringList m_testCases;
int m_testCaseCount = 0;
QString m_projectFile;
QString m_buildDir;
QString m_displayName;
QString m_deducedFrom;
QPointer<ProjectExplorer::Project> m_project;
bool m_deducedConfiguration = false;
Internal::TestRunConfiguration *m_runConfig = nullptr;
QSet<QString> m_buildTargets;
ProjectExplorer::RunConfiguration *m_origRunConfig = nullptr;
ProjectExplorer::Runnable m_runnable;
};
class DebuggableTestConfiguration : public TestConfiguration

View File

@@ -43,7 +43,7 @@ const QString TestResult::outputString(bool selected) const
return selected ? m_description : m_description.split('\n').first();
}
const TestTreeItem *TestResult::findTestTreeItem() const
const ITestTreeItem *TestResult::findTestTreeItem() const
{
return nullptr;
}

View File

@@ -34,7 +34,7 @@
namespace Autotest {
class TestTreeItem;
class ITestTreeItem;
enum class ResultType {
// result types (have icon, color, short text)
@@ -86,7 +86,7 @@ public:
virtual ~TestResult() {}
virtual const QString outputString(bool selected) const;
virtual const TestTreeItem *findTestTreeItem() const;
virtual const ITestTreeItem *findTestTreeItem() const;
QString id() const { return m_id; }
QString name() const { return m_name; }

View File

@@ -322,7 +322,7 @@ void TestResultModel::addTestResult(const TestResultPtr &testResult, bool autoEx
}
if (isFailed(testResult->result())) {
if (const TestTreeItem *it = testResult->findTestTreeItem()) {
if (const ITestTreeItem *it = testResult->findTestTreeItem()) {
TestTreeModel *model = TestTreeModel::instance();
model->setData(model->indexForItem(it), true, FailedRole);
}

View File

@@ -631,7 +631,9 @@ void TestResultsPane::onCustomContextMenuRequested(const QPoint &pos)
menu.addAction(action);
action = new QAction(tr("Debug This Test"), &menu);
action->setEnabled(correlatingItem && correlatingItem->canProvideDebugConfiguration());
// FIXME limit to Test Frameworks
auto testTreeItem = static_cast<const TestTreeItem *>(correlatingItem);
action->setEnabled(testTreeItem && testTreeItem->canProvideDebugConfiguration());
connect(action, &QAction::triggered, this, [this, clicked] {
onRunThisTestTriggered(TestRunMode::Debug, clicked);
});
@@ -681,7 +683,7 @@ void TestResultsPane::onRunThisTestTriggered(TestRunMode runMode, const TestResu
{
QTC_ASSERT(result, return);
const TestTreeItem *item = result->findTestTreeItem();
const ITestTreeItem *item = result->findTestTreeItem();
if (item)
TestRunner::instance()->runTest(runMode, item);

View File

@@ -27,6 +27,7 @@
#include "autotestconstants.h"
#include "autotestplugin.h"
#include "itestframework.h"
#include "testoutputreader.h"
#include "testprojectsettings.h"
#include "testresultspane.h"
@@ -111,7 +112,7 @@ TestRunner::~TestRunner()
s_instance = nullptr;
}
void TestRunner::setSelectedTests(const QList<TestConfiguration *> &selected)
void TestRunner::setSelectedTests(const QList<ITestConfiguration *> &selected)
{
QTC_ASSERT(!m_executingTests, return);
qDeleteAll(m_selectedTests);
@@ -119,10 +120,10 @@ void TestRunner::setSelectedTests(const QList<TestConfiguration *> &selected)
m_selectedTests.append(selected);
}
void TestRunner::runTest(TestRunMode mode, const TestTreeItem *item)
void TestRunner::runTest(TestRunMode mode, const ITestTreeItem *item)
{
QTC_ASSERT(!m_executingTests, return);
TestConfiguration *configuration = item->asConfiguration(mode);
ITestConfiguration *configuration = item->asConfiguration(mode);
if (configuration) {
setSelectedTests({configuration});
@@ -145,14 +146,16 @@ static QString processInformation(const QProcess *proc)
return information;
}
static QString rcInfo(const TestConfiguration * const config)
static QString rcInfo(const ITestConfiguration * const config)
{
// FIXME early return for test tools
const TestConfiguration *current = static_cast<const TestConfiguration *>(config);
QString info;
if (config->isDeduced())
if (current->isDeduced())
info = TestRunner::tr("\nRun configuration: deduced from \"%1\"");
else
info = TestRunner::tr("\nRun configuration: \"%1\"");
return info.arg(config->runConfigDisplayName());
return info.arg(current->runConfigDisplayName());
}
static QString constructOmittedDetailsString(const QStringList &omitted)
@@ -170,6 +173,71 @@ static QString constructOmittedVariablesDetailsString(const Utils::EnvironmentIt
+ '\n' + removedVars.join('\n');
}
bool TestRunner::currentConfigValid()
{
if (true) { // FIXME do this for frameworks
TestConfiguration *current = static_cast<TestConfiguration *>(m_currentConfig);
QString commandFilePath = current->executableFilePath();
if (commandFilePath.isEmpty()) {
reportResult(ResultType::MessageFatal,
tr("Executable path is empty. (%1)").arg(current->displayName()));
delete m_currentConfig;
m_currentConfig = nullptr;
if (m_selectedTests.isEmpty()) {
if (m_fakeFutureInterface)
m_fakeFutureInterface->reportFinished();
onFinished();
} else {
onProcessFinished();
}
return false;
}
return true;
}
// FIXME check TestTools as well
return false;
}
void TestRunner::setUpProcess()
{
QTC_ASSERT(m_currentConfig, return);
if (true) { // FIXME do this for frameworks
TestConfiguration *current = static_cast<TestConfiguration *>(m_currentConfig);
m_currentProcess = new QProcess;
m_currentProcess->setReadChannel(QProcess::StandardOutput);
m_currentProcess->setProgram(current->executableFilePath());
}
// FIXME prepare for TestTools as well
}
void TestRunner::setUpProcessEnv()
{
if (true) { // do this for frameworks
TestConfiguration *current = static_cast<TestConfiguration *>(m_currentConfig);
QStringList omitted;
m_currentProcess->setArguments(current->argumentsForTestRunner(&omitted));
if (!omitted.isEmpty()) {
const QString &details = constructOmittedDetailsString(omitted);
reportResult(ResultType::MessageWarn, details.arg(current->displayName()));
}
m_currentProcess->setWorkingDirectory(current->workingDirectory());
const Utils::Environment &original = current->environment();
Utils::Environment environment = current->filteredEnvironment(original);
const Utils::EnvironmentItems removedVariables = Utils::filtered(
original.diff(environment), [](const Utils::EnvironmentItem &it) {
return it.operation == Utils::EnvironmentItem::Unset;
});
if (!removedVariables.isEmpty()) {
const QString &details = constructOmittedVariablesDetailsString(removedVariables)
.arg(current->displayName());
reportResult(ResultType::MessageWarn, details);
}
m_currentProcess->setProcessEnvironment(environment.toProcessEnvironment());
}
// FIXME prepare for TestTools as well
}
void TestRunner::scheduleNext()
{
QTC_ASSERT(!m_selectedTests.isEmpty(), onFinished(); return);
@@ -179,28 +247,14 @@ void TestRunner::scheduleNext()
m_currentConfig = m_selectedTests.dequeue();
QString commandFilePath = m_currentConfig->executableFilePath();
if (commandFilePath.isEmpty()) {
reportResult(ResultType::MessageFatal,
tr("Executable path is empty. (%1)").arg(m_currentConfig->displayName()));
delete m_currentConfig;
m_currentConfig = nullptr;
if (m_selectedTests.isEmpty()) {
if (m_fakeFutureInterface)
m_fakeFutureInterface->reportFinished();
onFinished();
} else {
onProcessFinished();
}
if (!currentConfigValid())
return;
}
if (!m_currentConfig->project())
onProcessFinished();
m_currentProcess = new QProcess;
m_currentProcess->setReadChannel(QProcess::StandardOutput);
m_currentProcess->setProgram(commandFilePath);
setUpProcess();
QTC_ASSERT(m_currentProcess, onProcessFinished(); return);
QTC_ASSERT(!m_currentOutputReader, delete m_currentOutputReader);
m_currentOutputReader = m_currentConfig->outputReader(*m_fakeFutureInterface, m_currentProcess);
QTC_ASSERT(m_currentOutputReader, onProcessFinished();return);
@@ -208,26 +262,7 @@ void TestRunner::scheduleNext()
connect(m_currentOutputReader, &TestOutputReader::newOutputLineAvailable,
TestResultsPane::instance(), &TestResultsPane::addOutputLine);
QStringList omitted;
m_currentProcess->setArguments(m_currentConfig->argumentsForTestRunner(&omitted));
if (!omitted.isEmpty()) {
const QString &details = constructOmittedDetailsString(omitted);
reportResult(ResultType::MessageWarn, details.arg(m_currentConfig->displayName()));
}
m_currentProcess->setWorkingDirectory(m_currentConfig->workingDirectory());
const Utils::Environment &original = m_currentConfig->environment();
Utils::Environment environment = m_currentConfig->filteredEnvironment(original);
const Utils::EnvironmentItems removedVariables = Utils::filtered(
original.diff(environment), [](const Utils::EnvironmentItem &it) {
return it.operation == Utils::EnvironmentItem::Unset;
});
if (!removedVariables.isEmpty()) {
const QString &details = constructOmittedVariablesDetailsString(removedVariables)
.arg(m_currentConfig->displayName());
reportResult(ResultType::MessageWarn, details);
}
m_currentProcess->setProcessEnvironment(environment.toProcessEnvironment());
setUpProcessEnv();
connect(m_currentProcess, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
this, &TestRunner::onProcessFinished);
@@ -432,7 +467,9 @@ int TestRunner::precheckTestConfigurations()
{
const bool omitWarnings = AutotestPlugin::settings()->omitRunConfigWarn;
int testCaseCount = 0;
for (TestConfiguration *config : m_selectedTests) {
for (ITestConfiguration *itc : qAsConst(m_selectedTests)) {
// FIXME handle test tools
TestConfiguration *config = static_cast<TestConfiguration *>(itc);
config->completeTestInformation(TestRunMode::Run);
if (config->project()) {
testCaseCount += config->testCaseCount();
@@ -441,7 +478,7 @@ int TestRunner::precheckTestConfigurations()
"Project's run configuration was deduced for \"%1\".\n"
"This might cause trouble during execution.\n"
"(deduced from \"%2\")");
message = message.arg(config->displayName()).arg(config->runConfigDisplayName());
message = message.arg(config->displayName(), config->runConfigDisplayName());
reportResult(ResultType::MessageWarn, message);
}
} else {
@@ -466,9 +503,11 @@ void TestRunner::onBuildSystemUpdated()
void TestRunner::runTests()
{
QList<TestConfiguration *> toBeRemoved;
QList<ITestConfiguration *> toBeRemoved;
bool projectChanged = false;
for (TestConfiguration *config : m_selectedTests) {
for (ITestConfiguration *itc : qAsConst(m_selectedTests)) {
// FIXME handle test tools
TestConfiguration *config = static_cast<TestConfiguration *>(itc);
config->completeTestInformation(TestRunMode::Run);
if (!config->project()) {
projectChanged = true;
@@ -480,7 +519,7 @@ void TestRunner::runTests()
toBeRemoved.append(config);
}
}
for (TestConfiguration *config : toBeRemoved)
for (ITestConfiguration *config : toBeRemoved)
m_selectedTests.removeOne(config);
qDeleteAll(toBeRemoved);
toBeRemoved.clear();
@@ -540,7 +579,9 @@ void TestRunner::debugTests()
// TODO improve to support more than one test configuration
QTC_ASSERT(m_selectedTests.size() == 1, onFinished();return);
TestConfiguration *config = m_selectedTests.first();
ITestConfiguration *itc = m_selectedTests.first();
// FIXME handle test tools as well
TestConfiguration *config = static_cast<TestConfiguration *>(itc);
config->completeTestInformation(TestRunMode::Debug);
if (!config->project()) {
reportResult(ResultType::MessageWarn,
@@ -562,13 +603,11 @@ void TestRunner::debugTests()
const QString &commandFilePath = config->executableFilePath();
if (commandFilePath.isEmpty()) {
reportResult(ResultType::MessageFatal, tr("Could not find command \"%1\". (%2)")
.arg(config->executableFilePath())
.arg(config->displayName()));
.arg(config->executableFilePath(), config->displayName()));
onFinished();
return;
}
QString errorMessage;
auto runControl = new RunControl(ProjectExplorer::Constants::DEBUG_RUN_MODE);
runControl->setRunConfiguration(config->runConfiguration());

View File

@@ -46,7 +46,7 @@ namespace ProjectExplorer { class Project; }
namespace Autotest {
enum class TestRunMode;
class TestConfiguration;
class ITestConfiguration;
class TestOutputReader;
namespace Internal {
@@ -63,8 +63,8 @@ public:
static TestRunner* instance();
void setSelectedTests(const QList<TestConfiguration *> &selected);
void runTest(TestRunMode mode, const TestTreeItem *item);
void setSelectedTests(const QList<ITestConfiguration *> &selected);
void runTest(TestRunMode mode, const ITestTreeItem *item);
bool isTestRunning() const { return m_executingTests; }
void prepareToRunTests(TestRunMode mode);
@@ -84,6 +84,9 @@ private:
void onFinished();
int precheckTestConfigurations();
bool currentConfigValid();
void setUpProcess();
void setUpProcessEnv();
void scheduleNext();
void cancelCurrent(CancelReason reason);
void onProcessFinished();
@@ -98,10 +101,10 @@ private:
QFutureWatcher<TestResultPtr> m_futureWatcher;
QFutureInterface<TestResultPtr> *m_fakeFutureInterface = nullptr;
QQueue<TestConfiguration *> m_selectedTests;
QQueue<ITestConfiguration *> m_selectedTests;
bool m_executingTests = false;
bool m_canceled = false;
TestConfiguration *m_currentConfig = nullptr;
ITestConfiguration *m_currentConfig = nullptr;
QProcess *m_currentProcess = nullptr;
TestOutputReader *m_currentOutputReader = nullptr;
TestRunMode m_runMode = TestRunMode::None;

View File

@@ -151,6 +151,17 @@ bool ITestTreeItem::lessThan(const ITestTreeItem *other, ITestTreeItem::SortMode
return true;
}
ITestConfiguration *ITestTreeItem::asConfiguration(TestRunMode mode) const
{
switch (mode) {
case TestRunMode::Run:
case TestRunMode::RunWithoutDeploy:
return testConfiguration();
default:
return nullptr;
}
}
/****************************** TestTreeItem ********************************************/
TestTreeItem::TestTreeItem(ITestBase *testBase, const QString &name,
@@ -278,24 +289,20 @@ TestTreeItem *TestTreeItem::findChildByNameAndFile(const QString &name, const QS
});
}
TestConfiguration *TestTreeItem::asConfiguration(TestRunMode mode) const
ITestConfiguration *TestTreeItem::asConfiguration(TestRunMode mode) const
{
switch (mode) {
case TestRunMode::Run:
case TestRunMode::RunWithoutDeploy:
return testConfiguration();
case TestRunMode::Debug:
case TestRunMode::DebugWithoutDeploy:
return debugConfiguration();
default:
break;
return ITestTreeItem::asConfiguration(mode);
}
return nullptr;
}
QList<TestConfiguration *> TestTreeItem::getTestConfigurationsForFile(const Utils::FilePath &) const
QList<ITestConfiguration *> TestTreeItem::getTestConfigurationsForFile(const Utils::FilePath &) const
{
return QList<TestConfiguration *>();
return QList<ITestConfiguration *>();
}
bool TestTreeItem::isGroupNodeFor(const TestTreeItem *other) const

View File

@@ -49,7 +49,7 @@ namespace Autotest {
class ITestBase;
class ITestFramework;
class TestConfiguration;
class ITestConfiguration;
class TestParseResult;
enum class TestRunMode;
@@ -85,11 +85,12 @@ public:
virtual Qt::CheckState checked() const;
virtual bool canProvideTestConfiguration() const { return false; }
virtual TestConfiguration *testConfiguration() const { return nullptr; }
virtual ITestConfiguration *testConfiguration() const { return nullptr; }
virtual ITestConfiguration *asConfiguration(TestRunMode mode) const;
virtual QList<TestConfiguration *> getAllTestConfigurations() const { return {}; }
virtual QList<TestConfiguration *> getSelectedTestConfigurations() const { return {}; }
virtual QList<TestConfiguration *> getFailedTestConfigurations() const { return {}; }
virtual QList<ITestConfiguration *> getAllTestConfigurations() const { return {}; }
virtual QList<ITestConfiguration *> getSelectedTestConfigurations() const { return {}; };
virtual QList<ITestConfiguration *> getFailedTestConfigurations() const { return {}; }
const QString name() const { return m_name; }
void setName(const QString &name) { m_name = name; }
@@ -150,10 +151,10 @@ public:
TestTreeItem *findChildByFileAndType(const QString &filePath, Type type);
TestTreeItem *findChildByNameAndFile(const QString &name, const QString &filePath);
virtual TestConfiguration *debugConfiguration() const { return nullptr; }
virtual ITestConfiguration *debugConfiguration() const { return nullptr; }
virtual bool canProvideDebugConfiguration() const { return false; }
TestConfiguration *asConfiguration(TestRunMode mode) const;
virtual QList<TestConfiguration *> getTestConfigurationsForFile(const Utils::FilePath &fileName) const;
ITestConfiguration *asConfiguration(TestRunMode mode) const final;
virtual QList<ITestConfiguration *> getTestConfigurationsForFile(const Utils::FilePath &fileName) const;
virtual TestTreeItem *find(const TestParseResult *result) = 0;
virtual TestTreeItem *findChild(const TestTreeItem *other) = 0;
virtual bool modify(const TestParseResult *result) = 0;

View File

@@ -162,33 +162,35 @@ bool TestTreeModel::hasTests() const
return false;
}
QList<TestConfiguration *> TestTreeModel::getAllTestCases() const
QList<ITestConfiguration *> TestTreeModel::getAllTestCases() const
{
QList<TestConfiguration *> result;
QList<ITestConfiguration *> result;
for (Utils::TreeItem *frameworkRoot : *rootItem())
result.append(static_cast<ITestTreeItem *>(frameworkRoot)->getAllTestConfigurations());
return result;
}
QList<TestConfiguration *> TestTreeModel::getSelectedTests() const
QList<ITestConfiguration *> TestTreeModel::getSelectedTests() const
{
QList<TestConfiguration *> result;
QList<ITestConfiguration *> result;
for (Utils::TreeItem *frameworkRoot : *rootItem())
result.append(static_cast<ITestTreeItem *>(frameworkRoot)->getSelectedTestConfigurations());
return result;
}
QList<TestConfiguration *> TestTreeModel::getFailedTests() const
QList<ITestConfiguration *> TestTreeModel::getFailedTests() const
{
QList<TestConfiguration *> result;
QList<ITestConfiguration *> result;
// FIXME limit to frameworks
for (Utils::TreeItem *frameworkRoot : *rootItem())
result.append(static_cast<ITestTreeItem *>(frameworkRoot)->getFailedTestConfigurations());
return result;
}
QList<TestConfiguration *> TestTreeModel::getTestsForFile(const Utils::FilePath &fileName) const
QList<ITestConfiguration *> TestTreeModel::getTestsForFile(const Utils::FilePath &fileName) const
{
QList<TestConfiguration *> result;
QList<ITestConfiguration *> result;
// FIXME limit to frameworks
for (Utils::TreeItem *frameworkRoot : *rootItem())
result.append(static_cast<TestTreeItem *>(frameworkRoot)->getTestConfigurationsForFile(fileName));
return result;

View File

@@ -60,10 +60,10 @@ public:
Internal::TestCodeParser *parser() const { return m_parser; }
bool hasTests() const;
QList<TestConfiguration *> getAllTestCases() const;
QList<TestConfiguration *> getSelectedTests() const;
QList<TestConfiguration *> getFailedTests() const;
QList<TestConfiguration *> getTestsForFile(const Utils::FilePath &fileName) const;
QList<ITestConfiguration *> getAllTestCases() const;
QList<ITestConfiguration *> getSelectedTests() const;
QList<ITestConfiguration *> getFailedTests() const;
QList<ITestConfiguration *> getTestsForFile(const Utils::FilePath &fileName) const;
QList<TestTreeItem *> testItemsByName(const QString &testName);
void synchronizeTestFrameworks();
void rebuild(const QList<Utils::Id> &frameworkIds);