AutoTest: Add action to run all tests from current file

Run specific test functions since one test case can be implemented in multiple files.

Task-number: QTCREATORBUG-20329
Change-Id: I07f435c264f18e9608caa5b7ee20dff2d33ee9c0
Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io>
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
Sergey Morozov
2018-05-05 22:28:55 +03:00
committed by Christian Stenger
parent 887a0538cd
commit 57edd22d11
19 changed files with 156 additions and 2 deletions

View File

@@ -17,5 +17,7 @@
<file>images/text@2x.png</file> <file>images/text@2x.png</file>
<file>images/visual.png</file> <file>images/visual.png</file>
<file>images/visual@2x.png</file> <file>images/visual@2x.png</file>
<file>images/run_file.png</file>
<file>images/run_file@2x.png</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@@ -33,6 +33,7 @@ namespace Constants {
const char ACTION_SCAN_ID[] = "AutoTest.ScanAction"; const char ACTION_SCAN_ID[] = "AutoTest.ScanAction";
const char ACTION_RUN_ALL_ID[] = "AutoTest.RunAll"; const char ACTION_RUN_ALL_ID[] = "AutoTest.RunAll";
const char ACTION_RUN_SELECTED_ID[] = "AutoTest.RunSelected"; 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_UCURSOR[] = "AutoTest.RunUnderCursor";
const char ACTION_RUN_DBG_UCURSOR[] = "AutoTest.RunDebugUnderCursor"; const char ACTION_RUN_DBG_UCURSOR[] = "AutoTest.RunDebugUnderCursor";
const char MENU_ID[] = "AutoTest.Menu"; const char MENU_ID[] = "AutoTest.Menu";

View File

@@ -37,6 +37,8 @@ const Utils::Icon SORT_NATURALLY({
const Utils::Icon RUN_SELECTED_OVERLAY({ const Utils::Icon RUN_SELECTED_OVERLAY({
{":/autotest/images/runselected_boxes.png", Utils::Theme::BackgroundColorDark}, {":/autotest/images/runselected_boxes.png", Utils::Theme::BackgroundColorDark},
{":/autotest/images/runselected_tickmarks.png", Utils::Theme::IconsBaseColor}}); {":/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({ const Utils::Icon RESULT_PASS({
{":/utils/images/filledcircle.png", Utils::Theme::OutputPanes_TestPassTextColor}}, {":/utils/images/filledcircle.png", Utils::Theme::OutputPanes_TestPassTextColor}},

View File

@@ -127,6 +127,18 @@ void AutotestPlugin::initializeMenuEntries()
action->setEnabled(false); action->setEnabled(false);
menu->addAction(command); 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); action = new QAction(tr("Re&scan Tests"), this);
command = ActionManager::registerAction(action, Constants::ACTION_SCAN_ID); command = ActionManager::registerAction(action, Constants::ACTION_SCAN_ID);
command->setDefaultKeySequence(QKeySequence(tr("Alt+Shift+T,Alt+S"))); command->setDefaultKeySequence(QKeySequence(tr("Alt+Shift+T,Alt+S")));
@@ -219,6 +231,26 @@ void AutotestPlugin::onRunSelectedTriggered()
runner->prepareToRunTests(TestRunMode::Run); 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<TestConfiguration *> tests = model->getTestsForFile(fileName);
if (tests.isEmpty())
return;
TestRunner *runner = TestRunner::instance();
runner->setSelectedTests(tests);
runner->prepareToRunTests(TestRunMode::Run);
}
void AutotestPlugin::onRunUnderCursorTriggered(TestRunMode mode) void AutotestPlugin::onRunUnderCursorTriggered(TestRunMode mode)
{ {
QTextCursor cursor = Utils::Text::wordStartCursor( 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_ALL_ID)->action()->setEnabled(canRun);
ActionManager::command(Constants::ACTION_RUN_SELECTED_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); ActionManager::command(Constants::ACTION_SCAN_ID)->action()->setEnabled(canScan);
ActionContainer *contextMenu = ActionManager::actionContainer(CppEditor::Constants::M_CONTEXT); ActionContainer *contextMenu = ActionManager::actionContainer(CppEditor::Constants::M_CONTEXT);

View File

@@ -60,6 +60,7 @@ private:
void initializeMenuEntries(); void initializeMenuEntries();
void onRunAllTriggered(); void onRunAllTriggered();
void onRunSelectedTriggered(); void onRunSelectedTriggered();
void onRunFileTriggered();
void onRunUnderCursorTriggered(TestRunMode mode); void onRunUnderCursorTriggered(TestRunMode mode);
QList<QObject *> createTestObjects() const override; QList<QObject *> createTestObjects() const override;
const QSharedPointer<TestSettings> m_settings; const QSharedPointer<TestSettings> m_settings;

View File

@@ -268,6 +268,39 @@ QList<TestConfiguration *> GTestTreeItem::getSelectedTestConfigurations() const
return getTestConfigurations(false); return getTestConfigurations(false);
} }
QList<TestConfiguration *> GTestTreeItem::getTestConfigurationsForFile(const Utils::FileName &fileName) const
{
QList<TestConfiguration *> result;
ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject();
if (!project || type() != Root)
return result;
QHash<QString, TestCases> 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<GTestTreeItem *>(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) TestTreeItem *GTestTreeItem::find(const TestParseResult *result)
{ {
QTC_ASSERT(result, return nullptr); QTC_ASSERT(result, return nullptr);

View File

@@ -57,6 +57,7 @@ public:
TestConfiguration *debugConfiguration() const override; TestConfiguration *debugConfiguration() const override;
QList<TestConfiguration *> getAllTestConfigurations() const override; QList<TestConfiguration *> getAllTestConfigurations() const override;
QList<TestConfiguration *> getSelectedTestConfigurations() const override; QList<TestConfiguration *> getSelectedTestConfigurations() const override;
QList<TestConfiguration *> getTestConfigurationsForFile(const Utils::FileName &fileName) const override;
TestTreeItem *find(const TestParseResult *result) override; TestTreeItem *find(const TestParseResult *result) override;
TestTreeItem *findChild(const TestTreeItem *other) override; TestTreeItem *findChild(const TestTreeItem *other) override;
bool modify(const TestParseResult *result) override; bool modify(const TestParseResult *result) override;

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 B

View File

@@ -235,6 +235,35 @@ QList<TestConfiguration *> QtTestTreeItem::getSelectedTestConfigurations() const
return result; return result;
} }
QList<TestConfiguration *> QtTestTreeItem::getTestConfigurationsForFile(const Utils::FileName &fileName) const
{
QList<TestConfiguration *> result;
ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject();
if (!project || type() != Root)
return result;
QHash<TestTreeItem *, QStringList> 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) TestTreeItem *QtTestTreeItem::find(const TestParseResult *result)
{ {
QTC_ASSERT(result, return nullptr); QTC_ASSERT(result, return nullptr);

View File

@@ -45,6 +45,7 @@ public:
TestConfiguration *debugConfiguration() const override; TestConfiguration *debugConfiguration() const override;
QList<TestConfiguration *> getAllTestConfigurations() const override; QList<TestConfiguration *> getAllTestConfigurations() const override;
QList<TestConfiguration *> getSelectedTestConfigurations() const override; QList<TestConfiguration *> getSelectedTestConfigurations() const override;
QList<TestConfiguration *> getTestConfigurationsForFile(const Utils::FileName &fileName) const override;
TestTreeItem *find(const TestParseResult *result) override; TestTreeItem *find(const TestParseResult *result) override;
TestTreeItem *findChild(const TestTreeItem *other) override; TestTreeItem *findChild(const TestTreeItem *other) override;
bool modify(const TestParseResult *result) override; bool modify(const TestParseResult *result) override;

View File

@@ -279,6 +279,36 @@ QList<TestConfiguration *> QuickTestTreeItem::getSelectedTestConfigurations() co
return result; return result;
} }
QList<TestConfiguration *> QuickTestTreeItem::getTestConfigurationsForFile(const Utils::FileName &fileName) const
{
QList<TestConfiguration *> result;
ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject();
if (!project || type() != Root)
return result;
QHash<TestTreeItem *, QStringList> 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) TestTreeItem *QuickTestTreeItem::find(const TestParseResult *result)
{ {
QTC_ASSERT(result, return nullptr); QTC_ASSERT(result, return nullptr);

View File

@@ -45,6 +45,7 @@ public:
TestConfiguration *debugConfiguration() const override; TestConfiguration *debugConfiguration() const override;
QList<TestConfiguration *> getAllTestConfigurations() const override; QList<TestConfiguration *> getAllTestConfigurations() const override;
QList<TestConfiguration *> getSelectedTestConfigurations() const override; QList<TestConfiguration *> getSelectedTestConfigurations() const override;
QList<TestConfiguration *> getTestConfigurationsForFile(const Utils::FileName &fileName) const override;
TestTreeItem *find(const TestParseResult *result) override; TestTreeItem *find(const TestParseResult *result) override;
TestTreeItem *findChild(const TestTreeItem *other) override; TestTreeItem *findChild(const TestTreeItem *other) override;
bool modify(const TestParseResult *result) override; bool modify(const TestParseResult *result) override;

View File

@@ -178,6 +178,9 @@ void TestResultsPane::createToolButtons()
m_runSelected = new QToolButton(m_treeView); m_runSelected = new QToolButton(m_treeView);
m_runSelected->setDefaultAction(Core::ActionManager::command(Constants::ACTION_RUN_SELECTED_ID)->action()); 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 = new QToolButton(m_treeView);
m_stopTestRun->setIcon(Utils::Icons::STOP_SMALL_TOOLBAR.icon()); m_stopTestRun->setIcon(Utils::Icons::STOP_SMALL_TOOLBAR.icon());
m_stopTestRun->setToolTip(tr("Stop Test Run")); m_stopTestRun->setToolTip(tr("Stop Test Run"));
@@ -248,8 +251,8 @@ QWidget *TestResultsPane::outputWidget(QWidget *parent)
QList<QWidget *> TestResultsPane::toolBarWidgets() const QList<QWidget *> TestResultsPane::toolBarWidgets() const
{ {
return {m_expandCollapse, m_runAll, m_runSelected, m_stopTestRun, m_outputToggleButton, return {m_expandCollapse, m_runAll, m_runSelected, m_runFile, m_stopTestRun,
m_filterButton}; m_outputToggleButton, m_filterButton};
} }
QString TestResultsPane::displayName() const QString TestResultsPane::displayName() const

View File

@@ -132,6 +132,7 @@ private:
QToolButton *m_expandCollapse; QToolButton *m_expandCollapse;
QToolButton *m_runAll; QToolButton *m_runAll;
QToolButton *m_runSelected; QToolButton *m_runSelected;
QToolButton *m_runFile;
QToolButton *m_stopTestRun; QToolButton *m_stopTestRun;
QToolButton *m_filterButton; QToolButton *m_filterButton;
QToolButton *m_outputToggleButton; QToolButton *m_outputToggleButton;

View File

@@ -259,6 +259,11 @@ QList<TestConfiguration *> TestTreeItem::getSelectedTestConfigurations() const
return QList<TestConfiguration *>(); return QList<TestConfiguration *>();
} }
QList<TestConfiguration *> TestTreeItem::getTestConfigurationsForFile(const Utils::FileName &) const
{
return QList<TestConfiguration *>();
}
bool TestTreeItem::lessThan(const TestTreeItem *other, SortMode mode) const bool TestTreeItem::lessThan(const TestTreeItem *other, SortMode mode) const
{ {
const QString &lhs = data(0, Qt::DisplayRole).toString(); const QString &lhs = data(0, Qt::DisplayRole).toString();

View File

@@ -42,6 +42,7 @@ namespace {
} }
namespace CppTools { class CppModelManager; } namespace CppTools { class CppModelManager; }
namespace Utils { class FileName; }
namespace Autotest { namespace Autotest {
namespace Internal { namespace Internal {
@@ -113,6 +114,7 @@ public:
TestConfiguration *asConfiguration(TestRunMode mode) const; TestConfiguration *asConfiguration(TestRunMode mode) const;
virtual QList<TestConfiguration *> getAllTestConfigurations() const; virtual QList<TestConfiguration *> getAllTestConfigurations() const;
virtual QList<TestConfiguration *> getSelectedTestConfigurations() const; virtual QList<TestConfiguration *> getSelectedTestConfigurations() const;
virtual QList<TestConfiguration *> getTestConfigurationsForFile(const Utils::FileName &fileName) const;
virtual bool lessThan(const TestTreeItem *other, SortMode mode) const; virtual bool lessThan(const TestTreeItem *other, SortMode mode) const;
virtual TestTreeItem *find(const TestParseResult *result) = 0; virtual TestTreeItem *find(const TestParseResult *result) = 0;
virtual TestTreeItem *findChild(const TestTreeItem *other) = 0; virtual TestTreeItem *findChild(const TestTreeItem *other) = 0;

View File

@@ -158,6 +158,14 @@ QList<TestConfiguration *> TestTreeModel::getSelectedTests() const
return result; return result;
} }
QList<TestConfiguration *> TestTreeModel::getTestsForFile(const Utils::FileName &fileName) const
{
QList<TestConfiguration *> result;
for (Utils::TreeItem *frameworkRoot : *rootItem())
result.append(static_cast<TestTreeItem *>(frameworkRoot)->getTestConfigurationsForFile(fileName));
return result;
}
QList<TestTreeItem *> TestTreeModel::testItemsByName(TestTreeItem *root, const QString &testName) QList<TestTreeItem *> TestTreeModel::testItemsByName(TestTreeItem *root, const QString &testName)
{ {
QList<TestTreeItem *> result; QList<TestTreeItem *> result;

View File

@@ -54,6 +54,7 @@ public:
bool hasTests() const; bool hasTests() const;
QList<TestConfiguration *> getAllTestCases() const; QList<TestConfiguration *> getAllTestCases() const;
QList<TestConfiguration *> getSelectedTests() const; QList<TestConfiguration *> getSelectedTests() const;
QList<TestConfiguration *> getTestsForFile(const Utils::FileName &fileName) const;
QList<TestTreeItem *> testItemsByName(const QString &testName); QList<TestTreeItem *> testItemsByName(const QString &testName);
void syncTestFrameworks(); void syncTestFrameworks();
void rebuild(const QList<Core::Id> &frameworkIds); void rebuild(const QList<Core::Id> &frameworkIds);