summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Stenger <christian.stenger@digia.com>2014-10-21 13:10:37 +0200
committerChristian Stenger <christian.stenger@theqtcompany.com>2014-12-04 13:52:15 +0100
commiteba497d92103072dd7dd88ee70d714e369e8063f (patch)
tree585b6a3d044dd2edb9bd79cb8503a43bbf5ebdad
parent44db2be195b38316e238eddad80b816ab96b6058 (diff)
downloadqt-creator-eba497d92103072dd7dd88ee70d714e369e8063f.tar.gz
Add filtering to test results
-rw-r--r--plugins/autotest/testresult.h2
-rw-r--r--plugins/autotest/testresultdelegate.cpp10
-rw-r--r--plugins/autotest/testresultmodel.cpp58
-rw-r--r--plugins/autotest/testresultmodel.h25
-rw-r--r--plugins/autotest/testresultspane.cpp66
-rw-r--r--plugins/autotest/testresultspane.h8
-rw-r--r--plugins/autotest/testtreemodel.cpp25
7 files changed, 163 insertions, 31 deletions
diff --git a/plugins/autotest/testresult.h b/plugins/autotest/testresult.h
index dc47691664..b8b6a2dd1a 100644
--- a/plugins/autotest/testresult.h
+++ b/plugins/autotest/testresult.h
@@ -76,4 +76,6 @@ bool operator==(const TestResult &t1, const TestResult &t2);
} // namespace Internal
} // namespace Autotest
+Q_DECLARE_METATYPE(Autotest::Internal::ResultType)
+
#endif // TESTRESULT_H
diff --git a/plugins/autotest/testresultdelegate.cpp b/plugins/autotest/testresultdelegate.cpp
index 1f423d2e3a..4231278276 100644
--- a/plugins/autotest/testresultdelegate.cpp
+++ b/plugins/autotest/testresultdelegate.cpp
@@ -64,9 +64,10 @@ void TestResultDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op
painter->drawRect(opt.rect);
painter->setPen(foreground);
- TestResultModel *resultModel = static_cast<TestResultModel *>(view->model());
+ TestResultFilterModel *resultFilterModel = static_cast<TestResultFilterModel *>(view->model());
+ TestResultModel *resultModel = static_cast<TestResultModel *>(resultFilterModel->sourceModel());
LayoutPositions positions(opt, resultModel);
- TestResult testResult = resultModel->testResult(index);
+ TestResult testResult = resultModel->testResult(resultFilterModel->mapToSource(index));
ResultType type = testResult.result();
QIcon icon = index.data(Qt::DecorationRole).value<QIcon>();
@@ -176,13 +177,14 @@ QSize TestResultDelegate::sizeHint(const QStyleOptionViewItem &option, const QMo
QFontMetrics fm(opt.font);
int fontHeight = fm.height();
- TestResultModel *resultModel = static_cast<TestResultModel *>(view->model());
+ TestResultFilterModel *resultFilterModel = static_cast<TestResultFilterModel *>(view->model());
+ TestResultModel *resultModel = static_cast<TestResultModel *>(resultFilterModel->sourceModel());
LayoutPositions positions(opt, resultModel);
QSize s;
s.setWidth(opt.rect.width());
if (selected) {
- TestResult testResult = resultModel->testResult(index);
+ TestResult testResult = resultModel->testResult(resultFilterModel->mapToSource(index));
QString output;
switch (testResult.result()) {
diff --git a/plugins/autotest/testresultmodel.cpp b/plugins/autotest/testresultmodel.cpp
index 1867987aa1..9c7291d2e1 100644
--- a/plugins/autotest/testresultmodel.cpp
+++ b/plugins/autotest/testresultmodel.cpp
@@ -21,6 +21,7 @@
#include <QDebug>
#include <QFontMetrics>
#include <QIcon>
+#include <QSortFilterProxyModel>
namespace Autotest {
namespace Internal {
@@ -70,7 +71,7 @@ static QIcon testResultIcon(ResultType result) {
QIcon(QLatin1String(":/images/debug.png")),
QIcon(QLatin1String(":/images/warn.png")),
QIcon(QLatin1String(":/images/fatal.png")),
- };
+ }; // provide an icon for unknown??
if (result < 0 || result >= MESSAGE_INTERNAL)
return QIcon();
@@ -116,6 +117,9 @@ void TestResultModel::clearTestResults()
return;
beginRemoveRows(QModelIndex(), 0, m_testResults.size() - 1);
m_testResults.clear();
+ m_lastMaxWidthIndex = 0;
+ m_maxWidthOfFileName = 0;
+ m_widthOfLineNumber = 0;
endRemoveRows();
}
@@ -159,5 +163,57 @@ int TestResultModel::maxWidthOfLineNumber(const QFont &font)
return m_widthOfLineNumber;
}
+/********************************** Filter Model **********************************/
+
+TestResultFilterModel::TestResultFilterModel(TestResultModel *sourceModel, QObject *parent)
+ : QSortFilterProxyModel(parent),
+ m_sourceModel(sourceModel)
+{
+ setSourceModel(sourceModel);
+ enableAllResultTypes();
+}
+
+void TestResultFilterModel::enableAllResultTypes()
+{
+ m_enabled << ResultType::PASS << ResultType::FAIL << ResultType::EXPECTED_FAIL
+ << ResultType::UNEXPECTED_PASS << ResultType::SKIP << ResultType::MESSAGE_DEBUG
+ << ResultType::MESSAGE_WARN << ResultType::MESSAGE_INTERNAL
+ << ResultType::MESSAGE_FATAL << ResultType::UNKNOWN;
+ invalidateFilter();
+}
+
+void TestResultFilterModel::toggleTestResultType(ResultType type)
+{
+ if (m_enabled.contains(type)) {
+ m_enabled.remove(type);
+ } else {
+ m_enabled.insert(type);
+ }
+ invalidateFilter();
+}
+
+void TestResultFilterModel::clearTestResults()
+{
+ m_sourceModel->clearTestResults();
+}
+
+bool TestResultFilterModel::hasResults()
+{
+ return rowCount(QModelIndex());
+}
+
+TestResult TestResultFilterModel::testResult(const QModelIndex &index) const
+{
+ return m_sourceModel->testResult(mapToSource(index));
+}
+
+bool TestResultFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
+{
+ QModelIndex index = m_sourceModel->index(sourceRow, 0, sourceParent);
+ if (!index.isValid())
+ return false;
+ return m_enabled.contains(m_sourceModel->testResult(index).result());
+}
+
} // namespace Internal
} // namespace Autotest
diff --git a/plugins/autotest/testresultmodel.h b/plugins/autotest/testresultmodel.h
index fa35820554..c0a71fe44b 100644
--- a/plugins/autotest/testresultmodel.h
+++ b/plugins/autotest/testresultmodel.h
@@ -22,7 +22,9 @@
#include "testresult.h"
#include <QAbstractItemModel>
+#include <QSortFilterProxyModel>
#include <QFont>
+#include <QSet>
namespace Autotest {
namespace Internal {
@@ -48,6 +50,9 @@ public:
int maxWidthOfFileName(const QFont &font);
int maxWidthOfLineNumber(const QFont &font);
+ void enableAllResultTypes();
+ void toggleTestResultType(ResultType type);
+
signals:
public slots:
@@ -60,6 +65,26 @@ private:
QFont m_measurementFont;
};
+class TestResultFilterModel : public QSortFilterProxyModel
+{
+ Q_OBJECT
+public:
+ TestResultFilterModel(TestResultModel *sourceModel, QObject *parent = 0);
+
+ void enableAllResultTypes();
+ void toggleTestResultType(ResultType type);
+ void clearTestResults();
+ bool hasResults();
+ TestResult testResult(const QModelIndex &index) const;
+
+protected:
+ bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
+
+private:
+ TestResultModel *m_sourceModel;
+ QSet<ResultType> m_enabled;
+};
+
} // namespace Internal
} // namespace Autotest
diff --git a/plugins/autotest/testresultspane.cpp b/plugins/autotest/testresultspane.cpp
index 100de73e58..244b775f93 100644
--- a/plugins/autotest/testresultspane.cpp
+++ b/plugins/autotest/testresultspane.cpp
@@ -22,12 +22,14 @@
#include "testrunner.h"
#include "testtreemodel.h"
+#include <coreplugin/coreconstants.h>
#include <coreplugin/icontext.h>
#include <texteditor/texteditor.h>
#include <utils/itemviews.h>
+#include <QDebug>
#include <QToolButton>
namespace Autotest {
@@ -39,7 +41,9 @@ TestResultsPane::TestResultsPane(QObject *parent) :
{
m_listView = new Utils::ListView;
m_model = new TestResultModel(this);
- m_listView->setModel(m_model);
+ m_filterModel = new TestResultFilterModel(m_model, this);
+ m_filterModel->setDynamicSortFilter(true);
+ m_listView->setModel(m_filterModel);
TestResultDelegate *trd = new TestResultDelegate(this);
m_listView->setItemDelegate(trd);
@@ -61,6 +65,17 @@ void TestResultsPane::createToolButtons()
m_runSelected->setIcon(QIcon(QLatin1String(":/images/runselected.png")));
m_runSelected->setToolTip(tr("Run Selected Tests"));
connect(m_runSelected, &QToolButton::clicked, this, &TestResultsPane::onRunSelectedTriggered);
+
+ m_filterButton = new QToolButton(m_listView);
+ m_filterButton->setIcon(QIcon(QLatin1String(Core::Constants::ICON_FILTER)));
+ m_filterButton->setToolTip(tr("Filter Test Results"));
+ m_filterButton->setProperty("noArrow", true);
+ m_filterButton->setAutoRaise(true);
+ m_filterButton->setPopupMode(QToolButton::InstantPopup);
+ m_filterMenu = new QMenu(m_filterButton);
+ initializeFilterMenu();
+ connect(m_filterMenu, &QMenu::triggered, this, &TestResultsPane::filterMenuTriggered);
+ m_filterButton->setMenu(m_filterMenu);
}
static TestResultsPane *m_instance = 0;
@@ -99,7 +114,7 @@ QWidget *TestResultsPane::outputWidget(QWidget *parent)
QList<QWidget *> TestResultsPane::toolBarWidgets() const
{
- return QList<QWidget *>() << m_runAll << m_runSelected; // add filter as well
+ return QList<QWidget *>() << m_runAll << m_runSelected << m_filterButton;
}
QString TestResultsPane::displayName() const
@@ -114,7 +129,7 @@ int TestResultsPane::priorityInStatusBar() const
void TestResultsPane::clearContents()
{
- m_model->clearTestResults();
+ m_filterModel->clearTestResults();
navigateStateChanged();
}
@@ -143,12 +158,12 @@ bool TestResultsPane::canNavigate() const
bool TestResultsPane::canNext() const
{
- return m_model->hasResults();
+ return m_filterModel->hasResults();
}
bool TestResultsPane::canPrevious() const
{
- return m_model->hasResults();
+ return m_filterModel->hasResults();
}
void TestResultsPane::goToNext()
@@ -159,11 +174,11 @@ void TestResultsPane::goToNext()
QModelIndex currentIndex = m_listView->currentIndex();
if (currentIndex.isValid()) {
int row = currentIndex.row() + 1;
- if (row == m_model->rowCount(QModelIndex()))
+ if (row == m_filterModel->rowCount(QModelIndex()))
row = 0;
- currentIndex = m_model->index(row, 0, QModelIndex());
+ currentIndex = m_filterModel->index(row, 0, QModelIndex());
} else {
- currentIndex = m_model->index(0, 0, QModelIndex());
+ currentIndex = m_filterModel->index(0, 0, QModelIndex());
}
m_listView->setCurrentIndex(currentIndex);
onItemActivated(currentIndex);
@@ -178,10 +193,10 @@ void TestResultsPane::goToPrev()
if (currentIndex.isValid()) {
int row = currentIndex.row() - 1;
if (row < 0)
- row = m_model->rowCount(QModelIndex()) - 1;
- currentIndex = m_model->index(row, 0, QModelIndex());
+ row = m_filterModel->rowCount(QModelIndex()) - 1;
+ currentIndex = m_filterModel->index(row, 0, QModelIndex());
} else {
- currentIndex = m_model->index(m_model->rowCount(QModelIndex()) - 1, 0, QModelIndex());
+ currentIndex = m_filterModel->index(m_filterModel->rowCount(QModelIndex()) - 1, 0, QModelIndex());
}
m_listView->setCurrentIndex(currentIndex);
onItemActivated(currentIndex);
@@ -192,7 +207,7 @@ void TestResultsPane::onItemActivated(const QModelIndex &index)
if (!index.isValid())
return;
- TestResult tr = m_model->testResult(index);
+ TestResult tr = m_filterModel->testResult(index);
if (!tr.fileName().isEmpty())
Core::EditorManager::openEditorAt(tr.fileName(), tr.line(), 0);
}
@@ -209,7 +224,34 @@ void TestResultsPane::onRunSelectedTriggered()
TestRunner *runner = TestRunner::instance();
runner->setSelectedTests(TestTreeModel::instance()->getSelectedTests());
runner->runTests();
+}
+
+void TestResultsPane::initializeFilterMenu()
+{
+ QMap<ResultType, QString> textAndType;
+ textAndType.clear();
+ textAndType.insert(ResultType::PASS, QLatin1String("Pass"));
+ textAndType.insert(ResultType::FAIL, QLatin1String("Fail"));
+ textAndType.insert(ResultType::EXPECTED_FAIL, QLatin1String("Expected Fail"));
+ textAndType.insert(ResultType::UNEXPECTED_PASS, QLatin1String("Unexpected Pass"));
+ textAndType.insert(ResultType::SKIP, QLatin1String("Skip"));
+ textAndType.insert(ResultType::MESSAGE_DEBUG, QLatin1String("Debug Messages"));
+ textAndType.insert(ResultType::MESSAGE_WARN, QLatin1String("Warning Messages"));
+ textAndType.insert(ResultType::MESSAGE_INTERNAL, QLatin1String("Internal Messages"));
+ foreach (ResultType result, textAndType.keys()) {
+ QAction *action = new QAction(m_filterMenu);
+ action->setText(textAndType.value(result));
+ action->setCheckable(true);
+ action->setChecked(true);
+ action->setData(result);
+ m_filterMenu->addAction(action);
+ }
+}
+void TestResultsPane::filterMenuTriggered(QAction *action)
+{
+ m_filterModel->toggleTestResultType(static_cast<ResultType>(action->data().value<int>()));
+ navigateStateChanged();
}
} // namespace Internal
diff --git a/plugins/autotest/testresultspane.h b/plugins/autotest/testresultspane.h
index 28aff09103..86936223ac 100644
--- a/plugins/autotest/testresultspane.h
+++ b/plugins/autotest/testresultspane.h
@@ -22,7 +22,9 @@
#include <coreplugin/ioutputpane.h>
QT_BEGIN_NAMESPACE
+class QAction;
class QModelIndex;
+class QMenu;
class QToolButton;
QT_END_NAMESPACE
@@ -39,6 +41,7 @@ namespace Internal {
class TestResult;
class TestResultModel;
+class TestResultFilterModel;
class TestResultsPane : public Core::IOutputPane
{
@@ -73,6 +76,8 @@ private slots:
void onItemActivated(const QModelIndex &index);
void onRunAllTriggered();
void onRunSelectedTriggered();
+ void initializeFilterMenu();
+ void filterMenuTriggered(QAction *action);
private:
explicit TestResultsPane(QObject *parent = 0);
@@ -80,9 +85,12 @@ private:
Utils::ListView *m_listView;
TestResultModel *m_model;
+ TestResultFilterModel *m_filterModel;
Core::IContext *m_context;
QToolButton *m_runAll;
QToolButton *m_runSelected;
+ QToolButton *m_filterButton;
+ QMenu *m_filterMenu;
};
} // namespace Internal
diff --git a/plugins/autotest/testtreemodel.cpp b/plugins/autotest/testtreemodel.cpp
index 7cf8d2888d..fe9a091b55 100644
--- a/plugins/autotest/testtreemodel.cpp
+++ b/plugins/autotest/testtreemodel.cpp
@@ -20,9 +20,7 @@
#include "testtreeitem.h"
#include "testtreemodel.h"
-#include <texteditor/texteditor.h>
-
-#include <QIcon>
+#include <cpptools/cppmodelmanager.h>
#include <projectexplorer/buildtargetinfo.h>
#include <projectexplorer/environmentaspect.h>
@@ -32,7 +30,11 @@
#include <projectexplorer/session.h>
#include <projectexplorer/target.h>
-#include <cpptools/cppmodelmanager.h>
+#include <texteditor/texteditor.h>
+
+#include <utils/fileutils.h>
+
+#include <QIcon>
namespace Autotest {
namespace Internal {
@@ -276,16 +278,11 @@ static void addProjectInformation(TestConfiguration *config, const QString &file
if (ProjectExplorer::LocalApplicationRunConfiguration *localRunConfiguration
= qobject_cast<ProjectExplorer::LocalApplicationRunConfiguration *>(rc)) {
if (localRunConfiguration->executable() == targetFile) {
- workDir = localRunConfiguration->workingDirectory();
- QList<ProjectExplorer::IRunConfigurationAspect *> aspects
- = localRunConfiguration->extraAspects();
- foreach (ProjectExplorer::IRunConfigurationAspect *aspect, aspects) {
- if (ProjectExplorer::EnvironmentAspect *asp
- = qobject_cast<ProjectExplorer::EnvironmentAspect *>(aspect)) {
- env = asp->environment();
- break;
- }
- }
+ workDir = Utils::FileUtils::normalizePathName(
+ localRunConfiguration->workingDirectory());
+ ProjectExplorer::EnvironmentAspect *envAsp
+ = localRunConfiguration->extraAspect<ProjectExplorer::EnvironmentAspect>();
+ env = envAsp->environment();
break;
}
}