diff --git a/src/plugins/autotest/autotest.qrc b/src/plugins/autotest/autotest.qrc
index f4f6892d47d..0c3a24d7ace 100644
--- a/src/plugins/autotest/autotest.qrc
+++ b/src/plugins/autotest/autotest.qrc
@@ -17,5 +17,7 @@
images/text@2x.png
images/visual.png
images/visual@2x.png
+ images/run_file.png
+ images/run_file@2x.png
diff --git a/src/plugins/autotest/autotestconstants.h b/src/plugins/autotest/autotestconstants.h
index 2de0fe43abc..1f92aba915e 100644
--- a/src/plugins/autotest/autotestconstants.h
+++ b/src/plugins/autotest/autotestconstants.h
@@ -33,6 +33,7 @@ namespace Constants {
const char ACTION_SCAN_ID[] = "AutoTest.ScanAction";
const char ACTION_RUN_ALL_ID[] = "AutoTest.RunAll";
const char ACTION_RUN_SELECTED_ID[] = "AutoTest.RunSelected";
+const char ACTION_RUN_FILE_ID[] = "AutoTest.RunFile";
const char ACTION_RUN_UCURSOR[] = "AutoTest.RunUnderCursor";
const char ACTION_RUN_DBG_UCURSOR[] = "AutoTest.RunDebugUnderCursor";
const char MENU_ID[] = "AutoTest.Menu";
diff --git a/src/plugins/autotest/autotesticons.h b/src/plugins/autotest/autotesticons.h
index 07a8f86875a..30f5a0d424d 100644
--- a/src/plugins/autotest/autotesticons.h
+++ b/src/plugins/autotest/autotesticons.h
@@ -37,6 +37,8 @@ const Utils::Icon SORT_NATURALLY({
const Utils::Icon RUN_SELECTED_OVERLAY({
{":/autotest/images/runselected_boxes.png", Utils::Theme::BackgroundColorDark},
{":/autotest/images/runselected_tickmarks.png", Utils::Theme::IconsBaseColor}});
+const Utils::Icon RUN_FILE_OVERLAY({
+ {":/autotest/images/run_file.png", Utils::Theme::IconsBaseColor}});
const Utils::Icon RESULT_PASS({
{":/utils/images/filledcircle.png", Utils::Theme::OutputPanes_TestPassTextColor}},
diff --git a/src/plugins/autotest/autotestplugin.cpp b/src/plugins/autotest/autotestplugin.cpp
index d7bb68cdec6..e3b48316c7c 100644
--- a/src/plugins/autotest/autotestplugin.cpp
+++ b/src/plugins/autotest/autotestplugin.cpp
@@ -127,6 +127,18 @@ void AutotestPlugin::initializeMenuEntries()
action->setEnabled(false);
menu->addAction(command);
+ action = new QAction(tr("Run Tests for Current &File"), this);
+ Utils::Icon runFileIcon = Utils::Icons::RUN_SMALL_TOOLBAR;
+ for (const Utils::IconMaskAndColor &maskAndColor : Icons::RUN_FILE_OVERLAY)
+ runFileIcon.append(maskAndColor);
+ action->setIcon(runFileIcon.icon());
+ action->setToolTip(tr("Run Tests for Current File"));
+ command = ActionManager::registerAction(action, Constants::ACTION_RUN_FILE_ID);
+ command->setDefaultKeySequence(QKeySequence(tr("Alt+Shift+T,Alt+F")));
+ connect(action, &QAction::triggered, this, &AutotestPlugin::onRunFileTriggered);
+ action->setEnabled(false);
+ menu->addAction(command);
+
action = new QAction(tr("Re&scan Tests"), this);
command = ActionManager::registerAction(action, Constants::ACTION_SCAN_ID);
command->setDefaultKeySequence(QKeySequence(tr("Alt+Shift+T,Alt+S")));
@@ -219,6 +231,26 @@ void AutotestPlugin::onRunSelectedTriggered()
runner->prepareToRunTests(TestRunMode::Run);
}
+void AutotestPlugin::onRunFileTriggered()
+{
+ const IDocument *document = EditorManager::currentDocument();
+ if (!document)
+ return;
+
+ const Utils::FileName &fileName = document->filePath();
+ if (fileName.isEmpty())
+ return;
+
+ TestTreeModel *model = TestTreeModel::instance();
+ const QList tests = model->getTestsForFile(fileName);
+ if (tests.isEmpty())
+ return;
+
+ TestRunner *runner = TestRunner::instance();
+ runner->setSelectedTests(tests);
+ runner->prepareToRunTests(TestRunMode::Run);
+}
+
void AutotestPlugin::onRunUnderCursorTriggered(TestRunMode mode)
{
QTextCursor cursor = Utils::Text::wordStartCursor(
@@ -263,6 +295,7 @@ void AutotestPlugin::updateMenuItemsEnabledState()
ActionManager::command(Constants::ACTION_RUN_ALL_ID)->action()->setEnabled(canRun);
ActionManager::command(Constants::ACTION_RUN_SELECTED_ID)->action()->setEnabled(canRun);
+ ActionManager::command(Constants::ACTION_RUN_FILE_ID)->action()->setEnabled(canRun);
ActionManager::command(Constants::ACTION_SCAN_ID)->action()->setEnabled(canScan);
ActionContainer *contextMenu = ActionManager::actionContainer(CppEditor::Constants::M_CONTEXT);
diff --git a/src/plugins/autotest/autotestplugin.h b/src/plugins/autotest/autotestplugin.h
index cbd85937eb6..efd8d31e77f 100644
--- a/src/plugins/autotest/autotestplugin.h
+++ b/src/plugins/autotest/autotestplugin.h
@@ -60,6 +60,7 @@ private:
void initializeMenuEntries();
void onRunAllTriggered();
void onRunSelectedTriggered();
+ void onRunFileTriggered();
void onRunUnderCursorTriggered(TestRunMode mode);
QList createTestObjects() const override;
const QSharedPointer m_settings;
diff --git a/src/plugins/autotest/gtest/gtesttreeitem.cpp b/src/plugins/autotest/gtest/gtesttreeitem.cpp
index b24f57f6943..8f7c56dab97 100644
--- a/src/plugins/autotest/gtest/gtesttreeitem.cpp
+++ b/src/plugins/autotest/gtest/gtesttreeitem.cpp
@@ -268,6 +268,39 @@ QList GTestTreeItem::getSelectedTestConfigurations() const
return getTestConfigurations(false);
}
+QList GTestTreeItem::getTestConfigurationsForFile(const Utils::FileName &fileName) const
+{
+ QList result;
+ ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject();
+ if (!project || type() != Root)
+ return result;
+
+ QHash testCases;
+ const QString &file = fileName.toString();
+ forAllChildren([&testCases, &file](TestTreeItem *node) {
+ if (node->type() == Type::TestFunctionOrSet && node->filePath() == file) {
+ QTC_ASSERT(node->parentItem(), return);
+ const GTestTreeItem *testCase = static_cast(node->parentItem());
+ QTC_ASSERT(testCase->type() == Type::TestCase, return);
+ TestCases &cases = testCases[testCase->proFile()];
+ cases.filters.append(
+ gtestFilter(testCase->state()).arg(testCase->name(), node->name()));
+ cases.internalTargets.unite(node->internalTargets());
+ }
+ });
+ for (auto it = testCases.begin(), end = testCases.end(); it != end; ++it) {
+ for (const QString &target : qAsConst(it.value().internalTargets)) {
+ GTestConfiguration *tc = new GTestConfiguration;
+ tc->setTestCases(it.value().filters);
+ tc->setProjectFile(it.key());
+ tc->setProject(project);
+ tc->setInternalTarget(target);
+ result << tc;
+ }
+ }
+ return result;
+}
+
TestTreeItem *GTestTreeItem::find(const TestParseResult *result)
{
QTC_ASSERT(result, return nullptr);
diff --git a/src/plugins/autotest/gtest/gtesttreeitem.h b/src/plugins/autotest/gtest/gtesttreeitem.h
index c3ff8dba71f..22225ae7f5d 100644
--- a/src/plugins/autotest/gtest/gtesttreeitem.h
+++ b/src/plugins/autotest/gtest/gtesttreeitem.h
@@ -57,6 +57,7 @@ public:
TestConfiguration *debugConfiguration() const override;
QList getAllTestConfigurations() const override;
QList getSelectedTestConfigurations() const override;
+ QList getTestConfigurationsForFile(const Utils::FileName &fileName) const override;
TestTreeItem *find(const TestParseResult *result) override;
TestTreeItem *findChild(const TestTreeItem *other) override;
bool modify(const TestParseResult *result) override;
diff --git a/src/plugins/autotest/images/run_file.png b/src/plugins/autotest/images/run_file.png
new file mode 100644
index 00000000000..6a3bfc766f3
Binary files /dev/null and b/src/plugins/autotest/images/run_file.png differ
diff --git a/src/plugins/autotest/images/run_file@2x.png b/src/plugins/autotest/images/run_file@2x.png
new file mode 100644
index 00000000000..4b386818c99
Binary files /dev/null and b/src/plugins/autotest/images/run_file@2x.png differ
diff --git a/src/plugins/autotest/qtest/qttesttreeitem.cpp b/src/plugins/autotest/qtest/qttesttreeitem.cpp
index 46a2ca03e92..2f375a484e7 100644
--- a/src/plugins/autotest/qtest/qttesttreeitem.cpp
+++ b/src/plugins/autotest/qtest/qttesttreeitem.cpp
@@ -235,6 +235,35 @@ QList QtTestTreeItem::getSelectedTestConfigurations() const
return result;
}
+QList QtTestTreeItem::getTestConfigurationsForFile(const Utils::FileName &fileName) const
+{
+ QList result;
+
+ ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject();
+ if (!project || type() != Root)
+ return result;
+
+ QHash testFunctions;
+ const QString &file = fileName.toString();
+ forAllChildren([&testFunctions, &file](TestTreeItem *node) {
+ if (node->type() == Type::TestFunctionOrSet && node->filePath() == file) {
+ QTC_ASSERT(node->parentItem(), return);
+ TestTreeItem *testCase = node->parentItem();
+ QTC_ASSERT(testCase->type() == Type::TestCase, return);
+ testFunctions[testCase] << node->name();
+ }
+ });
+
+ for (auto it = testFunctions.cbegin(), end = testFunctions.cend(); it != end; ++it) {
+ TestConfiguration *tc = it.key()->testConfiguration();
+ QTC_ASSERT(tc, continue);
+ tc->setTestCases(it.value());
+ result << tc;
+ }
+
+ return result;
+}
+
TestTreeItem *QtTestTreeItem::find(const TestParseResult *result)
{
QTC_ASSERT(result, return nullptr);
diff --git a/src/plugins/autotest/qtest/qttesttreeitem.h b/src/plugins/autotest/qtest/qttesttreeitem.h
index 9b70b735fad..2de8eb8f821 100644
--- a/src/plugins/autotest/qtest/qttesttreeitem.h
+++ b/src/plugins/autotest/qtest/qttesttreeitem.h
@@ -45,6 +45,7 @@ public:
TestConfiguration *debugConfiguration() const override;
QList getAllTestConfigurations() const override;
QList getSelectedTestConfigurations() const override;
+ QList getTestConfigurationsForFile(const Utils::FileName &fileName) const override;
TestTreeItem *find(const TestParseResult *result) override;
TestTreeItem *findChild(const TestTreeItem *other) override;
bool modify(const TestParseResult *result) override;
diff --git a/src/plugins/autotest/quick/quicktesttreeitem.cpp b/src/plugins/autotest/quick/quicktesttreeitem.cpp
index 6c0c4b4feb9..dc17be469b7 100644
--- a/src/plugins/autotest/quick/quicktesttreeitem.cpp
+++ b/src/plugins/autotest/quick/quicktesttreeitem.cpp
@@ -279,6 +279,36 @@ QList QuickTestTreeItem::getSelectedTestConfigurations() co
return result;
}
+QList QuickTestTreeItem::getTestConfigurationsForFile(const Utils::FileName &fileName) const
+{
+ QList result;
+ ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject();
+ if (!project || type() != Root)
+ return result;
+
+ QHash testFunctions;
+ const QString &file = fileName.toString();
+ forAllChildren([&testFunctions, &file](TestTreeItem *node) {
+ if (node->type() == Type::TestFunctionOrSet && node->filePath() == file) {
+ QTC_ASSERT(node->parentItem(), return);
+ TestTreeItem *testCase = node->parentItem();
+ QTC_ASSERT(testCase->type() == Type::TestCase, return);
+ if (testCase->name().isEmpty())
+ return;
+ testFunctions[testCase] << testCase->name() + "::" + node->name();
+ }
+ });
+
+ for (auto it = testFunctions.cbegin(), end = testFunctions.cend(); it != end; ++it) {
+ TestConfiguration *tc = it.key()->testConfiguration();
+ QTC_ASSERT(tc, continue);
+ tc->setTestCases(it.value());
+ result << tc;
+ }
+
+ return result;
+}
+
TestTreeItem *QuickTestTreeItem::find(const TestParseResult *result)
{
QTC_ASSERT(result, return nullptr);
diff --git a/src/plugins/autotest/quick/quicktesttreeitem.h b/src/plugins/autotest/quick/quicktesttreeitem.h
index 48c2467de98..e00afc434b2 100644
--- a/src/plugins/autotest/quick/quicktesttreeitem.h
+++ b/src/plugins/autotest/quick/quicktesttreeitem.h
@@ -45,6 +45,7 @@ public:
TestConfiguration *debugConfiguration() const override;
QList getAllTestConfigurations() const override;
QList getSelectedTestConfigurations() const override;
+ QList getTestConfigurationsForFile(const Utils::FileName &fileName) const override;
TestTreeItem *find(const TestParseResult *result) override;
TestTreeItem *findChild(const TestTreeItem *other) override;
bool modify(const TestParseResult *result) override;
diff --git a/src/plugins/autotest/testresultspane.cpp b/src/plugins/autotest/testresultspane.cpp
index d2b3ec97dd1..3047e6d7107 100644
--- a/src/plugins/autotest/testresultspane.cpp
+++ b/src/plugins/autotest/testresultspane.cpp
@@ -178,6 +178,9 @@ void TestResultsPane::createToolButtons()
m_runSelected = new QToolButton(m_treeView);
m_runSelected->setDefaultAction(Core::ActionManager::command(Constants::ACTION_RUN_SELECTED_ID)->action());
+ m_runFile = new QToolButton(m_treeView);
+ m_runFile->setDefaultAction(Core::ActionManager::command(Constants::ACTION_RUN_FILE_ID)->action());
+
m_stopTestRun = new QToolButton(m_treeView);
m_stopTestRun->setIcon(Utils::Icons::STOP_SMALL_TOOLBAR.icon());
m_stopTestRun->setToolTip(tr("Stop Test Run"));
@@ -248,8 +251,8 @@ QWidget *TestResultsPane::outputWidget(QWidget *parent)
QList TestResultsPane::toolBarWidgets() const
{
- return {m_expandCollapse, m_runAll, m_runSelected, m_stopTestRun, m_outputToggleButton,
- m_filterButton};
+ return {m_expandCollapse, m_runAll, m_runSelected, m_runFile, m_stopTestRun,
+ m_outputToggleButton, m_filterButton};
}
QString TestResultsPane::displayName() const
diff --git a/src/plugins/autotest/testresultspane.h b/src/plugins/autotest/testresultspane.h
index 7156cd1c859..285b5baf0f4 100644
--- a/src/plugins/autotest/testresultspane.h
+++ b/src/plugins/autotest/testresultspane.h
@@ -132,6 +132,7 @@ private:
QToolButton *m_expandCollapse;
QToolButton *m_runAll;
QToolButton *m_runSelected;
+ QToolButton *m_runFile;
QToolButton *m_stopTestRun;
QToolButton *m_filterButton;
QToolButton *m_outputToggleButton;
diff --git a/src/plugins/autotest/testtreeitem.cpp b/src/plugins/autotest/testtreeitem.cpp
index 3d07c8076d4..c136ed30ab2 100644
--- a/src/plugins/autotest/testtreeitem.cpp
+++ b/src/plugins/autotest/testtreeitem.cpp
@@ -259,6 +259,11 @@ QList TestTreeItem::getSelectedTestConfigurations() const
return QList();
}
+QList TestTreeItem::getTestConfigurationsForFile(const Utils::FileName &) const
+{
+ return QList();
+}
+
bool TestTreeItem::lessThan(const TestTreeItem *other, SortMode mode) const
{
const QString &lhs = data(0, Qt::DisplayRole).toString();
diff --git a/src/plugins/autotest/testtreeitem.h b/src/plugins/autotest/testtreeitem.h
index 0180c88fefe..dbb82f486a3 100644
--- a/src/plugins/autotest/testtreeitem.h
+++ b/src/plugins/autotest/testtreeitem.h
@@ -42,6 +42,7 @@ namespace {
}
namespace CppTools { class CppModelManager; }
+namespace Utils { class FileName; }
namespace Autotest {
namespace Internal {
@@ -113,6 +114,7 @@ public:
TestConfiguration *asConfiguration(TestRunMode mode) const;
virtual QList getAllTestConfigurations() const;
virtual QList getSelectedTestConfigurations() const;
+ virtual QList getTestConfigurationsForFile(const Utils::FileName &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;
diff --git a/src/plugins/autotest/testtreemodel.cpp b/src/plugins/autotest/testtreemodel.cpp
index ef7a30c4c91..48e32240328 100644
--- a/src/plugins/autotest/testtreemodel.cpp
+++ b/src/plugins/autotest/testtreemodel.cpp
@@ -158,6 +158,14 @@ QList TestTreeModel::getSelectedTests() const
return result;
}
+QList TestTreeModel::getTestsForFile(const Utils::FileName &fileName) const
+{
+ QList result;
+ for (Utils::TreeItem *frameworkRoot : *rootItem())
+ result.append(static_cast(frameworkRoot)->getTestConfigurationsForFile(fileName));
+ return result;
+}
+
QList TestTreeModel::testItemsByName(TestTreeItem *root, const QString &testName)
{
QList result;
diff --git a/src/plugins/autotest/testtreemodel.h b/src/plugins/autotest/testtreemodel.h
index b9f4d5ea13d..78974e67bdd 100644
--- a/src/plugins/autotest/testtreemodel.h
+++ b/src/plugins/autotest/testtreemodel.h
@@ -54,6 +54,7 @@ public:
bool hasTests() const;
QList getAllTestCases() const;
QList getSelectedTests() const;
+ QList getTestsForFile(const Utils::FileName &fileName) const;
QList testItemsByName(const QString &testName);
void syncTestFrameworks();
void rebuild(const QList &frameworkIds);