From 369753acbc0aca71156eecd8c40ca2a9825986a3 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Tue, 28 Feb 2023 09:15:40 +0100 Subject: [PATCH] AutoTest: Redo results filtering Instead of performing costly computations keep track of the currently present types in the respective branch of the subtree. This also makes the filter invalidation on newly added items obsolete. Fixes: QTCREATORBUG-28831 Change-Id: I12cd31dc95b4c310a04ced2c98de3d509032482c Reviewed-by: David Schulz --- src/plugins/autotest/testresultmodel.cpp | 59 ++++++++++++------------ src/plugins/autotest/testresultmodel.h | 5 +- src/plugins/autotest/testresultspane.cpp | 1 + 3 files changed, 35 insertions(+), 30 deletions(-) diff --git a/src/plugins/autotest/testresultmodel.cpp b/src/plugins/autotest/testresultmodel.cpp index 7bf750412f6..434d6474103 100644 --- a/src/plugins/autotest/testresultmodel.cpp +++ b/src/plugins/autotest/testresultmodel.cpp @@ -197,6 +197,23 @@ QString TestResultItem::resultString() const return m_summaryResult->failed ? QString("FAIL") : QString("PASS"); } +//! \return true if descendant types have changed, false otherwise +bool TestResultItem::updateDescendantTypes(ResultType t) +{ + if (t == ResultType::TestStart || t == ResultType::TestEnd) // these are special + return false; + + if (m_descendantsTypes.contains(t)) + return false; + m_descendantsTypes.insert(t); + return true; +} + +bool TestResultItem::descendantTypesContainsAnyOf(const QSet &types) const +{ + return !m_descendantsTypes.isEmpty() && m_descendantsTypes.intersects(types); +} + /********************************* TestResultModel *****************************************/ TestResultModel::TestResultModel(QObject *parent) @@ -217,7 +234,8 @@ void TestResultModel::updateParent(const TestResultItem *item) return; bool changed = false; parentItem->updateResult(changed, item->testResult().result(), item->summaryResult()); - if (!changed) + bool changedType = parentItem->updateDescendantTypes(item->testResult().result()); + if (!changed && !changedType) return; emit dataChanged(parentItem->index(), parentItem->index()); updateParent(parentItem); @@ -426,10 +444,6 @@ TestResultFilterModel::TestResultFilterModel(TestResultModel *sourceModel, QObje { setSourceModel(sourceModel); enableAllResultTypes(true); - - // instead of using invalidate() from results pane when adding a new result ( QTBUG-103952 ) - connect(sourceModel, &QAbstractItemModel::rowsInserted, - this, &TestResultFilterModel::invalidateFilter); } void TestResultFilterModel::enableAllResultTypes(bool enabled) @@ -441,7 +455,7 @@ void TestResultFilterModel::enableAllResultTypes(bool enabled) << ResultType::MessageFatal << ResultType::Invalid << ResultType::BlacklistedPass << ResultType::BlacklistedFail << ResultType::BlacklistedXFail << ResultType::BlacklistedXPass << ResultType::Benchmark - << ResultType::MessageCurrentTest << ResultType::TestStart << ResultType::TestEnd + << ResultType::MessageCurrentTest << ResultType::MessageInfo << ResultType::MessageSystem << ResultType::Application << ResultType::MessageError; } else { @@ -499,34 +513,21 @@ bool TestResultFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &s QModelIndex index = m_sourceModel->index(sourceRow, 0, sourceParent); if (!index.isValid()) return false; + const ResultType resultType = m_sourceModel->testResult(index).result(); if (resultType == ResultType::TestStart) { - TestResultItem *item = m_sourceModel->itemForIndex(index); - QTC_ASSERT(item, return false); - if (!item->summaryResult()) - return true; - return acceptTestCaseResult(index); + auto item = m_sourceModel->itemForIndex(index); + return item && item->descendantTypesContainsAnyOf(m_enabled); + } else if (resultType == ResultType::TestEnd) { + auto item = m_sourceModel->itemForIndex(index); + if (!item) + return false; + auto parent = item->parent(); + return parent && parent->descendantTypesContainsAnyOf(m_enabled); } + return m_enabled.contains(resultType); } -bool TestResultFilterModel::acceptTestCaseResult(const QModelIndex &srcIndex) const -{ - for (int row = 0, count = m_sourceModel->rowCount(srcIndex); row < count; ++row) { - const QModelIndex &child = m_sourceModel->index(row, 0, srcIndex); - TestResultItem *item = m_sourceModel->itemForIndex(child); - const ResultType type = item->testResult().result(); - - if (type == ResultType::TestStart) { - if (!item->summaryResult()) - return true; - if (acceptTestCaseResult(child)) - return true; - } else if (m_enabled.contains(type)) - return true; - } - return false; -} - } // namespace Internal } // namespace Autotest diff --git a/src/plugins/autotest/testresultmodel.h b/src/plugins/autotest/testresultmodel.h index 97655ca57b9..cbf3422b78f 100644 --- a/src/plugins/autotest/testresultmodel.h +++ b/src/plugins/autotest/testresultmodel.h @@ -44,8 +44,12 @@ public: QString resultString() const; std::optional summaryResult() const { return m_summaryResult; } + bool updateDescendantTypes(ResultType t); + bool descendantTypesContainsAnyOf(const QSet &types) const; + private: TestResult m_testResult; + QSet m_descendantsTypes; std::optional m_summaryResult; }; @@ -99,7 +103,6 @@ protected: bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override; private: - bool acceptTestCaseResult(const QModelIndex &srcIndex) const; TestResultModel *m_sourceModel; QSet m_enabled; }; diff --git a/src/plugins/autotest/testresultspane.cpp b/src/plugins/autotest/testresultspane.cpp index d101d2027b3..87d44b0f2f9 100644 --- a/src/plugins/autotest/testresultspane.cpp +++ b/src/plugins/autotest/testresultspane.cpp @@ -107,6 +107,7 @@ TestResultsPane::TestResultsPane(QObject *parent) : m_model = new TestResultModel(this); m_filterModel = new TestResultFilterModel(m_model, this); m_filterModel->setDynamicSortFilter(true); + m_filterModel->setRecursiveFilteringEnabled(true); m_treeView->setModel(m_filterModel); TestResultDelegate *trd = new TestResultDelegate(this); m_treeView->setItemDelegate(trd);