AutoTest: Introduce ITestTreeItem

Preparation for having separated test tree items with a
common base.

Change-Id: I3735f582cc96910e971f5a41c799cc0729a10a58
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Christian Stenger
2020-10-12 14:11:10 +02:00
parent b057ea1ab8
commit 55298cc211
14 changed files with 313 additions and 256 deletions

View File

@@ -286,7 +286,7 @@ TestConfiguration *BoostTestTreeItem::testConfiguration() const
if (itemType == TestSuite || itemType == TestCase) { if (itemType == TestSuite || itemType == TestCase) {
QStringList testCases; QStringList testCases;
if (itemType == TestSuite) { if (itemType == TestSuite) {
forFirstLevelChildren([&testCases](TestTreeItem *child) { forFirstLevelChildItems([&testCases](TestTreeItem *child) {
QTC_ASSERT(child, return); QTC_ASSERT(child, return);
if (auto boostItem = static_cast<BoostTestTreeItem *>(child)) { if (auto boostItem = static_cast<BoostTestTreeItem *>(child)) {
if (boostItem->enabled()) { if (boostItem->enabled()) {

View File

@@ -89,7 +89,7 @@ TestTreeItem *CatchTreeItem::find(const TestParseResult *result)
if (static_cast<CatchFramework *>(result->base)->grouping()) { if (static_cast<CatchFramework *>(result->base)->grouping()) {
const QString path = QFileInfo(result->fileName).absolutePath(); const QString path = QFileInfo(result->fileName).absolutePath();
for (int row = 0; row < childCount(); ++row) { for (int row = 0; row < childCount(); ++row) {
TestTreeItem *group = childAt(row); TestTreeItem *group = childItem(row);
if (group->filePath() != path) if (group->filePath() != path)
continue; continue;
if (auto groupChild = group->findChildByFile(result->fileName)) if (auto groupChild = group->findChildByFile(result->fileName))
@@ -192,7 +192,7 @@ static void collectTestInfo(const TestTreeItem *item,
QTC_ASSERT(item, return); QTC_ASSERT(item, return);
const int childCount = item->childCount(); const int childCount = item->childCount();
if (item->type() == TestTreeItem::GroupNode) { if (item->type() == TestTreeItem::GroupNode) {
item->forFirstLevelChildren([&testCasesForProfile, ignoreCheckState](TestTreeItem *it) { item->forFirstLevelChildItems([&testCasesForProfile, ignoreCheckState](TestTreeItem *it) {
collectTestInfo(it, testCasesForProfile, ignoreCheckState); collectTestInfo(it, testCasesForProfile, ignoreCheckState);
}); });
return; return;
@@ -201,14 +201,14 @@ 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 QString &projectFile = item->childAt(0)->proFile(); const QString &projectFile = item->childItem(0)->proFile();
item->forAllChildren([&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());
}); });
testCasesForProfile[projectFile].internalTargets.unite(item->internalTargets()); testCasesForProfile[projectFile].internalTargets.unite(item->internalTargets());
} else if (item->checked() == Qt::PartiallyChecked) { } else if (item->checked() == Qt::PartiallyChecked) {
item->forFirstLevelChildren([&testCasesForProfile](TestTreeItem *child) { item->forFirstLevelChildItems([&testCasesForProfile](TestTreeItem *child) {
QTC_ASSERT(child->type() == TestTreeItem::TestCase, return); QTC_ASSERT(child->type() == TestTreeItem::TestCase, return);
if (child->checked() == Qt::Checked) { if (child->checked() == Qt::Checked) {
CatchTreeItem *current = static_cast<CatchTreeItem *>(child); CatchTreeItem *current = static_cast<CatchTreeItem *>(child);
@@ -227,7 +227,7 @@ static void collectFailedTestInfo(const CatchTreeItem *item,
QTC_ASSERT(item, return); QTC_ASSERT(item, return);
QTC_ASSERT(item->type() == TestTreeItem::Root, return); QTC_ASSERT(item->type() == TestTreeItem::Root, return);
item->forAllChildren([&testCasesForProfile](TestTreeItem *it) { item->forAllChildItems([&testCasesForProfile](TestTreeItem *it) {
QTC_ASSERT(it, return); QTC_ASSERT(it, return);
CatchTreeItem *parent = static_cast<CatchTreeItem *>(it->parentItem()); CatchTreeItem *parent = static_cast<CatchTreeItem *>(it->parentItem());
QTC_ASSERT(parent, return); QTC_ASSERT(parent, return);
@@ -283,7 +283,7 @@ QList<TestConfiguration *> CatchTreeItem::getTestConfigurationsForFile(const Uti
const QString filePath = fileName.toString(); const QString filePath = fileName.toString();
for (int row = 0, count = childCount(); row < count; ++row) { for (int row = 0, count = childCount(); row < count; ++row) {
const TestTreeItem *item = childAt(row); const TestTreeItem *item = childItem(row);
QTC_ASSERT(item, continue); QTC_ASSERT(item, continue);
if (childAt(row)->name() != filePath) if (childAt(row)->name() != filePath)
@@ -292,7 +292,7 @@ QList<TestConfiguration *> CatchTreeItem::getTestConfigurationsForFile(const Uti
CatchConfiguration *testConfig = nullptr; CatchConfiguration *testConfig = nullptr;
QStringList testCases; QStringList testCases;
item->forFirstLevelChildren([&testCases](TestTreeItem *child) { item->forFirstLevelChildItems([&testCases](TestTreeItem *child) {
CatchTreeItem *current = static_cast<CatchTreeItem *>(child); CatchTreeItem *current = static_cast<CatchTreeItem *>(child);
testCases << current->testCasesString(); testCases << current->testCasesString();
}); });
@@ -326,9 +326,8 @@ QList<TestConfiguration *> CatchTreeItem::getTestConfigurations(bool ignoreCheck
return result; return result;
QHash<QString, CatchTestCases> testCasesForProfile; QHash<QString, CatchTestCases> testCasesForProfile;
forFirstLevelChildren([&testCasesForProfile, ignoreCheckState](TestTreeItem *item) { for (int row = 0, end = childCount(); row < end; ++row)
collectTestInfo(item, testCasesForProfile, ignoreCheckState); collectTestInfo(childItem(row), testCasesForProfile, ignoreCheckState);
});
for (auto it = testCasesForProfile.begin(), end = testCasesForProfile.end(); it != end; ++it) { for (auto it = testCasesForProfile.begin(), end = testCasesForProfile.end(); it != end; ++it) {
for (const QString &target : qAsConst(it.value().internalTargets)) { for (const QString &target : qAsConst(it.value().internalTargets)) {

View File

@@ -230,13 +230,13 @@ 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 QString &projectFile = item->childAt(0)->proFile(); const QString &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;
testCasesForProFile[projectFile].internalTargets.unite(item->internalTargets()); testCasesForProFile[projectFile].internalTargets.unite(item->internalTargets());
} else if (item->checked() == Qt::PartiallyChecked) { } else if (item->checked() == Qt::PartiallyChecked) {
item->forFirstLevelChildren([&testCasesForProFile, item](TestTreeItem *child){ item->forFirstLevelChildItems([&testCasesForProFile, item](TestTreeItem *child){
QTC_ASSERT(child->type() == TestTreeItem::TestCase, return); QTC_ASSERT(child->type() == TestTreeItem::TestCase, return);
if (child->checked() == Qt::Checked) { if (child->checked() == Qt::Checked) {
testCasesForProFile[child->proFile()].filters.append( testCasesForProFile[child->proFile()].filters.append(
@@ -254,7 +254,7 @@ static void collectFailedTestInfo(const GTestTreeItem *item,
QTC_ASSERT(item, return); QTC_ASSERT(item, return);
QTC_ASSERT(item->type() == TestTreeItem::Root, return); QTC_ASSERT(item->type() == TestTreeItem::Root, return);
item->forAllChildren([&testCasesForProfile](TestTreeItem *it) { item->forAllChildItems([&testCasesForProfile](TestTreeItem *it) {
QTC_ASSERT(it, return); QTC_ASSERT(it, return);
GTestTreeItem *parent = static_cast<GTestTreeItem *>(it->parentItem()); GTestTreeItem *parent = static_cast<GTestTreeItem *>(it->parentItem());
QTC_ASSERT(parent, return); QTC_ASSERT(parent, return);
@@ -340,7 +340,7 @@ QList<TestConfiguration *> GTestTreeItem::getTestConfigurationsForFile(const Uti
QHash<QString, GTestCases> testCases; QHash<QString, GTestCases> testCases;
const QString &file = fileName.toString(); const QString &file = fileName.toString();
forAllChildren([&testCases, &file](TestTreeItem *node) { forAllChildItems([&testCases, &file](TestTreeItem *node) {
if (node->type() == Type::TestCase && node->filePath() == file) { if (node->type() == Type::TestCase && node->filePath() == file) {
QTC_ASSERT(node->parentItem(), return); QTC_ASSERT(node->parentItem(), return);
const GTestTreeItem *testCase = static_cast<GTestTreeItem *>(node->parentItem()); const GTestTreeItem *testCase = static_cast<GTestTreeItem *>(node->parentItem());
@@ -469,7 +469,7 @@ TestTreeItem *GTestTreeItem::createParentGroupNode() const
return new GTestTreeItem(framework(), base.baseName(), fileInfo.absolutePath(), TestTreeItem::GroupNode); return new GTestTreeItem(framework(), base.baseName(), fileInfo.absolutePath(), TestTreeItem::GroupNode);
} else { // GTestFilter } else { // GTestFilter
QTC_ASSERT(childCount(), return nullptr); // paranoia QTC_ASSERT(childCount(), return nullptr); // paranoia
const TestTreeItem *firstChild = childAt(0); const TestTreeItem *firstChild = childItem(0);
const QString activeFilter = GTestFramework::currentGTestFilter(); const QString activeFilter = GTestFramework::currentGTestFilter();
const QString fullTestName = name() + '.' + firstChild->name(); const QString fullTestName = name() + '.' + firstChild->name();
const QString groupNodeName = const QString groupNodeName =
@@ -497,7 +497,7 @@ TestTreeItem *GTestTreeItem::findChildByNameStateAndFile(const QString &name,
GTestTreeItem::TestStates state, GTestTreeItem::TestStates state,
const QString &proFile) const const QString &proFile) const
{ {
return findFirstLevelChild([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);
return other->proFile() == proFile && other->name() == name && gtestItem->state() == state; return other->proFile() == proFile && other->name() == name && gtestItem->state() == state;
}); });

View File

@@ -38,7 +38,7 @@ template<class T>
class ItemDataCache class ItemDataCache
{ {
public: public:
void insert(TestTreeItem *item, const T &value) { m_cache[item->cacheName()] = {0, value}; } void insert(ITestTreeItem *item, const T &value) { m_cache[item->cacheName()] = {0, value}; }
void evolve() void evolve()
{ {
auto it = m_cache.begin(), end = m_cache.end(); auto it = m_cache.begin(), end = m_cache.end();
@@ -46,7 +46,7 @@ public:
it = it->generation++ >= maxGen ? m_cache.erase(it) : ++it; it = it->generation++ >= maxGen ? m_cache.erase(it) : ++it;
} }
Utils::optional<T> get(TestTreeItem *item) Utils::optional<T> get(ITestTreeItem *item)
{ {
auto entry = m_cache.find(item->cacheName()); auto entry = m_cache.find(item->cacheName());
if (entry == m_cache.end()) if (entry == m_cache.end())

View File

@@ -53,10 +53,10 @@ QHash<QString, QString> testCaseNamesForFiles(ITestFramework *framework, const Q
TestTreeItem *rootNode = framework->rootNode(); TestTreeItem *rootNode = framework->rootNode();
QTC_ASSERT(rootNode, return result); QTC_ASSERT(rootNode, return result);
rootNode->forFirstLevelChildren([&result, &files](TestTreeItem *child) { rootNode->forFirstLevelChildren([&result, &files](ITestTreeItem *child) {
if (files.contains(child->filePath())) if (files.contains(child->filePath()))
result.insert(child->filePath(), child->name()); result.insert(child->filePath(), child->name());
child->forFirstLevelChildren([&result, &files, child](TestTreeItem *grandChild) { child->forFirstLevelChildren([&result, &files, child](ITestTreeItem *grandChild) {
if (files.contains(grandChild->filePath())) if (files.contains(grandChild->filePath()))
result.insert(grandChild->filePath(), child->name()); result.insert(grandChild->filePath(), child->name());
}); });
@@ -70,7 +70,7 @@ QMultiHash<QString, QString> alternativeFiles(ITestFramework *framework, const Q
TestTreeItem *rootNode = framework->rootNode(); TestTreeItem *rootNode = framework->rootNode();
QTC_ASSERT(rootNode, return result); QTC_ASSERT(rootNode, return result);
rootNode->forFirstLevelChildren([&result, &files](TestTreeItem *child) { rootNode->forFirstLevelChildren([&result, &files](ITestTreeItem *child) {
const QString &baseFilePath = child->filePath(); const QString &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));

View File

@@ -154,7 +154,7 @@ static void fillTestConfigurationsFromCheckState(const TestTreeItem *item,
QTC_ASSERT(item, return); QTC_ASSERT(item, return);
if (item->type() == TestTreeItem::GroupNode) { if (item->type() == TestTreeItem::GroupNode) {
for (int row = 0, count = item->childCount(); row < count; ++row) for (int row = 0, count = item->childCount(); row < count; ++row)
fillTestConfigurationsFromCheckState(item->childAt(row), testConfigurations); fillTestConfigurationsFromCheckState(item->childItem(row), testConfigurations);
return; return;
} }
QTC_ASSERT(item->type() == TestTreeItem::TestCase, return); QTC_ASSERT(item->type() == TestTreeItem::TestCase, return);
@@ -169,12 +169,12 @@ static void fillTestConfigurationsFromCheckState(const TestTreeItem *item,
return; return;
case Qt::PartiallyChecked: case Qt::PartiallyChecked:
QStringList testCases; QStringList testCases;
item->forFirstLevelChildren([&testCases](TestTreeItem *grandChild) { item->forFirstLevelChildren([&testCases](ITestTreeItem *grandChild) {
if (grandChild->checked() == Qt::Checked) { if (grandChild->checked() == Qt::Checked) {
testCases << grandChild->name(); testCases << grandChild->name();
} else if (grandChild->checked() == Qt::PartiallyChecked) { } else if (grandChild->checked() == Qt::PartiallyChecked) {
const QString funcName = grandChild->name(); const QString funcName = grandChild->name();
grandChild->forFirstLevelChildren([&testCases, &funcName](TestTreeItem *dataTag) { grandChild->forFirstLevelChildren([&testCases, &funcName](ITestTreeItem *dataTag) {
if (dataTag->checked() == Qt::Checked) if (dataTag->checked() == Qt::Checked)
testCases << funcName + ':' + dataTag->name(); testCases << funcName + ':' + dataTag->name();
}); });
@@ -195,16 +195,16 @@ static void collectFailedTestInfo(TestTreeItem *item, QList<TestConfiguration *>
QTC_ASSERT(item, return); QTC_ASSERT(item, return);
if (item->type() == TestTreeItem::GroupNode) { if (item->type() == TestTreeItem::GroupNode) {
for (int row = 0, count = item->childCount(); row < count; ++row) for (int row = 0, count = item->childCount(); row < count; ++row)
collectFailedTestInfo(item->childAt(row), testConfigs); collectFailedTestInfo(item->childItem(row), testConfigs);
return; return;
} }
QTC_ASSERT(item->type() == TestTreeItem::TestCase, return); QTC_ASSERT(item->type() == TestTreeItem::TestCase, return);
QStringList testCases; QStringList testCases;
item->forFirstLevelChildren([&testCases](TestTreeItem *func) { item->forFirstLevelChildren([&testCases](ITestTreeItem *func) {
if (func->data(0, FailedRole).toBool()) { if (func->data(0, FailedRole).toBool()) {
testCases << func->name(); testCases << func->name();
} else { } else {
func->forFirstLevelChildren([&testCases, func](TestTreeItem *dataTag) { func->forFirstLevelChildren([&testCases, func](ITestTreeItem *dataTag) {
if (dataTag->data(0, FailedRole).toBool()) if (dataTag->data(0, FailedRole).toBool())
testCases << func->name() + ':' + dataTag->name(); testCases << func->name() + ':' + dataTag->name();
}); });
@@ -237,13 +237,13 @@ QList<TestConfiguration *> QtTestTreeItem::getAllTestConfigurations() const
if (!project || type() != Root) if (!project || type() != Root)
return result; return result;
forFirstLevelChildren([&result](TestTreeItem *child) { forFirstLevelChildren([&result](ITestTreeItem *child) {
if (child->type() == TestCase) { if (child->type() == TestCase) {
TestConfiguration *tc = child->testConfiguration(); TestConfiguration *tc = child->testConfiguration();
QTC_ASSERT(tc, return); QTC_ASSERT(tc, return);
result << tc; result << tc;
} else if (child->type() == GroupNode) { } else if (child->type() == GroupNode) {
child->forFirstLevelChildren([&result](TestTreeItem *groupChild) { child->forFirstLevelChildren([&result](ITestTreeItem *groupChild) {
TestConfiguration *tc = groupChild->testConfiguration(); TestConfiguration *tc = groupChild->testConfiguration();
QTC_ASSERT(tc, return); QTC_ASSERT(tc, return);
result << tc; result << tc;
@@ -261,7 +261,7 @@ QList<TestConfiguration *> QtTestTreeItem::getSelectedTestConfigurations() const
return result; return result;
for (int row = 0, count = childCount(); row < count; ++row) for (int row = 0, count = childCount(); row < count; ++row)
fillTestConfigurationsFromCheckState(childAt(row), result); fillTestConfigurationsFromCheckState(childItem(row), result);
return result; return result;
} }
@@ -270,9 +270,8 @@ QList<TestConfiguration *> QtTestTreeItem::getFailedTestConfigurations() const
{ {
QList<TestConfiguration *> result; QList<TestConfiguration *> result;
QTC_ASSERT(type() == TestTreeItem::Root, return result); QTC_ASSERT(type() == TestTreeItem::Root, return result);
forFirstLevelChildren([&result](TestTreeItem *child) { for (int row = 0, end = childCount(); row < end; ++row)
collectFailedTestInfo(child, result); collectFailedTestInfo(childItem(row), result);
});
return result; return result;
} }
@@ -286,7 +285,7 @@ QList<TestConfiguration *> QtTestTreeItem::getTestConfigurationsForFile(const Ut
QHash<TestTreeItem *, QStringList> testFunctions; QHash<TestTreeItem *, QStringList> testFunctions;
const QString &file = fileName.toString(); const QString &file = fileName.toString();
forAllChildren([&testFunctions, &file](TestTreeItem *node) { forAllChildItems([&testFunctions, &file](TestTreeItem *node) {
if (node->type() == Type::TestFunction && node->filePath() == file) { if (node->type() == Type::TestFunction && node->filePath() == file) {
QTC_ASSERT(node->parentItem(), return); QTC_ASSERT(node->parentItem(), return);
TestTreeItem *testCase = node->parentItem(); TestTreeItem *testCase = node->parentItem();
@@ -314,7 +313,7 @@ TestTreeItem *QtTestTreeItem::find(const TestParseResult *result)
if (static_cast<QtTestFramework *>(result->base)->grouping()) { if (static_cast<QtTestFramework *>(result->base)->grouping()) {
const QString path = QFileInfo(result->fileName).absolutePath(); const QString path = QFileInfo(result->fileName).absolutePath();
for (int row = 0; row < childCount(); ++row) { for (int row = 0; row < childCount(); ++row) {
TestTreeItem *group = childAt(row); TestTreeItem *group = childItem(row);
if (group->filePath() != path) if (group->filePath() != path)
continue; continue;
if (auto groupChild = group->findChildByFile(result->fileName)) if (auto groupChild = group->findChildByFile(result->fileName))
@@ -394,7 +393,7 @@ bool QtTestTreeItem::isGroupable() const
TestTreeItem *QtTestTreeItem::findChildByNameAndInheritance(const QString &name, bool inherited) const TestTreeItem *QtTestTreeItem::findChildByNameAndInheritance(const QString &name, bool inherited) const
{ {
return findFirstLevelChild([name, inherited](const TestTreeItem *other) { return findFirstLevelChildItem([name, inherited](const TestTreeItem *other) {
const QtTestTreeItem *qtOther = static_cast<const QtTestTreeItem *>(other); const QtTestTreeItem *qtOther = static_cast<const QtTestTreeItem *>(other);
return qtOther->inherited() == inherited && qtOther->name() == name; return qtOther->inherited() == inherited && qtOther->name() == name;
}); });

View File

@@ -52,14 +52,14 @@ QHash<QString, QString> proFilesForQmlFiles(ITestFramework *framework, const QSt
if (files.isEmpty()) if (files.isEmpty())
return result; return result;
rootNode->forFirstLevelChildren([&result, &files](TestTreeItem *child) { rootNode->forFirstLevelChildItems([&result, &files](TestTreeItem *child) {
const QString &file = child->filePath(); const QString &file = child->filePath();
if (!file.isEmpty() && files.contains(file)) { if (!file.isEmpty() && files.contains(file)) {
const QString &proFile = child->proFile(); const QString &proFile = child->proFile();
if (!proFile.isEmpty()) if (!proFile.isEmpty())
result.insert(file, proFile); result.insert(file, proFile);
} }
child->forFirstLevelChildren([&result, &files](TestTreeItem *grandChild) { child->forFirstLevelChildItems([&result, &files](TestTreeItem *grandChild) {
const QString &file = grandChild->filePath(); const QString &file = grandChild->filePath();
if (!file.isEmpty() && files.contains(file)) { if (!file.isEmpty() && files.contains(file)) {
const QString &proFile = grandChild->proFile(); const QString &proFile = grandChild->proFile();

View File

@@ -133,7 +133,7 @@ TestConfiguration *QuickTestTreeItem::testConfiguration() const
case TestCase: { case TestCase: {
const QString testName = name(); const QString testName = name();
QStringList testFunctions; QStringList testFunctions;
forFirstLevelChildren([&testFunctions, &testName](TestTreeItem *child) { forFirstLevelChildren([&testFunctions, &testName](ITestTreeItem *child) {
if (child->type() == TestTreeItem::TestFunction) if (child->type() == TestTreeItem::TestFunction)
testFunctions << testName + "::" + child->name(); testFunctions << testName + "::" + child->name();
}); });
@@ -177,7 +177,7 @@ static QList<TestConfiguration *> testConfigurationsFor(
const QString name = treeItem->name(); const QString name = treeItem->name();
QStringList functions; QStringList functions;
treeItem->forFirstLevelChildren([&functions, &name, &predicate](TestTreeItem *child) { treeItem->forFirstLevelChildItems([&functions, &name, &predicate](TestTreeItem *child) {
if (predicate(child)) if (predicate(child))
functions << name + "::" + child->name(); functions << name + "::" + child->name();
}); });
@@ -228,10 +228,10 @@ QList<TestConfiguration *> QuickTestTreeItem::getAllTestConfigurations() const
return result; return result;
QHash<QString, Tests> testsForProfile; QHash<QString, Tests> testsForProfile;
forFirstLevelChildren([&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->forFirstLevelChildren([&testsForProfile](TestTreeItem *grandChild) { child->forFirstLevelChildItems([&testsForProfile](TestTreeItem *grandChild) {
const QString &proFile = grandChild->proFile(); const QString &proFile = grandChild->proFile();
++(testsForProfile[proFile].testCount); ++(testsForProfile[proFile].testCount);
testsForProfile[proFile].internalTargets = grandChild->internalTargets(); testsForProfile[proFile].internalTargets = grandChild->internalTargets();
@@ -242,7 +242,7 @@ QList<TestConfiguration *> QuickTestTreeItem::getAllTestConfigurations() const
if (child->type() == TestCase) { if (child->type() == TestCase) {
addTestsForItem(testsForProfile[child->proFile()], child); addTestsForItem(testsForProfile[child->proFile()], child);
} else if (child->type() == GroupNode) { } else if (child->type() == GroupNode) {
child->forFirstLevelChildren([&testsForProfile](TestTreeItem *grandChild) { child->forFirstLevelChildItems([&testsForProfile](TestTreeItem *grandChild) {
addTestsForItem(testsForProfile[grandChild->proFile()], grandChild); addTestsForItem(testsForProfile[grandChild->proFile()], grandChild);
}); });
} }
@@ -292,7 +292,7 @@ TestTreeItem *QuickTestTreeItem::find(const TestParseResult *result)
return unnamedQuickTests(); return unnamedQuickTests();
if (static_cast<QuickTestFramework *>(result->base)->grouping()) { if (static_cast<QuickTestFramework *>(result->base)->grouping()) {
const QString path = QFileInfo(result->fileName).absolutePath(); const QString path = QFileInfo(result->fileName).absolutePath();
TestTreeItem *group = findFirstLevelChild([path](TestTreeItem *group) { TestTreeItem *group = findFirstLevelChildItem([path](TestTreeItem *group) {
return group->filePath() == path; return group->filePath() == path;
}); });
return group ? group->findChildByNameAndFile(result->name, result->fileName) : nullptr; return group ? group->findChildByNameAndFile(result->name, result->fileName) : nullptr;
@@ -348,14 +348,14 @@ bool QuickTestTreeItem::modify(const TestParseResult *result)
} }
} }
bool QuickTestTreeItem::lessThan(const TestTreeItem *other, TestTreeItem::SortMode mode) const bool QuickTestTreeItem::lessThan(const ITestTreeItem *other, TestTreeItem::SortMode mode) const
{ {
// handle special item (<unnamed>) // handle special item (<unnamed>)
if (name().isEmpty()) if (name().isEmpty())
return false; return false;
if (other->name().isEmpty()) if (other->name().isEmpty())
return true; return true;
return TestTreeItem::lessThan(other, mode); return ITestTreeItem::lessThan(other, mode);
} }
bool QuickTestTreeItem::isGroupNodeFor(const TestTreeItem *other) const bool QuickTestTreeItem::isGroupNodeFor(const TestTreeItem *other) const
@@ -405,7 +405,7 @@ void QuickTestTreeItem::markForRemovalRecursively(const QString &filePath)
const QString proFile = parser->projectFileForMainCppFile(filePath); const QString proFile = parser->projectFileForMainCppFile(filePath);
if (!proFile.isEmpty()) { if (!proFile.isEmpty()) {
TestTreeItem *root = framework()->rootNode(); TestTreeItem *root = framework()->rootNode();
root->forAllChildren([proFile](TestTreeItem *it) { root->forAllChildItems([proFile](TestTreeItem *it) {
if (it->proFile() == proFile) if (it->proFile() == proFile)
it->markForRemoval(true); it->markForRemoval(true);
}); });
@@ -417,7 +417,7 @@ TestTreeItem *QuickTestTreeItem::findChildByFileNameAndType(const QString &fileP
TestTreeItem::Type tType) TestTreeItem::Type tType)
{ {
return findFirstLevelChild([filePath, name, tType](const TestTreeItem *other) { return findFirstLevelChildItem([filePath, name, tType](const TestTreeItem *other) {
return other->type() == tType && other->name() == name && other->filePath() == filePath; return other->type() == tType && other->name() == name && other->filePath() == filePath;
}); });
} }
@@ -425,7 +425,7 @@ TestTreeItem *QuickTestTreeItem::findChildByFileNameAndType(const QString &fileP
TestTreeItem *QuickTestTreeItem::findChildByNameFileAndLine(const QString &name, TestTreeItem *QuickTestTreeItem::findChildByNameFileAndLine(const QString &name,
const QString &filePath, int line) const QString &filePath, int line)
{ {
return findFirstLevelChild([name, filePath, line](const TestTreeItem *other) { return findFirstLevelChildItem([name, filePath, line](const TestTreeItem *other) {
return other->filePath() == filePath && other->line() == line && other->name() == name; return other->filePath() == filePath && other->line() == line && other->name() == name;
}); });
} }
@@ -435,7 +435,7 @@ TestTreeItem *QuickTestTreeItem::unnamedQuickTests() const
if (type() != Root) if (type() != Root)
return nullptr; return nullptr;
return findFirstLevelChild([](TestTreeItem *child) { return child->name().isEmpty(); }); return findFirstLevelChildItem([](TestTreeItem *child) { return child->name().isEmpty(); });
} }
} // namespace Internal } // namespace Internal

View File

@@ -54,7 +54,7 @@ public:
TestTreeItem *find(const TestParseResult *result) override; TestTreeItem *find(const TestParseResult *result) override;
TestTreeItem *findChild(const TestTreeItem *other) override; TestTreeItem *findChild(const TestTreeItem *other) override;
bool modify(const TestParseResult *result) override; bool modify(const TestParseResult *result) override;
bool lessThan(const TestTreeItem *other, SortMode mode) const override; bool lessThan(const ITestTreeItem *other, SortMode mode) const override;
bool isGroupNodeFor(const TestTreeItem *other) const override; bool isGroupNodeFor(const TestTreeItem *other) const override;
bool removeOnSweepIfEmpty() const override; bool removeOnSweepIfEmpty() const override;
TestTreeItem *createParentGroupNode() const override; TestTreeItem *createParentGroupNode() const override;

View File

@@ -242,7 +242,7 @@ void TestNavigationWidget::updateExpandedStateCache()
for (Utils::TreeItem *rootNode : *m_model->rootItem()) { for (Utils::TreeItem *rootNode : *m_model->rootItem()) {
rootNode->forAllChildren([this](Utils::TreeItem *child) { rootNode->forAllChildren([this](Utils::TreeItem *child) {
m_expandedStateCache.insert(static_cast<TestTreeItem *>(child), m_expandedStateCache.insert(static_cast<ITestTreeItem *>(child),
m_view->isExpanded(child->index())); m_view->isExpanded(child->index()));
}); });
} }
@@ -322,7 +322,7 @@ void TestNavigationWidget::reapplyCachedExpandedState()
using namespace Utils; using namespace Utils;
for (TreeItem *rootNode : *m_model->rootItem()) { for (TreeItem *rootNode : *m_model->rootItem()) {
rootNode->forAllChildren([this](TreeItem *child) { rootNode->forAllChildren([this](TreeItem *child) {
optional<bool> cached = m_expandedStateCache.get(static_cast<TestTreeItem *>(child)); optional<bool> cached = m_expandedStateCache.get(static_cast<ITestTreeItem *>(child));
if (cached.has_value()) { if (cached.has_value()) {
QModelIndex index = child->index(); QModelIndex index = child->index();
if (m_view->isExpanded(index) != cached.value()) if (m_view->isExpanded(index) != cached.value())

View File

@@ -40,27 +40,6 @@
namespace Autotest { namespace Autotest {
TestTreeItem::TestTreeItem(ITestBase *testBase, const QString &name,
const QString &filePath, Type type)
: m_testBase(testBase),
m_name(name),
m_filePath(filePath),
m_type(type)
{
switch (m_type) {
case Root:
case GroupNode:
case TestSuite:
case TestCase:
case TestFunction:
m_checked = Qt::Checked;
break;
default:
m_checked = Qt::Unchecked;
break;
}
}
static QIcon testTreeIcon(TestTreeItem::Type type) static QIcon testTreeIcon(TestTreeItem::Type type)
{ {
static QIcon icons[] = { static QIcon icons[] = {
@@ -77,7 +56,15 @@ static QIcon testTreeIcon(TestTreeItem::Type type)
return icons[type]; return icons[type];
} }
QVariant TestTreeItem::data(int /*column*/, int role) const ITestTreeItem::ITestTreeItem(ITestBase *testBase, const QString &name,
const QString &filePath, Type type)
: m_testBase(testBase)
, m_name(name)
, m_filePath(filePath)
, m_type(type)
{}
QVariant ITestTreeItem::data(int /*column*/, int role) const
{ {
switch (role) { switch (role) {
case Qt::DisplayRole: case Qt::DisplayRole:
@@ -91,13 +78,6 @@ QVariant TestTreeItem::data(int /*column*/, int role) const
return testTreeIcon(m_type); return testTreeIcon(m_type);
case Qt::CheckStateRole: case Qt::CheckStateRole:
return QVariant(); return QVariant();
case LinkRole: {
if (m_type == GroupNode)
return QVariant();
QVariant itemLink;
itemLink.setValue(Utils::Link(m_filePath, int(m_line), int(m_column)));
return itemLink;
}
case ItalicRole: case ItalicRole:
return false; return false;
case TypeRole: case TypeRole:
@@ -110,7 +90,7 @@ QVariant TestTreeItem::data(int /*column*/, int role) const
return QVariant(); return QVariant();
} }
bool TestTreeItem::setData(int /*column*/, const QVariant &data, int role) bool ITestTreeItem::setData(int /*column*/, const QVariant &data, int role)
{ {
if (role == Qt::CheckStateRole) { if (role == Qt::CheckStateRole) {
Qt::CheckState old = m_checked; Qt::CheckState old = m_checked;
@@ -122,10 +102,10 @@ bool TestTreeItem::setData(int /*column*/, const QVariant &data, int role)
return false; return false;
} }
Qt::ItemFlags TestTreeItem::flags(int /*column*/) const Qt::ItemFlags ITestTreeItem::flags(int /*column*/) const
{ {
static const Qt::ItemFlags defaultFlags = Qt::ItemIsEnabled | Qt::ItemIsSelectable; static const Qt::ItemFlags defaultFlags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
switch (m_type) { switch (type()) {
case Root: case Root:
case GroupNode: case GroupNode:
return Qt::ItemIsEnabled | Qt::ItemIsAutoTristate | Qt::ItemIsUserCheckable; return Qt::ItemIsEnabled | Qt::ItemIsAutoTristate | Qt::ItemIsUserCheckable;
@@ -139,6 +119,70 @@ Qt::ItemFlags TestTreeItem::flags(int /*column*/) const
} }
} }
Qt::CheckState ITestTreeItem::checked() const
{
return m_checked;
}
bool ITestTreeItem::lessThan(const ITestTreeItem *other, ITestTreeItem::SortMode mode) const
{
const QString &lhs = data(0, Qt::DisplayRole).toString();
const QString &rhs = other->data(0, Qt::DisplayRole).toString();
switch (mode) {
case Alphabetically:
if (lhs == rhs)
return index().row() > other->index().row();
return lhs > rhs;
case Naturally: {
if (type() == GroupNode && other->type() == GroupNode)
return filePath() > other->filePath();
const Utils::Link &leftLink = data(0, LinkRole).value<Utils::Link>();
const Utils::Link &rightLink = other->data(0, LinkRole).value<Utils::Link>();
if (leftLink.targetFileName == rightLink.targetFileName) {
return leftLink.targetLine == rightLink.targetLine
? leftLink.targetColumn > rightLink.targetColumn
: leftLink.targetLine > rightLink.targetLine;
}
return leftLink.targetFileName > rightLink.targetFileName;
}
}
return true;
}
/****************************** TestTreeItem ********************************************/
TestTreeItem::TestTreeItem(ITestBase *testBase, const QString &name,
const QString &filePath, Type type)
: ITestTreeItem(testBase, name, filePath, type)
{
switch (type) {
case Root:
case GroupNode:
case TestSuite:
case TestCase:
case TestFunction:
m_checked = Qt::Checked;
break;
default:
m_checked = Qt::Unchecked;
break;
}
}
QVariant TestTreeItem::data(int column, int role) const
{
if (role == LinkRole) {
if (type() == GroupNode)
return QVariant();
QVariant itemLink;
itemLink.setValue(Utils::Link(filePath(), line(), int(m_column)));
return itemLink;
}
return ITestTreeItem::data(column, role);
}
bool TestTreeItem::modifyTestCaseOrSuiteContent(const TestParseResult *result) bool TestTreeItem::modifyTestCaseOrSuiteContent(const TestParseResult *result)
{ {
bool hasBeenModified = modifyName(result->name); bool hasBeenModified = modifyName(result->name);
@@ -164,8 +208,8 @@ bool TestTreeItem::modifyDataTagContent(const TestParseResult *result)
bool TestTreeItem::modifyLineAndColumn(const TestParseResult *result) bool TestTreeItem::modifyLineAndColumn(const TestParseResult *result)
{ {
bool hasBeenModified = false; bool hasBeenModified = false;
if (m_line != result->line) { if (line() != result->line) {
m_line = result->line; setLine(result->line);
hasBeenModified = true; hasBeenModified = true;
} }
if (m_column != result->column) { if (m_column != result->column) {
@@ -175,21 +219,6 @@ bool TestTreeItem::modifyLineAndColumn(const TestParseResult *result)
return hasBeenModified; return hasBeenModified;
} }
Qt::CheckState TestTreeItem::checked() const
{
switch (m_type) {
case Root:
case GroupNode:
case TestSuite:
case TestCase:
case TestFunction:
case TestDataTag:
return m_checked;
default:
return Qt::Unchecked;
}
}
void TestTreeItem::markForRemoval(bool mark) void TestTreeItem::markForRemoval(bool mark)
{ {
m_status = mark ? MarkedForRemoval : Cleared; m_status = mark ? MarkedForRemoval : Cleared;
@@ -199,19 +228,24 @@ void TestTreeItem::markForRemovalRecursively(bool mark)
{ {
markForRemoval(mark); markForRemoval(mark);
for (int row = 0, count = childCount(); row < count; ++row) for (int row = 0, count = childCount(); row < count; ++row)
childAt(row)->markForRemovalRecursively(mark); childItem(row)->markForRemovalRecursively(mark);
} }
void TestTreeItem::markForRemovalRecursively(const QString &filePath) void TestTreeItem::markForRemovalRecursively(const QString &filepath)
{ {
bool mark = m_filePath == filePath; bool mark = filePath() == filepath;
forFirstLevelChildren([&mark, &filePath](TestTreeItem *child) { forFirstLevelChildItems([&mark, &filepath](TestTreeItem *child) {
child->markForRemovalRecursively(filePath); child->markForRemovalRecursively(filepath);
mark &= child->markedForRemoval(); mark &= child->markedForRemoval();
}); });
markForRemoval(mark); markForRemoval(mark);
} }
TestTreeItem *TestTreeItem::childItem(int at) const
{
return static_cast<TestTreeItem *>(childAt(at));
}
TestTreeItem *TestTreeItem::parentItem() const TestTreeItem *TestTreeItem::parentItem() const
{ {
return static_cast<TestTreeItem *>(parent()); return static_cast<TestTreeItem *>(parent());
@@ -219,26 +253,27 @@ TestTreeItem *TestTreeItem::parentItem() const
TestTreeItem *TestTreeItem::findChildByName(const QString &name) TestTreeItem *TestTreeItem::findChildByName(const QString &name)
{ {
return findFirstLevelChild([name](const TestTreeItem *other) { return other->name() == name; }); return findFirstLevelChildItem([name](const TestTreeItem *other) {
return other->name() == name;
});
} }
TestTreeItem *TestTreeItem::findChildByFile(const QString &filePath) TestTreeItem *TestTreeItem::findChildByFile(const QString &filePath)
{ {
return findFirstLevelChild([filePath](const TestTreeItem *other) { return findFirstLevelChildItem([filePath](const TestTreeItem *other) {
return other->filePath() == filePath; return other->filePath() == filePath;
}); });
} }
TestTreeItem *TestTreeItem::findChildByFileAndType(const QString &filePath, Type tType) TestTreeItem *TestTreeItem::findChildByFileAndType(const QString &filePath, Type tType)
{ {
return findFirstLevelChild([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 QString &filePath) TestTreeItem *TestTreeItem::findChildByNameAndFile(const QString &name, const QString &filePath)
{ {
return findFirstLevelChild([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;
}); });
} }
@@ -258,53 +293,11 @@ TestConfiguration *TestTreeItem::asConfiguration(TestRunMode mode) const
return nullptr; return nullptr;
} }
QList<TestConfiguration *> TestTreeItem::getAllTestConfigurations() const
{
return QList<TestConfiguration *>();
}
QList<TestConfiguration *> TestTreeItem::getSelectedTestConfigurations() const
{
return QList<TestConfiguration *>();
}
QList<TestConfiguration *> TestTreeItem::getFailedTestConfigurations() const
{
return QList<TestConfiguration *>();
}
QList<TestConfiguration *> TestTreeItem::getTestConfigurationsForFile(const Utils::FilePath &) const QList<TestConfiguration *> TestTreeItem::getTestConfigurationsForFile(const Utils::FilePath &) const
{ {
return QList<TestConfiguration *>(); return QList<TestConfiguration *>();
} }
bool TestTreeItem::lessThan(const TestTreeItem *other, SortMode mode) const
{
const QString &lhs = data(0, Qt::DisplayRole).toString();
const QString &rhs = other->data(0, Qt::DisplayRole).toString();
switch (mode) {
case Alphabetically:
if (lhs == rhs)
return index().row() > other->index().row();
return lhs > rhs;
case Naturally: {
if (m_type == GroupNode && other->type() == GroupNode)
return m_filePath > other->filePath();
const Utils::Link &leftLink = data(0, LinkRole).value<Utils::Link>();
const Utils::Link &rightLink = other->data(0, LinkRole).value<Utils::Link>();
if (leftLink.targetFileName == rightLink.targetFileName) {
return leftLink.targetLine == rightLink.targetLine
? leftLink.targetColumn > rightLink.targetColumn
: leftLink.targetLine > rightLink.targetLine;
}
return leftLink.targetFileName > rightLink.targetFileName;
}
}
return true;
}
bool TestTreeItem::isGroupNodeFor(const TestTreeItem *other) const bool TestTreeItem::isGroupNodeFor(const TestTreeItem *other) const
{ {
QTC_ASSERT(other, return false); QTC_ASSERT(other, return false);
@@ -323,47 +316,74 @@ bool TestTreeItem::isGroupable() const
QSet<QString> TestTreeItem::internalTargets() const QSet<QString> TestTreeItem::internalTargets() const
{ {
auto cppMM = CppTools::CppModelManager::instance(); auto cppMM = CppTools::CppModelManager::instance();
const QList<CppTools::ProjectPart::Ptr> projectParts = cppMM->projectPart(m_filePath); const QList<CppTools::ProjectPart::Ptr> projectParts = cppMM->projectPart(filePath());
// if we have no project parts it's most likely a header with declarations only and CMake based // if we have no project parts it's most likely a header with declarations only and CMake based
if (projectParts.isEmpty()) if (projectParts.isEmpty())
return TestTreeItem::dependingInternalTargets(cppMM, m_filePath); return TestTreeItem::dependingInternalTargets(cppMM, filePath());
QSet<QString> targets; QSet<QString> targets;
for (const CppTools::ProjectPart::Ptr &part : projectParts) { for (const CppTools::ProjectPart::Ptr &part : projectParts) {
targets.insert(part->buildSystemTarget); targets.insert(part->buildSystemTarget);
if (part->buildTargetType != ProjectExplorer::BuildTargetType::Executable) if (part->buildTargetType != ProjectExplorer::BuildTargetType::Executable)
targets.unite(TestTreeItem::dependingInternalTargets(cppMM, m_filePath)); targets.unite(TestTreeItem::dependingInternalTargets(cppMM, filePath()));
} }
return targets; return targets;
} }
void TestTreeItem::forAllChildItems(const std::function<void(TestTreeItem *)> &pred) const
{
for (int row = 0, end = childCount(); row < end; ++row) {
TestTreeItem *child = childItem(row);
pred(child);
child->forAllChildItems(pred);
}
}
void TestTreeItem::forFirstLevelChildItems(const std::function<void(TestTreeItem *)> &pred) const
{
for (int row = 0, end = childCount(); row < end; ++row)
pred(childItem(row));
}
TestTreeItem *TestTreeItem::findFirstLevelChildItem(const std::function<bool(TestTreeItem *)> &pred) const
{
for (int row = 0, end = childCount(); row < end; ++row) {
TestTreeItem *child = childItem(row);
if (pred(child))
return child;
}
return nullptr;
}
void TestTreeItem::copyBasicDataFrom(const TestTreeItem *other) void TestTreeItem::copyBasicDataFrom(const TestTreeItem *other)
{ {
if (!other) if (!other)
return; return;
m_name = other->m_name;
m_filePath = other->m_filePath; setName(other->name());
m_type = other->m_type; setFilePath(other->filePath());
m_checked = other->m_checked; setType(other->type());
m_failed = other->m_failed; setLine(other->line());
m_line = other->m_line; setData(0, other->checked(), Qt::CheckStateRole);
setData(0, other->data(0, FailedRole), FailedRole);
m_column = other->m_column; m_column = other->m_column;
m_proFile = other->m_proFile; m_proFile = other->m_proFile;
m_status = other->m_status; m_status = other->m_status;
} }
inline bool TestTreeItem::modifyFilePath(const QString &filePath) inline bool TestTreeItem::modifyFilePath(const QString &filepath)
{ {
if (m_filePath != filePath) { if (filePath() != filepath) {
m_filePath = filePath; setFilePath(filepath);
return true; return true;
} }
return false; return false;
} }
inline bool TestTreeItem::modifyName(const QString &name) inline bool TestTreeItem::modifyName(const QString &newName)
{ {
if (m_name != name) { if (name() != newName) {
m_name = name; setName(newName);
return true; return true;
} }
return false; return false;
@@ -371,7 +391,7 @@ inline bool TestTreeItem::modifyName(const QString &name)
ITestFramework *TestTreeItem::framework() const ITestFramework *TestTreeItem::framework() const
{ {
return static_cast<ITestFramework *>(m_testBase); return static_cast<ITestFramework *>(testBase());
} }
/* /*

View File

@@ -53,7 +53,7 @@ class TestConfiguration;
class TestParseResult; class TestParseResult;
enum class TestRunMode; enum class TestRunMode;
class TestTreeItem : public Utils::TypedTreeItem<TestTreeItem> class ITestTreeItem : public Utils::TypedTreeItem<ITestTreeItem>
{ {
public: public:
@@ -74,6 +74,51 @@ public:
Naturally Naturally
}; };
explicit ITestTreeItem(ITestBase *testBase,
const QString &name = QString(),
const QString &filePath = QString(),
Type type = Root);
virtual QVariant data(int column, int role) const override;
virtual bool setData(int column, const QVariant &data, int role) override;
virtual Qt::ItemFlags flags(int column) const override;
virtual Qt::CheckState checked() const;
virtual bool canProvideTestConfiguration() const { return false; }
virtual TestConfiguration *testConfiguration() const { return nullptr; }
virtual QList<TestConfiguration *> getAllTestConfigurations() const { return {}; }
virtual QList<TestConfiguration *> getSelectedTestConfigurations() const { return {}; }
virtual QList<TestConfiguration *> getFailedTestConfigurations() const { return {}; }
const QString name() const { return m_name; }
void setName(const QString &name) { m_name = name; }
const QString filePath() const { return m_filePath; }
void setFilePath(const QString &filePath) { m_filePath = filePath; }
Type type() const { return m_type; }
int line() const { return m_line; }
void setLine(int line) { m_line = line;}
ITestBase *testBase() const { return m_testBase; }
virtual bool lessThan(const ITestTreeItem *other, SortMode mode) const;
QString cacheName() const { return m_filePath + ':' + m_name; }
protected:
void setType(Type type) { m_type = type; }
Qt::CheckState m_checked = Qt::Checked;
private:
ITestBase *m_testBase = nullptr; // not owned
QString m_name;
QString m_filePath;
Type m_type;
int m_line = 0;
bool m_failed = false;
};
class TestTreeItem : public ITestTreeItem
{
public:
explicit TestTreeItem(ITestBase *testBase, explicit TestTreeItem(ITestBase *testBase,
const QString &name = QString(), const QString &name = QString(),
const QString &filePath = QString(), const QString &filePath = QString(),
@@ -81,32 +126,23 @@ public:
virtual TestTreeItem *copyWithoutChildren() = 0; virtual TestTreeItem *copyWithoutChildren() = 0;
virtual QVariant data(int column, int role) const override; virtual QVariant data(int column, int role) const override;
virtual bool setData(int column, const QVariant &data, int role) override;
virtual Qt::ItemFlags flags(int column) const override;
bool modifyTestCaseOrSuiteContent(const TestParseResult *result); bool modifyTestCaseOrSuiteContent(const TestParseResult *result);
bool modifyTestFunctionContent(const TestParseResult *result); bool modifyTestFunctionContent(const TestParseResult *result);
bool modifyDataTagContent(const TestParseResult *result); bool modifyDataTagContent(const TestParseResult *result);
bool modifyLineAndColumn(const TestParseResult *result); bool modifyLineAndColumn(const TestParseResult *result);
ITestFramework *framework() const; ITestFramework *framework() const;
const QString name() const { return m_name; }
void setName(const QString &name) { m_name = name; }
const QString filePath() const { return m_filePath; }
void setFilePath(const QString &filePath) { m_filePath = filePath; }
void setLine(int line) { m_line = line;}
int line() const { return m_line; }
void setColumn(int column) { m_column = column; } void setColumn(int column) { m_column = column; }
int column() const { return m_column; } int column() const { return m_column; }
QString proFile() const { return m_proFile; } QString proFile() const { return m_proFile; }
void setProFile(const QString &proFile) { m_proFile = proFile; } void setProFile(const QString &proFile) { m_proFile = proFile; }
virtual Qt::CheckState checked() const;
Type type() const { return m_type; }
void markForRemoval(bool mark); void markForRemoval(bool mark);
void markForRemovalRecursively(bool mark); void markForRemovalRecursively(bool mark);
virtual void markForRemovalRecursively(const QString &filePath); virtual void markForRemovalRecursively(const QString &filepath);
virtual bool removeOnSweepIfEmpty() const { return m_type == GroupNode; } virtual bool removeOnSweepIfEmpty() const { return type() == GroupNode; }
bool markedForRemoval() const { return m_status == MarkedForRemoval; } bool markedForRemoval() const { return m_status == MarkedForRemoval; }
bool newlyAdded() const { return m_status == NewlyAdded; } bool newlyAdded() const { return m_status == NewlyAdded; }
TestTreeItem *childItem(int at) const;
TestTreeItem *parentItem() const; TestTreeItem *parentItem() const;
TestTreeItem *findChildByName(const QString &name); TestTreeItem *findChildByName(const QString &name);
@@ -114,16 +150,10 @@ public:
TestTreeItem *findChildByFileAndType(const QString &filePath, Type type); TestTreeItem *findChildByFileAndType(const QString &filePath, Type type);
TestTreeItem *findChildByNameAndFile(const QString &name, const QString &filePath); TestTreeItem *findChildByNameAndFile(const QString &name, const QString &filePath);
virtual bool canProvideTestConfiguration() const { return false; }
virtual bool canProvideDebugConfiguration() const { return false; }
virtual TestConfiguration *testConfiguration() const { return nullptr; }
virtual TestConfiguration *debugConfiguration() const { return nullptr; } virtual TestConfiguration *debugConfiguration() const { return nullptr; }
virtual bool canProvideDebugConfiguration() const { return false; }
TestConfiguration *asConfiguration(TestRunMode mode) const; TestConfiguration *asConfiguration(TestRunMode mode) const;
virtual QList<TestConfiguration *> getAllTestConfigurations() const;
virtual QList<TestConfiguration *> getSelectedTestConfigurations() const;
virtual QList<TestConfiguration *> getFailedTestConfigurations() const;
virtual QList<TestConfiguration *> getTestConfigurationsForFile(const Utils::FilePath &fileName) const; virtual QList<TestConfiguration *> getTestConfigurationsForFile(const Utils::FilePath &fileName) const;
virtual bool lessThan(const TestTreeItem *other, SortMode mode) const;
virtual TestTreeItem *find(const TestParseResult *result) = 0; virtual TestTreeItem *find(const TestParseResult *result) = 0;
virtual TestTreeItem *findChild(const TestTreeItem *other) = 0; virtual TestTreeItem *findChild(const TestTreeItem *other) = 0;
virtual bool modify(const TestParseResult *result) = 0; virtual bool modify(const TestParseResult *result) = 0;
@@ -137,7 +167,9 @@ public:
virtual bool shouldBeAddedAfterFiltering() const { return true; } virtual bool shouldBeAddedAfterFiltering() const { return true; }
virtual QSet<QString> internalTargets() const; virtual QSet<QString> internalTargets() const;
QString cacheName() const { return m_filePath + ':' + m_name; } void forAllChildItems(const std::function<void(TestTreeItem *)> &pred) const;
void forFirstLevelChildItems(const std::function<void(TestTreeItem *)> &pred) const;
TestTreeItem *findFirstLevelChildItem(const std::function<bool(TestTreeItem *)> &pred) const;
protected: protected:
void copyBasicDataFrom(const TestTreeItem *other); void copyBasicDataFrom(const TestTreeItem *other);
typedef std::function<bool(const TestTreeItem *)> CompareFunction; typedef std::function<bool(const TestTreeItem *)> CompareFunction;
@@ -145,7 +177,7 @@ protected:
const QString &file); const QString &file);
private: private:
bool modifyFilePath(const QString &filePath); bool modifyFilePath(const QString &filepath);
bool modifyName(const QString &name); bool modifyName(const QString &name);
enum Status enum Status
@@ -155,13 +187,6 @@ private:
Cleared Cleared
}; };
ITestBase *m_testBase = nullptr;
QString m_name;
QString m_filePath;
Qt::CheckState m_checked;
bool m_failed = false;
Type m_type;
int m_line = 0;
int m_column = 0; int m_column = 0;
QString m_proFile; QString m_proFile;
Status m_status = NewlyAdded; Status m_status = NewlyAdded;

View File

@@ -119,7 +119,7 @@ bool TestTreeModel::setData(const QModelIndex &index, const QVariant &value, int
if (!index.isValid()) if (!index.isValid())
return false; return false;
TestTreeItem *item = static_cast<TestTreeItem *>(index.internalPointer()); ITestTreeItem *item = static_cast<ITestTreeItem *>(index.internalPointer());
if (item && item->setData(index.column(), value, role)) { if (item && item->setData(index.column(), value, role)) {
emit dataChanged(index, index, {role}); emit dataChanged(index, index, {role});
if (role == Qt::CheckStateRole) { if (role == Qt::CheckStateRole) {
@@ -131,11 +131,14 @@ bool TestTreeModel::setData(const QModelIndex &index, const QVariant &value, int
setData(idx, checked ? Qt::Checked : Qt::Unchecked, Qt::CheckStateRole); setData(idx, checked ? Qt::Checked : Qt::Unchecked, Qt::CheckStateRole);
} }
} }
if (item->parent() != rootItem() && item->parentItem()->checked() != checked) if (item->parent() != rootItem()) {
revalidateCheckState(item->parentItem()); // handle parent too auto parent = static_cast<ITestTreeItem *>(item->parent());
if (parent->checked() != checked)
revalidateCheckState(parent); // handle parent too
}
return true; return true;
} else if (role == FailedRole) { } else if (role == FailedRole) { // FIXME limit to Frameworks
m_failedStateCache.insert(item, true); m_failedStateCache.insert(static_cast<TestTreeItem *>(item), true);
} }
} }
return false; return false;
@@ -146,7 +149,7 @@ Qt::ItemFlags TestTreeModel::flags(const QModelIndex &index) const
if (!index.isValid()) if (!index.isValid())
return Qt::ItemIsEnabled | Qt::ItemIsSelectable; return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
TestTreeItem *item = static_cast<TestTreeItem *>(itemForIndex(index)); ITestTreeItem *item = static_cast<ITestTreeItem *>(itemForIndex(index));
return item->flags(index.column()); return item->flags(index.column());
} }
@@ -163,7 +166,7 @@ QList<TestConfiguration *> TestTreeModel::getAllTestCases() const
{ {
QList<TestConfiguration *> result; QList<TestConfiguration *> result;
for (Utils::TreeItem *frameworkRoot : *rootItem()) for (Utils::TreeItem *frameworkRoot : *rootItem())
result.append(static_cast<TestTreeItem *>(frameworkRoot)->getAllTestConfigurations()); result.append(static_cast<ITestTreeItem *>(frameworkRoot)->getAllTestConfigurations());
return result; return result;
} }
@@ -171,7 +174,7 @@ QList<TestConfiguration *> TestTreeModel::getSelectedTests() const
{ {
QList<TestConfiguration *> result; QList<TestConfiguration *> result;
for (Utils::TreeItem *frameworkRoot : *rootItem()) for (Utils::TreeItem *frameworkRoot : *rootItem())
result.append(static_cast<TestTreeItem *>(frameworkRoot)->getSelectedTestConfigurations()); result.append(static_cast<ITestTreeItem *>(frameworkRoot)->getSelectedTestConfigurations());
return result; return result;
} }
@@ -179,7 +182,7 @@ QList<TestConfiguration *> TestTreeModel::getFailedTests() const
{ {
QList<TestConfiguration *> result; QList<TestConfiguration *> result;
for (Utils::TreeItem *frameworkRoot : *rootItem()) for (Utils::TreeItem *frameworkRoot : *rootItem())
result.append(static_cast<TestTreeItem *>(frameworkRoot)->getFailedTestConfigurations()); result.append(static_cast<ITestTreeItem *>(frameworkRoot)->getFailedTestConfigurations());
return result; return result;
} }
@@ -195,13 +198,13 @@ QList<TestTreeItem *> TestTreeModel::testItemsByName(TestTreeItem *root, const Q
{ {
QList<TestTreeItem *> result; QList<TestTreeItem *> result;
root->forFirstLevelChildren([&testName, &result, this](TestTreeItem *node) { root->forFirstLevelChildItems([&testName, &result, this](TestTreeItem *node) {
if (node->type() == TestTreeItem::TestSuite || node->type() == TestTreeItem::TestCase) { if (node->type() == TestTreeItem::TestSuite || node->type() == TestTreeItem::TestCase) {
if (node->name() == testName) { if (node->name() == testName) {
result << node; result << node;
return; // prioritize test suites and cases over test functions return; // prioritize test suites and cases over test functions
} }
TestTreeItem *testCase = node->findFirstLevelChild([&testName](TestTreeItem *it) { TestTreeItem *testCase = node->findFirstLevelChildItem([&testName](TestTreeItem *it) {
QTC_ASSERT(it, return false); QTC_ASSERT(it, return false);
return (it->type() == TestTreeItem::TestCase return (it->type() == TestTreeItem::TestCase
|| it->type() == TestTreeItem::TestFunction) && it->name() == testName; || it->type() == TestTreeItem::TestFunction) && it->name() == testName;
@@ -218,6 +221,7 @@ QList<TestTreeItem *> TestTreeModel::testItemsByName(TestTreeItem *root, const Q
QList<TestTreeItem *> TestTreeModel::testItemsByName(const QString &testName) QList<TestTreeItem *> TestTreeModel::testItemsByName(const QString &testName)
{ {
QList<TestTreeItem *> result; QList<TestTreeItem *> result;
// FIXME limit to frameworks
for (Utils::TreeItem *frameworkRoot : *rootItem()) for (Utils::TreeItem *frameworkRoot : *rootItem())
result << testItemsByName(static_cast<TestTreeItem *>(frameworkRoot), testName); result << testItemsByName(static_cast<TestTreeItem *>(frameworkRoot), testName);
@@ -286,12 +290,12 @@ void TestTreeModel::rebuild(const QList<Utils::Id> &frameworkIds)
TestTreeItem *frameworkRoot = framework->rootNode(); TestTreeItem *frameworkRoot = framework->rootNode();
const bool groupingEnabled = framework->grouping(); const bool groupingEnabled = framework->grouping();
for (int row = frameworkRoot->childCount() - 1; row >= 0; --row) { for (int row = frameworkRoot->childCount() - 1; row >= 0; --row) {
auto testItem = frameworkRoot->childAt(row); auto testItem = frameworkRoot->childItem(row);
if (testItem->type() == TestTreeItem::GroupNode) { if (testItem->type() == TestTreeItem::GroupNode) {
// process children of group node and delete it afterwards if necessary // process children of group node and delete it afterwards if necessary
for (int childRow = testItem->childCount() - 1; childRow >= 0; --childRow) { for (int childRow = testItem->childCount() - 1; childRow >= 0; --childRow) {
// FIXME should this be done recursively until we have a non-GroupNode? // FIXME should this be done recursively until we have a non-GroupNode?
TestTreeItem *childTestItem = testItem->childAt(childRow); TestTreeItem *childTestItem = testItem->childItem(childRow);
takeItem(childTestItem); takeItem(childTestItem);
filterAndInsert(childTestItem, frameworkRoot, groupingEnabled); filterAndInsert(childTestItem, frameworkRoot, groupingEnabled);
} }
@@ -311,8 +315,9 @@ void TestTreeModel::updateCheckStateCache()
m_checkStateCache->evolve(); m_checkStateCache->evolve();
for (Utils::TreeItem *rootNode : *rootItem()) { for (Utils::TreeItem *rootNode : *rootItem()) {
// FIXME limit to framework items
rootNode->forAllChildren([this](Utils::TreeItem *child) { rootNode->forAllChildren([this](Utils::TreeItem *child) {
auto childItem = static_cast<TestTreeItem *>(child); auto childItem = static_cast<ITestTreeItem *>(child);
m_checkStateCache->insert(childItem, childItem->checked()); m_checkStateCache->insert(childItem, childItem->checked());
}); });
} }
@@ -359,7 +364,7 @@ void TestTreeModel::markForRemoval(const QString &filePath)
for (Utils::TreeItem *frameworkRoot : *rootItem()) { for (Utils::TreeItem *frameworkRoot : *rootItem()) {
TestTreeItem *root = static_cast<TestTreeItem *>(frameworkRoot); TestTreeItem *root = static_cast<TestTreeItem *>(frameworkRoot);
for (int childRow = root->childCount() - 1; childRow >= 0; --childRow) { for (int childRow = root->childCount() - 1; childRow >= 0; --childRow) {
TestTreeItem *child = root->childAt(childRow); TestTreeItem *child = root->childItem(childRow);
child->markForRemovalRecursively(filePath); child->markForRemovalRecursively(filePath);
} }
} }
@@ -387,7 +392,7 @@ bool TestTreeModel::sweepChildren(TestTreeItem *item)
{ {
bool hasChanged = false; bool hasChanged = false;
for (int row = item->childCount() - 1; row >= 0; --row) { for (int row = item->childCount() - 1; row >= 0; --row) {
TestTreeItem *child = item->childAt(row); TestTreeItem *child = item->childItem(row);
if (child->type() != TestTreeItem::Root && child->markedForRemoval()) { if (child->type() != TestTreeItem::Root && child->markedForRemoval()) {
destroyItem(child); destroyItem(child);
@@ -411,11 +416,11 @@ static TestTreeItem *fullCopyOf(TestTreeItem *other)
QTC_ASSERT(other, return nullptr); QTC_ASSERT(other, return nullptr);
TestTreeItem *result = other->copyWithoutChildren(); TestTreeItem *result = other->copyWithoutChildren();
for (int row = 0, count = other->childCount(); row < count; ++row) for (int row = 0, count = other->childCount(); row < count; ++row)
result->appendChild(fullCopyOf(other->childAt(row))); result->appendChild(fullCopyOf(other->childItem(row)));
return result; return result;
} }
static void applyParentCheckState(TestTreeItem *parent, TestTreeItem *newItem) static void applyParentCheckState(ITestTreeItem *parent, ITestTreeItem *newItem)
{ {
QTC_ASSERT(parent && newItem, return); QTC_ASSERT(parent && newItem, return);
@@ -433,7 +438,7 @@ void TestTreeModel::insertItemInParent(TestTreeItem *item, TestTreeItem *root, b
{ {
TestTreeItem *parentNode = root; TestTreeItem *parentNode = root;
if (groupingEnabled && item->isGroupable()) { if (groupingEnabled && item->isGroupable()) {
parentNode = root->findFirstLevelChild([item] (const TestTreeItem *it) { parentNode = root->findFirstLevelChildItem([item] (const TestTreeItem *it) {
return it->isGroupNodeFor(item); return it->isGroupNodeFor(item);
}); });
if (!parentNode) { if (!parentNode) {
@@ -448,7 +453,7 @@ void TestTreeModel::insertItemInParent(TestTreeItem *item, TestTreeItem *root, b
if (auto otherItem = parentNode->findChild(item)) { if (auto otherItem = parentNode->findChild(item)) {
// only handle item's children and add them to the already present one // only handle item's children and add them to the already present one
for (int row = 0, count = item->childCount(); row < count; ++row) { for (int row = 0, count = item->childCount(); row < count; ++row) {
TestTreeItem *child = fullCopyOf(item->childAt(row)); TestTreeItem *child = fullCopyOf(item->childItem(row));
// use check state of the original // use check state of the original
child->setData(0, item->childAt(row)->checked(), Qt::CheckStateRole); child->setData(0, item->childAt(row)->checked(), Qt::CheckStateRole);
otherItem->appendChild(child); otherItem->appendChild(child);
@@ -471,26 +476,22 @@ void TestTreeModel::insertItemInParent(TestTreeItem *item, TestTreeItem *root, b
} }
} }
void TestTreeModel::revalidateCheckState(TestTreeItem *item) static Qt::CheckState computeCheckStateByChildren(ITestTreeItem *item)
{ {
QTC_ASSERT(item, return);
const TestTreeItem::Type type = item->type();
if (type == TestTreeItem::TestSpecialFunction || type == TestTreeItem::TestDataFunction
|| type == TestTreeItem::TestDataTag) {
return;
}
const Qt::CheckState oldState = Qt::CheckState(item->data(0, Qt::CheckStateRole).toInt());
Qt::CheckState newState = Qt::Checked; Qt::CheckState newState = Qt::Checked;
bool foundChecked = false; bool foundChecked = false;
bool foundUnchecked = false; bool foundUnchecked = false;
bool foundPartiallyChecked = false; bool foundPartiallyChecked = false;
for (int row = 0, count = item->childCount(); row < count; ++row) {
TestTreeItem *child = item->childAt(row); item->forFirstLevelChildren([&](ITestTreeItem *child) {
if (foundPartiallyChecked || (foundChecked && foundUnchecked)) {
newState = Qt::PartiallyChecked;
return;
}
switch (child->type()) { switch (child->type()) {
case TestTreeItem::TestDataFunction: case TestTreeItem::TestDataFunction:
case TestTreeItem::TestSpecialFunction: case TestTreeItem::TestSpecialFunction:
continue; return;
default: default:
break; break;
} }
@@ -498,18 +499,32 @@ void TestTreeModel::revalidateCheckState(TestTreeItem *item)
foundChecked |= (child->checked() == Qt::Checked); foundChecked |= (child->checked() == Qt::Checked);
foundUnchecked |= (child->checked() == Qt::Unchecked); foundUnchecked |= (child->checked() == Qt::Unchecked);
foundPartiallyChecked |= (child->checked() == Qt::PartiallyChecked); foundPartiallyChecked |= (child->checked() == Qt::PartiallyChecked);
if (foundPartiallyChecked || (foundChecked && foundUnchecked)) { });
newState = Qt::PartiallyChecked;
break;
}
}
if (newState != Qt::PartiallyChecked) if (newState != Qt::PartiallyChecked)
newState = foundUnchecked ? Qt::Unchecked : Qt::Checked; newState = foundUnchecked ? Qt::Unchecked : Qt::Checked;
return newState;
}
void TestTreeModel::revalidateCheckState(ITestTreeItem *item)
{
QTC_ASSERT(item, return);
const ITestTreeItem::Type type = item->type();
if (type == ITestTreeItem::TestSpecialFunction || type == ITestTreeItem::TestDataFunction
|| type == ITestTreeItem::TestDataTag) {
return;
}
const Qt::CheckState oldState = Qt::CheckState(item->data(0, Qt::CheckStateRole).toInt());
Qt::CheckState newState = computeCheckStateByChildren(item);
if (oldState != newState) { if (oldState != newState) {
item->setData(0, newState, Qt::CheckStateRole); item->setData(0, newState, Qt::CheckStateRole);
emit dataChanged(item->index(), item->index(), {Qt::CheckStateRole}); emit dataChanged(item->index(), item->index(), {Qt::CheckStateRole});
if (item->parent() != rootItem() && item->parentItem()->checked() != newState) if (item->parent() != rootItem()) {
revalidateCheckState(item->parentItem()); auto parent = static_cast<ITestTreeItem *>(item->parent());
if (parent->checked() != newState)
revalidateCheckState(parent);
}
} }
} }
@@ -530,7 +545,7 @@ void Autotest::TestTreeModel::onDataChanged(const QModelIndex &topLeft,
return; return;
for (int row = topLeft.row(), endRow = bottomRight.row(); row <= endRow; ++row) { for (int row = topLeft.row(), endRow = bottomRight.row(); row <= endRow; ++row) {
if (auto item = static_cast<TestTreeItem *>(itemForIndex(index(row, 0, parent)))) if (auto item = static_cast<ITestTreeItem *>(itemForIndex(index(row, 0, parent))))
m_checkStateCache->insert(item, item->checked()); m_checkStateCache->insert(item, item->checked());
} }
} }
@@ -564,8 +579,7 @@ void TestTreeModel::handleParseResult(const TestParseResult *result, TestTreeIte
QTC_ASSERT(newItem, return); QTC_ASSERT(newItem, return);
// restore former check state and fail state if available // restore former check state and fail state if available
newItem->forAllChildren([this](Utils::TreeItem *child) { newItem->forAllChildItems([this](TestTreeItem *childItem) {
auto childItem = static_cast<TestTreeItem *>(child);
Utils::optional<Qt::CheckState> cached = m_checkStateCache->get(childItem); Utils::optional<Qt::CheckState> cached = m_checkStateCache->get(childItem);
if (cached.has_value()) if (cached.has_value())
childItem->setData(0, cached.value(), Qt::CheckStateRole); childItem->setData(0, cached.value(), Qt::CheckStateRole);
@@ -635,7 +649,7 @@ TestTreeItem *TestTreeModel::unnamedQuickTests() const
if (!rootNode) if (!rootNode)
return nullptr; return nullptr;
return rootNode->findFirstLevelChild([](TestTreeItem *it) { return it->name().isEmpty(); }); return rootNode->findFirstLevelChildItem([](TestTreeItem *it) { return it->name().isEmpty(); });
} }
int TestTreeModel::namedQuickTestsCount() const int TestTreeModel::namedQuickTestsCount() const
@@ -660,8 +674,8 @@ int TestTreeModel::dataTagsCount() const
return 0; return 0;
int dataTagCount = 0; int dataTagCount = 0;
rootNode->forFirstLevelChildren([&dataTagCount](TestTreeItem *classItem) { rootNode->forFirstLevelChildren([&dataTagCount](ITestTreeItem *classItem) {
classItem->forFirstLevelChildren([&dataTagCount](TestTreeItem *functionItem) { classItem->forFirstLevelChildren([&dataTagCount](ITestTreeItem *functionItem) {
dataTagCount += functionItem->childCount(); dataTagCount += functionItem->childCount();
}); });
}); });
@@ -679,7 +693,7 @@ QMultiMap<QString, int> TestTreeModel::gtestNamesAndSets() const
QMultiMap<QString, int> result; QMultiMap<QString, int> result;
if (TestTreeItem *rootNode = gtestRootNode()) { if (TestTreeItem *rootNode = gtestRootNode()) {
rootNode->forFirstLevelChildren([&result](TestTreeItem *child) { rootNode->forFirstLevelChildren([&result](ITestTreeItem *child) {
result.insert(child->name(), child->childCount()); result.insert(child->name(), child->childCount());
}); });
} }
@@ -697,7 +711,7 @@ QMap<QString, int> TestTreeModel::boostTestSuitesAndTests() const
QMap<QString, int> result; QMap<QString, int> result;
if (TestTreeItem *rootNode = boostTestRootNode()) { if (TestTreeItem *rootNode = boostTestRootNode()) {
rootNode->forFirstLevelChildren([&result](TestTreeItem *child) { rootNode->forFirstLevelChildItems([&result](TestTreeItem *child) {
result.insert(child->name() + '|' + child->proFile(), child->childCount()); result.insert(child->name() + '|' + child->proFile(), child->childCount());
}); });
} }
@@ -749,11 +763,11 @@ TestTreeSortFilterModel::FilterMode TestTreeSortFilterModel::toFilterMode(int f)
bool TestTreeSortFilterModel::lessThan(const QModelIndex &left, const QModelIndex &right) const bool TestTreeSortFilterModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
{ {
// root items keep the intended order // root items keep the intended order
const TestTreeItem *leftItem = static_cast<TestTreeItem *>(left.internalPointer()); const ITestTreeItem *leftItem = static_cast<ITestTreeItem *>(left.internalPointer());
if (leftItem->type() == TestTreeItem::Root) if (leftItem->type() == ITestTreeItem::Root)
return left.row() > right.row(); return left.row() > right.row();
const TestTreeItem *rightItem = static_cast<TestTreeItem *>(right.internalPointer()); const ITestTreeItem *rightItem = static_cast<ITestTreeItem *>(right.internalPointer());
return leftItem->lessThan(rightItem, m_sortMode); return leftItem->lessThan(rightItem, m_sortMode);
} }
@@ -763,12 +777,12 @@ bool TestTreeSortFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex
if (!index.isValid()) if (!index.isValid())
return false; return false;
const TestTreeItem *item = static_cast<TestTreeItem *>(index.internalPointer()); const ITestTreeItem *item = static_cast<ITestTreeItem *>(index.internalPointer());
switch (item->type()) { switch (item->type()) {
case TestTreeItem::TestDataFunction: case ITestTreeItem::TestDataFunction:
return m_filterMode & ShowTestData; return m_filterMode & ShowTestData;
case TestTreeItem::TestSpecialFunction: case ITestTreeItem::TestSpecialFunction:
return m_filterMode & ShowInitAndCleanup; return m_filterMode & ShowInitAndCleanup;
default: default:
return true; return true;

View File

@@ -104,7 +104,7 @@ private:
void removeFiles(const QStringList &files); void removeFiles(const QStringList &files);
bool sweepChildren(TestTreeItem *item); bool sweepChildren(TestTreeItem *item);
void insertItemInParent(TestTreeItem *item, TestTreeItem *root, bool groupingEnabled); void insertItemInParent(TestTreeItem *item, TestTreeItem *root, bool groupingEnabled);
void revalidateCheckState(TestTreeItem *item); void revalidateCheckState(ITestTreeItem *item);
void setupParsingConnections(); void setupParsingConnections();
void filterAndInsert(TestTreeItem *item, TestTreeItem *root, bool groupingEnabled); void filterAndInsert(TestTreeItem *item, TestTreeItem *root, bool groupingEnabled);
QList<TestTreeItem *> testItemsByName(TestTreeItem *root, const QString &testName); QList<TestTreeItem *> testItemsByName(TestTreeItem *root, const QString &testName);