diff --git a/src/plugins/autotest/gtest/gtest_utils.cpp b/src/plugins/autotest/gtest/gtest_utils.cpp index 4ce68760a25..94f608b3341 100644 --- a/src/plugins/autotest/gtest/gtest_utils.cpp +++ b/src/plugins/autotest/gtest/gtest_utils.cpp @@ -25,6 +25,7 @@ #include "gtest_utils.h" +#include #include namespace Autotest { @@ -51,6 +52,17 @@ bool isGTestTyped(const QString ¯o) return macro == QStringLiteral("TYPED_TEST") || macro == QStringLiteral("TYPED_TEST_P"); } +bool isValidGTestFilter(const QString &filterExpression) +{ + // this still is not a 100% validation - but a compromise + // - numbers after '.' should get prohibited + // - more than one '.' inside a single filter should be prohibited + static const QRegularExpression regex("^(:*([_a-zA-Z*.?][_a-zA-Z0-9*.?]*:*)*)?" + "(-(:*([_a-zA-Z*.?][_a-zA-Z0-9*.?]*:*)*)?)?$"); + + return regex.match(filterExpression).hasMatch(); +} + } // namespace GTestUtils } // namespace Internal } // namespace Autotest diff --git a/src/plugins/autotest/gtest/gtest_utils.h b/src/plugins/autotest/gtest/gtest_utils.h index 93dd1ad6215..9336c3309c2 100644 --- a/src/plugins/autotest/gtest/gtest_utils.h +++ b/src/plugins/autotest/gtest/gtest_utils.h @@ -34,6 +34,7 @@ namespace GTestUtils { bool isGTestMacro(const QString ¯o); bool isGTestParameterized(const QString ¯o); bool isGTestTyped(const QString ¯o); +bool isValidGTestFilter(const QString &filterExpression); } // namespace GTestUtils } // namespace Internal diff --git a/src/plugins/autotest/gtest/gtestconstants.h b/src/plugins/autotest/gtest/gtestconstants.h index ef7c3e94f68..9df49767946 100644 --- a/src/plugins/autotest/gtest/gtestconstants.h +++ b/src/plugins/autotest/gtest/gtestconstants.h @@ -35,6 +35,13 @@ const char FRAMEWORK_NAME[] = "GTest"; const char FRAMEWORK_SETTINGS_CATEGORY[] = QT_TRANSLATE_NOOP("GTestFramework", "Google Test"); const unsigned FRAMEWORK_PRIORITY = 10; +enum GroupMode +{ + None, + Directory, + GTestFilter +}; + } // namespace Constants } // namespace GTest } // namespace AutoTest diff --git a/src/plugins/autotest/gtest/gtestframework.cpp b/src/plugins/autotest/gtest/gtestframework.cpp index 3117e9d3f1b..682a66f5475 100644 --- a/src/plugins/autotest/gtest/gtestframework.cpp +++ b/src/plugins/autotest/gtest/gtestframework.cpp @@ -24,11 +24,11 @@ ****************************************************************************/ #include "gtestframework.h" -#include "gtestconstants.h" #include "gtestsettings.h" #include "gtestsettingspage.h" #include "gtesttreeitem.h" #include "gtestparser.h" +#include "../testframeworkmanager.h" namespace Autotest { namespace Internal { @@ -71,5 +71,27 @@ bool GTestFramework::hasFrameworkSettings() const return true; } +QString GTestFramework::currentGTestFilter() +{ + static const Core::Id id + = Core::Id(Constants::FRAMEWORK_PREFIX).withSuffix(GTest::Constants::FRAMEWORK_NAME); + const auto manager = TestFrameworkManager::instance(); + + auto gSettings = qSharedPointerCast(manager->settingsForTestFramework(id)); + return gSettings.isNull() ? QString("*.*") : gSettings->gtestFilter; +} + +GTest::Constants::GroupMode GTestFramework::groupMode() +{ + static const Core::Id id + = Core::Id(Constants::FRAMEWORK_PREFIX).withSuffix(GTest::Constants::FRAMEWORK_NAME); + const auto manager = TestFrameworkManager::instance(); + if (!manager->groupingEnabled(id)) + return GTest::Constants::None; + + auto gSettings = qSharedPointerCast(manager->settingsForTestFramework(id)); + return gSettings.isNull() ? GTest::Constants::Directory : gSettings->groupMode; +} + } // namespace Internal } // namespace Autotest diff --git a/src/plugins/autotest/gtest/gtestframework.h b/src/plugins/autotest/gtest/gtestframework.h index 42c91118f52..754bd9e3fb5 100644 --- a/src/plugins/autotest/gtest/gtestframework.h +++ b/src/plugins/autotest/gtest/gtestframework.h @@ -26,6 +26,7 @@ #pragma once #include "../itestframework.h" +#include "gtestconstants.h" namespace Autotest { namespace Internal { @@ -39,6 +40,8 @@ public: IFrameworkSettings *createFrameworkSettings() const override; ITestSettingsPage *createSettingsPage(QSharedPointer settings) const override; bool hasFrameworkSettings() const override; + static GTest::Constants::GroupMode groupMode(); + static QString currentGTestFilter(); protected: ITestParser *createTestParser() const override; TestTreeItem *createRootNode() const override; diff --git a/src/plugins/autotest/gtest/gtestsettings.cpp b/src/plugins/autotest/gtest/gtestsettings.cpp index 9e68e7912b4..014d1eb8cd6 100644 --- a/src/plugins/autotest/gtest/gtestsettings.cpp +++ b/src/plugins/autotest/gtest/gtestsettings.cpp @@ -24,6 +24,7 @@ ****************************************************************************/ #include "gtestsettings.h" +#include "gtest_utils.h" namespace Autotest { namespace Internal { @@ -35,6 +36,8 @@ static const char runDisabledKey[] = "RunDisabled"; static const char seedKey[] = "Seed"; static const char shuffleKey[] = "Shuffle"; static const char throwOnFailureKey[] = "ThrowOnFailure"; +static const char groupModeKey[] = "GroupMode"; +static const char gtestFilterKey[] = "GTestFilter"; QString GTestSettings::name() const { @@ -50,6 +53,13 @@ void GTestSettings::fromFrameworkSettings(const QSettings *s) seed = s->value(seedKey, 0).toInt(); breakOnFailure = s->value(breakOnFailureKey, true).toBool(); throwOnFailure = s->value(throwOnFailureKey, false).toBool(); + // avoid problems if user messes around with the settings file + bool ok = false; + const int tmp = s->value(groupModeKey, GTest::Constants::Directory).toInt(&ok); + groupMode = ok ? static_cast(tmp) : GTest::Constants::Directory; + gtestFilter = s->value(gtestFilterKey, "*.*").toString(); + if (!GTestUtils::isValidGTestFilter(gtestFilter)) + gtestFilter = "*.*"; } void GTestSettings::toFrameworkSettings(QSettings *s) const @@ -61,6 +71,8 @@ void GTestSettings::toFrameworkSettings(QSettings *s) const s->setValue(seedKey, seed); s->setValue(breakOnFailureKey, breakOnFailure); s->setValue(throwOnFailureKey, throwOnFailure); + s->setValue(groupModeKey, groupMode); + s->setValue(gtestFilterKey, gtestFilter); } } // namespace Internal diff --git a/src/plugins/autotest/gtest/gtestsettings.h b/src/plugins/autotest/gtest/gtestsettings.h index 5cc68523f83..b7d34684009 100644 --- a/src/plugins/autotest/gtest/gtestsettings.h +++ b/src/plugins/autotest/gtest/gtestsettings.h @@ -26,6 +26,7 @@ #pragma once #include "../iframeworksettings.h" +#include "gtestconstants.h" namespace Autotest { namespace Internal { @@ -43,6 +44,8 @@ public: bool repeat = false; bool throwOnFailure = false; bool breakOnFailure = true; + GTest::Constants::GroupMode groupMode = GTest::Constants::Directory; + QString gtestFilter{"*.*"}; protected: void fromFrameworkSettings(const QSettings *s) override; diff --git a/src/plugins/autotest/gtest/gtestsettingspage.cpp b/src/plugins/autotest/gtest/gtestsettingspage.cpp index 932fc947dea..17054adaee9 100644 --- a/src/plugins/autotest/gtest/gtestsettingspage.cpp +++ b/src/plugins/autotest/gtest/gtestsettingspage.cpp @@ -23,20 +23,34 @@ ** ****************************************************************************/ -#include "../autotestconstants.h" #include "gtestconstants.h" #include "gtestsettingspage.h" #include "gtestsettings.h" +#include "gtest_utils.h" +#include "../autotestconstants.h" +#include "../testframeworkmanager.h" #include namespace Autotest { namespace Internal { +static bool validateFilter(Utils::FancyLineEdit *edit, QString */*error*/) +{ + return edit && GTestUtils::isValidGTestFilter(edit->text()); +} + GTestSettingsWidget::GTestSettingsWidget(QWidget *parent) : QWidget(parent) { m_ui.setupUi(this); + m_ui.filterLineEdit->setValidationFunction(&validateFilter); + m_ui.filterLineEdit->setEnabled(m_ui.groupModeCombo->currentIndex() == 1); + + connect(m_ui.groupModeCombo, &QComboBox::currentTextChanged, + this, [this] () { + m_ui.filterLineEdit->setEnabled(m_ui.groupModeCombo->currentIndex() == 1); + }); connect(m_ui.repeatGTestsCB, &QCheckBox::toggled, m_ui.repetitionSpin, &QSpinBox::setEnabled); connect(m_ui.shuffleGTestsCB, &QCheckBox::toggled, m_ui.seedSpin, &QSpinBox::setEnabled); } @@ -50,6 +64,9 @@ void GTestSettingsWidget::setSettings(const GTestSettings &settings) m_ui.seedSpin->setValue(settings.seed); m_ui.breakOnFailureCB->setChecked(settings.breakOnFailure); m_ui.throwOnFailureCB->setChecked(settings.throwOnFailure); + m_ui.groupModeCombo->setCurrentIndex(settings.groupMode - 1); // there's None for internal use + m_ui.filterLineEdit->setText(settings.gtestFilter); + m_currentGTestFilter = settings.gtestFilter; // store it temporarily (if edit is invalid) } GTestSettings GTestSettingsWidget::settings() const @@ -62,6 +79,12 @@ GTestSettings GTestSettingsWidget::settings() const result.seed = m_ui.seedSpin->value(); result.breakOnFailure = m_ui.breakOnFailureCB->isChecked(); result.throwOnFailure = m_ui.throwOnFailureCB->isChecked(); + result.groupMode = static_cast( + m_ui.groupModeCombo->currentIndex() + 1); + if (m_ui.filterLineEdit->isValid()) + result.gtestFilter = m_ui.filterLineEdit->text(); + else + result.gtestFilter = m_currentGTestFilter; return result; } @@ -88,8 +111,16 @@ void GTestSettingsPage::apply() { if (!m_widget) // page was not shown at all return; + + GTest::Constants::GroupMode oldGroupMode = m_settings->groupMode; + const QString oldFilter = m_settings->gtestFilter; *m_settings = m_widget->settings(); m_settings->toSettings(Core::ICore::settings()); + if (m_settings->groupMode == oldGroupMode && oldFilter == m_settings->gtestFilter) + return; + + auto id = Core::Id(Constants::FRAMEWORK_PREFIX).withSuffix(GTest::Constants::FRAMEWORK_NAME); + TestTreeModel::instance()->rebuild({id}); } } // namespace Internal diff --git a/src/plugins/autotest/gtest/gtestsettingspage.h b/src/plugins/autotest/gtest/gtestsettingspage.h index c17753be4b5..3d4bc787788 100644 --- a/src/plugins/autotest/gtest/gtestsettingspage.h +++ b/src/plugins/autotest/gtest/gtestsettingspage.h @@ -48,6 +48,7 @@ public: private: Ui::GTestSettingsPage m_ui; + QString m_currentGTestFilter; }; class GTestSettingsPage : public ITestSettingsPage diff --git a/src/plugins/autotest/gtest/gtestsettingspage.ui b/src/plugins/autotest/gtest/gtestsettingspage.ui index 5c20da93cb4..e0a13196df0 100644 --- a/src/plugins/autotest/gtest/gtestsettingspage.ui +++ b/src/plugins/autotest/gtest/gtestsettingspage.ui @@ -7,7 +7,7 @@ 0 0 449 - 210 + 232 @@ -128,6 +128,65 @@ + + + + + + Group mode: + + + + + + + Active filter: + + + + + + + Select on what grouping the tests should be based. + + + + Directory + + + + + GTest Filter + + + + + + + + Set the GTest filter to be used for grouping. +See Google Test documentation for further information on GTest filters. + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 60 + 20 + + + + + + @@ -158,6 +217,13 @@ + + + Utils::FancyLineEdit + QLineEdit +
utils/fancylineedit.h
+
+
diff --git a/src/plugins/autotest/gtest/gtesttreeitem.cpp b/src/plugins/autotest/gtest/gtesttreeitem.cpp index aab040a3107..2d69f769f79 100644 --- a/src/plugins/autotest/gtest/gtesttreeitem.cpp +++ b/src/plugins/autotest/gtest/gtesttreeitem.cpp @@ -25,6 +25,8 @@ #include "gtesttreeitem.h" #include "gtestconfiguration.h" +#include "gtestconstants.h" +#include "gtestframework.h" #include "gtestparser.h" #include "../testframeworkmanager.h" @@ -32,10 +34,23 @@ #include #include #include +#include + +#include namespace Autotest { namespace Internal { +static QString matchingString() +{ + return QCoreApplication::translate("GTestTreeItem", ""); +} + +static QString notMatchingString() +{ + return QCoreApplication::translate("GTestTreeItem", ""); +} + static QString gtestFilter(GTestTreeItem::TestStates states) { if ((states & GTestTreeItem::Parameterized) && (states & GTestTreeItem::Typed)) @@ -55,6 +70,35 @@ TestTreeItem *GTestTreeItem::copyWithoutChildren() return copied; } +static bool matchesFilter(const QString &filter, const QString &fullTestName) +{ + QStringList positive; + QStringList negative; + int startOfNegative = filter.indexOf('-'); + if (startOfNegative == -1) { + positive.append(filter.split(':', QString::SkipEmptyParts)); + } else { + positive.append(filter.left(startOfNegative).split(':', QString::SkipEmptyParts)); + negative.append(filter.mid(startOfNegative + 1).split(':', QString::SkipEmptyParts)); + } + + QString testName = fullTestName; + if (!testName.contains('.')) + testName.append('.'); + + for (const QString &curr : negative) { + QRegExp regex(curr, Qt::CaseSensitive, QRegExp::Wildcard); + if (regex.exactMatch(testName)) + return false; + } + for (const QString &curr : positive) { + QRegExp regex(curr, Qt::CaseSensitive, QRegExp::Wildcard); + if (regex.exactMatch(testName)) + return true; + } + return positive.isEmpty(); +} + QVariant GTestTreeItem::data(int column, int role) const { switch (role) { @@ -65,6 +109,20 @@ QVariant GTestTreeItem::data(int column, int role) const const QString &displayName = (m_state & Disabled) ? name().mid(9) : name(); return QVariant(displayName + nameSuffix()); } + case Qt::DecorationRole: + if (type() == GroupNode + && GTestFramework::groupMode() == GTest::Constants::GTestFilter) { + return Utils::Icons::FILTER.icon(); // TODO replace by an 'inked' filter w/o arrow + } + break; + case Qt::ToolTipRole: + if (type() == GroupNode + && GTestFramework::groupMode() == GTest::Constants::GTestFilter) { + const auto tpl = QString("

%1

%2

").arg(filePath()); + return tpl.arg(QCoreApplication::translate( + "GTestTreeItem", "Change GTest filter in use inside the settings.")); + } + break; case Qt::CheckStateRole: switch (type()) { case Root: @@ -225,18 +283,35 @@ TestTreeItem *GTestTreeItem::find(const TestParseResult *result) switch (type()) { case Root: if (TestFrameworkManager::instance()->groupingEnabled(result->frameworkId)) { - const QFileInfo fileInfo(parseResult->fileName); - const QFileInfo base(fileInfo.absolutePath()); - for (int row = 0; row < childCount(); ++row) { - GTestTreeItem *group = static_cast(childAt(row)); - if (group->filePath() != base.absoluteFilePath()) - continue; - if (auto groupChild = group->findChildByNameStateAndFile(parseResult->name, states, - parseResult->proFile)) { - return groupChild; + if (GTestFramework::groupMode() == GTest::Constants::Directory) { + const QFileInfo fileInfo(parseResult->fileName); + const QFileInfo base(fileInfo.absolutePath()); + for (int row = 0; row < childCount(); ++row) { + GTestTreeItem *group = static_cast(childAt(row)); + if (group->filePath() != base.absoluteFilePath()) + continue; + if (auto groupChild = group->findChildByNameStateAndFile( + parseResult->name, states,parseResult->proFile)) { + return groupChild; + } } + return nullptr; + } else { // GTestFilter + QTC_ASSERT(parseResult->children.size(), return nullptr); + auto fstChild = static_cast(parseResult->children.at(0)); + bool matching = matchesFilter(GTestFramework::currentGTestFilter(), + parseResult->name + '.' + fstChild->name); + for (int row = 0; row < childCount(); ++row) { + GTestTreeItem *group = static_cast(childAt(row)); + if ((matching && group->name() == matchingString()) + || (!matching && group->name() == notMatchingString())) { + if (auto groupChild = group->findChildByNameStateAndFile( + parseResult->name, states, parseResult->proFile)) + return groupChild; + } + } + return nullptr; } - return nullptr; } return findChildByNameStateAndFile(parseResult->name, states, parseResult->proFile); case GroupNode: @@ -264,9 +339,22 @@ TestTreeItem *GTestTreeItem::createParentGroupNode() const { if (type() != TestCase) return nullptr; - const QFileInfo fileInfo(filePath()); - const QFileInfo base(fileInfo.absolutePath()); - return new GTestTreeItem(base.baseName(), fileInfo.absolutePath(), TestTreeItem::GroupNode); + if (GTestFramework::groupMode() == GTest::Constants::Directory) { + const QFileInfo fileInfo(filePath()); + const QFileInfo base(fileInfo.absolutePath()); + return new GTestTreeItem(base.baseName(), fileInfo.absolutePath(), TestTreeItem::GroupNode); + } else { // GTestFilter + QTC_ASSERT(childCount(), return nullptr); // paranoia + const TestTreeItem *firstChild = childItem(0); + const QString activeFilter = GTestFramework::currentGTestFilter(); + const QString fullTestName = name() + '.' + firstChild->name(); + const QString groupNodeName = + matchesFilter(activeFilter, fullTestName) ? matchingString() : notMatchingString(); + auto groupNode = new GTestTreeItem(groupNodeName, activeFilter, TestTreeItem::GroupNode); + if (groupNodeName == notMatchingString()) + groupNode->setData(0, Qt::Unchecked, Qt::CheckStateRole); + return groupNode; + } } bool GTestTreeItem::modifyTestSetContent(const GTestParseResult *result) @@ -329,5 +417,61 @@ QSet GTestTreeItem::internalTargets() const return result; } +bool GTestTreeItem::isGroupNodeFor(const TestTreeItem *other) const +{ + QTC_ASSERT(other, return false); + if (type() != TestTreeItem::GroupNode) + return false; + + if (GTestFramework::groupMode() == GTest::Constants::Directory) { + return QFileInfo(other->filePath()).absolutePath() == filePath(); + } else { // GTestFilter + QString fullName; + if (other->type() == TestCase) { + fullName = other->name(); + if (other->childCount()) + fullName += '.' + other->childItem(0)->name(); + } else if (other->type() == TestFunctionOrSet) { + QTC_ASSERT(other->parentItem(), return false); + fullName = other->parentItem()->name() + '.' + other->name(); + } else if (other->type() == GroupNode) { // can happen on a rebuild if only filter changes + return false; + } else { + QTC_ASSERT(false, return false); + } + if (GTestFramework::currentGTestFilter() != filePath()) // filter has changed in settings + return false; + bool matches = matchesFilter(filePath(), fullName); + return (matches && name() == matchingString()) + || (!matches && name() == notMatchingString()); + } +} + +TestTreeItem *GTestTreeItem::applyFilters() +{ + if (type() != TestCase) + return nullptr; + + if (GTestFramework::groupMode() != GTest::Constants::GTestFilter) + return nullptr; + + const QString gtestFilter = GTestFramework::currentGTestFilter(); + TestTreeItem *filtered = nullptr; + for (int row = childCount() - 1; row >= 0; --row) { + GTestTreeItem *child = static_cast(childItem(row)); + if (!matchesFilter(gtestFilter, name() + '.' + child->name())) { + if (!filtered) { + filtered = copyWithoutChildren(); + filtered->setData(0, Qt::Unchecked, Qt::CheckStateRole); + } + auto childCopy = child->copyWithoutChildren(); + childCopy->setData(0, Qt::Unchecked, Qt::CheckStateRole); + filtered->appendChild(childCopy); + removeChildAt(row); + } + } + return filtered; +} + } // namespace Internal } // namespace Autotest diff --git a/src/plugins/autotest/gtest/gtesttreeitem.h b/src/plugins/autotest/gtest/gtesttreeitem.h index 08378a0718f..eac6c9696c6 100644 --- a/src/plugins/autotest/gtest/gtesttreeitem.h +++ b/src/plugins/autotest/gtest/gtesttreeitem.h @@ -69,7 +69,8 @@ public: const QString &proFile) const; QString nameSuffix() const; QSet internalTargets() const override; - + bool isGroupNodeFor(const TestTreeItem *other) const override; + TestTreeItem *applyFilters() override; private: bool modifyTestSetContent(const GTestParseResult *result); QList getTestConfigurations(bool ignoreCheckState) const; diff --git a/src/plugins/autotest/testtreeitem.h b/src/plugins/autotest/testtreeitem.h index 1a0c25e9bf0..44a91a1682b 100644 --- a/src/plugins/autotest/testtreeitem.h +++ b/src/plugins/autotest/testtreeitem.h @@ -118,6 +118,9 @@ public: virtual bool modify(const TestParseResult *result) = 0; virtual bool isGroupNodeFor(const TestTreeItem *other) const; virtual TestTreeItem *createParentGroupNode() const = 0; + // based on (internal) filters this will be used to filter out sub items (and remove them) + // returns a copy of the item that contains the filtered out children or nullptr + virtual TestTreeItem *applyFilters() { return nullptr; } virtual QSet internalTargets() const; protected: void copyBasicDataFrom(const TestTreeItem *other); diff --git a/src/plugins/autotest/testtreemodel.cpp b/src/plugins/autotest/testtreemodel.cpp index 805398bc9f3..d525c717a2c 100644 --- a/src/plugins/autotest/testtreemodel.cpp +++ b/src/plugins/autotest/testtreemodel.cpp @@ -211,6 +211,17 @@ void TestTreeModel::syncTestFrameworks() emit updatedActiveFrameworks(sortedIds.size()); } +void TestTreeModel::filterAndInsert(TestTreeItem *item, TestTreeItem *root, bool groupingEnabled) +{ + TestTreeItem *filtered = item->applyFilters(); + if (item->type() != TestTreeItem::TestCase || item->childCount()) + insertItemInParent(item, root, groupingEnabled); + else // might be that all children have been filtered out + delete item; + if (filtered) + insertItemInParent(filtered, root, groupingEnabled); +} + void TestTreeModel::rebuild(const QList &frameworkIds) { TestFrameworkManager *frameworkManager = TestFrameworkManager::instance(); @@ -219,18 +230,19 @@ void TestTreeModel::rebuild(const QList &frameworkIds) const bool groupingEnabled = TestFrameworkManager::instance()->groupingEnabled(id); for (int row = frameworkRoot->childCount() - 1; row >= 0; --row) { auto testItem = frameworkRoot->childItem(row); - if (!groupingEnabled && testItem->type() == TestTreeItem::GroupNode) { - // do not re-insert the GroupNode, but process its children and delete it afterwards + 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->childItem(childRow); takeItem(childTestItem); - insertItemInParent(childTestItem, frameworkRoot, groupingEnabled); + filterAndInsert(childTestItem, frameworkRoot, groupingEnabled); } - delete takeItem(testItem); + if (!groupingEnabled || testItem->childCount() == 0) + delete takeItem(testItem); } else { takeItem(testItem); - insertItemInParent(testItem, frameworkRoot, groupingEnabled); + filterAndInsert(testItem, frameworkRoot, groupingEnabled); } } } @@ -404,7 +416,8 @@ void TestTreeModel::handleParseResult(const TestParseResult *result, TestTreeIte TestTreeItem *newItem = result->createTestTreeItem(); QTC_ASSERT(newItem, return); - insertItemInParent(newItem, parentNode, groupingEnabled); + // it might be necessary to "split" created item + filterAndInsert(newItem, parentNode, groupingEnabled); } void TestTreeModel::removeAllTestItems() diff --git a/src/plugins/autotest/testtreemodel.h b/src/plugins/autotest/testtreemodel.h index 95298953ed2..b9f4d5ea13d 100644 --- a/src/plugins/autotest/testtreemodel.h +++ b/src/plugins/autotest/testtreemodel.h @@ -91,6 +91,7 @@ private: void revalidateCheckState(TestTreeItem *item); explicit TestTreeModel(QObject *parent = 0); void setupParsingConnections(); + void filterAndInsert(TestTreeItem *item, TestTreeItem *root, bool groupingEnabled); QList testItemsByName(TestTreeItem *root, const QString &testName); TestCodeParser *m_parser;