summaryrefslogtreecommitdiff
path: root/plugins/autotest/testtreemodel.cpp
diff options
context:
space:
mode:
authorChristian Stenger <christian.stenger@theqtcompany.com>2015-02-05 16:07:45 +0100
committerChristian Stenger <christian.stenger@theqtcompany.com>2015-02-16 15:43:02 +0200
commit2ce99680b20802a370e6d20a1467a1d41fbee690 (patch)
tree66d68ac3cb3231b121e90cb3be683da1b2e8b63a /plugins/autotest/testtreemodel.cpp
parent61c50e4aa343387b56192a34db6384d1dfcfa3c5 (diff)
downloadqt-creator-2ce99680b20802a370e6d20a1467a1d41fbee690.tar.gz
Decouple code parser and model
Additionally some minor refactorings to increase readability. Change-Id: I0be120fcedcf31dbb0116d84f0d3c23cf95e7d91 Reviewed-by: Andre Poenitz <andre.poenitz@theqtcompany.com>
Diffstat (limited to 'plugins/autotest/testtreemodel.cpp')
-rw-r--r--plugins/autotest/testtreemodel.cpp329
1 files changed, 216 insertions, 113 deletions
diff --git a/plugins/autotest/testtreemodel.cpp b/plugins/autotest/testtreemodel.cpp
index 9c8d235a04..f2ea94d626 100644
--- a/plugins/autotest/testtreemodel.cpp
+++ b/plugins/autotest/testtreemodel.cpp
@@ -50,6 +50,17 @@ TestTreeModel::TestTreeModel(QObject *parent) :
{
m_rootItem->appendChild(m_autoTestRootItem);
m_rootItem->appendChild(m_quickTestRootItem);
+
+ connect(m_parser, &TestCodeParser::cacheCleared, this, &TestTreeModel::removeAllTestItems);
+ connect(m_parser, &TestCodeParser::testItemCreated, this, &TestTreeModel::addTestTreeItem);
+ connect(m_parser, &TestCodeParser::testItemsCreated, this, &TestTreeModel::addTestTreeItems);
+ connect(m_parser, &TestCodeParser::testItemModified, this, &TestTreeModel::modifyTestTreeItem);
+ connect(m_parser, &TestCodeParser::testItemsRemoved, this, &TestTreeModel::removeTestTreeItems);
+ connect(m_parser, &TestCodeParser::unnamedQuickTestsUpdated,
+ this, &TestTreeModel::updateUnnamedQuickTest);
+ connect(m_parser, &TestCodeParser::unnamedQuickTestsRemoved,
+ this, &TestTreeModel::removeUnnamedQuickTests);
+
m_parser->updateTestTree();
// CppTools::CppModelManagerInterface *cppMM = CppTools::CppModelManagerInterface::instance();
@@ -524,6 +535,62 @@ QList<TestConfiguration *> TestTreeModel::getSelectedTests() const
return result;
}
+QString TestTreeModel::getMainFileForUnnamedQuickTest(const QString &qmlFile) const
+{
+ const TestTreeItem *unnamed = unnamedQuickTests();
+ for (int row = 0, count = unnamed->childCount(); row < count; ++row) {
+ const TestTreeItem *child = unnamed->child(row);
+ if (qmlFile == child->filePath())
+ return child->mainFile();
+ }
+ return QString();
+}
+
+void TestTreeModel::qmlFilesAndFunctionNamesForMainFile(const QString &mainFile,
+ QSet<QString> *filePaths,
+ QList<QString> *functionNames) const
+{
+ TestTreeItem *unnamed = unnamedQuickTests();
+ for (int i = 0; i < unnamed->childCount(); ++i) {
+ const TestTreeItem *child = unnamed->child(i);
+ if (child->mainFile() == mainFile) {
+ filePaths->insert(child->filePath());
+ functionNames->append(child->name());
+ }
+ }
+}
+
+QList<QString> TestTreeModel::getUnnamedQuickTestFunctions() const
+{
+ TestTreeItem *unnamed = unnamedQuickTests();
+ if (unnamed)
+ return unnamed->getChildNames();
+ return QList<QString>();
+}
+
+QSet<QString> TestTreeModel::qmlFilesForProFile(const QString &proFile) const
+{
+ QSet<QString> filePaths;
+ CppTools::CppModelManager *modelManager = CppTools::CppModelManager::instance();
+ if (TestTreeItem *unnamed = unnamedQuickTests()) {
+ for (int i = 0; i < unnamed->childCount(); ++i) {
+ const TestTreeItem *child = unnamed->child(i);
+ QList<CppTools::ProjectPart::Ptr> ppList = modelManager->projectPart(child->mainFile());
+ if (ppList.size() && ppList.at(0)->projectFile == proFile)
+ filePaths.insert(child->filePath());
+ }
+ }
+ return filePaths;
+}
+
+bool TestTreeModel::hasUnnamedQuickTests() const
+{
+ for (int row = 0, count = m_quickTestRootItem->childCount(); row < count; ++row)
+ if (m_quickTestRootItem->child(row)->name().isEmpty())
+ return true;
+ return false;
+}
+
TestTreeItem *TestTreeModel::unnamedQuickTests() const
{
for (int row = 0, count = m_quickTestRootItem->childCount(); row < count; ++row) {
@@ -534,177 +601,213 @@ TestTreeItem *TestTreeModel::unnamedQuickTests() const
return 0;
}
-void TestTreeModel::modifyAutoTestSubtree(int row, TestTreeItem *newItem)
+void TestTreeModel::removeUnnamedQuickTests(const QString &filePath)
{
- QModelIndex toBeModifiedIndex = index(0, 0).child(row, 0);
- modifyTestSubtree(toBeModifiedIndex, newItem);
-}
+ TestTreeItem *unnamedQT = unnamedQuickTests();
+ if (!unnamedQT)
+ return;
-void TestTreeModel::removeAutoTestSubtreeByFilePath(const QString &file)
-{
- const QModelIndex atRootIndex = index(0, 0);
- const int count = rowCount(atRootIndex);
- for (int row = 0; row < count; ++row) {
- const QModelIndex childIndex = atRootIndex.child(row, 0);
- TestTreeItem *childItem = static_cast<TestTreeItem *>(childIndex.internalPointer());
- if (file == childItem->filePath()) {
- removeRow(row, atRootIndex);
- break;
- }
+ const QModelIndex unnamedQTIndex = index(1, 0).child(unnamedQT->row(), 0);
+ for (int childRow = unnamedQT->childCount() - 1; childRow >= 0; --childRow) {
+ const TestTreeItem *child = unnamedQT->child(childRow);
+ if (filePath == child->filePath())
+ removeRow(childRow, unnamedQTIndex);
}
+
+ if (unnamedQT->childCount() == 0)
+ removeRow(unnamedQT->row(), unnamedQTIndex.parent());
emit testTreeModelChanged();
}
-void TestTreeModel::addAutoTest(TestTreeItem *newItem)
+void TestTreeModel::addTestTreeItem(const TestTreeItem &item, TestTreeModel::Type type)
{
- beginInsertRows(index(0, 0), m_autoTestRootItem->childCount(), m_autoTestRootItem->childCount());
- m_autoTestRootItem->appendChild(newItem);
+ TestTreeItem *parent = rootItemForType(type);
+ QModelIndex index = rootIndexForType(type);
+ TestTreeItem *toBeAdded = new TestTreeItem(item);
+ toBeAdded->setParent(parent);
+
+ beginInsertRows(index, parent->childCount(), parent->childCount());
+ parent->appendChild(toBeAdded);
endInsertRows();
emit testTreeModelChanged();
}
-void TestTreeModel::removeAllAutoTests()
+void TestTreeModel::addTestTreeItems(const QList<TestTreeItem> &itemList, TestTreeModel::Type type)
{
- beginResetModel();
- m_autoTestRootItem->removeChildren();
- endResetModel();
+ TestTreeItem *parent = rootItemForType(type);
+ QModelIndex index = rootIndexForType(type);
+
+ beginInsertRows(index, parent->childCount(), parent->childCount() + itemList.size() - 1);
+ foreach (const TestTreeItem &item, itemList) {
+ TestTreeItem *toBeAdded = new TestTreeItem(item);
+ toBeAdded->setParent(parent);
+ parent->appendChild(toBeAdded);
+ }
+ endInsertRows();
emit testTreeModelChanged();
}
-void TestTreeModel::modifyQuickTestSubtree(int row, TestTreeItem *newItem)
+void TestTreeModel::updateUnnamedQuickTest(const QString &fileName, const QString &mainFile,
+ const QMap<QString, TestCodeLocationAndType> &functions)
{
- QModelIndex toBeModifiedIndex = index(1, 0).child(row, 0);
- modifyTestSubtree(toBeModifiedIndex, newItem);
-}
+ removeUnnamedQuickTests(fileName);
+ TestTreeItem unnamed = hasUnnamedQuickTests()
+ ? TestTreeItem(*unnamedQuickTests())
+ : TestTreeItem(QString(), QString(), TestTreeItem::TEST_CLASS, rootItemForType(QuickTest));
-void TestTreeModel::removeQuickTestSubtreeByFilePath(const QString &file)
-{
- const QModelIndex qtRootIndex = index(1, 0);
- for (int row = 0, count = rowCount(qtRootIndex); row < count; ++row) {
- const QModelIndex childIndex = qtRootIndex.child(row, 0);
- const TestTreeItem *childItem = static_cast<TestTreeItem *>(childIndex.internalPointer());
- if (file == childItem->filePath()) {
- removeRow(row, qtRootIndex);
- break;
- }
+ foreach (const QString &functionName, functions.keys()) {
+ const TestCodeLocationAndType locationAndType = functions.value(functionName);
+ TestTreeItem *testFunction = new TestTreeItem(functionName, locationAndType.m_fileName,
+ locationAndType.m_type, &unnamed);
+ testFunction->setLine(locationAndType.m_line);
+ testFunction->setColumn(locationAndType.m_column);
+ testFunction->setMainFile(mainFile);
+ unnamed.appendChild(testFunction);
}
- emit testTreeModelChanged();
+ if (hasUnnamedQuickTests())
+ modifyTestTreeItem(unnamed, QuickTest, QString());
+ else
+ addTestTreeItem(unnamed, QuickTest);
}
-void TestTreeModel::addQuickTest(TestTreeItem *newItem)
+void TestTreeModel::modifyTestTreeItem(TestTreeItem item, TestTreeModel::Type type, const QString &file)
{
- beginInsertRows(index(1, 0), m_quickTestRootItem->childCount(), m_quickTestRootItem->childCount());
- m_quickTestRootItem->appendChild(newItem);
- endInsertRows();
- emit testTreeModelChanged();
+ QModelIndex index = rootIndexForType(type);
+ TestTreeItem *parent = rootItemForType(type);
+ item.setParent(parent);
+ if (file.isEmpty()) {
+ if (TestTreeItem *unnamed = unnamedQuickTests()) {
+ index = index.child(unnamed->row(), 0);
+ modifyTestSubtree(index, item);
+ }
+ } else {
+ for (int row = 0; row < parent->childCount(); ++row) {
+ if (parent->child(row)->filePath() == file) {
+ index = index.child(row, 0);
+ modifyTestSubtree(index, item);
+ break;
+ }
+ }
+ }
}
-void TestTreeModel::removeAllQuickTests()
+void TestTreeModel::removeAllTestItems()
{
beginResetModel();
+ m_autoTestRootItem->removeChildren();
m_quickTestRootItem->removeChildren();
endResetModel();
emit testTreeModelChanged();
}
-bool TestTreeModel::removeUnnamedQuickTests(const QString &filePath)
+void TestTreeModel::removeTestTreeItems(const QString &filePath, Type type)
{
- TestTreeItem *unnamedQT = unnamedQuickTests();
- if (!unnamedQT)
- return false;
-
bool removed = false;
- const QModelIndex unnamedQTIndex = index(1, 0).child(unnamedQT->row(), 0);
- for (int childRow = unnamedQT->childCount() - 1; childRow >= 0; --childRow) {
- const TestTreeItem *child = unnamedQT->child(childRow);
- if (filePath == child->filePath())
- removed |= removeRow(childRow, unnamedQTIndex);
+ const QModelIndex rootIndex = rootIndexForType(type);
+ const int count = rowCount(rootIndex);
+ for (int row = count - 1; row >= 0; --row) {
+ const QModelIndex childIndex = rootIndex.child(row, 0);
+ TestTreeItem *childItem = static_cast<TestTreeItem *>(childIndex.internalPointer());
+ if (filePath == childItem->filePath())
+ removed |= removeRow(row, rootIndex);
}
+ if (removed)
+ emit testTreeModelChanged();
+}
- if (unnamedQT->childCount() == 0)
- removeRow(unnamedQT->row(), unnamedQTIndex.parent());
- emit testTreeModelChanged();
- return removed;
+TestTreeItem *TestTreeModel::rootItemForType(TestTreeModel::Type type)
+{
+ switch (type) {
+ case AutoTest:
+ return m_autoTestRootItem;
+ case QuickTest:
+ return m_quickTestRootItem;
+ }
+ QTC_ASSERT(false, return 0);
+}
+
+QModelIndex TestTreeModel::rootIndexForType(TestTreeModel::Type type)
+{
+ switch (type) {
+ case AutoTest:
+ return index(0, 0);
+ case QuickTest:
+ return index(1, 0);
+ }
+ QTC_ASSERT(false, return QModelIndex());
}
-void TestTreeModel::modifyTestSubtree(QModelIndex &toBeModifiedIndex, TestTreeItem *newItem)
+void TestTreeModel::modifyTestSubtree(QModelIndex &toBeModifiedIndex, const TestTreeItem &newItem)
+
{
if (!toBeModifiedIndex.isValid())
return;
- static QVector<int> modificationRoles = QVector<int>() << Qt::DisplayRole
- << Qt::ToolTipRole << LinkRole;
TestTreeItem *toBeModifiedItem = static_cast<TestTreeItem *>(toBeModifiedIndex.internalPointer());
- if (toBeModifiedItem->modifyContent(newItem))
- emit dataChanged(toBeModifiedIndex, toBeModifiedIndex, modificationRoles);
+ if (toBeModifiedItem->modifyContent(&newItem))
+ emit dataChanged(toBeModifiedIndex, toBeModifiedIndex,
+ QVector<int>() << Qt::DisplayRole << Qt::ToolTipRole << LinkRole);
// process sub-items as well...
const int childCount = toBeModifiedItem->childCount();
- const int newChildCount = newItem->childCount();
+ const int newChildCount = newItem.childCount();
// for keeping the CheckState on modifications
- // TODO might still fail for duplicate entries (e.g. unnamed Quick Tests)
- QHash<QString, Qt::CheckState> originalItems;
+ // TODO might still fail for duplicate entries
+ QHash<QString, Qt::CheckState> checkStates;
for (int row = 0; row < childCount; ++row) {
const TestTreeItem *child = toBeModifiedItem->child(row);
- originalItems.insert(child->name(), child->checked());
+ checkStates.insert(child->name(), child->checked());
}
if (childCount <= newChildCount) {
- for (int row = 0; row < childCount; ++row) {
- QModelIndex child = toBeModifiedIndex.child(row, 0);
- TestTreeItem *toBeModifiedChild = toBeModifiedItem->child(row);
- TestTreeItem *modifiedChild = newItem->child(row);
- if (toBeModifiedChild->modifyContent(modifiedChild)) {
- emit dataChanged(child, child, modificationRoles);
- }
- if (originalItems.contains(toBeModifiedChild->name())) {
- Qt::CheckState state = originalItems.value(toBeModifiedChild->name());
- if (state != toBeModifiedChild->checked()) {
- toBeModifiedChild->setChecked(state);
- emit dataChanged(child, child, QVector<int>() << Qt::CheckStateRole);
- }
- } else { // newly added (BAD: happens for renaming as well)
- toBeModifiedChild->setChecked(Qt::Checked);
- emit dataChanged(child, child, QVector<int>() << Qt::CheckStateRole);
- }
- }
- if (childCount < newChildCount) { // add aditional items
- for (int row = childCount; row < newChildCount; ++row) {
- TestTreeItem *newChild = newItem->child(row);
- TestTreeItem *toBeAdded = new TestTreeItem(*newChild);
- toBeAdded->setParent(toBeModifiedItem);
- beginInsertRows(toBeModifiedIndex, row, row);
- toBeModifiedItem->appendChild(toBeAdded);
- endInsertRows();
- if (originalItems.contains(toBeAdded->name())
- && originalItems.value(toBeAdded->name()) != Qt::Checked)
- toBeAdded->setChecked(originalItems.value(toBeAdded->name()));
- }
+ processChildren(toBeModifiedIndex, newItem, childCount, checkStates);
+ // add additional items
+ for (int row = childCount; row < newChildCount; ++row) {
+ TestTreeItem *newChild = newItem.child(row);
+ TestTreeItem *toBeAdded = new TestTreeItem(*newChild);
+ toBeAdded->setParent(toBeModifiedItem);
+ if (checkStates.contains(toBeAdded->name())
+ && checkStates.value(toBeAdded->name()) != Qt::Checked)
+ toBeAdded->setChecked(checkStates.value(toBeAdded->name()));
+ beginInsertRows(toBeModifiedIndex, row, row);
+ toBeModifiedItem->appendChild(toBeAdded);
+ endInsertRows();
}
} else {
- for (int row = 0; row < newChildCount; ++row) {
- QModelIndex child = toBeModifiedIndex.child(row, 0);
- TestTreeItem *toBeModifiedChild = toBeModifiedItem->child(row);
- TestTreeItem *modifiedChild = newItem->child(row);
- if (toBeModifiedChild->modifyContent(modifiedChild))
- emit dataChanged(child, child, modificationRoles);
- if (originalItems.contains(toBeModifiedChild->name())) {
- Qt::CheckState state = originalItems.value(toBeModifiedChild->name());
- if (state != toBeModifiedChild->checked()) {
- toBeModifiedChild->setChecked(state);
- emit dataChanged(child, child, QVector<int>() << Qt::CheckStateRole);
- }
- } else { // newly added (BAD: happens for renaming as well)
- toBeModifiedChild->setChecked(Qt::Checked);
- emit dataChanged(child, child, QVector<int>() << Qt::CheckStateRole);
- }
- } // remove rest of the items
+ processChildren(toBeModifiedIndex, newItem, newChildCount, checkStates);
+ // remove rest of the items
removeRows(newChildCount, childCount - newChildCount, toBeModifiedIndex);
}
emit testTreeModelChanged();
}
+void TestTreeModel::processChildren(QModelIndex &parentIndex, const TestTreeItem &newItem,
+ const int upperBound,
+ const QHash<QString, Qt::CheckState> &checkStates)
+{
+ static QVector<int> modificationRoles = QVector<int>() << Qt::DisplayRole
+ << Qt::ToolTipRole << LinkRole;
+ TestTreeItem *toBeModifiedItem = static_cast<TestTreeItem *>(parentIndex.internalPointer());
+ for (int row = 0; row < upperBound; ++row) {
+ QModelIndex child = parentIndex.child(row, 0);
+ TestTreeItem *toBeModifiedChild = toBeModifiedItem->child(row);
+ TestTreeItem *modifiedChild = newItem.child(row);
+ if (toBeModifiedChild->modifyContent(modifiedChild))
+ emit dataChanged(child, child, modificationRoles);
+ if (checkStates.contains(toBeModifiedChild->name())) {
+ Qt::CheckState state = checkStates.value(toBeModifiedChild->name());
+ if (state != toBeModifiedChild->checked()) {
+ toBeModifiedChild->setChecked(state);
+ emit dataChanged(child, child, QVector<int>() << Qt::CheckStateRole);
+ }
+ } else { // newly added (BAD: happens for renaming as well)
+ toBeModifiedChild->setChecked(Qt::Checked);
+ emit dataChanged(child, child, QVector<int>() << Qt::CheckStateRole);
+ }
+ }
+}
+
/***************************** Sort/Filter Model **********************************/
TestTreeSortFilterModel::TestTreeSortFilterModel(TestTreeModel *sourceModel, QObject *parent)