AutoTest: Introduce inherited state for Qt test tree items

Preparation for later detection and displaying inherited functions
for Qt tests.

Task-number: QTCREATORBUG-17522
Change-Id: I2af1f758a837049ef676840b03f9cd73a2cb9873
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Christian Stenger
2017-01-04 12:06:46 +01:00
parent e575f054db
commit 7d1d4471f0
6 changed files with 51 additions and 17 deletions

View File

@@ -132,11 +132,11 @@ static CPlusPlus::Document::Ptr declaringDocument(CPlusPlus::Document::Ptr doc,
} }
static QSet<QString> filesWithDataFunctionDefinitions( static QSet<QString> filesWithDataFunctionDefinitions(
const QMap<QString, TestCodeLocationAndType> &testFunctions) const QMap<QString, QtTestCodeLocationAndType> &testFunctions)
{ {
QSet<QString> result; QSet<QString> result;
QMap<QString, TestCodeLocationAndType>::ConstIterator it = testFunctions.begin(); QMap<QString, QtTestCodeLocationAndType>::ConstIterator it = testFunctions.begin();
const QMap<QString, TestCodeLocationAndType>::ConstIterator end = testFunctions.end(); const QMap<QString, QtTestCodeLocationAndType>::ConstIterator end = testFunctions.end();
for ( ; it != end; ++it) { for ( ; it != end; ++it) {
const QString &key = it.key(); const QString &key = it.key();
@@ -146,7 +146,7 @@ static QSet<QString> filesWithDataFunctionDefinitions(
return result; return result;
} }
static QMap<QString, TestCodeLocationList> checkForDataTags(const QString &fileName, static QMap<QString, QtTestCodeLocationList> checkForDataTags(const QString &fileName,
const CPlusPlus::Snapshot &snapshot) const CPlusPlus::Snapshot &snapshot)
{ {
const QByteArray fileContent = CppParser::getFileContent(fileName); const QByteArray fileContent = CppParser::getFileContent(fileName);
@@ -183,11 +183,11 @@ static bool handleQtTest(QFutureInterface<TestParseResultPtr> futureInterface,
if (!visitor.resultValid()) if (!visitor.resultValid())
return false; return false;
const QMap<QString, TestCodeLocationAndType> &testFunctions = visitor.privateSlots(); const QMap<QString, QtTestCodeLocationAndType> &testFunctions = visitor.privateSlots();
const QSet<QString> &files = filesWithDataFunctionDefinitions(testFunctions); const QSet<QString> &files = filesWithDataFunctionDefinitions(testFunctions);
// TODO: change to QHash<> // TODO: change to QHash<>
QMap<QString, TestCodeLocationList> dataTags; QMap<QString, QtTestCodeLocationList> dataTags;
foreach (const QString &file, files) foreach (const QString &file, files)
dataTags.unite(checkForDataTags(file, snapshot)); dataTags.unite(checkForDataTags(file, snapshot));
@@ -202,10 +202,10 @@ static bool handleQtTest(QFutureInterface<TestParseResultPtr> futureInterface,
if (projectParts.isEmpty()) // happens if shutting down while parsing if (projectParts.isEmpty()) // happens if shutting down while parsing
return false; return false;
parseResult->proFile = projectParts.first()->projectFile; parseResult->proFile = projectParts.first()->projectFile;
QMap<QString, TestCodeLocationAndType>::ConstIterator it = testFunctions.begin(); QMap<QString, QtTestCodeLocationAndType>::ConstIterator it = testFunctions.begin();
const QMap<QString, TestCodeLocationAndType>::ConstIterator end = testFunctions.end(); const QMap<QString, QtTestCodeLocationAndType>::ConstIterator end = testFunctions.end();
for ( ; it != end; ++it) { for ( ; it != end; ++it) {
const TestCodeLocationAndType &location = it.value(); const QtTestCodeLocationAndType &location = it.value();
QtTestParseResult *func = new QtTestParseResult(id); QtTestParseResult *func = new QtTestParseResult(id);
func->itemType = location.m_type; func->itemType = location.m_type;
func->name = testCaseName + "::" + it.key(); func->name = testCaseName + "::" + it.key();
@@ -213,8 +213,9 @@ static bool handleQtTest(QFutureInterface<TestParseResultPtr> futureInterface,
func->fileName = location.m_name; func->fileName = location.m_name;
func->line = location.m_line; func->line = location.m_line;
func->column = location.m_column; func->column = location.m_column;
func->setInherited(location.m_inherited);
foreach (const TestCodeLocationAndType &tag, dataTags.value(func->name)) { foreach (const QtTestCodeLocationAndType &tag, dataTags.value(func->name)) {
QtTestParseResult *dataTag = new QtTestParseResult(id); QtTestParseResult *dataTag = new QtTestParseResult(id);
dataTag->itemType = tag.m_type; dataTag->itemType = tag.m_type;
dataTag->name = tag.m_name; dataTag->name = tag.m_name;
@@ -222,6 +223,7 @@ static bool handleQtTest(QFutureInterface<TestParseResultPtr> futureInterface,
dataTag->fileName = testFunctions.value(it.key() + "_data").m_name; dataTag->fileName = testFunctions.value(it.key() + "_data").m_name;
dataTag->line = tag.m_line; dataTag->line = tag.m_line;
dataTag->column = tag.m_column; dataTag->column = tag.m_column;
dataTag->setInherited(tag.m_inherited);
func->children.append(dataTag); func->children.append(dataTag);
} }

View File

@@ -34,7 +34,11 @@ class QtTestParseResult : public TestParseResult
{ {
public: public:
explicit QtTestParseResult(const Core::Id &id) : TestParseResult(id) {} explicit QtTestParseResult(const Core::Id &id) : TestParseResult(id) {}
void setInherited(bool inherited) { m_inherited = inherited; }
bool inherited() const { return m_inherited; }
TestTreeItem *createTestTreeItem() const override; TestTreeItem *createTestTreeItem() const override;
private:
bool m_inherited = false;
}; };
class QtTestParser : public CppParser class QtTestParser : public CppParser

View File

@@ -43,11 +43,13 @@ QtTestTreeItem::QtTestTreeItem(const QString &name, const QString &filePath, Tes
QtTestTreeItem *QtTestTreeItem::createTestItem(const TestParseResult *result) QtTestTreeItem *QtTestTreeItem::createTestItem(const TestParseResult *result)
{ {
const QtTestParseResult *qtResult = static_cast<const QtTestParseResult *>(result);
QtTestTreeItem *item = new QtTestTreeItem(result->displayName, result->fileName, QtTestTreeItem *item = new QtTestTreeItem(result->displayName, result->fileName,
result->itemType); result->itemType);
item->setProFile(result->proFile); item->setProFile(result->proFile);
item->setLine(result->line); item->setLine(result->line);
item->setColumn(result->column); item->setColumn(result->column);
item->setInherited(qtResult->inherited());
foreach (const TestParseResult *funcParseResult, result->children) foreach (const TestParseResult *funcParseResult, result->children)
item->appendChild(createTestItem(funcParseResult)); item->appendChild(createTestItem(funcParseResult));
@@ -57,6 +59,10 @@ QtTestTreeItem *QtTestTreeItem::createTestItem(const TestParseResult *result)
QVariant QtTestTreeItem::data(int column, int role) const QVariant QtTestTreeItem::data(int column, int role) const
{ {
switch (role) { switch (role) {
case Qt::DisplayRole:
if (type() == Root)
break;
return QVariant(name() + nameSuffix());
case Qt::CheckStateRole: case Qt::CheckStateRole:
switch (type()) { switch (type()) {
case Root: case Root:
@@ -274,5 +280,13 @@ bool QtTestTreeItem::modify(const TestParseResult *result)
} }
} }
QString QtTestTreeItem::nameSuffix() const
{
static QString inheritedSuffix = QLatin1String(" [")
+ QCoreApplication::translate("QtTestTreeItem", "inherited")
+ QLatin1String("]");
return m_inherited ? inheritedSuffix : QString();
}
} // namespace Internal } // namespace Internal
} // namespace Autotest } // namespace Autotest

View File

@@ -48,7 +48,20 @@ public:
QList<TestConfiguration *> getSelectedTestConfigurations() const override; QList<TestConfiguration *> getSelectedTestConfigurations() const override;
TestTreeItem *find(const TestParseResult *result) override; TestTreeItem *find(const TestParseResult *result) override;
bool modify(const TestParseResult *result) override; bool modify(const TestParseResult *result) override;
void setInherited(bool inherited) { m_inherited = inherited; }
bool inherited() const { return m_inherited; }
private:
QString nameSuffix() const;
bool m_inherited = false;
}; };
class QtTestCodeLocationAndType : public TestCodeLocationAndType
{
public:
bool m_inherited = false;
};
typedef QVector<QtTestCodeLocationAndType> QtTestCodeLocationList;
} // namespace Internal } // namespace Internal
} // namespace Autotest } // namespace Autotest

View File

@@ -64,7 +64,7 @@ bool TestVisitor::visit(CPlusPlus::Class *symbol)
if (const auto func = type->asFunctionType()) { if (const auto func = type->asFunctionType()) {
if (func->isSlot() && member->isPrivate()) { if (func->isSlot() && member->isPrivate()) {
const QString name = o.prettyName(func->name()); const QString name = o.prettyName(func->name());
TestCodeLocationAndType locationAndType; QtTestCodeLocationAndType locationAndType;
CPlusPlus::Function *functionDefinition = m_symbolFinder.findMatchingDefinition( CPlusPlus::Function *functionDefinition = m_symbolFinder.findMatchingDefinition(
func, m_snapshot, true); func, m_snapshot, true);
@@ -83,6 +83,7 @@ bool TestVisitor::visit(CPlusPlus::Class *symbol)
locationAndType.m_type = TestTreeItem::TestDataFunction; locationAndType.m_type = TestTreeItem::TestDataFunction;
else else
locationAndType.m_type = TestTreeItem::TestFunctionOrSet; locationAndType.m_type = TestTreeItem::TestFunctionOrSet;
locationAndType.m_inherited = false; // for now
m_privSlots.insert(name, locationAndType); m_privSlots.insert(name, locationAndType);
} }
} }
@@ -220,7 +221,7 @@ bool TestDataFunctionVisitor::visit(CPlusPlus::CallAST *ast)
unsigned column = 0; unsigned column = 0;
m_currentDoc->translationUnit()->getTokenStartPosition( m_currentDoc->translationUnit()->getTokenStartPosition(
firstToken, &line, &column); firstToken, &line, &column);
TestCodeLocationAndType locationAndType; QtTestCodeLocationAndType locationAndType;
locationAndType.m_name = name; locationAndType.m_name = name;
locationAndType.m_column = column - 1; locationAndType.m_column = column - 1;
locationAndType.m_line = line; locationAndType.m_line = line;

View File

@@ -44,7 +44,7 @@ class TestVisitor : public CPlusPlus::SymbolVisitor
public: public:
explicit TestVisitor(const QString &fullQualifiedClassName, const CPlusPlus::Snapshot &snapshot); explicit TestVisitor(const QString &fullQualifiedClassName, const CPlusPlus::Snapshot &snapshot);
QMap<QString, TestCodeLocationAndType> privateSlots() const { return m_privSlots; } QMap<QString, QtTestCodeLocationAndType> privateSlots() const { return m_privSlots; }
bool resultValid() const { return m_valid; } bool resultValid() const { return m_valid; }
bool visit(CPlusPlus::Class *symbol); bool visit(CPlusPlus::Class *symbol);
@@ -53,7 +53,7 @@ private:
CppTools::SymbolFinder m_symbolFinder; CppTools::SymbolFinder m_symbolFinder;
QString m_className; QString m_className;
CPlusPlus::Snapshot m_snapshot; CPlusPlus::Snapshot m_snapshot;
QMap<QString, TestCodeLocationAndType> m_privSlots; QMap<QString, QtTestCodeLocationAndType> m_privSlots;
bool m_valid = false; bool m_valid = false;
}; };
@@ -84,7 +84,7 @@ public:
bool visit(CPlusPlus::CallAST *ast); bool visit(CPlusPlus::CallAST *ast);
bool preVisit(CPlusPlus::AST *ast); bool preVisit(CPlusPlus::AST *ast);
void postVisit(CPlusPlus::AST *ast); void postVisit(CPlusPlus::AST *ast);
QMap<QString, TestCodeLocationList> dataTags() const { return m_dataTags; } QMap<QString, QtTestCodeLocationList> dataTags() const { return m_dataTags; }
private: private:
QString extractNameFromAST(CPlusPlus::StringLiteralAST *ast, bool *ok) const; QString extractNameFromAST(CPlusPlus::StringLiteralAST *ast, bool *ok) const;
@@ -93,8 +93,8 @@ private:
CPlusPlus::Document::Ptr m_currentDoc; CPlusPlus::Document::Ptr m_currentDoc;
CPlusPlus::Overview m_overview; CPlusPlus::Overview m_overview;
QString m_currentFunction; QString m_currentFunction;
QMap<QString, TestCodeLocationList> m_dataTags; QMap<QString, QtTestCodeLocationList> m_dataTags;
TestCodeLocationList m_currentTags; QtTestCodeLocationList m_currentTags;
unsigned m_currentAstDepth = 0; unsigned m_currentAstDepth = 0;
unsigned m_insideUsingQTestDepth = 0; unsigned m_insideUsingQTestDepth = 0;
bool m_insideUsingQTest = false; bool m_insideUsingQTest = false;