forked from qt-creator/qt-creator
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:
@@ -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);
|
||||||
}
|
}
|
||||||
|
@@ -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
|
||||||
|
@@ -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
|
||||||
|
@@ -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
|
||||||
|
@@ -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;
|
||||||
|
@@ -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;
|
||||||
|
Reference in New Issue
Block a user