forked from qt-creator/qt-creator
Display gtest related tests inside test tree model
Change-Id: I8f7a80e1b136f03a1437dd9c7ae0e6f4db0e2bcc Reviewed-by: Niels Weber <niels.weber@theqtcompany.com>
This commit is contained in:
@@ -459,6 +459,20 @@ static TestTreeItem *constructTestTreeItem(const QString &fileName,
|
|||||||
return treeItem;
|
return treeItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static TestTreeItem *constructGTestTreeItem(const QString &filePath, const QString &caseName,
|
||||||
|
const TestCodeLocationList &testNames)
|
||||||
|
{
|
||||||
|
TestTreeItem *item = new TestTreeItem(caseName, QString(), TestTreeItem::GTestCase);
|
||||||
|
foreach (const TestCodeLocationAndType &locationAndType, testNames) {
|
||||||
|
TestTreeItem *treeItemChild = new TestTreeItem(locationAndType.m_name, filePath,
|
||||||
|
locationAndType.m_type);
|
||||||
|
treeItemChild->setLine(locationAndType.m_line);
|
||||||
|
treeItemChild->setColumn(locationAndType.m_column);
|
||||||
|
item->appendChild(treeItemChild);
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
/****** end of helpers ******/
|
/****** end of helpers ******/
|
||||||
|
|
||||||
// used internally to indicate a parse that failed due to having triggered a parse for a file that
|
// used internally to indicate a parse that failed due to having triggered a parse for a file that
|
||||||
@@ -607,6 +621,7 @@ void TestCodeParser::handleGTest(const QString &filePath, const QSet<QString> &n
|
|||||||
|
|
||||||
QMap<QString, TestCodeLocationList> result = visitor.gtestFunctions();
|
QMap<QString, TestCodeLocationList> result = visitor.gtestFunctions();
|
||||||
QTC_CHECK(names.contains(result.keys().toSet()));
|
QTC_CHECK(names.contains(result.keys().toSet()));
|
||||||
|
updateGTests(document, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestCodeParser::onCppDocumentUpdated(const CPlusPlus::Document::Ptr &document)
|
void TestCodeParser::onCppDocumentUpdated(const CPlusPlus::Document::Ptr &document)
|
||||||
@@ -801,6 +816,8 @@ void TestCodeParser::clearCache()
|
|||||||
m_cppDocMap.clear();
|
m_cppDocMap.clear();
|
||||||
m_quickDocMap.clear();
|
m_quickDocMap.clear();
|
||||||
m_unnamedQuickDocList.clear();
|
m_unnamedQuickDocList.clear();
|
||||||
|
m_gtestDocMap.clear();
|
||||||
|
m_gtestDocList.clear();
|
||||||
emit cacheCleared();
|
emit cacheCleared();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -810,6 +827,9 @@ void TestCodeParser::removeTestsIfNecessary(const QString &fileName)
|
|||||||
if (m_cppDocMap.contains(fileName)) {
|
if (m_cppDocMap.contains(fileName)) {
|
||||||
m_cppDocMap.remove(fileName);
|
m_cppDocMap.remove(fileName);
|
||||||
emit testItemsRemoved(fileName, TestTreeModel::AutoTest);
|
emit testItemsRemoved(fileName, TestTreeModel::AutoTest);
|
||||||
|
} else if (m_gtestDocMap.contains(fileName)) {
|
||||||
|
m_gtestDocMap.remove(fileName);
|
||||||
|
emit testItemsRemoved(fileName, TestTreeModel::GoogleTest);
|
||||||
} else { // handle Qt Quick Tests
|
} else { // handle Qt Quick Tests
|
||||||
QList<QString> toBeRemoved;
|
QList<QString> toBeRemoved;
|
||||||
foreach (const QString &file, m_quickDocMap.keys()) {
|
foreach (const QString &file, m_quickDocMap.keys()) {
|
||||||
@@ -997,6 +1017,33 @@ void TestCodeParser::updateModelAndQuickDocMap(QmlJS::Document::Ptr document,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestCodeParser::updateGTests(const CPlusPlus::Document::Ptr &doc,
|
||||||
|
const QMap<QString, TestCodeLocationList> &tests)
|
||||||
|
{
|
||||||
|
const QString &fileName = doc->fileName();
|
||||||
|
removeGTestsByName(fileName);
|
||||||
|
|
||||||
|
QString proFile;
|
||||||
|
const CppTools::CppModelManager *cppMM = CppTools::CppModelManager::instance();
|
||||||
|
QList<CppTools::ProjectPart::Ptr> ppList = cppMM->projectPart(fileName);
|
||||||
|
if (ppList.size())
|
||||||
|
proFile = ppList.at(0)->projectFile;
|
||||||
|
|
||||||
|
foreach (const QString &testName, tests.keys()) {
|
||||||
|
TestTreeItem *item = constructGTestTreeItem(fileName, testName, tests.value(testName));
|
||||||
|
TestInfo info(item->name(), item->getChildNames(), doc->revision(), doc->editorRevision());
|
||||||
|
info.setProfile(proFile);
|
||||||
|
foreach (const TestCodeLocationAndType &testSet, tests.value(testName)) {
|
||||||
|
GTestInfo gtestInfo(testName, testSet.m_name, fileName);
|
||||||
|
if (testSet.m_type == TestTreeItem::GTestNameDisabled)
|
||||||
|
gtestInfo.setEnabled(false);
|
||||||
|
m_gtestDocList.append(gtestInfo);
|
||||||
|
}
|
||||||
|
emit testItemCreated(item, TestTreeModel::GoogleTest);
|
||||||
|
m_gtestDocMap.insert(fileName, info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TestCodeParser::removeUnnamedQuickTestsByName(const QString &fileName)
|
void TestCodeParser::removeUnnamedQuickTestsByName(const QString &fileName)
|
||||||
{
|
{
|
||||||
for (int i = m_unnamedQuickDocList.size() - 1; i >= 0; --i) {
|
for (int i = m_unnamedQuickDocList.size() - 1; i >= 0; --i) {
|
||||||
@@ -1006,6 +1053,15 @@ void TestCodeParser::removeUnnamedQuickTestsByName(const QString &fileName)
|
|||||||
emit unnamedQuickTestsRemoved(fileName);
|
emit unnamedQuickTestsRemoved(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestCodeParser::removeGTestsByName(const QString &fileName)
|
||||||
|
{
|
||||||
|
for (int i = m_gtestDocList.size() - 1; i >= 0; --i)
|
||||||
|
if (m_gtestDocList.at(i).fileName() == fileName)
|
||||||
|
m_gtestDocList.removeAt(i);
|
||||||
|
|
||||||
|
emit gTestsRemoved(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef WITH_TESTS
|
#ifdef WITH_TESTS
|
||||||
int TestCodeParser::autoTestsCount() const
|
int TestCodeParser::autoTestsCount() const
|
||||||
{
|
{
|
||||||
|
@@ -40,6 +40,7 @@ namespace Internal {
|
|||||||
struct TestCodeLocationAndType;
|
struct TestCodeLocationAndType;
|
||||||
class TestInfo;
|
class TestInfo;
|
||||||
class UnnamedQuickTestInfo;
|
class UnnamedQuickTestInfo;
|
||||||
|
class GTestInfo;
|
||||||
|
|
||||||
class TestCodeParser : public QObject
|
class TestCodeParser : public QObject
|
||||||
{
|
{
|
||||||
@@ -72,6 +73,7 @@ signals:
|
|||||||
void unnamedQuickTestsUpdated(const QString &mainFile,
|
void unnamedQuickTestsUpdated(const QString &mainFile,
|
||||||
const QMap<QString, TestCodeLocationAndType> &functions);
|
const QMap<QString, TestCodeLocationAndType> &functions);
|
||||||
void unnamedQuickTestsRemoved(const QString &filePath);
|
void unnamedQuickTestsRemoved(const QString &filePath);
|
||||||
|
void gTestsRemoved(const QString &filePath);
|
||||||
void parsingStarted();
|
void parsingStarted();
|
||||||
void parsingFinished();
|
void parsingFinished();
|
||||||
void parsingFailed();
|
void parsingFailed();
|
||||||
@@ -106,12 +108,17 @@ private:
|
|||||||
const QString &declaringFile, TestTreeItem *testItem);
|
const QString &declaringFile, TestTreeItem *testItem);
|
||||||
void updateModelAndQuickDocMap(QmlJS::Document::Ptr document,
|
void updateModelAndQuickDocMap(QmlJS::Document::Ptr document,
|
||||||
const QString &referencingFile, TestTreeItem *testItem);
|
const QString &referencingFile, TestTreeItem *testItem);
|
||||||
|
void updateGTests(const CPlusPlus::Document::Ptr &doc,
|
||||||
|
const QMap<QString, TestCodeLocationList> &tests);
|
||||||
void removeUnnamedQuickTestsByName(const QString &fileName);
|
void removeUnnamedQuickTestsByName(const QString &fileName);
|
||||||
|
void removeGTestsByName(const QString &fileName);
|
||||||
|
|
||||||
TestTreeModel *m_model;
|
TestTreeModel *m_model;
|
||||||
QMap<QString, TestInfo> m_cppDocMap;
|
QMap<QString, TestInfo> m_cppDocMap;
|
||||||
QMap<QString, TestInfo> m_quickDocMap;
|
QMap<QString, TestInfo> m_quickDocMap;
|
||||||
|
QMap<QString, TestInfo> m_gtestDocMap;
|
||||||
QList<UnnamedQuickTestInfo> m_unnamedQuickDocList;
|
QList<UnnamedQuickTestInfo> m_unnamedQuickDocList;
|
||||||
|
QList<GTestInfo> m_gtestDocList;
|
||||||
bool m_codeModelParsing;
|
bool m_codeModelParsing;
|
||||||
bool m_fullUpdatePostponed;
|
bool m_fullUpdatePostponed;
|
||||||
bool m_partialUpdatePostponed;
|
bool m_partialUpdatePostponed;
|
||||||
|
@@ -42,5 +42,13 @@ UnnamedQuickTestInfo::UnnamedQuickTestInfo(const QString &function, const QStrin
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GTestInfo::GTestInfo(const QString &caseName, const QString &setName, const QString &file)
|
||||||
|
: m_caseName(caseName),
|
||||||
|
m_setName(setName),
|
||||||
|
m_fileName(file),
|
||||||
|
m_enabled(true)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace Autotest
|
} // namespace Autotest
|
||||||
|
@@ -71,6 +71,26 @@ private:
|
|||||||
QString m_fileName;
|
QString m_fileName;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class GTestInfo {
|
||||||
|
public:
|
||||||
|
explicit GTestInfo(const QString &caseName, const QString &setName, const QString &file);
|
||||||
|
|
||||||
|
const QString caseName() const { return m_caseName; }
|
||||||
|
void setCaseName(const QString &caseName) { m_caseName = caseName; }
|
||||||
|
const QString setName() const { return m_setName; }
|
||||||
|
void setSetName(const QString &setName) { m_setName = setName; }
|
||||||
|
const QString fileName() const { return m_fileName; }
|
||||||
|
void setFileName(const QString &fileName) { m_fileName = fileName; }
|
||||||
|
bool isEnabled() const { return m_enabled; }
|
||||||
|
void setEnabled(bool enabled) { m_enabled = enabled; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString m_caseName;
|
||||||
|
QString m_setName;
|
||||||
|
QString m_fileName;
|
||||||
|
bool m_enabled;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace Autotest
|
} // namespace Autotest
|
||||||
|
|
||||||
|
@@ -60,6 +60,8 @@ TestTreeModel::TestTreeModel(QObject *parent) :
|
|||||||
this, &TestTreeModel::updateUnnamedQuickTest, Qt::QueuedConnection);
|
this, &TestTreeModel::updateUnnamedQuickTest, Qt::QueuedConnection);
|
||||||
connect(m_parser, &TestCodeParser::unnamedQuickTestsRemoved,
|
connect(m_parser, &TestCodeParser::unnamedQuickTestsRemoved,
|
||||||
this, &TestTreeModel::removeUnnamedQuickTests, Qt::QueuedConnection);
|
this, &TestTreeModel::removeUnnamedQuickTests, Qt::QueuedConnection);
|
||||||
|
connect(m_parser, &TestCodeParser::gTestsRemoved,
|
||||||
|
this, &TestTreeModel::removeGTests, Qt::QueuedConnection);
|
||||||
|
|
||||||
// CppTools::CppModelManagerInterface *cppMM = CppTools::CppModelManagerInterface::instance();
|
// CppTools::CppModelManagerInterface *cppMM = CppTools::CppModelManagerInterface::instance();
|
||||||
// if (cppMM) {
|
// if (cppMM) {
|
||||||
@@ -481,10 +483,45 @@ void TestTreeModel::removeUnnamedQuickTests(const QString &filePath)
|
|||||||
emit testTreeModelChanged();
|
emit testTreeModelChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestTreeModel::removeGTests(const QString &filePath)
|
||||||
|
{
|
||||||
|
for (int childRow = m_googleTestRootItem->childCount() - 1; childRow >= 0; --childRow) {
|
||||||
|
TestTreeItem *child = m_googleTestRootItem->childItem(childRow);
|
||||||
|
for (int grandChildRow = child->childCount() - 1; grandChildRow >= 0; --grandChildRow) {
|
||||||
|
TestTreeItem *grandChild = child->childItem(grandChildRow);
|
||||||
|
if (filePath == grandChild->filePath())
|
||||||
|
delete takeItem(grandChild);
|
||||||
|
}
|
||||||
|
if (child->childCount() == 0)
|
||||||
|
delete takeItem(child);
|
||||||
|
}
|
||||||
|
emit testTreeModelChanged();
|
||||||
|
}
|
||||||
|
|
||||||
void TestTreeModel::addTestTreeItem(TestTreeItem *item, TestTreeModel::Type type)
|
void TestTreeModel::addTestTreeItem(TestTreeItem *item, TestTreeModel::Type type)
|
||||||
{
|
{
|
||||||
TestTreeItem *parent = rootItemForType(type);
|
TestTreeItem *parent = rootItemForType(type);
|
||||||
parent->appendChild(item);
|
if (type == TestTreeModel::GoogleTest) {
|
||||||
|
// check if there's already an item with the same test name...
|
||||||
|
TestTreeItem *toBeUpdated = 0;
|
||||||
|
for (int row = 0, count = parent->childCount(); row < count; ++row) {
|
||||||
|
TestTreeItem *current = parent->childItem(row);
|
||||||
|
if (current->name() == item->name()) {
|
||||||
|
toBeUpdated = current;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ...if so we have, to update this one instead of adding a new item
|
||||||
|
if (toBeUpdated) {
|
||||||
|
for (int row = 0, count = item->childCount(); row < count; ++row)
|
||||||
|
toBeUpdated->appendChild(new TestTreeItem(*item->childItem(row)));
|
||||||
|
delete item;
|
||||||
|
} else {
|
||||||
|
parent->appendChild(item);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
parent->appendChild(item);
|
||||||
|
}
|
||||||
emit testTreeModelChanged();
|
emit testTreeModelChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -84,6 +84,7 @@ private:
|
|||||||
void removeAllTestItems();
|
void removeAllTestItems();
|
||||||
void removeTestTreeItems(const QString &filePath, Type type);
|
void removeTestTreeItems(const QString &filePath, Type type);
|
||||||
void removeUnnamedQuickTests(const QString &filePath);
|
void removeUnnamedQuickTests(const QString &filePath);
|
||||||
|
void removeGTests(const QString &filePath);
|
||||||
|
|
||||||
TestTreeItem *unnamedQuickTests() const;
|
TestTreeItem *unnamedQuickTests() const;
|
||||||
TestTreeItem *rootItemForType(Type type);
|
TestTreeItem *rootItemForType(Type type);
|
||||||
|
Reference in New Issue
Block a user