AutoTest: Find inherited Qt test methods

Task-number: QTCREATORBUG-17522
Change-Id: Ie7cfed2bd38944c28ea8502552593e0083f9727c
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Christian Stenger
2017-01-04 12:15:39 +01:00
parent 7d1d4471f0
commit 4a634a23cf
5 changed files with 54 additions and 7 deletions

View File

@@ -109,7 +109,7 @@ static QString testClass(const CppTools::CppModelManager *modelManager,
static CPlusPlus::Document::Ptr declaringDocument(CPlusPlus::Document::Ptr doc,
const CPlusPlus::Snapshot &snapshot,
const QString &testCaseName,
unsigned *line, unsigned *column)
unsigned *line = 0, unsigned *column = 0)
{
CPlusPlus::Document::Ptr declaringDoc = doc;
CPlusPlus::TypeOfExpression typeOfExpr;
@@ -123,8 +123,10 @@ static CPlusPlus::Document::Ptr declaringDocument(CPlusPlus::Document::Ptr doc,
const QString declFileName = QLatin1String(toeClass->fileId()->chars(),
toeClass->fileId()->size());
declaringDoc = snapshot.document(declFileName);
*line = toeClass->line();
*column = toeClass->column() - 1;
if (line)
*line = toeClass->line();
if (column)
*column = toeClass->column() - 1;
}
}
}
@@ -158,6 +160,26 @@ static QMap<QString, QtTestCodeLocationList> checkForDataTags(const QString &fil
return visitor.dataTags();
}
static QMap<QString, QtTestCodeLocationAndType> baseClassTestFunctions(const QSet<QString> &bases,
const CPlusPlus::Document::Ptr &doc, const CPlusPlus::Snapshot &snapshot)
{
QMap<QString, QtTestCodeLocationAndType> testFunctions;
for (const QString &baseClassName : bases) {
TestVisitor baseVisitor(baseClassName, snapshot);
baseVisitor.setInheritedMode(true);
CPlusPlus::Document::Ptr declaringDoc = declaringDocument(doc, snapshot, baseClassName);
if (declaringDoc.isNull())
continue;
baseVisitor.accept(declaringDoc->globalNamespace());
if (baseVisitor.resultValid())
testFunctions.unite(baseVisitor.privateSlots());
const QSet<QString> currentBaseBases = baseVisitor.baseClasses();
// recursively check base classes
testFunctions.unite(baseClassTestFunctions(currentBaseBases, doc, snapshot));
}
return testFunctions;
}
static bool handleQtTest(QFutureInterface<TestParseResultPtr> futureInterface,
CPlusPlus::Document::Ptr document,
const CPlusPlus::Snapshot &snapshot,
@@ -183,7 +205,9 @@ static bool handleQtTest(QFutureInterface<TestParseResultPtr> futureInterface,
if (!visitor.resultValid())
return false;
const QMap<QString, QtTestCodeLocationAndType> &testFunctions = visitor.privateSlots();
QMap<QString, QtTestCodeLocationAndType> testFunctions = visitor.privateSlots();
// gather appropriate information of base classes as well
testFunctions.unite(baseClassTestFunctions(visitor.baseClasses(), declaringDoc, snapshot));
const QSet<QString> &files = filesWithDataFunctionDefinitions(testFunctions);
// TODO: change to QHash<>

View File

@@ -251,8 +251,10 @@ TestTreeItem *QtTestTreeItem::find(const TestParseResult *result)
switch (type()) {
case Root:
return findChildByFile(result->fileName);
case TestCase:
return findChildByName(result->displayName);
case TestCase: {
const QtTestParseResult *qtResult = static_cast<const QtTestParseResult *>(result);
return findChildByNameAndInheritance(qtResult->displayName, qtResult->inherited());
}
case TestFunctionOrSet:
case TestDataFunction:
case TestSpecialFunction:
@@ -280,6 +282,14 @@ bool QtTestTreeItem::modify(const TestParseResult *result)
}
}
TestTreeItem *QtTestTreeItem::findChildByNameAndInheritance(const QString &name, bool inherited) const
{
return findChildBy([name, inherited](const TestTreeItem *other) -> bool {
const QtTestTreeItem *qtOther = static_cast<const QtTestTreeItem *>(other);
return qtOther->inherited() == inherited && qtOther->name() == name;
});
}
QString QtTestTreeItem::nameSuffix() const
{
static QString inheritedSuffix = QLatin1String(" [")

View File

@@ -51,6 +51,7 @@ public:
void setInherited(bool inherited) { m_inherited = inherited; }
bool inherited() const { return m_inherited; }
private:
TestTreeItem *findChildByNameAndInheritance(const QString &name, bool inherited) const;
QString nameSuffix() const;
bool m_inherited = false;
};

View File

@@ -83,10 +83,17 @@ bool TestVisitor::visit(CPlusPlus::Class *symbol)
locationAndType.m_type = TestTreeItem::TestDataFunction;
else
locationAndType.m_type = TestTreeItem::TestFunctionOrSet;
locationAndType.m_inherited = false; // for now
locationAndType.m_inherited = m_inherited;
m_privSlots.insert(name, locationAndType);
}
}
for (unsigned counter = 0, end = symbol->baseClassCount(); counter < end; ++counter) {
if (CPlusPlus::BaseClass *base = symbol->baseClassAt(counter)) {
const QString &baseClassName = o.prettyName(lc.fullyQualifiedName(base));
if (baseClassName != "QObject")
m_baseClasses.insert(baseClassName);
}
}
}
return true;
}

View File

@@ -35,6 +35,7 @@
#include <cpptools/symbolfinder.h>
#include <QMap>
#include <QSet>
namespace Autotest {
namespace Internal {
@@ -44,7 +45,9 @@ class TestVisitor : public CPlusPlus::SymbolVisitor
public:
explicit TestVisitor(const QString &fullQualifiedClassName, const CPlusPlus::Snapshot &snapshot);
void setInheritedMode(bool inherited) { m_inherited = inherited; }
QMap<QString, QtTestCodeLocationAndType> privateSlots() const { return m_privSlots; }
QSet<QString> baseClasses() const { return m_baseClasses; }
bool resultValid() const { return m_valid; }
bool visit(CPlusPlus::Class *symbol);
@@ -55,6 +58,8 @@ private:
CPlusPlus::Snapshot m_snapshot;
QMap<QString, QtTestCodeLocationAndType> m_privSlots;
bool m_valid = false;
bool m_inherited = false;
QSet<QString> m_baseClasses;
};
class TestAstVisitor : public CPlusPlus::ASTVisitor