AutoTest: Add project based {en|dis}abling of test frameworks

Provide integration into the 'Project' view which allows to set
some settings on a per project base.
For now only enabling or disabling of test frameworks.

Task-number: QTCREATORBUG-16704
Change-Id: Iedd9a300164931e07a21cbb4e5a222be3266c81e
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Christian Stenger
2019-08-05 15:47:10 +02:00
committed by David Schulz
parent edcd955aad
commit 43e27f76b3
13 changed files with 476 additions and 49 deletions

View File

@@ -36,6 +36,7 @@ add_qtc_plugin(AutoTest
itestframework.h
itestparser.cpp itestparser.h
itestsettingspage.h
projectsettingswidget.cpp projectsettingswidget.h
qtest/qttest_utils.cpp qtest/qttest_utils.h
qtest/qttestconfiguration.cpp qtest/qttestconfiguration.h
qtest/qttestconstants.h
@@ -59,6 +60,7 @@ add_qtc_plugin(AutoTest
testframeworkmanager.cpp testframeworkmanager.h
testnavigationwidget.cpp testnavigationwidget.h
testoutputreader.cpp testoutputreader.h
testprojectsettings.cpp testprojectsettings.h
testresult.cpp testresult.h
testresultdelegate.cpp testresultdelegate.h
testresultmodel.cpp testresultmodel.h

View File

@@ -6,23 +6,27 @@ include(../../qtcreatorplugin.pri)
DEFINES += AUTOTEST_LIBRARY
SOURCES += \
testtreeview.cpp \
testtreemodel.cpp \
testtreeitem.cpp \
testcodeparser.cpp \
autotestplugin.cpp \
testrunner.cpp \
itestparser.cpp \
projectsettingswidget.cpp \
testcodeparser.cpp \
testconfiguration.cpp \
testresult.cpp \
testresultspane.cpp \
testresultmodel.cpp \
testresultdelegate.cpp \
testtreeitemdelegate.cpp \
testsettings.cpp \
testsettingspage.cpp \
testeditormark.cpp \
testframeworkmanager.cpp \
testnavigationwidget.cpp \
testoutputreader.cpp \
itestparser.cpp \
testprojectsettings.cpp \
testresult.cpp \
testresultdelegate.cpp \
testresultmodel.cpp \
testresultspane.cpp \
testrunner.cpp \
testsettings.cpp \
testsettingspage.cpp \
testtreeitem.cpp \
testtreeitemdelegate.cpp \
testtreemodel.cpp \
testtreeview.cpp \
gtest/gtestconfiguration.cpp \
gtest/gtestparser.cpp \
gtest/gtesttreeitem.cpp \
@@ -57,34 +61,37 @@ SOURCES += \
boost/boosttestoutputreader.cpp \
boost/boosttestresult.cpp \
boost/boosttestsettings.cpp \
boost/boosttestsettingspage.cpp \
testframeworkmanager.cpp \
testeditormark.cpp
boost/boosttestsettingspage.cpp
HEADERS += \
testtreeview.h \
testtreemodel.h \
testtreeitem.h \
testcodeparser.h \
autotestplugin.h \
autotest_global.h \
autotestconstants.h \
testrunner.h \
autotesticons.h \
autotestplugin.h \
iframeworksettings.h \
itestframework.h \
itestparser.h \
itestsettingspage.h \
projectsettingswidget.h \
testcodeparser.h \
testconfiguration.h \
testresult.h \
testresultspane.h \
testresultmodel.h \
testresultdelegate.h \
testtreeitemdelegate.h \
testsettings.h \
testsettingspage.h \
testeditormark.h \
testframeworkmanager.h \
testnavigationwidget.h \
testoutputreader.h \
autotesticons.h \
itestframework.h \
iframeworksettings.h \
itestparser.h \
testprojectsettings.h \
testresult.h \
testresultdelegate.h \
testresultmodel.h \
testresultspane.h \
testrunconfiguration.h \
testrunner.h \
testsettings.h \
testsettingspage.h \
testtreeitem.h \
testtreeitemdelegate.h \
testtreemodel.h \
testtreeview.h \
gtest/gtestconfiguration.h \
gtest/gtestparser.h \
gtest/gtesttreeitem.h \
@@ -122,11 +129,7 @@ HEADERS += \
boost/boosttestoutputreader.h \
boost/boosttestresult.h \
boost/boosttestsettingspage.h \
boost/boosttestsettings.h \
testframeworkmanager.h \
testrunconfiguration.h \
itestsettingspage.h \
testeditormark.h
boost/boosttestsettings.h
RESOURCES += \
autotest.qrc

View File

@@ -37,6 +37,8 @@ QtcPlugin {
"autotestconstants.h",
"autotestplugin.cpp",
"autotestplugin.h",
"projectsettingswidget.cpp",
"projectsettingswidget.h",
"testcodeparser.cpp",
"testcodeparser.h",
"testconfiguration.cpp",
@@ -70,6 +72,8 @@ QtcPlugin {
"testtreeview.h",
"testoutputreader.cpp",
"testoutputreader.h",
"testprojectsettings.cpp",
"testprojectsettings.h",
"itestparser.cpp",
"itestparser.h",
"itestframework.h",

View File

@@ -47,6 +47,7 @@ const char FRAMEWORK_PREFIX[] = "AutoTest.Framework.";
const char SETTINGSPAGE_PREFIX[] = "A.AutoTest.";
const char SETTINGSGROUP[] = "Autotest";
const char TASK_MARK_ID[] = "Autotest.TaskMark";
const char SK_USE_GLOBAL[] = "AutoTest.UseGlobal";
} // namespace Constants
namespace Internal {

View File

@@ -26,8 +26,10 @@
#include "autotestplugin.h"
#include "autotestconstants.h"
#include "autotesticons.h"
#include "projectsettingswidget.h"
#include "testcodeparser.h"
#include "testframeworkmanager.h"
#include "testprojectsettings.h"
#include "testrunner.h"
#include "testsettings.h"
#include "testsettingspage.h"
@@ -54,6 +56,7 @@
#include <projectexplorer/buildmanager.h>
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/projectexplorericons.h>
#include <projectexplorer/projectpanelfactory.h>
#include <projectexplorer/runconfiguration.h>
#include <projectexplorer/session.h>
#include <projectexplorer/target.h>
@@ -78,6 +81,7 @@ using namespace Autotest::Internal;
using namespace Core;
static AutotestPlugin *s_instance = nullptr;
static QHash<ProjectExplorer::Project *, TestProjectSettings *> s_projectSettings;
AutotestPlugin::AutotestPlugin()
: m_settings(new TestSettings)
@@ -103,6 +107,15 @@ QSharedPointer<TestSettings> AutotestPlugin::settings()
return s_instance->m_settings;
}
TestProjectSettings *AutotestPlugin::projectSettings(ProjectExplorer::Project *project)
{
auto &settings = s_projectSettings[project];
if (!settings)
settings = new TestProjectSettings(project);
return settings;
}
void AutotestPlugin::initializeMenuEntries()
{
ActionContainer *menu = ActionManager::createMenu(Constants::MENU_ID);
@@ -184,13 +197,27 @@ bool AutotestPlugin::initialize(const QStringList &arguments, QString *errorStri
m_navigationWidgetFactory = new TestNavigationWidgetFactory;
m_resultsPane = TestResultsPane::instance();
auto panelFactory = new ProjectExplorer::ProjectPanelFactory();
panelFactory->setPriority(666);
// panelFactory->setIcon(); // TODO ?
panelFactory->setDisplayName(tr("Testing"));
panelFactory->setCreateWidgetFunction([](ProjectExplorer::Project *project) {
return new ProjectTestSettingsWidget(project);
});
ProjectExplorer::ProjectPanelFactory::registerFactory(panelFactory);
m_frameworkManager->activateFrameworksFromSettings(m_settings);
TestTreeModel::instance()->syncTestFrameworks();
TestTreeModel::instance()->scheduleTestFrameworksSync(true);
connect(ProjectExplorer::SessionManager::instance(),
&ProjectExplorer::SessionManager::startupProjectChanged, this, [this] {
m_runconfigCache.clear();
});
connect(ProjectExplorer::SessionManager::instance(),
&ProjectExplorer::SessionManager::aboutToRemoveProject,
this, [] (ProjectExplorer::Project *project) {
delete s_projectSettings.take(project);
});
return true;
}

View File

@@ -31,13 +31,17 @@
#include <QMap>
namespace ProjectExplorer { class RunConfiguration; }
namespace ProjectExplorer {
class Project;
class RunConfiguration;
}
namespace Autotest {
namespace Internal {
class TestFrameworkManager;
class TestNavigationWidgetFactory;
class TestProjectSettings;
class TestResultsPane;
struct TestSettings;
class TestSettingsPage;
@@ -67,6 +71,7 @@ public:
ShutdownFlag aboutToShutdown() override;
static QSharedPointer<TestSettings> settings();
static TestProjectSettings *projectSettings(ProjectExplorer::Project *project);
static void updateMenuItemsEnabledState();
static void cacheRunConfigChoice(const QString &buildTargetKey, const ChoicePair &choice);
static ChoicePair cachedChoiceFor(const QString &buildTargetKey);

View File

@@ -0,0 +1,110 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "autotestplugin.h"
#include "projectsettingswidget.h"
#include "testframeworkmanager.h"
#include "testprojectsettings.h"
#include <QBoxLayout>
#include <QComboBox>
#include <QLabel>
#include <QTreeWidget>
namespace Autotest {
namespace Internal {
enum ItemDataRole { FrameworkIdRole = Qt::UserRole + 1 };
static QSpacerItem *createSpacer(QSizePolicy::Policy horizontal, QSizePolicy::Policy vertical)
{
return new QSpacerItem(20, 10, horizontal, vertical);
}
ProjectTestSettingsWidget::ProjectTestSettingsWidget(ProjectExplorer::Project *project,
QWidget *parent)
: QWidget(parent)
, m_projectSettings(AutotestPlugin::projectSettings(project))
{
auto verticalLayout = new QVBoxLayout(this);
m_useGlobalSettings = new QComboBox;
m_useGlobalSettings->addItem(tr("Global"));
m_useGlobalSettings->addItem(tr("Custom"));
auto generalWidget = new QWidget;
auto groupBoxLayout = new QVBoxLayout;
m_activeFrameworks = new QTreeWidget;
m_activeFrameworks->setHeaderHidden(true);
m_activeFrameworks->setRootIsDecorated(false);
groupBoxLayout->addWidget(new QLabel(tr("Active frameworks:")));
groupBoxLayout->addWidget(m_activeFrameworks);
generalWidget->setLayout(groupBoxLayout);
auto horizontalLayout = new QHBoxLayout;
horizontalLayout->addWidget(m_useGlobalSettings);
horizontalLayout->addItem(createSpacer(QSizePolicy::Expanding, QSizePolicy::Minimum));
verticalLayout->addLayout(horizontalLayout);
horizontalLayout = new QHBoxLayout;
verticalLayout->addItem(createSpacer(QSizePolicy::Minimum, QSizePolicy::Fixed));
horizontalLayout->addWidget(generalWidget);
horizontalLayout->addItem(createSpacer(QSizePolicy::Expanding, QSizePolicy::Minimum));
verticalLayout->addLayout(horizontalLayout);
verticalLayout->addItem(createSpacer(QSizePolicy::Minimum, QSizePolicy::Expanding));
m_useGlobalSettings->setCurrentIndex(m_projectSettings->useGlobalSettings() ? 0 : 1);
generalWidget->setDisabled(m_projectSettings->useGlobalSettings());
populateFrameworks(m_projectSettings->activeFrameworks());
connect(m_useGlobalSettings, QOverload<int>::of(&QComboBox::currentIndexChanged),
this, [this, generalWidget](int index) {
generalWidget->setEnabled(index != 0);
m_projectSettings->setUseGlobalSettings(index == 0);
});
connect(m_activeFrameworks, &QTreeWidget::itemChanged,
this, &ProjectTestSettingsWidget::onActiveFrameworkChanged);
}
void ProjectTestSettingsWidget::populateFrameworks(const QMap<Core::Id, bool> &frameworks)
{
TestFrameworkManager *frameworkManager = TestFrameworkManager::instance();
auto end = frameworks.cend();
for (auto it = frameworks.cbegin(); it != end; ++it) {
auto *item = new QTreeWidgetItem(m_activeFrameworks,
QStringList(frameworkManager->frameworkNameForId(it.key())));
item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable);
item->setCheckState(0, it.value() ? Qt::Checked : Qt::Unchecked);
item->setData(0, FrameworkIdRole, it.key().toSetting());
}
}
void ProjectTestSettingsWidget::onActiveFrameworkChanged(QTreeWidgetItem *item, int column)
{
auto id = Core::Id::fromSetting(item->data(column, FrameworkIdRole));
m_projectSettings->activateFramework(id, item->data(0, Qt::CheckStateRole) == Qt::Checked);
}
} // namespace Internal
} // namespace Autotest

View File

@@ -0,0 +1,59 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include <QWidget>
QT_BEGIN_NAMESPACE
class QComboBox;
class QTreeWidget;
class QTreeWidgetItem;
QT_END_NAMESPACE
namespace Core { class Id; }
namespace ProjectExplorer { class Project; }
namespace Autotest {
namespace Internal {
class TestProjectSettings;
class ProjectTestSettingsWidget : public QWidget
{
Q_OBJECT
public:
explicit ProjectTestSettingsWidget(ProjectExplorer::Project *project,
QWidget *parent = nullptr);
private:
void populateFrameworks(const QMap<Core::Id, bool> &frameworks);
void onActiveFrameworkChanged(QTreeWidgetItem *item, int column);
TestProjectSettings *m_projectSettings;
QComboBox *m_useGlobalSettings = nullptr;
QTreeWidget *m_activeFrameworks = nullptr;
};
} // namespace Internal
} // namespace Autotest

View File

@@ -0,0 +1,103 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "testprojectsettings.h"
#include "autotestconstants.h"
#include "testframeworkmanager.h"
#include <projectexplorer/session.h>
#include <utils/algorithm.h>
namespace Autotest {
namespace Internal {
static const char SK_ACTIVE_FRAMEWORKS[] = "AutoTest.ActiveFrameworks";
TestProjectSettings::TestProjectSettings(ProjectExplorer::Project *project)
: m_project(project)
{
load();
connect(project, &ProjectExplorer::Project::settingsLoaded,
this, &TestProjectSettings::load);
connect(project, &ProjectExplorer::Project::aboutToSaveSettings,
this, &TestProjectSettings::save);
}
TestProjectSettings::~TestProjectSettings()
{
save();
}
void TestProjectSettings::setUseGlobalSettings(bool useGlobal)
{
if (m_useGlobalSettings == useGlobal)
return;
m_useGlobalSettings = useGlobal;
TestTreeModel::instance()->scheduleTestFrameworksSync(false);
}
void TestProjectSettings::activateFramework(const Core::Id &id, bool activate)
{
if (m_activeTestFrameworks.value(id) != activate) {
m_activeTestFrameworks[id] = activate;
TestTreeModel::instance()->scheduleTestFrameworksSync(false);
}
}
void TestProjectSettings::load()
{
const QVariant useGlobal = m_project->namedSettings(Constants::SK_USE_GLOBAL);
m_useGlobalSettings = useGlobal.isValid() ? useGlobal.toBool() : true;
TestFrameworkManager *frameworkManager = TestFrameworkManager::instance();
const QList<Core::Id> registered = frameworkManager->sortedRegisteredFrameworkIds();
const QVariant activeFrameworks = m_project->namedSettings(SK_ACTIVE_FRAMEWORKS);
m_activeTestFrameworks.clear();
if (activeFrameworks.isValid()) {
const QMap<QString, QVariant> frameworksMap = activeFrameworks.toMap();
for (const Core::Id &id : registered) {
const QString idStr = id.toString();
bool active = frameworksMap.value(idStr, frameworkManager->isActive(id)).toBool();
m_activeTestFrameworks.insert(id, active);
}
} else {
for (const Core::Id &id : registered)
m_activeTestFrameworks.insert(id, frameworkManager->isActive(id));
}
}
void TestProjectSettings::save()
{
m_project->setNamedSettings(Constants::SK_USE_GLOBAL, m_useGlobalSettings);
QVariantMap activeFrameworks;
auto end = m_activeTestFrameworks.cend();
for (auto it = m_activeTestFrameworks.cbegin(); it != end; ++it)
activeFrameworks.insert(it.key().toString(), it.value());
m_project->setNamedSettings(SK_ACTIVE_FRAMEWORKS, activeFrameworks);
}
} // namespace Internal
} // namespace Autotest

View File

@@ -0,0 +1,56 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include <projectexplorer/project.h>
namespace Autotest {
namespace Internal {
class TestProjectSettings : public QObject
{
Q_OBJECT
public:
TestProjectSettings(ProjectExplorer::Project *project);
~TestProjectSettings();
void setUseGlobalSettings(bool useGlobal);
bool useGlobalSettings() const { return m_useGlobalSettings; }
void setActiveFrameworks(const QMap<Core::Id, bool> enabledFrameworks)
{ m_activeTestFrameworks = enabledFrameworks; }
QMap<Core::Id, bool> activeFrameworks() const { return m_activeTestFrameworks; }
void activateFramework(const Core::Id &id, bool activate);
private:
void load();
void save();
ProjectExplorer::Project *m_project;
bool m_useGlobalSettings = true;
QMap<Core::Id, bool> m_activeTestFrameworks;
};
} // namespace Internal
} // namespace Autotest

View File

@@ -165,7 +165,6 @@ void TestSettingsPage::apply()
if (!m_widget) // page was not shown at all
return;
const TestSettings newSettings = m_widget->settings();
bool frameworkSyncNecessary = newSettings.frameworks != m_settings->frameworks;
const QList<Core::Id> changedIds = Utils::filtered(newSettings.frameworksGrouping.keys(),
[newSettings, this] (const Core::Id &id) {
return newSettings.frameworksGrouping[id] != m_settings->frameworksGrouping[id];
@@ -174,9 +173,8 @@ void TestSettingsPage::apply()
m_settings->toSettings(Core::ICore::settings());
TestFrameworkManager *frameworkManager = TestFrameworkManager::instance();
frameworkManager->activateFrameworksFromSettings(m_settings);
if (frameworkSyncNecessary)
TestTreeModel::instance()->syncTestFrameworks();
else if (!changedIds.isEmpty())
TestTreeModel::instance()->scheduleTestFrameworksSync(true);
if (!changedIds.isEmpty())
TestTreeModel::instance()->rebuild(changedIds);
}

View File

@@ -27,6 +27,7 @@
#include "autotestplugin.h"
#include "testcodeparser.h"
#include "testframeworkmanager.h"
#include "testprojectsettings.h"
#include "testsettings.h"
#include "testtreeitem.h"
#include "testtreemodel.h"
@@ -53,6 +54,11 @@ TestTreeModel::TestTreeModel(QObject *parent) :
this, &TestTreeModel::sweep, Qt::QueuedConnection);
connect(m_parser, &TestCodeParser::parsingFailed,
this, &TestTreeModel::sweep, Qt::QueuedConnection);
connect(ProjectExplorer::SessionManager::instance(),
&ProjectExplorer::SessionManager::startupProjectChanged,
this, &TestTreeModel::onStartupProjectChanged);
connect(&m_syncFrameworksTimer, &QTimer::timeout, this, &TestTreeModel::syncTestFrameworks);
setupParsingConnections();
}
@@ -200,13 +206,55 @@ QList<TestTreeItem *> TestTreeModel::testItemsByName(const QString &testName)
void TestTreeModel::syncTestFrameworks()
{
ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject();
if (!project)
return;
QList<Core::Id> sortedIds;
TestFrameworkManager *frameworkManager = TestFrameworkManager::instance();
const QVariant useGlobal = project->namedSettings(Constants::SK_USE_GLOBAL);
if (!useGlobal.isValid() || AutotestPlugin::projectSettings(project)->useGlobalSettings()) {
sortedIds = frameworkManager->sortedActiveFrameworkIds();
} else { // we've got custom project settings
const TestProjectSettings *settings = AutotestPlugin::projectSettings(project);
const QMap<Core::Id, bool> active = settings->activeFrameworks();
sortedIds = Utils::filtered(active.keys(), [active](const Core::Id &id) {
return active.value(id);
});
}
syncFrameworks(sortedIds);
}
void TestTreeModel::scheduleTestFrameworksSync(bool immediately)
{
m_syncFrameworksTimer.start(immediately ? 0 : 3000);
}
void TestTreeModel::syncFrameworks(const QList<Core::Id> &sortedIds)
{
TestFrameworkManager *manager = TestFrameworkManager::instance();
// pre-check to avoid further processing when frameworks are unchanged
Utils::TreeItem *invisibleRoot = rootItem();
const int count = invisibleRoot->childCount();
if (count == sortedIds.size()) {
bool different = false;
QList<Core::Id> registered = manager->sortedRegisteredFrameworkIds();
for (int i = 0; i < count; ++i) {
if (manager->rootNodeForTestFramework(sortedIds[i]) != invisibleRoot->childAt(i)) {
different = true;
break;
}
}
if (!different)
return;
}
// remove all currently registered
removeTestRootNodes();
TestFrameworkManager *frameworkManager = TestFrameworkManager::instance();
QList<Core::Id> sortedIds = frameworkManager->sortedActiveFrameworkIds();
for (const Core::Id &id : sortedIds)
rootItem()->appendChild(frameworkManager->rootNodeForTestFramework(id));
rootItem()->appendChild(manager->rootNodeForTestFramework(id));
m_parser->syncTestFrameworks(sortedIds);
emit updatedActiveFrameworks(sortedIds.size());
@@ -424,6 +472,12 @@ void TestTreeModel::onParseResultReady(const TestParseResultPtr result)
handleParseResult(result.data(), rootNode);
}
void TestTreeModel::onStartupProjectChanged()
{
m_syncFrameworksTimer.stop();
scheduleTestFrameworksSync(true);
}
void TestTreeModel::handleParseResult(const TestParseResult *result, TestTreeItem *parentNode)
{
const bool groupingEnabled =

View File

@@ -33,6 +33,7 @@
#include <utils/treemodel.h>
#include <QSortFilterProxyModel>
#include <QTimer>
namespace Autotest {
namespace Internal {
@@ -58,7 +59,7 @@ public:
QList<TestConfiguration *> getSelectedTests() const;
QList<TestConfiguration *> getTestsForFile(const Utils::FilePath &fileName) const;
QList<TestTreeItem *> testItemsByName(const QString &testName);
void syncTestFrameworks();
void scheduleTestFrameworksSync(bool immediately);
void rebuild(const QList<Core::Id> &frameworkIds);
#ifdef WITH_TESTS
@@ -87,6 +88,7 @@ signals:
private:
void onParseResultReady(const TestParseResultPtr result);
void onStartupProjectChanged();
void handleParseResult(const TestParseResult *result, TestTreeItem *rootNode);
void removeAllTestItems();
void removeTestRootNodes();
@@ -97,9 +99,12 @@ private:
explicit TestTreeModel(QObject *parent = nullptr);
void setupParsingConnections();
void filterAndInsert(TestTreeItem *item, TestTreeItem *root, bool groupingEnabled);
void syncTestFrameworks();
void syncFrameworks(const QList<Core::Id> &sortedIds);
QList<TestTreeItem *> testItemsByName(TestTreeItem *root, const QString &testName);
TestCodeParser *m_parser;
QTimer m_syncFrameworksTimer;
};
class TestTreeSortFilterModel : public QSortFilterProxyModel