diff --git a/src/plugins/autotest/boost/boosttesttreeitem.cpp b/src/plugins/autotest/boost/boosttesttreeitem.cpp index 1cb115d2234..e04650a4e61 100644 --- a/src/plugins/autotest/boost/boosttesttreeitem.cpp +++ b/src/plugins/autotest/boost/boosttesttreeitem.cpp @@ -286,7 +286,7 @@ TestConfiguration *BoostTestTreeItem::testConfiguration() const if (itemType == TestSuite || itemType == TestCase) { QStringList testCases; if (itemType == TestSuite) { - forFirstLevelChildren([&testCases](TestTreeItem *child) { + forFirstLevelChildItems([&testCases](TestTreeItem *child) { QTC_ASSERT(child, return); if (auto boostItem = static_cast(child)) { if (boostItem->enabled()) { diff --git a/src/plugins/autotest/catch/catchtreeitem.cpp b/src/plugins/autotest/catch/catchtreeitem.cpp index c3f8ffdba3d..eb88a733df4 100644 --- a/src/plugins/autotest/catch/catchtreeitem.cpp +++ b/src/plugins/autotest/catch/catchtreeitem.cpp @@ -89,7 +89,7 @@ TestTreeItem *CatchTreeItem::find(const TestParseResult *result) if (static_cast(result->base)->grouping()) { const QString path = QFileInfo(result->fileName).absolutePath(); for (int row = 0; row < childCount(); ++row) { - TestTreeItem *group = childAt(row); + TestTreeItem *group = childItem(row); if (group->filePath() != path) continue; if (auto groupChild = group->findChildByFile(result->fileName)) @@ -192,7 +192,7 @@ static void collectTestInfo(const TestTreeItem *item, QTC_ASSERT(item, return); const int childCount = item->childCount(); if (item->type() == TestTreeItem::GroupNode) { - item->forFirstLevelChildren([&testCasesForProfile, ignoreCheckState](TestTreeItem *it) { + item->forFirstLevelChildItems([&testCasesForProfile, ignoreCheckState](TestTreeItem *it) { collectTestInfo(it, testCasesForProfile, ignoreCheckState); }); return; @@ -201,14 +201,14 @@ static void collectTestInfo(const TestTreeItem *item, QTC_ASSERT(childCount != 0, return); QTC_ASSERT(item->type() == TestTreeItem::TestSuite, return); if (ignoreCheckState || item->checked() == Qt::Checked) { - const QString &projectFile = item->childAt(0)->proFile(); - item->forAllChildren([&testCasesForProfile, &projectFile](TestTreeItem *it) { + const QString &projectFile = item->childItem(0)->proFile(); + item->forAllChildItems([&testCasesForProfile, &projectFile](TestTreeItem *it) { CatchTreeItem *current = static_cast(it); testCasesForProfile[projectFile].names.append(current->testCasesString()); }); testCasesForProfile[projectFile].internalTargets.unite(item->internalTargets()); } else if (item->checked() == Qt::PartiallyChecked) { - item->forFirstLevelChildren([&testCasesForProfile](TestTreeItem *child) { + item->forFirstLevelChildItems([&testCasesForProfile](TestTreeItem *child) { QTC_ASSERT(child->type() == TestTreeItem::TestCase, return); if (child->checked() == Qt::Checked) { CatchTreeItem *current = static_cast(child); @@ -227,7 +227,7 @@ static void collectFailedTestInfo(const CatchTreeItem *item, QTC_ASSERT(item, return); QTC_ASSERT(item->type() == TestTreeItem::Root, return); - item->forAllChildren([&testCasesForProfile](TestTreeItem *it) { + item->forAllChildItems([&testCasesForProfile](TestTreeItem *it) { QTC_ASSERT(it, return); CatchTreeItem *parent = static_cast(it->parentItem()); QTC_ASSERT(parent, return); @@ -283,7 +283,7 @@ QList CatchTreeItem::getTestConfigurationsForFile(const Uti const QString filePath = fileName.toString(); for (int row = 0, count = childCount(); row < count; ++row) { - const TestTreeItem *item = childAt(row); + const TestTreeItem *item = childItem(row); QTC_ASSERT(item, continue); if (childAt(row)->name() != filePath) @@ -292,7 +292,7 @@ QList CatchTreeItem::getTestConfigurationsForFile(const Uti CatchConfiguration *testConfig = nullptr; QStringList testCases; - item->forFirstLevelChildren([&testCases](TestTreeItem *child) { + item->forFirstLevelChildItems([&testCases](TestTreeItem *child) { CatchTreeItem *current = static_cast(child); testCases << current->testCasesString(); }); @@ -326,9 +326,8 @@ QList CatchTreeItem::getTestConfigurations(bool ignoreCheck return result; QHash testCasesForProfile; - forFirstLevelChildren([&testCasesForProfile, ignoreCheckState](TestTreeItem *item) { - collectTestInfo(item, testCasesForProfile, ignoreCheckState); - }); + for (int row = 0, end = childCount(); row < end; ++row) + collectTestInfo(childItem(row), testCasesForProfile, ignoreCheckState); for (auto it = testCasesForProfile.begin(), end = testCasesForProfile.end(); it != end; ++it) { for (const QString &target : qAsConst(it.value().internalTargets)) { diff --git a/src/plugins/autotest/gtest/gtesttreeitem.cpp b/src/plugins/autotest/gtest/gtesttreeitem.cpp index 837f8783d25..44bb6bef9ce 100644 --- a/src/plugins/autotest/gtest/gtesttreeitem.cpp +++ b/src/plugins/autotest/gtest/gtesttreeitem.cpp @@ -230,13 +230,13 @@ static void collectTestInfo(const GTestTreeItem *item, QTC_ASSERT(childCount != 0, return); QTC_ASSERT(item->type() == TestTreeItem::TestSuite, return); if (ignoreCheckState || item->checked() == Qt::Checked) { - const QString &projectFile = item->childAt(0)->proFile(); + const QString &projectFile = item->childItem(0)->proFile(); testCasesForProFile[projectFile].filters.append( gtestFilter(item->state()).arg(item->name()).arg('*')); testCasesForProFile[projectFile].testSetCount += childCount - 1; testCasesForProFile[projectFile].internalTargets.unite(item->internalTargets()); } 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); if (child->checked() == Qt::Checked) { testCasesForProFile[child->proFile()].filters.append( @@ -254,7 +254,7 @@ static void collectFailedTestInfo(const GTestTreeItem *item, QTC_ASSERT(item, return); QTC_ASSERT(item->type() == TestTreeItem::Root, return); - item->forAllChildren([&testCasesForProfile](TestTreeItem *it) { + item->forAllChildItems([&testCasesForProfile](TestTreeItem *it) { QTC_ASSERT(it, return); GTestTreeItem *parent = static_cast(it->parentItem()); QTC_ASSERT(parent, return); @@ -340,7 +340,7 @@ QList GTestTreeItem::getTestConfigurationsForFile(const Uti QHash testCases; const QString &file = fileName.toString(); - forAllChildren([&testCases, &file](TestTreeItem *node) { + forAllChildItems([&testCases, &file](TestTreeItem *node) { if (node->type() == Type::TestCase && node->filePath() == file) { QTC_ASSERT(node->parentItem(), return); const GTestTreeItem *testCase = static_cast(node->parentItem()); @@ -469,7 +469,7 @@ TestTreeItem *GTestTreeItem::createParentGroupNode() const return new GTestTreeItem(framework(), base.baseName(), fileInfo.absolutePath(), TestTreeItem::GroupNode); } else { // GTestFilter QTC_ASSERT(childCount(), return nullptr); // paranoia - const TestTreeItem *firstChild = childAt(0); + const TestTreeItem *firstChild = childItem(0); const QString activeFilter = GTestFramework::currentGTestFilter(); const QString fullTestName = name() + '.' + firstChild->name(); const QString groupNodeName = @@ -497,7 +497,7 @@ TestTreeItem *GTestTreeItem::findChildByNameStateAndFile(const QString &name, GTestTreeItem::TestStates state, 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(other); return other->proFile() == proFile && other->name() == name && gtestItem->state() == state; }); diff --git a/src/plugins/autotest/itemdatacache.h b/src/plugins/autotest/itemdatacache.h index 6db21388421..941f40d4e39 100644 --- a/src/plugins/autotest/itemdatacache.h +++ b/src/plugins/autotest/itemdatacache.h @@ -38,7 +38,7 @@ template class ItemDataCache { 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() { auto it = m_cache.begin(), end = m_cache.end(); @@ -46,7 +46,7 @@ public: it = it->generation++ >= maxGen ? m_cache.erase(it) : ++it; } - Utils::optional get(TestTreeItem *item) + Utils::optional get(ITestTreeItem *item) { auto entry = m_cache.find(item->cacheName()); if (entry == m_cache.end()) diff --git a/src/plugins/autotest/qtest/qttest_utils.cpp b/src/plugins/autotest/qtest/qttest_utils.cpp index 916a83aa060..ce98f959d2d 100644 --- a/src/plugins/autotest/qtest/qttest_utils.cpp +++ b/src/plugins/autotest/qtest/qttest_utils.cpp @@ -53,10 +53,10 @@ QHash testCaseNamesForFiles(ITestFramework *framework, const Q TestTreeItem *rootNode = framework->rootNode(); QTC_ASSERT(rootNode, return result); - rootNode->forFirstLevelChildren([&result, &files](TestTreeItem *child) { + rootNode->forFirstLevelChildren([&result, &files](ITestTreeItem *child) { if (files.contains(child->filePath())) 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())) result.insert(grandChild->filePath(), child->name()); }); @@ -70,7 +70,7 @@ QMultiHash alternativeFiles(ITestFramework *framework, const Q TestTreeItem *rootNode = framework->rootNode(); QTC_ASSERT(rootNode, return result); - rootNode->forFirstLevelChildren([&result, &files](TestTreeItem *child) { + rootNode->forFirstLevelChildren([&result, &files](ITestTreeItem *child) { const QString &baseFilePath = child->filePath(); for (int childRow = 0, count = child->childCount(); childRow < count; ++childRow) { auto grandChild = static_cast(child->childAt(childRow)); diff --git a/src/plugins/autotest/qtest/qttesttreeitem.cpp b/src/plugins/autotest/qtest/qttesttreeitem.cpp index 444f46acefb..8448a4ce265 100644 --- a/src/plugins/autotest/qtest/qttesttreeitem.cpp +++ b/src/plugins/autotest/qtest/qttesttreeitem.cpp @@ -154,7 +154,7 @@ static void fillTestConfigurationsFromCheckState(const TestTreeItem *item, QTC_ASSERT(item, return); if (item->type() == TestTreeItem::GroupNode) { for (int row = 0, count = item->childCount(); row < count; ++row) - fillTestConfigurationsFromCheckState(item->childAt(row), testConfigurations); + fillTestConfigurationsFromCheckState(item->childItem(row), testConfigurations); return; } QTC_ASSERT(item->type() == TestTreeItem::TestCase, return); @@ -169,12 +169,12 @@ static void fillTestConfigurationsFromCheckState(const TestTreeItem *item, return; case Qt::PartiallyChecked: QStringList testCases; - item->forFirstLevelChildren([&testCases](TestTreeItem *grandChild) { + item->forFirstLevelChildren([&testCases](ITestTreeItem *grandChild) { if (grandChild->checked() == Qt::Checked) { testCases << grandChild->name(); } else if (grandChild->checked() == Qt::PartiallyChecked) { const QString funcName = grandChild->name(); - grandChild->forFirstLevelChildren([&testCases, &funcName](TestTreeItem *dataTag) { + grandChild->forFirstLevelChildren([&testCases, &funcName](ITestTreeItem *dataTag) { if (dataTag->checked() == Qt::Checked) testCases << funcName + ':' + dataTag->name(); }); @@ -195,16 +195,16 @@ static void collectFailedTestInfo(TestTreeItem *item, QList QTC_ASSERT(item, return); if (item->type() == TestTreeItem::GroupNode) { for (int row = 0, count = item->childCount(); row < count; ++row) - collectFailedTestInfo(item->childAt(row), testConfigs); + collectFailedTestInfo(item->childItem(row), testConfigs); return; } QTC_ASSERT(item->type() == TestTreeItem::TestCase, return); QStringList testCases; - item->forFirstLevelChildren([&testCases](TestTreeItem *func) { + item->forFirstLevelChildren([&testCases](ITestTreeItem *func) { if (func->data(0, FailedRole).toBool()) { testCases << func->name(); } else { - func->forFirstLevelChildren([&testCases, func](TestTreeItem *dataTag) { + func->forFirstLevelChildren([&testCases, func](ITestTreeItem *dataTag) { if (dataTag->data(0, FailedRole).toBool()) testCases << func->name() + ':' + dataTag->name(); }); @@ -237,13 +237,13 @@ QList QtTestTreeItem::getAllTestConfigurations() const if (!project || type() != Root) return result; - forFirstLevelChildren([&result](TestTreeItem *child) { + forFirstLevelChildren([&result](ITestTreeItem *child) { if (child->type() == TestCase) { TestConfiguration *tc = child->testConfiguration(); QTC_ASSERT(tc, return); result << tc; } else if (child->type() == GroupNode) { - child->forFirstLevelChildren([&result](TestTreeItem *groupChild) { + child->forFirstLevelChildren([&result](ITestTreeItem *groupChild) { TestConfiguration *tc = groupChild->testConfiguration(); QTC_ASSERT(tc, return); result << tc; @@ -261,7 +261,7 @@ QList QtTestTreeItem::getSelectedTestConfigurations() const return result; for (int row = 0, count = childCount(); row < count; ++row) - fillTestConfigurationsFromCheckState(childAt(row), result); + fillTestConfigurationsFromCheckState(childItem(row), result); return result; } @@ -270,9 +270,8 @@ QList QtTestTreeItem::getFailedTestConfigurations() const { QList result; QTC_ASSERT(type() == TestTreeItem::Root, return result); - forFirstLevelChildren([&result](TestTreeItem *child) { - collectFailedTestInfo(child, result); - }); + for (int row = 0, end = childCount(); row < end; ++row) + collectFailedTestInfo(childItem(row), result); return result; } @@ -286,7 +285,7 @@ QList QtTestTreeItem::getTestConfigurationsForFile(const Ut QHash testFunctions; const QString &file = fileName.toString(); - forAllChildren([&testFunctions, &file](TestTreeItem *node) { + forAllChildItems([&testFunctions, &file](TestTreeItem *node) { if (node->type() == Type::TestFunction && node->filePath() == file) { QTC_ASSERT(node->parentItem(), return); TestTreeItem *testCase = node->parentItem(); @@ -314,7 +313,7 @@ TestTreeItem *QtTestTreeItem::find(const TestParseResult *result) if (static_cast(result->base)->grouping()) { const QString path = QFileInfo(result->fileName).absolutePath(); for (int row = 0; row < childCount(); ++row) { - TestTreeItem *group = childAt(row); + TestTreeItem *group = childItem(row); if (group->filePath() != path) continue; if (auto groupChild = group->findChildByFile(result->fileName)) @@ -394,7 +393,7 @@ bool QtTestTreeItem::isGroupable() 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(other); return qtOther->inherited() == inherited && qtOther->name() == name; }); diff --git a/src/plugins/autotest/quick/quicktest_utils.cpp b/src/plugins/autotest/quick/quicktest_utils.cpp index eab91c93243..ef7dc81f37b 100644 --- a/src/plugins/autotest/quick/quicktest_utils.cpp +++ b/src/plugins/autotest/quick/quicktest_utils.cpp @@ -52,14 +52,14 @@ QHash proFilesForQmlFiles(ITestFramework *framework, const QSt if (files.isEmpty()) return result; - rootNode->forFirstLevelChildren([&result, &files](TestTreeItem *child) { + rootNode->forFirstLevelChildItems([&result, &files](TestTreeItem *child) { const QString &file = child->filePath(); if (!file.isEmpty() && files.contains(file)) { const QString &proFile = child->proFile(); if (!proFile.isEmpty()) result.insert(file, proFile); } - child->forFirstLevelChildren([&result, &files](TestTreeItem *grandChild) { + child->forFirstLevelChildItems([&result, &files](TestTreeItem *grandChild) { const QString &file = grandChild->filePath(); if (!file.isEmpty() && files.contains(file)) { const QString &proFile = grandChild->proFile(); diff --git a/src/plugins/autotest/quick/quicktesttreeitem.cpp b/src/plugins/autotest/quick/quicktesttreeitem.cpp index f4ab8eee5d7..08ad05966d1 100644 --- a/src/plugins/autotest/quick/quicktesttreeitem.cpp +++ b/src/plugins/autotest/quick/quicktesttreeitem.cpp @@ -133,7 +133,7 @@ TestConfiguration *QuickTestTreeItem::testConfiguration() const case TestCase: { const QString testName = name(); QStringList testFunctions; - forFirstLevelChildren([&testFunctions, &testName](TestTreeItem *child) { + forFirstLevelChildren([&testFunctions, &testName](ITestTreeItem *child) { if (child->type() == TestTreeItem::TestFunction) testFunctions << testName + "::" + child->name(); }); @@ -177,7 +177,7 @@ static QList testConfigurationsFor( const QString name = treeItem->name(); QStringList functions; - treeItem->forFirstLevelChildren([&functions, &name, &predicate](TestTreeItem *child) { + treeItem->forFirstLevelChildItems([&functions, &name, &predicate](TestTreeItem *child) { if (predicate(child)) functions << name + "::" + child->name(); }); @@ -228,10 +228,10 @@ QList QuickTestTreeItem::getAllTestConfigurations() const return result; QHash testsForProfile; - forFirstLevelChildren([&testsForProfile](TestTreeItem *child) { + forFirstLevelChildItems([&testsForProfile](TestTreeItem *child) { // unnamed Quick Tests must be handled separately if (child->name().isEmpty()) { - child->forFirstLevelChildren([&testsForProfile](TestTreeItem *grandChild) { + child->forFirstLevelChildItems([&testsForProfile](TestTreeItem *grandChild) { const QString &proFile = grandChild->proFile(); ++(testsForProfile[proFile].testCount); testsForProfile[proFile].internalTargets = grandChild->internalTargets(); @@ -242,7 +242,7 @@ QList QuickTestTreeItem::getAllTestConfigurations() const if (child->type() == TestCase) { addTestsForItem(testsForProfile[child->proFile()], child); } else if (child->type() == GroupNode) { - child->forFirstLevelChildren([&testsForProfile](TestTreeItem *grandChild) { + child->forFirstLevelChildItems([&testsForProfile](TestTreeItem *grandChild) { addTestsForItem(testsForProfile[grandChild->proFile()], grandChild); }); } @@ -292,7 +292,7 @@ TestTreeItem *QuickTestTreeItem::find(const TestParseResult *result) return unnamedQuickTests(); if (static_cast(result->base)->grouping()) { 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 ? 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 () if (name().isEmpty()) return false; if (other->name().isEmpty()) return true; - return TestTreeItem::lessThan(other, mode); + return ITestTreeItem::lessThan(other, mode); } bool QuickTestTreeItem::isGroupNodeFor(const TestTreeItem *other) const @@ -405,7 +405,7 @@ void QuickTestTreeItem::markForRemovalRecursively(const QString &filePath) const QString proFile = parser->projectFileForMainCppFile(filePath); if (!proFile.isEmpty()) { TestTreeItem *root = framework()->rootNode(); - root->forAllChildren([proFile](TestTreeItem *it) { + root->forAllChildItems([proFile](TestTreeItem *it) { if (it->proFile() == proFile) it->markForRemoval(true); }); @@ -417,7 +417,7 @@ TestTreeItem *QuickTestTreeItem::findChildByFileNameAndType(const QString &fileP 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; }); } @@ -425,7 +425,7 @@ TestTreeItem *QuickTestTreeItem::findChildByFileNameAndType(const QString &fileP TestTreeItem *QuickTestTreeItem::findChildByNameFileAndLine(const QString &name, 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; }); } @@ -435,7 +435,7 @@ TestTreeItem *QuickTestTreeItem::unnamedQuickTests() const if (type() != Root) return nullptr; - return findFirstLevelChild([](TestTreeItem *child) { return child->name().isEmpty(); }); + return findFirstLevelChildItem([](TestTreeItem *child) { return child->name().isEmpty(); }); } } // namespace Internal diff --git a/src/plugins/autotest/quick/quicktesttreeitem.h b/src/plugins/autotest/quick/quicktesttreeitem.h index 1bc9315c9ee..47199a9fe24 100644 --- a/src/plugins/autotest/quick/quicktesttreeitem.h +++ b/src/plugins/autotest/quick/quicktesttreeitem.h @@ -54,7 +54,7 @@ public: TestTreeItem *find(const TestParseResult *result) override; TestTreeItem *findChild(const TestTreeItem *other) 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 removeOnSweepIfEmpty() const override; TestTreeItem *createParentGroupNode() const override; diff --git a/src/plugins/autotest/testnavigationwidget.cpp b/src/plugins/autotest/testnavigationwidget.cpp index 9c0a8255afa..32f06d69b8a 100644 --- a/src/plugins/autotest/testnavigationwidget.cpp +++ b/src/plugins/autotest/testnavigationwidget.cpp @@ -242,7 +242,7 @@ void TestNavigationWidget::updateExpandedStateCache() for (Utils::TreeItem *rootNode : *m_model->rootItem()) { rootNode->forAllChildren([this](Utils::TreeItem *child) { - m_expandedStateCache.insert(static_cast(child), + m_expandedStateCache.insert(static_cast(child), m_view->isExpanded(child->index())); }); } @@ -322,7 +322,7 @@ void TestNavigationWidget::reapplyCachedExpandedState() using namespace Utils; for (TreeItem *rootNode : *m_model->rootItem()) { rootNode->forAllChildren([this](TreeItem *child) { - optional cached = m_expandedStateCache.get(static_cast(child)); + optional cached = m_expandedStateCache.get(static_cast(child)); if (cached.has_value()) { QModelIndex index = child->index(); if (m_view->isExpanded(index) != cached.value()) diff --git a/src/plugins/autotest/testtreeitem.cpp b/src/plugins/autotest/testtreeitem.cpp index d085f12a35a..2b54f80fd78 100644 --- a/src/plugins/autotest/testtreeitem.cpp +++ b/src/plugins/autotest/testtreeitem.cpp @@ -40,27 +40,6 @@ 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 icons[] = { @@ -77,7 +56,15 @@ static QIcon testTreeIcon(TestTreeItem::Type 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) { case Qt::DisplayRole: @@ -91,13 +78,6 @@ QVariant TestTreeItem::data(int /*column*/, int role) const return testTreeIcon(m_type); case Qt::CheckStateRole: 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: return false; case TypeRole: @@ -110,7 +90,7 @@ QVariant TestTreeItem::data(int /*column*/, int role) const 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) { Qt::CheckState old = m_checked; @@ -122,10 +102,10 @@ bool TestTreeItem::setData(int /*column*/, const QVariant &data, int role) 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; - switch (m_type) { + switch (type()) { case Root: case GroupNode: 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(); + const Utils::Link &rightLink = other->data(0, LinkRole).value(); + 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 hasBeenModified = modifyName(result->name); @@ -164,8 +208,8 @@ bool TestTreeItem::modifyDataTagContent(const TestParseResult *result) bool TestTreeItem::modifyLineAndColumn(const TestParseResult *result) { bool hasBeenModified = false; - if (m_line != result->line) { - m_line = result->line; + if (line() != result->line) { + setLine(result->line); hasBeenModified = true; } if (m_column != result->column) { @@ -175,21 +219,6 @@ bool TestTreeItem::modifyLineAndColumn(const TestParseResult *result) 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) { m_status = mark ? MarkedForRemoval : Cleared; @@ -199,19 +228,24 @@ void TestTreeItem::markForRemovalRecursively(bool mark) { markForRemoval(mark); 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; - forFirstLevelChildren([&mark, &filePath](TestTreeItem *child) { - child->markForRemovalRecursively(filePath); + bool mark = filePath() == filepath; + forFirstLevelChildItems([&mark, &filepath](TestTreeItem *child) { + child->markForRemovalRecursively(filepath); mark &= child->markedForRemoval(); }); markForRemoval(mark); } +TestTreeItem *TestTreeItem::childItem(int at) const +{ + return static_cast(childAt(at)); +} + TestTreeItem *TestTreeItem::parentItem() const { return static_cast(parent()); @@ -219,26 +253,27 @@ TestTreeItem *TestTreeItem::parentItem() const 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) { - return findFirstLevelChild([filePath](const TestTreeItem *other) { + return findFirstLevelChildItem([filePath](const TestTreeItem *other) { return other->filePath() == filePath; }); } 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; - }); -} + });} 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; }); } @@ -258,53 +293,11 @@ TestConfiguration *TestTreeItem::asConfiguration(TestRunMode mode) const return nullptr; } -QList TestTreeItem::getAllTestConfigurations() const -{ - return QList(); -} - -QList TestTreeItem::getSelectedTestConfigurations() const -{ - return QList(); -} - -QList TestTreeItem::getFailedTestConfigurations() const -{ - return QList(); -} - QList TestTreeItem::getTestConfigurationsForFile(const Utils::FilePath &) const { return QList(); } -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(); - const Utils::Link &rightLink = other->data(0, LinkRole).value(); - 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 { QTC_ASSERT(other, return false); @@ -323,47 +316,74 @@ bool TestTreeItem::isGroupable() const QSet TestTreeItem::internalTargets() const { auto cppMM = CppTools::CppModelManager::instance(); - const QList projectParts = cppMM->projectPart(m_filePath); + const QList projectParts = cppMM->projectPart(filePath()); // if we have no project parts it's most likely a header with declarations only and CMake based if (projectParts.isEmpty()) - return TestTreeItem::dependingInternalTargets(cppMM, m_filePath); + return TestTreeItem::dependingInternalTargets(cppMM, filePath()); QSet targets; for (const CppTools::ProjectPart::Ptr &part : projectParts) { targets.insert(part->buildSystemTarget); if (part->buildTargetType != ProjectExplorer::BuildTargetType::Executable) - targets.unite(TestTreeItem::dependingInternalTargets(cppMM, m_filePath)); + targets.unite(TestTreeItem::dependingInternalTargets(cppMM, filePath())); } return targets; } +void TestTreeItem::forAllChildItems(const std::function &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 &pred) const +{ + for (int row = 0, end = childCount(); row < end; ++row) + pred(childItem(row)); +} + +TestTreeItem *TestTreeItem::findFirstLevelChildItem(const std::function &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) { if (!other) return; - m_name = other->m_name; - m_filePath = other->m_filePath; - m_type = other->m_type; - m_checked = other->m_checked; - m_failed = other->m_failed; - m_line = other->m_line; + + setName(other->name()); + setFilePath(other->filePath()); + setType(other->type()); + setLine(other->line()); + setData(0, other->checked(), Qt::CheckStateRole); + setData(0, other->data(0, FailedRole), FailedRole); + m_column = other->m_column; m_proFile = other->m_proFile; m_status = other->m_status; } -inline bool TestTreeItem::modifyFilePath(const QString &filePath) +inline bool TestTreeItem::modifyFilePath(const QString &filepath) { - if (m_filePath != filePath) { - m_filePath = filePath; + if (filePath() != filepath) { + setFilePath(filepath); return true; } return false; } -inline bool TestTreeItem::modifyName(const QString &name) +inline bool TestTreeItem::modifyName(const QString &newName) { - if (m_name != name) { - m_name = name; + if (name() != newName) { + setName(newName); return true; } return false; @@ -371,7 +391,7 @@ inline bool TestTreeItem::modifyName(const QString &name) ITestFramework *TestTreeItem::framework() const { - return static_cast(m_testBase); + return static_cast(testBase()); } /* diff --git a/src/plugins/autotest/testtreeitem.h b/src/plugins/autotest/testtreeitem.h index ac45a5c8f36..4e6995869d8 100644 --- a/src/plugins/autotest/testtreeitem.h +++ b/src/plugins/autotest/testtreeitem.h @@ -53,7 +53,7 @@ class TestConfiguration; class TestParseResult; enum class TestRunMode; -class TestTreeItem : public Utils::TypedTreeItem +class ITestTreeItem : public Utils::TypedTreeItem { public: @@ -74,6 +74,51 @@ public: 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 getAllTestConfigurations() const { return {}; } + virtual QList getSelectedTestConfigurations() const { return {}; } + virtual QList 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, const QString &name = QString(), const QString &filePath = QString(), @@ -81,32 +126,23 @@ public: virtual TestTreeItem *copyWithoutChildren() = 0; 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 modifyTestFunctionContent(const TestParseResult *result); bool modifyDataTagContent(const TestParseResult *result); bool modifyLineAndColumn(const TestParseResult *result); 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; } int column() const { return m_column; } QString proFile() const { return m_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 markForRemovalRecursively(bool mark); - virtual void markForRemovalRecursively(const QString &filePath); - virtual bool removeOnSweepIfEmpty() const { return m_type == GroupNode; } + virtual void markForRemovalRecursively(const QString &filepath); + virtual bool removeOnSweepIfEmpty() const { return type() == GroupNode; } bool markedForRemoval() const { return m_status == MarkedForRemoval; } bool newlyAdded() const { return m_status == NewlyAdded; } + TestTreeItem *childItem(int at) const; TestTreeItem *parentItem() const; TestTreeItem *findChildByName(const QString &name); @@ -114,16 +150,10 @@ public: TestTreeItem *findChildByFileAndType(const QString &filePath, Type type); 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 bool canProvideDebugConfiguration() const { return false; } TestConfiguration *asConfiguration(TestRunMode mode) const; - virtual QList getAllTestConfigurations() const; - virtual QList getSelectedTestConfigurations() const; - virtual QList getFailedTestConfigurations() const; virtual QList getTestConfigurationsForFile(const Utils::FilePath &fileName) const; - virtual bool lessThan(const TestTreeItem *other, SortMode mode) const; virtual TestTreeItem *find(const TestParseResult *result) = 0; virtual TestTreeItem *findChild(const TestTreeItem *other) = 0; virtual bool modify(const TestParseResult *result) = 0; @@ -137,7 +167,9 @@ public: virtual bool shouldBeAddedAfterFiltering() const { return true; } virtual QSet internalTargets() const; - QString cacheName() const { return m_filePath + ':' + m_name; } + void forAllChildItems(const std::function &pred) const; + void forFirstLevelChildItems(const std::function &pred) const; + TestTreeItem *findFirstLevelChildItem(const std::function &pred) const; protected: void copyBasicDataFrom(const TestTreeItem *other); typedef std::function CompareFunction; @@ -145,7 +177,7 @@ protected: const QString &file); private: - bool modifyFilePath(const QString &filePath); + bool modifyFilePath(const QString &filepath); bool modifyName(const QString &name); enum Status @@ -155,13 +187,6 @@ private: 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; QString m_proFile; Status m_status = NewlyAdded; diff --git a/src/plugins/autotest/testtreemodel.cpp b/src/plugins/autotest/testtreemodel.cpp index ff74b0eed70..84529dd99cb 100644 --- a/src/plugins/autotest/testtreemodel.cpp +++ b/src/plugins/autotest/testtreemodel.cpp @@ -119,7 +119,7 @@ bool TestTreeModel::setData(const QModelIndex &index, const QVariant &value, int if (!index.isValid()) return false; - TestTreeItem *item = static_cast(index.internalPointer()); + ITestTreeItem *item = static_cast(index.internalPointer()); if (item && item->setData(index.column(), value, role)) { emit dataChanged(index, index, {role}); 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); } } - if (item->parent() != rootItem() && item->parentItem()->checked() != checked) - revalidateCheckState(item->parentItem()); // handle parent too + if (item->parent() != rootItem()) { + auto parent = static_cast(item->parent()); + if (parent->checked() != checked) + revalidateCheckState(parent); // handle parent too + } return true; - } else if (role == FailedRole) { - m_failedStateCache.insert(item, true); + } else if (role == FailedRole) { // FIXME limit to Frameworks + m_failedStateCache.insert(static_cast(item), true); } } return false; @@ -146,7 +149,7 @@ Qt::ItemFlags TestTreeModel::flags(const QModelIndex &index) const if (!index.isValid()) return Qt::ItemIsEnabled | Qt::ItemIsSelectable; - TestTreeItem *item = static_cast(itemForIndex(index)); + ITestTreeItem *item = static_cast(itemForIndex(index)); return item->flags(index.column()); } @@ -163,7 +166,7 @@ QList TestTreeModel::getAllTestCases() const { QList result; for (Utils::TreeItem *frameworkRoot : *rootItem()) - result.append(static_cast(frameworkRoot)->getAllTestConfigurations()); + result.append(static_cast(frameworkRoot)->getAllTestConfigurations()); return result; } @@ -171,7 +174,7 @@ QList TestTreeModel::getSelectedTests() const { QList result; for (Utils::TreeItem *frameworkRoot : *rootItem()) - result.append(static_cast(frameworkRoot)->getSelectedTestConfigurations()); + result.append(static_cast(frameworkRoot)->getSelectedTestConfigurations()); return result; } @@ -179,7 +182,7 @@ QList TestTreeModel::getFailedTests() const { QList result; for (Utils::TreeItem *frameworkRoot : *rootItem()) - result.append(static_cast(frameworkRoot)->getFailedTestConfigurations()); + result.append(static_cast(frameworkRoot)->getFailedTestConfigurations()); return result; } @@ -195,13 +198,13 @@ QList TestTreeModel::testItemsByName(TestTreeItem *root, const Q { QList 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->name() == testName) { result << node; 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); return (it->type() == TestTreeItem::TestCase || it->type() == TestTreeItem::TestFunction) && it->name() == testName; @@ -218,6 +221,7 @@ QList TestTreeModel::testItemsByName(TestTreeItem *root, const Q QList TestTreeModel::testItemsByName(const QString &testName) { QList result; + // FIXME limit to frameworks for (Utils::TreeItem *frameworkRoot : *rootItem()) result << testItemsByName(static_cast(frameworkRoot), testName); @@ -286,12 +290,12 @@ void TestTreeModel::rebuild(const QList &frameworkIds) TestTreeItem *frameworkRoot = framework->rootNode(); const bool groupingEnabled = framework->grouping(); for (int row = frameworkRoot->childCount() - 1; row >= 0; --row) { - auto testItem = frameworkRoot->childAt(row); + auto testItem = frameworkRoot->childItem(row); if (testItem->type() == TestTreeItem::GroupNode) { // process children of group node and delete it afterwards if necessary for (int childRow = testItem->childCount() - 1; childRow >= 0; --childRow) { // FIXME should this be done recursively until we have a non-GroupNode? - TestTreeItem *childTestItem = testItem->childAt(childRow); + TestTreeItem *childTestItem = testItem->childItem(childRow); takeItem(childTestItem); filterAndInsert(childTestItem, frameworkRoot, groupingEnabled); } @@ -311,8 +315,9 @@ void TestTreeModel::updateCheckStateCache() m_checkStateCache->evolve(); for (Utils::TreeItem *rootNode : *rootItem()) { + // FIXME limit to framework items rootNode->forAllChildren([this](Utils::TreeItem *child) { - auto childItem = static_cast(child); + auto childItem = static_cast(child); m_checkStateCache->insert(childItem, childItem->checked()); }); } @@ -359,7 +364,7 @@ void TestTreeModel::markForRemoval(const QString &filePath) for (Utils::TreeItem *frameworkRoot : *rootItem()) { TestTreeItem *root = static_cast(frameworkRoot); for (int childRow = root->childCount() - 1; childRow >= 0; --childRow) { - TestTreeItem *child = root->childAt(childRow); + TestTreeItem *child = root->childItem(childRow); child->markForRemovalRecursively(filePath); } } @@ -387,7 +392,7 @@ bool TestTreeModel::sweepChildren(TestTreeItem *item) { bool hasChanged = false; 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()) { destroyItem(child); @@ -411,11 +416,11 @@ static TestTreeItem *fullCopyOf(TestTreeItem *other) QTC_ASSERT(other, return nullptr); TestTreeItem *result = other->copyWithoutChildren(); for (int row = 0, count = other->childCount(); row < count; ++row) - result->appendChild(fullCopyOf(other->childAt(row))); + result->appendChild(fullCopyOf(other->childItem(row))); return result; } -static void applyParentCheckState(TestTreeItem *parent, TestTreeItem *newItem) +static void applyParentCheckState(ITestTreeItem *parent, ITestTreeItem *newItem) { QTC_ASSERT(parent && newItem, return); @@ -433,7 +438,7 @@ void TestTreeModel::insertItemInParent(TestTreeItem *item, TestTreeItem *root, b { TestTreeItem *parentNode = root; if (groupingEnabled && item->isGroupable()) { - parentNode = root->findFirstLevelChild([item] (const TestTreeItem *it) { + parentNode = root->findFirstLevelChildItem([item] (const TestTreeItem *it) { return it->isGroupNodeFor(item); }); if (!parentNode) { @@ -448,7 +453,7 @@ void TestTreeModel::insertItemInParent(TestTreeItem *item, TestTreeItem *root, b if (auto otherItem = parentNode->findChild(item)) { // only handle item's children and add them to the already present one 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 child->setData(0, item->childAt(row)->checked(), Qt::CheckStateRole); 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; bool foundChecked = false; bool foundUnchecked = 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()) { case TestTreeItem::TestDataFunction: case TestTreeItem::TestSpecialFunction: - continue; + return; default: break; } @@ -498,18 +499,32 @@ void TestTreeModel::revalidateCheckState(TestTreeItem *item) foundChecked |= (child->checked() == Qt::Checked); foundUnchecked |= (child->checked() == Qt::Unchecked); foundPartiallyChecked |= (child->checked() == Qt::PartiallyChecked); - if (foundPartiallyChecked || (foundChecked && foundUnchecked)) { - newState = Qt::PartiallyChecked; - break; - } - } + }); + if (newState != Qt::PartiallyChecked) 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) { item->setData(0, newState, Qt::CheckStateRole); emit dataChanged(item->index(), item->index(), {Qt::CheckStateRole}); - if (item->parent() != rootItem() && item->parentItem()->checked() != newState) - revalidateCheckState(item->parentItem()); + if (item->parent() != rootItem()) { + auto parent = static_cast(item->parent()); + if (parent->checked() != newState) + revalidateCheckState(parent); + } } } @@ -530,7 +545,7 @@ void Autotest::TestTreeModel::onDataChanged(const QModelIndex &topLeft, return; for (int row = topLeft.row(), endRow = bottomRight.row(); row <= endRow; ++row) { - if (auto item = static_cast(itemForIndex(index(row, 0, parent)))) + if (auto item = static_cast(itemForIndex(index(row, 0, parent)))) m_checkStateCache->insert(item, item->checked()); } } @@ -564,8 +579,7 @@ void TestTreeModel::handleParseResult(const TestParseResult *result, TestTreeIte QTC_ASSERT(newItem, return); // restore former check state and fail state if available - newItem->forAllChildren([this](Utils::TreeItem *child) { - auto childItem = static_cast(child); + newItem->forAllChildItems([this](TestTreeItem *childItem) { Utils::optional cached = m_checkStateCache->get(childItem); if (cached.has_value()) childItem->setData(0, cached.value(), Qt::CheckStateRole); @@ -635,7 +649,7 @@ TestTreeItem *TestTreeModel::unnamedQuickTests() const if (!rootNode) return nullptr; - return rootNode->findFirstLevelChild([](TestTreeItem *it) { return it->name().isEmpty(); }); + return rootNode->findFirstLevelChildItem([](TestTreeItem *it) { return it->name().isEmpty(); }); } int TestTreeModel::namedQuickTestsCount() const @@ -660,8 +674,8 @@ int TestTreeModel::dataTagsCount() const return 0; int dataTagCount = 0; - rootNode->forFirstLevelChildren([&dataTagCount](TestTreeItem *classItem) { - classItem->forFirstLevelChildren([&dataTagCount](TestTreeItem *functionItem) { + rootNode->forFirstLevelChildren([&dataTagCount](ITestTreeItem *classItem) { + classItem->forFirstLevelChildren([&dataTagCount](ITestTreeItem *functionItem) { dataTagCount += functionItem->childCount(); }); }); @@ -679,7 +693,7 @@ QMultiMap TestTreeModel::gtestNamesAndSets() const QMultiMap result; if (TestTreeItem *rootNode = gtestRootNode()) { - rootNode->forFirstLevelChildren([&result](TestTreeItem *child) { + rootNode->forFirstLevelChildren([&result](ITestTreeItem *child) { result.insert(child->name(), child->childCount()); }); } @@ -697,7 +711,7 @@ QMap TestTreeModel::boostTestSuitesAndTests() const QMap result; if (TestTreeItem *rootNode = boostTestRootNode()) { - rootNode->forFirstLevelChildren([&result](TestTreeItem *child) { + rootNode->forFirstLevelChildItems([&result](TestTreeItem *child) { 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 { // root items keep the intended order - const TestTreeItem *leftItem = static_cast(left.internalPointer()); - if (leftItem->type() == TestTreeItem::Root) + const ITestTreeItem *leftItem = static_cast(left.internalPointer()); + if (leftItem->type() == ITestTreeItem::Root) return left.row() > right.row(); - const TestTreeItem *rightItem = static_cast(right.internalPointer()); + const ITestTreeItem *rightItem = static_cast(right.internalPointer()); return leftItem->lessThan(rightItem, m_sortMode); } @@ -763,12 +777,12 @@ bool TestTreeSortFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex if (!index.isValid()) return false; - const TestTreeItem *item = static_cast(index.internalPointer()); + const ITestTreeItem *item = static_cast(index.internalPointer()); switch (item->type()) { - case TestTreeItem::TestDataFunction: + case ITestTreeItem::TestDataFunction: return m_filterMode & ShowTestData; - case TestTreeItem::TestSpecialFunction: + case ITestTreeItem::TestSpecialFunction: return m_filterMode & ShowInitAndCleanup; default: return true; diff --git a/src/plugins/autotest/testtreemodel.h b/src/plugins/autotest/testtreemodel.h index 9ec8c4f6efc..f979a5ebdcd 100644 --- a/src/plugins/autotest/testtreemodel.h +++ b/src/plugins/autotest/testtreemodel.h @@ -104,7 +104,7 @@ private: void removeFiles(const QStringList &files); bool sweepChildren(TestTreeItem *item); void insertItemInParent(TestTreeItem *item, TestTreeItem *root, bool groupingEnabled); - void revalidateCheckState(TestTreeItem *item); + void revalidateCheckState(ITestTreeItem *item); void setupParsingConnections(); void filterAndInsert(TestTreeItem *item, TestTreeItem *root, bool groupingEnabled); QList testItemsByName(TestTreeItem *root, const QString &testName);