summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Stenger <christian.stenger@digia.com>2014-11-13 12:31:58 +0100
committerChristian Stenger <christian.stenger@theqtcompany.com>2014-12-04 13:52:16 +0100
commitb0c4a9cc3bbe6697692c07c31c96a2c937171364 (patch)
tree3477dce68824001005eb3d67dddeadac1e9c9bbb
parent9a644d1257199a58cbb208c79c33831458d4aa01 (diff)
downloadqt-creator-b0c4a9cc3bbe6697692c07c31c96a2c937171364.tar.gz
Improve support for Qt Quick Tests
-rw-r--r--plugins/autotest/autotest.pro6
-rw-r--r--plugins/autotest/testcodeparser.cpp52
-rw-r--r--plugins/autotest/testconfiguration.cpp5
-rw-r--r--plugins/autotest/testconfiguration.h3
-rw-r--r--plugins/autotest/testresultspane.cpp4
-rw-r--r--plugins/autotest/testrunner.cpp8
-rw-r--r--plugins/autotest/testtreeitem.cpp58
-rw-r--r--plugins/autotest/testtreeitem.h8
-rw-r--r--plugins/autotest/testtreeitemdelegate.cpp69
-rw-r--r--plugins/autotest/testtreeitemdelegate.h41
-rw-r--r--plugins/autotest/testtreemodel.cpp132
-rw-r--r--plugins/autotest/testtreemodel.h3
-rw-r--r--plugins/autotest/testtreeview.cpp2
-rw-r--r--plugins/autotest/testvisitor.cpp36
-rw-r--r--plugins/autotest/testvisitor.h17
15 files changed, 353 insertions, 91 deletions
diff --git a/plugins/autotest/autotest.pro b/plugins/autotest/autotest.pro
index 566c6131d1..6d2423bdd7 100644
--- a/plugins/autotest/autotest.pro
+++ b/plugins/autotest/autotest.pro
@@ -21,7 +21,8 @@ SOURCES += \
testresult.cpp \
testresultspane.cpp \
testresultmodel.cpp \
- testresultdelegate.cpp
+ testresultdelegate.cpp \
+ testtreeitemdelegate.cpp
HEADERS += \
testtreeview.h \
@@ -38,7 +39,8 @@ HEADERS += \
testresult.h \
testresultspane.h \
testresultmodel.h \
- testresultdelegate.h
+ testresultdelegate.h \
+ testtreeitemdelegate.h
RESOURCES += \
autotest.qrc
diff --git a/plugins/autotest/testcodeparser.cpp b/plugins/autotest/testcodeparser.cpp
index 9d4f41af06..240bb418d5 100644
--- a/plugins/autotest/testcodeparser.cpp
+++ b/plugins/autotest/testcodeparser.cpp
@@ -60,8 +60,10 @@ void TestCodeParser::updateTestTree()
m_model->removeAllAutoTests();
m_model->removeAllQuickTests();
const ProjectExplorer::SessionManager *session = ProjectExplorer::SessionManager::instance();
- if (!session || !session->hasProjects())
+ if (!session || !session->hasProjects()) {
+ m_currentProject = 0;
return;
+ }
m_currentProject = session->startupProject();
if (!m_currentProject)
@@ -285,13 +287,13 @@ void TestCodeParser::checkDocumentForTestCode(CPlusPlus::Document::Ptr doc)
}
TestVisitor myVisitor(tc);
myVisitor.accept(declaringDoc->globalNamespace());
- const QMap<QString, TestCodeLocation> privSlots = myVisitor.privateSlots();
+ const QMap<QString, TestCodeLocationAndType> privSlots = myVisitor.privateSlots();
foreach (const QString &privS, privSlots.keys()) {
- const TestCodeLocation location = privSlots.value(privS);
- TestTreeItem *ttSub = new TestTreeItem(privS, location.m_fileName,
- TestTreeItem::TEST_FUNCTION, ttItem);
- ttSub->setLine(location.m_line);
- ttSub->setColumn(location.m_column);
+ const TestCodeLocationAndType locationAndType = privSlots.value(privS);
+ TestTreeItem *ttSub = new TestTreeItem(privS, locationAndType.m_fileName,
+ locationAndType.m_type, ttItem);
+ ttSub->setLine(locationAndType.m_line);
+ ttSub->setColumn(locationAndType.m_column);
ttItem->appendChild(ttSub);
}
@@ -374,8 +376,8 @@ void TestCodeParser::handleQtQuickTest(CPlusPlus::Document::Ptr doc)
QmlJS::AST::Node::accept(ast, &qmlVisitor);
const QString tcName = qmlVisitor.testCaseName();
- const TestCodeLocation tcLocation = qmlVisitor.testCaseLocation();
- const QMap<QString, TestCodeLocation> testFunctions = qmlVisitor.testFunctions();
+ const TestCodeLocationAndType tcLocationAndType = qmlVisitor.testCaseLocation();
+ const QMap<QString, TestCodeLocationAndType> testFunctions = qmlVisitor.testFunctions();
const QModelIndex quickTestRootIndex = m_model->index(1, 0);
TestTreeItem *quickTestRootItem = static_cast<TestTreeItem *>(quickTestRootIndex.internalPointer());
@@ -417,11 +419,11 @@ void TestCodeParser::handleQtQuickTest(CPlusPlus::Document::Ptr doc)
}
foreach (const QString &func, testFunctions.keys()) {
- const TestCodeLocation location = testFunctions.value(func);
- TestTreeItem *ttSub = new TestTreeItem(func, location.m_fileName,
- TestTreeItem::TEST_FUNCTION, ttItem);
- ttSub->setLine(location.m_line);
- ttSub->setColumn(location.m_column);
+ const TestCodeLocationAndType locationAndType = testFunctions.value(func);
+ TestTreeItem *ttSub = new TestTreeItem(func, locationAndType.m_fileName,
+ locationAndType.m_type, ttItem);
+ ttSub->setLine(locationAndType.m_line);
+ ttSub->setColumn(locationAndType.m_column);
ttSub->setMainFile(doc->fileName());
ttItem->appendChild(ttSub);
}
@@ -445,23 +447,23 @@ void TestCodeParser::handleQtQuickTest(CPlusPlus::Document::Ptr doc)
} // end of handling test cases without name property
// construct new/modified TestTreeItem
- TestTreeItem *ttItem = new TestTreeItem(tcName, tcLocation.m_fileName,
- TestTreeItem::TEST_CLASS, quickTestRootItem);
- ttItem->setLine(tcLocation.m_line);
- ttItem->setColumn(tcLocation.m_column);
+ TestTreeItem *ttItem = new TestTreeItem(tcName, tcLocationAndType.m_fileName,
+ tcLocationAndType.m_type, quickTestRootItem);
+ ttItem->setLine(tcLocationAndType.m_line);
+ ttItem->setColumn(tcLocationAndType.m_column);
ttItem->setMainFile(doc->fileName());
foreach (const QString &func, testFunctions.keys()) {
- const TestCodeLocation location = testFunctions.value(func);
- TestTreeItem *ttSub = new TestTreeItem(func, location.m_fileName,
- TestTreeItem::TEST_FUNCTION, ttItem);
- ttSub->setLine(location.m_line);
- ttSub->setColumn(location.m_column);
+ const TestCodeLocationAndType locationAndType = testFunctions.value(func);
+ TestTreeItem *ttSub = new TestTreeItem(func, locationAndType.m_fileName,
+ locationAndType.m_type, ttItem);
+ ttSub->setLine(locationAndType.m_line);
+ ttSub->setColumn(locationAndType.m_column);
ttItem->appendChild(ttSub);
}
// update model and internal map
- const QString fileName(tcLocation.m_fileName);
+ const QString fileName(tcLocationAndType.m_fileName);
const QmlJS::Document::Ptr qmlDoc =
QmlJSTools::Internal::ModelManager::instance()->snapshot().document(fileName);
@@ -497,7 +499,7 @@ void TestCodeParser::handleQtQuickTest(CPlusPlus::Document::Ptr doc)
m_model->addQuickTest(ttItem);
TestInfo ti(tcName, testFunctions.keys(), 0, qmlDoc->editorRevision());
ti.setReferencingFile(doc->fileName());
- m_quickDocMap.insert(tcLocation.m_fileName, ti);
+ m_quickDocMap.insert(tcLocationAndType.m_fileName, ti);
}
}
}
diff --git a/plugins/autotest/testconfiguration.cpp b/plugins/autotest/testconfiguration.cpp
index bcb90d75b5..73cdbdb918 100644
--- a/plugins/autotest/testconfiguration.cpp
+++ b/plugins/autotest/testconfiguration.cpp
@@ -81,6 +81,11 @@ void TestConfiguration::setWorkingDirectory(const QString &workingDirectory)
m_workingDir = workingDirectory;
}
+void TestConfiguration::setDisplayName(const QString &displayName)
+{
+ m_displayName = displayName;
+}
+
void TestConfiguration::setEnvironment(const Utils::Environment &env)
{
m_environment = env;
diff --git a/plugins/autotest/testconfiguration.h b/plugins/autotest/testconfiguration.h
index aa82b8e2b5..54be3697aa 100644
--- a/plugins/autotest/testconfiguration.h
+++ b/plugins/autotest/testconfiguration.h
@@ -46,6 +46,7 @@ public:
void setTargetName(const QString &targetName);
void setProFile(const QString &proFile);
void setWorkingDirectory(const QString &workingDirectory);
+ void setDisplayName(const QString &displayName);
void setEnvironment(const Utils::Environment &env);
void setProject(ProjectExplorer::Project *project);
@@ -56,6 +57,7 @@ public:
QString targetFile() const { return m_targetFile; }
QString targetName() const { return m_targetName; }
QString workingDirectory() const { return m_workingDir; }
+ QString displayName() const { return m_displayName; }
Utils::Environment environment() const { return m_environment; }
ProjectExplorer::Project *project() const { return m_project; }
@@ -72,6 +74,7 @@ private:
QString m_targetFile;
QString m_targetName;
QString m_workingDir;
+ QString m_displayName;
Utils::Environment m_environment;
ProjectExplorer::Project *m_project;
};
diff --git a/plugins/autotest/testresultspane.cpp b/plugins/autotest/testresultspane.cpp
index e9d0f1be56..39441d9087 100644
--- a/plugins/autotest/testresultspane.cpp
+++ b/plugins/autotest/testresultspane.cpp
@@ -50,9 +50,9 @@ TestResultsPane::TestResultsPane(QObject *parent) :
QPalette pal;
pal.setColor(QPalette::Window,
- Utils::creatorTheme()->color(Utils::Theme::SearchResultWidgetBackgroundColor));
+ Utils::creatorTheme()->color(Utils::Theme::InfoBarBackground));
pal.setColor(QPalette::WindowText,
- Utils::creatorTheme()->color(Utils::Theme::SearchResultWidgetTextColor));
+ Utils::creatorTheme()->color(Utils::Theme::InfoBarText));
m_summaryWidget = new QFrame;
m_summaryWidget->setPalette(pal);
m_summaryWidget->setAutoFillBackground(true);
diff --git a/plugins/autotest/testrunner.cpp b/plugins/autotest/testrunner.cpp
index ed2383bb3f..420360468b 100644
--- a/plugins/autotest/testrunner.cpp
+++ b/plugins/autotest/testrunner.cpp
@@ -351,8 +351,14 @@ void TestRunner::runTests()
}
ProjectExplorer::Project *project = m_selectedTests.at(0)->project();
- if (!project) // add a warning or info to output? possible at all?
+ if (!project) {
+ TestResultsPane::instance()->addTestResult(
+ TestResult(QString(), QString(), QString(), ResultType::MESSAGE_WARN,
+ tr("*** Project is null - canceling Test Run ***\n"
+ "Actually only Desktop kits are supported - make sure the "
+ "current active kit is a Desktop kit.")));
return;
+ }
ProjectExplorer::ProjectExplorerPlugin *pep = ProjectExplorer::ProjectExplorerPlugin::instance();
ProjectExplorer::Internal::ProjectExplorerSettings pes = pep->projectExplorerSettings();
diff --git a/plugins/autotest/testtreeitem.cpp b/plugins/autotest/testtreeitem.cpp
index 5ffd192761..2da060da52 100644
--- a/plugins/autotest/testtreeitem.cpp
+++ b/plugins/autotest/testtreeitem.cpp
@@ -24,11 +24,29 @@ namespace Internal {
TestTreeItem::TestTreeItem(const QString &name, const QString &filePath, Type type, TestTreeItem *parent)
: m_name(name),
m_filePath(filePath),
- m_checked(type == ROOT ? Qt::Unchecked : Qt::Checked),
m_type(type),
m_line(0),
m_parent(parent)
{
+ switch (m_type) {
+ case ROOT:
+ m_checked = Qt::Unchecked;
+ break;
+ case TEST_CLASS:
+ case TEST_FUNCTION:
+ m_checked = Qt::Checked;
+ break;
+ case TEST_DATAFUNCTION:
+ case TEST_SPECIALFUNCTION:
+ if (m_parent)
+ m_checked = m_parent->checked() == Qt::PartiallyChecked ? Qt::Unchecked
+ : m_parent->checked();
+ else
+ m_checked = Qt::Unchecked;
+ break;
+ default:
+ m_checked = Qt::Unchecked;
+ }
}
TestTreeItem::~TestTreeItem()
@@ -121,19 +139,37 @@ bool TestTreeItem::modifyContent(const TestTreeItem *modified)
void TestTreeItem::setChecked(const Qt::CheckState checkState)
{
switch (m_type) {
- case ROOT:
- return;
- case TEST_FUNCTION:
+ case TEST_FUNCTION: {
m_checked = (checkState == Qt::Unchecked ? Qt::Unchecked : Qt::Checked);
m_parent->revalidateCheckState();
break;
- case TEST_CLASS:
+ }
+ case TEST_CLASS: {
Qt::CheckState usedState = (checkState == Qt::Unchecked ? Qt::Unchecked : Qt::Checked);
foreach (TestTreeItem *child, m_children) {
child->setChecked(usedState);
}
m_checked = usedState;
}
+ default:
+ return;
+ }
+}
+
+Qt::CheckState TestTreeItem::checked() const
+{
+ switch (m_type) {
+ case TEST_CLASS:
+ case TEST_FUNCTION:
+ return m_checked;
+ case TEST_DATAFUNCTION:
+ case TEST_SPECIALFUNCTION:
+ return m_parent->m_checked == Qt::PartiallyChecked ? Qt::Unchecked : m_parent->m_checked;
+ default:
+ if (m_parent)
+ return m_parent->m_checked;
+ }
+ return Qt::Unchecked;
}
void TestTreeItem::revalidateCheckState()
@@ -143,8 +179,16 @@ void TestTreeItem::revalidateCheckState()
bool foundChecked = false;
bool foundUnchecked = false;
foreach (const TestTreeItem *child, m_children) {
- foundChecked |= (child->m_checked != Qt::Unchecked);
- foundUnchecked |= (child->m_checked == Qt::Unchecked);
+ switch (child->type()) {
+ case TEST_DATAFUNCTION:
+ case TEST_SPECIALFUNCTION:
+ continue;
+ default:
+ break;
+ }
+
+ foundChecked |= (child->checked() != Qt::Unchecked);
+ foundUnchecked |= (child->checked() == Qt::Unchecked);
if (foundChecked && foundUnchecked) {
m_checked = Qt::PartiallyChecked;
return;
diff --git a/plugins/autotest/testtreeitem.h b/plugins/autotest/testtreeitem.h
index 6f0ca88e2d..8ec916b0bf 100644
--- a/plugins/autotest/testtreeitem.h
+++ b/plugins/autotest/testtreeitem.h
@@ -30,7 +30,11 @@ class TestTreeItem
public:
enum Type {
- ROOT, TEST_CLASS, TEST_FUNCTION
+ ROOT,
+ TEST_CLASS,
+ TEST_FUNCTION,
+ TEST_DATAFUNCTION,
+ TEST_SPECIALFUNCTION
};
TestTreeItem(const QString &name, const QString &filePath, Type type, TestTreeItem *parent = 0);
@@ -57,7 +61,7 @@ public:
QString mainFile() const { return m_mainFile; }
void setMainFile(const QString &mainFile) { m_mainFile = mainFile; }
void setChecked(const Qt::CheckState checked);
- Qt::CheckState checked() const { return m_checked; }
+ Qt::CheckState checked() const;
Type type() const { return m_type; }
void setParent(TestTreeItem *parent) { m_parent = parent; }
diff --git a/plugins/autotest/testtreeitemdelegate.cpp b/plugins/autotest/testtreeitemdelegate.cpp
new file mode 100644
index 0000000000..71ccef5756
--- /dev/null
+++ b/plugins/autotest/testtreeitemdelegate.cpp
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Creator Enterprise Auto Test Add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "testtreeitemdelegate.h"
+#include "testtreemodel.h"
+
+#include <QPainter>
+
+namespace Autotest {
+namespace Internal {
+
+TestTreeItemDelegate::TestTreeItemDelegate(QObject *parent)
+ : QStyledItemDelegate(parent)
+{
+}
+
+TestTreeItemDelegate::~TestTreeItemDelegate()
+{
+}
+
+void TestTreeItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
+{
+ QStyleOptionViewItem opt = option;
+ initStyleOption(&opt, index);
+
+ bool italic = index.data(ItalicRole).toBool();
+ if (italic) {
+ QFont font(option.font);
+ font.setItalic(true);
+ opt.font = font;
+
+ // correct margin of items without a checkbox (except for root items)
+ QStyleOptionButton styleOpt;
+ styleOpt.initFrom(opt.widget);
+ const QSize sz; // no text, no icon - we just need the size of the check box
+ QSize cbSize = opt.widget->style()->sizeFromContents(QStyle::CT_CheckBox, &styleOpt, sz);
+ // the 6 results from hard coded margins of the checkbox itself (2x2) and the item (1x2)
+ opt.rect.setLeft(opt.rect.left() + cbSize.width() + 6);
+
+ // HACK make sure the pixels that have been moved right are painted for selections
+ if (opt.state & QStyle::State_Selected) {
+ QPalette::ColorGroup cg = opt.state & QStyle::State_Enabled
+ ? QPalette::Normal : QPalette::Disabled;
+ if (cg == QPalette::Normal && !(opt.state & QStyle::State_Active))
+ cg = QPalette::Inactive;
+ painter->fillRect(option.rect, opt.palette.brush(cg, QPalette::Highlight));
+ }
+ }
+
+ QStyledItemDelegate::paint(painter, opt, index);
+}
+
+} // namespace Internal
+} // namespace Autotest
diff --git a/plugins/autotest/testtreeitemdelegate.h b/plugins/autotest/testtreeitemdelegate.h
new file mode 100644
index 0000000000..af31022b0b
--- /dev/null
+++ b/plugins/autotest/testtreeitemdelegate.h
@@ -0,0 +1,41 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Creator Enterprise Auto Test Add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#ifndef TESTTREEITEMDELEGATE_H
+#define TESTTREEITEMDELEGATE_H
+
+#include <QStyledItemDelegate>
+
+namespace Autotest {
+namespace Internal {
+
+class TestTreeItemDelegate : public QStyledItemDelegate
+{
+ Q_OBJECT
+public:
+ TestTreeItemDelegate(QObject *parent = 0);
+ ~TestTreeItemDelegate();
+
+public:
+ void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
+};
+
+} // namespace Internal
+} // namespace Autotest
+
+#endif // TESTTREEITEMDELEGATE_H
diff --git a/plugins/autotest/testtreemodel.cpp b/plugins/autotest/testtreemodel.cpp
index 93d9d160ef..8425c27c1d 100644
--- a/plugins/autotest/testtreemodel.cpp
+++ b/plugins/autotest/testtreemodel.cpp
@@ -135,6 +135,8 @@ static QIcon testTreeIcon(TestTreeItem::Type type)
QIcon(QLatin1String(":/images/class.png")),
QIcon(QLatin1String(":/images/func.png"))
};
+ if (type >= 3)
+ return icons[2];
return icons[type];
}
@@ -169,15 +171,46 @@ QVariant TestTreeModel::data(const QModelIndex &index, int role) const
case Qt::DecorationRole:
return testTreeIcon(item->type());
case Qt::CheckStateRole:
- if (item->type() == TestTreeItem::ROOT)
+ switch (item->type()) {
+ case TestTreeItem::ROOT:
+ case TestTreeItem::TEST_DATAFUNCTION:
+ case TestTreeItem::TEST_SPECIALFUNCTION:
return QVariant();
- return item->checked();
- case LinkRole:
+ case TestTreeItem::TEST_CLASS:
+ if (item->name().isEmpty())
+ return QVariant();
+ else
+ return item->checked();
+ case TestTreeItem::TEST_FUNCTION:
+ if (TestTreeItem *parent = item->parent())
+ return parent->name().isEmpty() ? QVariant() : item->checked();
+ else
+ return item->checked();
+ default:
+ return item->checked();
+ }
+ case LinkRole: {
QVariant itemLink;
TextEditor::TextEditorWidget::Link link(item->filePath(), item->line(), item->column());
itemLink.setValue(link);
return itemLink;
}
+ case ItalicRole:
+ switch (item->type()) {
+ case TestTreeItem::TEST_DATAFUNCTION:
+ case TestTreeItem::TEST_SPECIALFUNCTION:
+ return true;
+ case TestTreeItem::TEST_CLASS:
+ return item->name().isEmpty();
+ case TestTreeItem::TEST_FUNCTION:
+ if (TestTreeItem *parent = item->parent())
+ return parent->name().isEmpty();
+ else
+ return false;
+ default:
+ return false;
+ }
+ }
// TODO ?
return QVariant();
@@ -222,15 +255,18 @@ Qt::ItemFlags TestTreeModel::flags(const QModelIndex &index) const
switch(item->type()) {
case TestTreeItem::TEST_CLASS:
if (item->name().isEmpty())
- return Qt::ItemIsSelectable | Qt::ItemIsTristate;
+ return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsTristate | Qt::ItemIsUserCheckable;
case TestTreeItem::TEST_FUNCTION:
if (item->parent()->name().isEmpty())
- return Qt::ItemIsSelectable;
+ return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable;
case TestTreeItem::ROOT:
- default:
return Qt::ItemIsEnabled;
+ case TestTreeItem::TEST_DATAFUNCTION:
+ case TestTreeItem::TEST_SPECIALFUNCTION:
+ default:
+ return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}
}
@@ -261,18 +297,38 @@ bool TestTreeModel::hasTests() const
static void addProjectInformation(TestConfiguration *config, const QString &filePath)
{
+ const ProjectExplorer::SessionManager *session = ProjectExplorer::SessionManager::instance();
+ if (!session || !session->hasProjects())
+ return;
+
+ ProjectExplorer::Project *project = session->startupProject();
+ if (!project)
+ return;
+
QString targetFile;
QString targetName;
QString workDir;
QString proFile;
+ QString displayName;
Utils::Environment env;
- ProjectExplorer::Project *project = 0;
+ bool hasDesktopTarget = false;
CppTools::CppModelManager *cppMM = CppTools::CppModelManager::instance();
- QList<CppTools::ProjectPart::Ptr> projParts = cppMM->projectPart(filePath);
+ QList<CppTools::ProjectPart::Ptr> projParts = cppMM->projectInfo(project).projectParts();
+
if (!projParts.empty()) {
- proFile = projParts.at(0)->projectFile;
- project = projParts.at(0)->project; // necessary to grab this here? or should this be the current active startup project anyway?
+ foreach (const CppTools::ProjectPart::Ptr &part, projParts) {
+ foreach (const CppTools::ProjectFile currentFile, part->files) {
+ if (currentFile.path == filePath) {
+ proFile = part->projectFile;
+ displayName = part->displayName;
+ break;
+ }
+ }
+ if (!proFile.isEmpty()) // maybe better use a goto instead of the break above??
+ break;
+ }
}
+
if (project) {
if (auto target = project->activeTarget()) {
ProjectExplorer::BuildTargetInfoList appTargets = target->applicationTargets();
@@ -289,6 +345,7 @@ static void addProjectInformation(TestConfiguration *config, const QString &file
if (ProjectExplorer::LocalApplicationRunConfiguration *localRunConfiguration
= qobject_cast<ProjectExplorer::LocalApplicationRunConfiguration *>(rc)) {
if (localRunConfiguration->executable() == targetFile) {
+ hasDesktopTarget = true;
workDir = Utils::FileUtils::normalizePathName(
localRunConfiguration->workingDirectory());
ProjectExplorer::EnvironmentAspect *envAsp
@@ -300,12 +357,19 @@ static void addProjectInformation(TestConfiguration *config, const QString &file
}
}
}
- config->setTargetFile(targetFile);
- config->setTargetName(targetName);
- config->setWorkingDirectory(workDir);
- config->setProFile(proFile);
- config->setEnvironment(env);
- config->setProject(project);
+
+ if (hasDesktopTarget) {
+ config->setTargetFile(targetFile);
+ config->setTargetName(targetName);
+ config->setWorkingDirectory(workDir);
+ config->setProFile(proFile);
+ config->setEnvironment(env);
+ config->setProject(project);
+ config->setDisplayName(displayName);
+ } else {
+ config->setProFile(proFile);
+ config->setDisplayName(displayName);
+ }
}
QList<TestConfiguration *> TestTreeModel::getAllTestCases() const
@@ -392,17 +456,18 @@ QList<TestConfiguration *> TestTreeModel::getSelectedTests() const
QMap<QString, TestConfiguration *> foundMains;
- TestTreeItem *unnamed = unnamedQuickTests();
- for (int childRow = 0, ccount = unnamed->childCount(); childRow < ccount; ++ childRow) {
- const TestTreeItem *grandChild = unnamed->child(childRow);
- const QString mainFile = grandChild->mainFile();
- if (foundMains.contains(mainFile)) {
- foundMains[mainFile]->setTestCaseCount(tc->testCaseCount() + 1);
- } else {
- TestConfiguration *tc = new TestConfiguration(QString(), QStringList());
- tc->setTestCaseCount(1);
- addProjectInformation(tc, mainFile);
- foundMains.insert(mainFile, tc);
+ if (TestTreeItem *unnamed = unnamedQuickTests()) {
+ for (int childRow = 0, ccount = unnamed->childCount(); childRow < ccount; ++ childRow) {
+ const TestTreeItem *grandChild = unnamed->child(childRow);
+ const QString mainFile = grandChild->mainFile();
+ if (foundMains.contains(mainFile)) {
+ foundMains[mainFile]->setTestCaseCount(tc->testCaseCount() + 1);
+ } else {
+ TestConfiguration *tc = new TestConfiguration(QString(), QStringList());
+ tc->setTestCaseCount(1);
+ addProjectInformation(tc, mainFile);
+ foundMains.insert(mainFile, tc);
+ }
}
}
@@ -695,6 +760,8 @@ bool TestTreeSortFilterModel::lessThan(const QModelIndex &left, const QModelInde
switch (m_sortMode) {
case Alphabetically:
+ if (leftVal == rightVal)
+ return left.row() > right.row();
return leftVal > rightVal;
case Naturally: {
const TextEditor::TextEditorWidget::Link leftLink =
@@ -717,13 +784,20 @@ bool TestTreeSortFilterModel::lessThan(const QModelIndex &left, const QModelInde
bool TestTreeSortFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
{
- // TODO add filtering capabilities
QModelIndex index = m_sourceModel->index(sourceRow, 0,sourceParent);
if (!index.isValid())
return false;
+ const TestTreeItem *item = static_cast<TestTreeItem *>(index.internalPointer());
- return true;
+ switch (item->type()) {
+ case TestTreeItem::TEST_DATAFUNCTION:
+ return m_filterMode & ShowTestData;
+ case TestTreeItem::TEST_SPECIALFUNCTION:
+ return m_filterMode & ShowInitAndCleanup;
+ default:
+ return true;
+ }
}
} // namespace Internal
diff --git a/plugins/autotest/testtreemodel.h b/plugins/autotest/testtreemodel.h
index 94cb874f8e..5ae83f0df7 100644
--- a/plugins/autotest/testtreemodel.h
+++ b/plugins/autotest/testtreemodel.h
@@ -29,7 +29,8 @@
namespace {
enum ItemRole {
// AnnotationRole = Qt::UserRole + 1,
- LinkRole = Qt::UserRole + 2 // can be removed if AnnotationRole comes back
+ LinkRole = Qt::UserRole + 2, // can be removed if AnnotationRole comes back
+ ItalicRole // used only inside the delegate
};
}
diff --git a/plugins/autotest/testtreeview.cpp b/plugins/autotest/testtreeview.cpp
index 45376db383..fdd3ee4096 100644
--- a/plugins/autotest/testtreeview.cpp
+++ b/plugins/autotest/testtreeview.cpp
@@ -20,6 +20,7 @@
#include "testcodeparser.h"
#include "testrunner.h"
#include "testtreeitem.h"
+#include "testtreeitemdelegate.h"
#include "testtreemodel.h"
#include "testtreeview.h"
@@ -53,6 +54,7 @@ TestTreeViewWidget::TestTreeViewWidget(QWidget *parent) :
m_view = new TestTreeView(this);
m_view->setModel(m_sortFilterModel);
m_view->setSortingEnabled(true);
+ m_view->setItemDelegate(new TestTreeItemDelegate(this));
QVBoxLayout *layout = new QVBoxLayout;
layout->setMargin(0);
diff --git a/plugins/autotest/testvisitor.cpp b/plugins/autotest/testvisitor.cpp
index 199f3236b2..b6706b5bf4 100644
--- a/plugins/autotest/testvisitor.cpp
+++ b/plugins/autotest/testvisitor.cpp
@@ -44,7 +44,7 @@ TestVisitor::~TestVisitor()
{
}
-static QList<QString> ignoredFunctions = QList<QString>() << QLatin1String("initTestCase")
+static QList<QString> specialFunctions = QList<QString>() << QLatin1String("initTestCase")
<< QLatin1String("cleanupTestCase")
<< QLatin1String("init")
<< QLatin1String("cleanup");
@@ -66,14 +66,18 @@ bool TestVisitor::visit(CPlusPlus::Class *symbol)
if (const auto func = type->asFunctionType()) {
if (func->isSlot() && member->isPrivate()) {
const QString name = o.prettyName(func->name());
- if (!ignoredFunctions.contains(name) && !name.endsWith(QLatin1String("_data"))) {
- // TODO use definition of function instead of declaration!
- TestCodeLocation location;
- location.m_fileName = QLatin1String(member->fileName());
- location.m_line = member->line();
- location.m_column = member->column() - 1;
- m_privSlots.insert(name, location);
- }
+ // TODO use definition of function instead of declaration!
+ TestCodeLocationAndType locationAndType;
+ locationAndType.m_fileName = QLatin1String(member->fileName());
+ locationAndType.m_line = member->line();
+ locationAndType.m_column = member->column() - 1;
+ if (specialFunctions.contains(name))
+ locationAndType.m_type = TestTreeItem::TEST_SPECIALFUNCTION;
+ else if (name.endsWith(QLatin1String("_data")))
+ locationAndType.m_type = TestTreeItem::TEST_DATAFUNCTION;
+ else
+ locationAndType.m_type = TestTreeItem::TEST_FUNCTION;
+ m_privSlots.insert(name, locationAndType);
}
}
}
@@ -146,13 +150,14 @@ bool TestQmlVisitor::visit(QmlJS::AST::UiObjectDefinition *ast)
{
const QStringRef name = ast->qualifiedTypeNameId->name;
if (name != QLatin1String("TestCase"))
- return false;
+ return true; // find nested TestCase items as well
m_currentTestCaseName.clear();
const auto sourceLocation = ast->firstSourceLocation();
m_testCaseLocation.m_fileName = m_currentDoc->fileName();
m_testCaseLocation.m_line = sourceLocation.startLine;
m_testCaseLocation.m_column = sourceLocation.startColumn - 1;
+ m_testCaseLocation.m_type = TestTreeItem::TEST_CLASS;
return true;
}
@@ -173,12 +178,13 @@ bool TestQmlVisitor::visit(QmlJS::AST::FunctionDeclaration *ast)
const QStringRef name = ast->name;
if (name.startsWith(QLatin1String("test_"))) {
const auto sourceLocation = ast->firstSourceLocation();
- TestCodeLocation location;
- location.m_fileName = m_currentDoc->fileName();
- location.m_line = sourceLocation.startLine;
- location.m_column = sourceLocation.startColumn - 1;
+ TestCodeLocationAndType locationAndType;
+ locationAndType.m_fileName = m_currentDoc->fileName();
+ locationAndType.m_line = sourceLocation.startLine;
+ locationAndType.m_column = sourceLocation.startColumn - 1;
+ locationAndType.m_type = TestTreeItem::TEST_FUNCTION;
- m_testFunctions.insert(name.toString(), location);
+ m_testFunctions.insert(name.toString(), locationAndType);
}
return false;
}
diff --git a/plugins/autotest/testvisitor.h b/plugins/autotest/testvisitor.h
index 92bfa009ae..bba9f0ebda 100644
--- a/plugins/autotest/testvisitor.h
+++ b/plugins/autotest/testvisitor.h
@@ -19,6 +19,8 @@
#ifndef TESTVISITOR_H
#define TESTVISITOR_H
+#include "testtreeitem.h"
+
#include <cplusplus/ASTVisitor.h>
#include <cplusplus/CppDocument.h>
#include <cplusplus/Scope.h>
@@ -33,10 +35,11 @@
namespace Autotest {
namespace Internal {
-struct TestCodeLocation {
+struct TestCodeLocationAndType {
QString m_fileName;
unsigned m_line;
unsigned m_column;
+ TestTreeItem::Type m_type;
};
class TestVisitor : public CPlusPlus::SymbolVisitor
@@ -45,13 +48,13 @@ public:
TestVisitor(const QString &fullQualifiedClassName);
virtual ~TestVisitor();
- QMap<QString, TestCodeLocation> privateSlots() const { return m_privSlots; }
+ QMap<QString, TestCodeLocationAndType> privateSlots() const { return m_privSlots; }
bool visit(CPlusPlus::Class *symbol);
private:
QString m_className;
- QMap<QString, TestCodeLocation> m_privSlots;
+ QMap<QString, TestCodeLocationAndType> m_privSlots;
};
class TestAstVisitor : public CPlusPlus::ASTVisitor
@@ -85,14 +88,14 @@ public:
bool visit(QmlJS::AST::StringLiteral *ast);
QString testCaseName() const { return m_currentTestCaseName; }
- TestCodeLocation testCaseLocation() const { return m_testCaseLocation; }
- QMap<QString, TestCodeLocation> testFunctions() const { return m_testFunctions; }
+ TestCodeLocationAndType testCaseLocation() const { return m_testCaseLocation; }
+ QMap<QString, TestCodeLocationAndType> testFunctions() const { return m_testFunctions; }
private:
QmlJS::Document::Ptr m_currentDoc;
QString m_currentTestCaseName;
- TestCodeLocation m_testCaseLocation;
- QMap<QString, TestCodeLocation> m_testFunctions;
+ TestCodeLocationAndType m_testCaseLocation;
+ QMap<QString, TestCodeLocationAndType> m_testFunctions;
};