summaryrefslogtreecommitdiff
path: root/src/plugins/autotest/qtest/qttestparser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/autotest/qtest/qttestparser.cpp')
-rw-r--r--src/plugins/autotest/qtest/qttestparser.cpp171
1 files changed, 97 insertions, 74 deletions
diff --git a/src/plugins/autotest/qtest/qttestparser.cpp b/src/plugins/autotest/qtest/qttestparser.cpp
index 29e861a927..d1c27723fc 100644
--- a/src/plugins/autotest/qtest/qttestparser.cpp
+++ b/src/plugins/autotest/qtest/qttestparser.cpp
@@ -81,7 +81,7 @@ static bool includesQtTest(const CPlusPlus::Document::Ptr &doc, const CPlusPlus:
return false;
}
-static bool qtTestLibDefined(const QString &fileName)
+static bool qtTestLibDefined(const Utils::FilePath &fileName)
{
const QList<CppTools::ProjectPart::Ptr> parts =
CppTools::CppModelManager::instance()->projectPart(fileName);
@@ -93,10 +93,11 @@ static bool qtTestLibDefined(const QString &fileName)
return false;
}
-QString QtTestParser::testClass(const CppTools::CppModelManager *modelManager, const QString &fileName) const
+QString QtTestParser::testClass(const CppTools::CppModelManager *modelManager,
+ const Utils::FilePath &fileName) const
{
const QByteArray &fileContent = getFileContent(fileName);
- CPlusPlus::Document::Ptr document = modelManager->document(fileName);
+ CPlusPlus::Document::Ptr document = modelManager->document(fileName.toString());
if (document.isNull())
return QString();
@@ -124,7 +125,7 @@ QString QtTestParser::testClass(const CppTools::CppModelManager *modelManager, c
static CPlusPlus::Document::Ptr declaringDocument(CPlusPlus::Document::Ptr doc,
const CPlusPlus::Snapshot &snapshot,
const QString &testCaseName,
- const QStringList &alternativeFiles = {},
+ const Utils::FilePaths &alternativeFiles = {},
int *line = nullptr,
int *column = nullptr)
{
@@ -136,7 +137,7 @@ static CPlusPlus::Document::Ptr declaringDocument(CPlusPlus::Document::Ptr doc,
doc->globalNamespace());
// fallback for inherited functions
if (lookupItems.size() == 0 && !alternativeFiles.isEmpty()) {
- for (const QString &alternativeFile : alternativeFiles) {
+ for (const Utils::FilePath &alternativeFile : alternativeFiles) {
if (snapshot.contains(alternativeFile)) {
CPlusPlus::Document::Ptr document = snapshot.document(alternativeFile);
CPlusPlus::TypeOfExpression typeOfExpr; // we need a new one with no bindings
@@ -181,7 +182,7 @@ static QSet<QString> filesWithDataFunctionDefinitions(
QHash<QString, QtTestCodeLocationList> QtTestParser::checkForDataTags(const QString &fileName) const
{
- const QByteArray fileContent = getFileContent(fileName);
+ const QByteArray fileContent = getFileContent(Utils::FilePath::fromString(fileName));
CPlusPlus::Document::Ptr document = m_cppSnapshot.preprocessedDocument(fileContent, fileName);
document->check();
CPlusPlus::AST *ast = document->translationUnit()->ast();
@@ -278,7 +279,7 @@ static bool isQObject(const CPlusPlus::Document::Ptr &declaringDoc)
}
bool QtTestParser::processDocument(QFutureInterface<TestParseResultPtr> futureInterface,
- const QString &fileName)
+ const Utils::FilePath &fileName)
{
CPlusPlus::Document::Ptr doc = document(fileName);
if (doc.isNull())
@@ -293,84 +294,106 @@ bool QtTestParser::processDocument(QFutureInterface<TestParseResultPtr> futureIn
if (testCaseName.isEmpty())
testCaseName = oldTestCaseName;
if (!testCaseName.isEmpty()) {
- int line = 0;
- int column = 0;
- const QStringList &alternativeFiles = m_alternativeFiles.values(fileName);
- CPlusPlus::Document::Ptr declaringDoc = declaringDocument(doc, m_cppSnapshot, testCaseName,
- alternativeFiles, &line, &column);
- if (declaringDoc.isNull())
- return false;
-
- TestVisitor visitor(testCaseName, m_cppSnapshot);
- visitor.accept(declaringDoc->globalNamespace());
- if (!visitor.resultValid())
- return false;
+ TestCaseData data;
+ Utils::optional<bool> earlyReturn = fillTestCaseData(testCaseName, doc, data);
+ if (earlyReturn.has_value())
+ return earlyReturn.value();
- QMap<QString, QtTestCodeLocationAndType> testFunctions = visitor.privateSlots();
- // gather appropriate information of base classes as well and merge into already found
- // functions - but only as far as QtTest can handle this appropriate
- fetchAndMergeBaseTestFunctions(
- visitor.baseClasses(), testFunctions, declaringDoc, m_cppSnapshot);
-
- // handle tests that are not runnable without more information (plugin unit test of QC)
- if (testFunctions.isEmpty() && testCaseName == "QObject" && isQObject(declaringDoc))
- return true; // we did not handle it, but we do not expect any test defined there either
-
- const QSet<QString> &files = filesWithDataFunctionDefinitions(testFunctions);
-
- QHash<QString, QtTestCodeLocationList> dataTags;
- for (const QString &file : files)
- Utils::addToHash(&dataTags, checkForDataTags(file));
-
- QtTestParseResult *parseResult = new QtTestParseResult(framework());
- parseResult->itemType = TestTreeItem::TestCase;
- parseResult->fileName = declaringDoc->fileName();
- parseResult->name = testCaseName;
- parseResult->displayName = testCaseName;
- parseResult->line = line;
- parseResult->column = column;
QList<CppTools::ProjectPart::Ptr> projectParts = modelManager->projectPart(fileName);
if (projectParts.isEmpty()) // happens if shutting down while parsing
return false;
- parseResult->proFile = projectParts.first()->projectFile;
- QMap<QString, QtTestCodeLocationAndType>::ConstIterator it = testFunctions.begin();
- const QMap<QString, QtTestCodeLocationAndType>::ConstIterator end = testFunctions.end();
- for ( ; it != end; ++it) {
- const QtTestCodeLocationAndType &location = it.value();
- QString functionName = it.key();
- functionName = functionName.mid(functionName.lastIndexOf(':') + 1);
- QtTestParseResult *func = new QtTestParseResult(framework());
- func->itemType = location.m_type;
- func->name = testCaseName + "::" + functionName;
- func->displayName = functionName;
- func->fileName = location.m_name;
- func->line = location.m_line;
- func->column = location.m_column;
- func->setInherited(location.m_inherited);
-
- const QtTestCodeLocationList &tagLocations = tagLocationsFor(func, dataTags);
- for (const QtTestCodeLocationAndType &tag : tagLocations) {
- QtTestParseResult *dataTag = new QtTestParseResult(framework());
- dataTag->itemType = tag.m_type;
- dataTag->name = tag.m_name;
- dataTag->displayName = tag.m_name;
- dataTag->fileName = testFunctions.value(it.key() + "_data").m_name;
- dataTag->line = tag.m_line;
- dataTag->column = tag.m_column;
- dataTag->setInherited(tag.m_inherited);
-
- func->children.append(dataTag);
- }
- parseResult->children.append(func);
- }
+ QtTestParseResult *parseResult
+ = createParseResult(testCaseName, data, projectParts.first()->projectFile);
futureInterface.reportResult(TestParseResultPtr(parseResult));
return true;
}
return false;
}
-void QtTestParser::init(const QStringList &filesToParse, bool fullParse)
+Utils::optional<bool> QtTestParser::fillTestCaseData(
+ const QString &testCaseName, const CPlusPlus::Document::Ptr &doc,
+ TestCaseData &data) const
+{
+ const Utils::FilePath filePath = Utils::FilePath::fromString(doc->fileName());
+ const Utils::FilePaths &alternativeFiles = m_alternativeFiles.values(filePath);
+ CPlusPlus::Document::Ptr declaringDoc = declaringDocument(doc, m_cppSnapshot, testCaseName,
+ alternativeFiles,
+ &(data.line), &(data.column));
+ if (declaringDoc.isNull())
+ return false;
+
+ TestVisitor visitor(testCaseName, m_cppSnapshot);
+ visitor.accept(declaringDoc->globalNamespace());
+ if (!visitor.resultValid())
+ return false;
+
+ data.testFunctions = visitor.privateSlots();
+ // gather appropriate information of base classes as well and merge into already found
+ // functions - but only as far as QtTest can handle this appropriate
+ fetchAndMergeBaseTestFunctions(
+ visitor.baseClasses(), data.testFunctions, declaringDoc, m_cppSnapshot);
+
+ // handle tests that are not runnable without more information (plugin unit test of QC)
+ if (data.testFunctions.isEmpty() && testCaseName == "QObject" && isQObject(declaringDoc))
+ return true; // we did not handle it, but we do not expect any test defined there either
+
+ const QSet<QString> &files = filesWithDataFunctionDefinitions(data.testFunctions);
+
+ for (const QString &file : files)
+ Utils::addToHash(&(data.dataTags), checkForDataTags(file));
+
+ data.fileName = Utils::FilePath::fromString(declaringDoc->fileName());
+ data.valid = true;
+ return Utils::optional<bool>();
+}
+
+QtTestParseResult *QtTestParser::createParseResult(
+ const QString &testCaseName, const TestCaseData &data, const QString &projectFile) const
+{
+ QtTestParseResult *parseResult = new QtTestParseResult(framework());
+ parseResult->itemType = TestTreeItem::TestCase;
+ parseResult->fileName = data.fileName;
+ parseResult->name = testCaseName;
+ parseResult->displayName = testCaseName;
+ parseResult->line = data.line;
+ parseResult->column = data.column;
+ parseResult->proFile = Utils::FilePath::fromString(projectFile);
+ QMap<QString, QtTestCodeLocationAndType>::ConstIterator it = data.testFunctions.begin();
+ const QMap<QString, QtTestCodeLocationAndType>::ConstIterator end = data.testFunctions.end();
+ for ( ; it != end; ++it) {
+ const QtTestCodeLocationAndType &location = it.value();
+ QString functionName = it.key();
+ functionName = functionName.mid(functionName.lastIndexOf(':') + 1);
+ QtTestParseResult *func = new QtTestParseResult(framework());
+ func->itemType = location.m_type;
+ func->name = testCaseName + "::" + functionName;
+ func->displayName = functionName;
+ func->fileName = Utils::FilePath::fromString(location.m_name);
+ func->line = location.m_line;
+ func->column = location.m_column;
+ func->setInherited(location.m_inherited);
+
+ const QtTestCodeLocationList &tagLocations = tagLocationsFor(func, data.dataTags);
+ for (const QtTestCodeLocationAndType &tag : tagLocations) {
+ QtTestParseResult *dataTag = new QtTestParseResult(framework());
+ dataTag->itemType = tag.m_type;
+ dataTag->name = tag.m_name;
+ dataTag->displayName = tag.m_name;
+ dataTag->fileName = Utils::FilePath::fromString(
+ data.testFunctions.value(it.key() + "_data").m_name);
+ dataTag->line = tag.m_line;
+ dataTag->column = tag.m_column;
+ dataTag->setInherited(tag.m_inherited);
+
+ func->children.append(dataTag);
+ }
+ parseResult->children.append(func);
+ }
+ return parseResult;
+}
+
+void QtTestParser::init(const Utils::FilePaths &filesToParse, bool fullParse)
{
if (!fullParse) { // in a full parse cached information might lead to wrong results
m_testCaseNames = QTestUtils::testCaseNamesForFiles(framework(), filesToParse);