AutoTest: Use working copy of own parser

In TestCodeParser::syncTestFrameworks(), a parser is created for every
test framework. As a result, the last parser being created would "win"
the global s_parserInstance variable, which is not predictable and
probably not intended. So turn CppParser::getFileContent() into a non-
static method, avoiding the global variable altogether.

Change-Id: I9f7560f1185bc4a3bc7b2b36e89280351998465e
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
Bernhard Beschow
2021-01-01 19:19:10 +01:00
parent d8c1e51bfe
commit 5d7f2d7444
9 changed files with 71 additions and 103 deletions

View File

@@ -115,11 +115,13 @@ static BoostTestParseResult *createParseResult(const QString &name, const QStrin
} }
static bool handleBoostTest(QFutureInterface<TestParseResultPtr> futureInterface, bool BoostTestParser::processDocument(QFutureInterface<TestParseResultPtr> futureInterface,
const CPlusPlus::Document::Ptr &doc, const QString &fileName)
const CPlusPlus::Snapshot &snapshot,
ITestBase *base)
{ {
CPlusPlus::Document::Ptr doc = document(fileName);
if (doc.isNull() || !includesBoostTest(doc, m_cppSnapshot) || !hasBoostTestMacros(doc))
return false;
const CppTools::CppModelManager *modelManager = CppTools::CppModelManager::instance(); const CppTools::CppModelManager *modelManager = CppTools::CppModelManager::instance();
const QString &filePath = doc->fileName(); const QString &filePath = doc->fileName();
@@ -128,9 +130,9 @@ static bool handleBoostTest(QFutureInterface<TestParseResultPtr> futureInterface
return false; return false;
const CppTools::ProjectPart::Ptr projectPart = projectParts.first(); const CppTools::ProjectPart::Ptr projectPart = projectParts.first();
const auto projectFile = projectPart->projectFile; const auto projectFile = projectPart->projectFile;
const QByteArray &fileContent = CppParser::getFileContent(filePath); const QByteArray &fileContent = getFileContent(filePath);
BoostCodeParser codeParser(fileContent, projectPart->languageFeatures, doc, snapshot); BoostCodeParser codeParser(fileContent, projectPart->languageFeatures, doc, m_cppSnapshot);
const BoostTestCodeLocationList foundTests = codeParser.findTests(); const BoostTestCodeLocationList foundTests = codeParser.findTests();
if (foundTests.isEmpty()) if (foundTests.isEmpty())
return false; return false;
@@ -140,7 +142,7 @@ static bool handleBoostTest(QFutureInterface<TestParseResultPtr> futureInterface
BoostTestInfo firstSuite = suitesStates.first(); BoostTestInfo firstSuite = suitesStates.first();
QStringList suites = firstSuite.fullName.split('/'); QStringList suites = firstSuite.fullName.split('/');
BoostTestParseResult *topLevelSuite = createParseResult(suites.first(), filePath, BoostTestParseResult *topLevelSuite = createParseResult(suites.first(), filePath,
projectFile, base, projectFile, framework(),
TestTreeItem::TestSuite, TestTreeItem::TestSuite,
firstSuite); firstSuite);
BoostTestParseResult *currentSuite = topLevelSuite; BoostTestParseResult *currentSuite = topLevelSuite;
@@ -149,7 +151,7 @@ static bool handleBoostTest(QFutureInterface<TestParseResultPtr> futureInterface
firstSuite = suitesStates.first(); firstSuite = suitesStates.first();
suites = firstSuite.fullName.split('/'); suites = firstSuite.fullName.split('/');
BoostTestParseResult *suiteResult = createParseResult(suites.last(), filePath, BoostTestParseResult *suiteResult = createParseResult(suites.last(), filePath,
projectFile, base, projectFile, framework(),
TestTreeItem::TestSuite, TestTreeItem::TestSuite,
firstSuite); firstSuite);
currentSuite->children.append(suiteResult); currentSuite->children.append(suiteResult);
@@ -162,7 +164,7 @@ static bool handleBoostTest(QFutureInterface<TestParseResultPtr> futureInterface
locationAndType.m_suitesState.last().fullName + "::" + locationAndType.m_name, locationAndType.m_suitesState.last().fullName + "::" + locationAndType.m_name,
locationAndType.m_state, locationAndType.m_line}; locationAndType.m_state, locationAndType.m_line};
BoostTestParseResult *funcResult = createParseResult(locationAndType.m_name, filePath, BoostTestParseResult *funcResult = createParseResult(locationAndType.m_name, filePath,
projectFile, base, projectFile, framework(),
locationAndType.m_type, locationAndType.m_type,
tmpInfo); tmpInfo);
currentSuite->children.append(funcResult); currentSuite->children.append(funcResult);
@@ -172,14 +174,5 @@ static bool handleBoostTest(QFutureInterface<TestParseResultPtr> futureInterface
return true; return true;
} }
bool BoostTestParser::processDocument(QFutureInterface<TestParseResultPtr> futureInterface,
const QString &fileName)
{
CPlusPlus::Document::Ptr doc = document(fileName);
if (doc.isNull() || !includesBoostTest(doc, m_cppSnapshot) || !hasBoostTestMacros(doc))
return false;
return handleBoostTest(futureInterface, doc, m_cppSnapshot, framework());
}
} // namespace Internal } // namespace Internal
} // namespace Autotest } // namespace Autotest

View File

@@ -96,13 +96,15 @@ static bool hasCatchNames(const CPlusPlus::Document::Ptr &document)
return false; return false;
} }
static bool handleCatchDocument(QFutureInterface<TestParseResultPtr> futureInterface, bool CatchTestParser::processDocument(QFutureInterface<TestParseResultPtr> futureInterface, const QString &fileName)
const CPlusPlus::Document::Ptr &doc,
ITestBase *base)
{ {
CPlusPlus::Document::Ptr doc = document(fileName);
if (doc.isNull() || !includesCatchHeader(doc, m_cppSnapshot) || !hasCatchNames(doc))
return false;
const CppTools::CppModelManager *modelManager = CppTools::CppModelManager::instance(); const CppTools::CppModelManager *modelManager = CppTools::CppModelManager::instance();
const QString &filePath = doc->fileName(); const QString &filePath = doc->fileName();
const QByteArray &fileContent = CppParser::getFileContent(filePath); const QByteArray &fileContent = getFileContent(filePath);
const QList<CppTools::ProjectPart::Ptr> projectParts = modelManager->projectPart(filePath); const QList<CppTools::ProjectPart::Ptr> projectParts = modelManager->projectPart(filePath);
if (projectParts.isEmpty()) // happens if shutting down while parsing if (projectParts.isEmpty()) // happens if shutting down while parsing
@@ -114,7 +116,7 @@ static bool handleCatchDocument(QFutureInterface<TestParseResultPtr> futureInter
CatchCodeParser codeParser(fileContent, projectPart->languageFeatures); CatchCodeParser codeParser(fileContent, projectPart->languageFeatures);
const CatchTestCodeLocationList foundTests = codeParser.findTests(); const CatchTestCodeLocationList foundTests = codeParser.findTests();
CatchParseResult *parseResult = new CatchParseResult(base); CatchParseResult *parseResult = new CatchParseResult(framework());
parseResult->itemType = TestTreeItem::TestSuite; parseResult->itemType = TestTreeItem::TestSuite;
parseResult->fileName = filePath; parseResult->fileName = filePath;
parseResult->name = filePath; parseResult->name = filePath;
@@ -122,7 +124,7 @@ static bool handleCatchDocument(QFutureInterface<TestParseResultPtr> futureInter
parseResult->proFile = projectParts.first()->projectFile; parseResult->proFile = projectParts.first()->projectFile;
for (const CatchTestCodeLocationAndType & testLocation : foundTests) { for (const CatchTestCodeLocationAndType & testLocation : foundTests) {
CatchParseResult *testCase = new CatchParseResult(base); CatchParseResult *testCase = new CatchParseResult(framework());
testCase->fileName = filePath; testCase->fileName = filePath;
testCase->name = testLocation.m_name; testCase->name = testLocation.m_name;
testCase->proFile = proFile; testCase->proFile = proFile;
@@ -139,15 +141,6 @@ static bool handleCatchDocument(QFutureInterface<TestParseResultPtr> futureInter
return !foundTests.isEmpty(); return !foundTests.isEmpty();
} }
bool CatchTestParser::processDocument(QFutureInterface<TestParseResultPtr> futureInterface, const QString &fileName)
{
CPlusPlus::Document::Ptr doc = document(fileName);
if (doc.isNull() || !includesCatchHeader(doc, m_cppSnapshot) || !hasCatchNames(doc))
return false;
return handleCatchDocument(futureInterface, doc, framework());
}
TestTreeItem *CatchParseResult::createTestTreeItem() const TestTreeItem *CatchParseResult::createTestTreeItem() const
{ {
if (itemType == TestTreeItem::Root) if (itemType == TestTreeItem::Root)

View File

@@ -87,15 +87,17 @@ static bool hasGTestNames(const CPlusPlus::Document::Ptr &document)
return false; return false;
} }
static bool handleGTest(QFutureInterface<TestParseResultPtr> futureInterface, bool GTestParser::processDocument(QFutureInterface<TestParseResultPtr> futureInterface,
const CPlusPlus::Document::Ptr &doc, const QString &fileName)
const CPlusPlus::Snapshot &snapshot,
ITestBase *base)
{ {
CPlusPlus::Document::Ptr doc = document(fileName);
if (doc.isNull() || !includesGTest(doc, m_cppSnapshot) || !hasGTestNames(doc))
return false;
const CppTools::CppModelManager *modelManager = CppTools::CppModelManager::instance(); const CppTools::CppModelManager *modelManager = CppTools::CppModelManager::instance();
const QString &filePath = doc->fileName(); const QString &filePath = doc->fileName();
const QByteArray &fileContent = CppParser::getFileContent(filePath); const QByteArray &fileContent = getFileContent(filePath);
CPlusPlus::Document::Ptr document = snapshot.preprocessedDocument(fileContent, filePath); CPlusPlus::Document::Ptr document = m_cppSnapshot.preprocessedDocument(fileContent, filePath);
document->check(); document->check();
CPlusPlus::AST *ast = document->translationUnit()->ast(); CPlusPlus::AST *ast = document->translationUnit()->ast();
GTestVisitor visitor(document); GTestVisitor visitor(document);
@@ -111,7 +113,7 @@ static bool handleGTest(QFutureInterface<TestParseResultPtr> futureInterface,
for (auto it = result.cbegin(); it != result.cend(); ++it) { for (auto it = result.cbegin(); it != result.cend(); ++it) {
const GTestCaseSpec &testSpec = it.key(); const GTestCaseSpec &testSpec = it.key();
GTestParseResult *parseResult = new GTestParseResult(base); GTestParseResult *parseResult = new GTestParseResult(framework());
parseResult->itemType = TestTreeItem::TestSuite; parseResult->itemType = TestTreeItem::TestSuite;
parseResult->fileName = filePath; parseResult->fileName = filePath;
parseResult->name = testSpec.testCaseName; parseResult->name = testSpec.testCaseName;
@@ -121,7 +123,7 @@ static bool handleGTest(QFutureInterface<TestParseResultPtr> futureInterface,
parseResult->proFile = proFile; parseResult->proFile = proFile;
for (const GTestCodeLocationAndType &location : it.value()) { for (const GTestCodeLocationAndType &location : it.value()) {
GTestParseResult *testSet = new GTestParseResult(base); GTestParseResult *testSet = new GTestParseResult(framework());
testSet->name = location.m_name; testSet->name = location.m_name;
testSet->fileName = filePath; testSet->fileName = filePath;
testSet->line = location.m_line; testSet->line = location.m_line;
@@ -138,14 +140,5 @@ static bool handleGTest(QFutureInterface<TestParseResultPtr> futureInterface,
return !result.isEmpty(); return !result.isEmpty();
} }
bool GTestParser::processDocument(QFutureInterface<TestParseResultPtr> futureInterface,
const QString &fileName)
{
CPlusPlus::Document::Ptr doc = document(fileName);
if (doc.isNull() || !includesGTest(doc, m_cppSnapshot) || !hasGTestNames(doc))
return false;
return handleGTest(futureInterface, doc, m_cppSnapshot, framework());
}
} // namespace Internal } // namespace Internal
} // namespace Autotest } // namespace Autotest

View File

@@ -31,12 +31,9 @@
namespace Autotest { namespace Autotest {
static CppParser *s_parserInstance = nullptr;
CppParser::CppParser(ITestFramework *framework) CppParser::CppParser(ITestFramework *framework)
: ITestParser(framework) : ITestParser(framework)
{ {
s_parserInstance = this;
} }
void CppParser::init(const QStringList &filesToParse, bool fullParse) void CppParser::init(const QStringList &filesToParse, bool fullParse)
@@ -55,11 +52,11 @@ bool CppParser::selectedForBuilding(const QString &fileName)
return !projParts.isEmpty() && projParts.at(0)->selectedForBuilding; return !projParts.isEmpty() && projParts.at(0)->selectedForBuilding;
} }
QByteArray CppParser::getFileContent(const QString &filePath) QByteArray CppParser::getFileContent(const QString &filePath) const
{ {
QByteArray fileContent; QByteArray fileContent;
if (s_parserInstance->m_workingCopy.contains(filePath)) { if (m_workingCopy.contains(filePath)) {
fileContent = s_parserInstance->m_workingCopy.source(filePath); fileContent = m_workingCopy.source(filePath);
} else { } else {
QString error; QString error;
const QTextCodec *codec = Core::EditorManager::defaultTextCodec(); const QTextCodec *codec = Core::EditorManager::defaultTextCodec();

View File

@@ -80,7 +80,7 @@ public:
explicit CppParser(ITestFramework *framework); explicit CppParser(ITestFramework *framework);
void init(const QStringList &filesToParse, bool fullParse) override; void init(const QStringList &filesToParse, bool fullParse) override;
static bool selectedForBuilding(const QString &fileName); static bool selectedForBuilding(const QString &fileName);
static QByteArray getFileContent(const QString &filePath); QByteArray getFileContent(const QString &filePath) const;
void release() override; void release() override;
CPlusPlus::Document::Ptr document(const QString &fileName); CPlusPlus::Document::Ptr document(const QString &fileName);

View File

@@ -25,7 +25,6 @@
#include "qttestparser.h" #include "qttestparser.h"
#include "qttestframework.h" #include "qttestframework.h"
#include "qttesttreeitem.h"
#include "qttestvisitors.h" #include "qttestvisitors.h"
#include "qttest_utils.h" #include "qttest_utils.h"
@@ -94,10 +93,9 @@ static bool qtTestLibDefined(const QString &fileName)
return false; return false;
} }
static QString testClass(const CppTools::CppModelManager *modelManager, QString QtTestParser::testClass(const CppTools::CppModelManager *modelManager, const QString &fileName) const
const CPlusPlus::Snapshot &snapshot, const QString &fileName)
{ {
const QByteArray &fileContent = CppParser::getFileContent(fileName); const QByteArray &fileContent = getFileContent(fileName);
CPlusPlus::Document::Ptr document = modelManager->document(fileName); CPlusPlus::Document::Ptr document = modelManager->document(fileName);
if (document.isNull()) if (document.isNull())
return QString(); return QString();
@@ -115,10 +113,10 @@ static QString testClass(const CppTools::CppModelManager *modelManager,
} }
} }
// check if one has used a self-defined macro or QTest::qExec() directly // check if one has used a self-defined macro or QTest::qExec() directly
document = snapshot.preprocessedDocument(fileContent, fileName); document = m_cppSnapshot.preprocessedDocument(fileContent, fileName);
document->check(); document->check();
CPlusPlus::AST *ast = document->translationUnit()->ast(); CPlusPlus::AST *ast = document->translationUnit()->ast();
TestAstVisitor astVisitor(document, snapshot); TestAstVisitor astVisitor(document, m_cppSnapshot);
astVisitor.accept(ast); astVisitor.accept(ast);
return astVisitor.className(); return astVisitor.className();
} }
@@ -181,11 +179,10 @@ static QSet<QString> filesWithDataFunctionDefinitions(
return result; return result;
} }
static QHash<QString, QtTestCodeLocationList> checkForDataTags(const QString &fileName, QHash<QString, QtTestCodeLocationList> QtTestParser::checkForDataTags(const QString &fileName) const
const CPlusPlus::Snapshot &snapshot)
{ {
const QByteArray fileContent = CppParser::getFileContent(fileName); const QByteArray fileContent = getFileContent(fileName);
CPlusPlus::Document::Ptr document = snapshot.preprocessedDocument(fileContent, fileName); CPlusPlus::Document::Ptr document = m_cppSnapshot.preprocessedDocument(fileContent, fileName);
document->check(); document->check();
CPlusPlus::AST *ast = document->translationUnit()->ast(); CPlusPlus::AST *ast = document->translationUnit()->ast();
TestDataFunctionVisitor visitor(document); TestDataFunctionVisitor visitor(document);
@@ -280,28 +277,31 @@ static bool isQObject(const CPlusPlus::Document::Ptr &declaringDoc)
|| file.endsWith("QtCore/qobject.h") || file.endsWith("kernel/qobject.h"); || file.endsWith("QtCore/qobject.h") || file.endsWith("kernel/qobject.h");
} }
static bool handleQtTest(QFutureInterface<TestParseResultPtr> futureInterface, bool QtTestParser::processDocument(QFutureInterface<TestParseResultPtr> futureInterface,
CPlusPlus::Document::Ptr document, const QString &fileName)
const CPlusPlus::Snapshot &snapshot,
const QString &oldTestCaseName,
const QStringList &alternativeFiles,
ITestBase *base)
{ {
CPlusPlus::Document::Ptr doc = document(fileName);
if (doc.isNull())
return false;
const QString &oldTestCaseName = m_testCaseNames.value(fileName);
if ((!includesQtTest(doc, m_cppSnapshot) || !qtTestLibDefined(fileName)) && oldTestCaseName.isEmpty())
return false;
const CppTools::CppModelManager *modelManager = CppTools::CppModelManager::instance(); const CppTools::CppModelManager *modelManager = CppTools::CppModelManager::instance();
const QString &fileName = document->fileName(); QString testCaseName(testClass(modelManager, fileName));
QString testCaseName(testClass(modelManager, snapshot, fileName));
// we might be in a reparse without the original entry point with the QTest::qExec() // we might be in a reparse without the original entry point with the QTest::qExec()
if (testCaseName.isEmpty()) if (testCaseName.isEmpty())
testCaseName = oldTestCaseName; testCaseName = oldTestCaseName;
if (!testCaseName.isEmpty()) { if (!testCaseName.isEmpty()) {
int line = 0; int line = 0;
int column = 0; int column = 0;
CPlusPlus::Document::Ptr declaringDoc = declaringDocument(document, snapshot, testCaseName, const QStringList &alternativeFiles = m_alternativeFiles.values(fileName);
CPlusPlus::Document::Ptr declaringDoc = declaringDocument(doc, m_cppSnapshot, testCaseName,
alternativeFiles, &line, &column); alternativeFiles, &line, &column);
if (declaringDoc.isNull()) if (declaringDoc.isNull())
return false; return false;
TestVisitor visitor(testCaseName, snapshot); TestVisitor visitor(testCaseName, m_cppSnapshot);
visitor.accept(declaringDoc->globalNamespace()); visitor.accept(declaringDoc->globalNamespace());
if (!visitor.resultValid()) if (!visitor.resultValid())
return false; return false;
@@ -310,7 +310,7 @@ static bool handleQtTest(QFutureInterface<TestParseResultPtr> futureInterface,
// gather appropriate information of base classes as well and merge into already found // gather appropriate information of base classes as well and merge into already found
// functions - but only as far as QtTest can handle this appropriate // functions - but only as far as QtTest can handle this appropriate
fetchAndMergeBaseTestFunctions( fetchAndMergeBaseTestFunctions(
visitor.baseClasses(), testFunctions, declaringDoc, snapshot); visitor.baseClasses(), testFunctions, declaringDoc, m_cppSnapshot);
// handle tests that are not runnable without more information (plugin unit test of QC) // handle tests that are not runnable without more information (plugin unit test of QC)
if (testFunctions.isEmpty() && testCaseName == "QObject" && isQObject(declaringDoc)) if (testFunctions.isEmpty() && testCaseName == "QObject" && isQObject(declaringDoc))
@@ -320,9 +320,9 @@ static bool handleQtTest(QFutureInterface<TestParseResultPtr> futureInterface,
QHash<QString, QtTestCodeLocationList> dataTags; QHash<QString, QtTestCodeLocationList> dataTags;
for (const QString &file : files) for (const QString &file : files)
Utils::addToHash(&dataTags, checkForDataTags(file, snapshot)); Utils::addToHash(&dataTags, checkForDataTags(file));
QtTestParseResult *parseResult = new QtTestParseResult(base); QtTestParseResult *parseResult = new QtTestParseResult(framework());
parseResult->itemType = TestTreeItem::TestCase; parseResult->itemType = TestTreeItem::TestCase;
parseResult->fileName = declaringDoc->fileName(); parseResult->fileName = declaringDoc->fileName();
parseResult->name = testCaseName; parseResult->name = testCaseName;
@@ -339,7 +339,7 @@ static bool handleQtTest(QFutureInterface<TestParseResultPtr> futureInterface,
const QtTestCodeLocationAndType &location = it.value(); const QtTestCodeLocationAndType &location = it.value();
QString functionName = it.key(); QString functionName = it.key();
functionName = functionName.mid(functionName.lastIndexOf(':') + 1); functionName = functionName.mid(functionName.lastIndexOf(':') + 1);
QtTestParseResult *func = new QtTestParseResult(base); QtTestParseResult *func = new QtTestParseResult(framework());
func->itemType = location.m_type; func->itemType = location.m_type;
func->name = testCaseName + "::" + functionName; func->name = testCaseName + "::" + functionName;
func->displayName = functionName; func->displayName = functionName;
@@ -350,7 +350,7 @@ static bool handleQtTest(QFutureInterface<TestParseResultPtr> futureInterface,
const QtTestCodeLocationList &tagLocations = tagLocationsFor(func, dataTags); const QtTestCodeLocationList &tagLocations = tagLocationsFor(func, dataTags);
for (const QtTestCodeLocationAndType &tag : tagLocations) { for (const QtTestCodeLocationAndType &tag : tagLocations) {
QtTestParseResult *dataTag = new QtTestParseResult(base); QtTestParseResult *dataTag = new QtTestParseResult(framework());
dataTag->itemType = tag.m_type; dataTag->itemType = tag.m_type;
dataTag->name = tag.m_name; dataTag->name = tag.m_name;
dataTag->displayName = tag.m_name; dataTag->displayName = tag.m_name;
@@ -386,19 +386,5 @@ void QtTestParser::release()
CppParser::release(); CppParser::release();
} }
bool QtTestParser::processDocument(QFutureInterface<TestParseResultPtr> futureInterface,
const QString &fileName)
{
CPlusPlus::Document::Ptr doc = document(fileName);
if (doc.isNull())
return false;
const QString &oldName = m_testCaseNames.value(fileName);
const QStringList &alternativeFiles = m_alternativeFiles.values(fileName);
if ((!includesQtTest(doc, m_cppSnapshot) || !qtTestLibDefined(fileName)) && oldName.isEmpty())
return false;
return handleQtTest(futureInterface, doc, m_cppSnapshot, oldName, alternativeFiles, framework());
}
} // namespace Internal } // namespace Internal
} // namespace Autotest } // namespace Autotest

View File

@@ -27,6 +27,10 @@
#include "../itestparser.h" #include "../itestparser.h"
#include "qttesttreeitem.h"
namespace CppTools { class CppModelManager; }
namespace Autotest { namespace Autotest {
namespace Internal { namespace Internal {
@@ -52,6 +56,8 @@ public:
const QString &fileName) override; const QString &fileName) override;
private: private:
QString testClass(const CppTools::CppModelManager *modelManager, const QString &fileName) const;
QHash<QString, QtTestCodeLocationList> checkForDataTags(const QString &fileName) const;
QHash<QString, QString> m_testCaseNames; QHash<QString, QString> m_testCaseNames;
QMultiHash<QString, QString> m_alternativeFiles; QMultiHash<QString, QString> m_alternativeFiles;
}; };

View File

@@ -112,8 +112,7 @@ static QString quickTestSrcDir(const CppTools::CppModelManager *cppMM,
return QString(); return QString();
} }
static QString quickTestName(const CPlusPlus::Document::Ptr &doc, QString QuickTestParser::quickTestName(const CPlusPlus::Document::Ptr &doc) const
const CPlusPlus::Snapshot &snapshot)
{ {
const QList<CPlusPlus::Document::MacroUse> macros = doc->macroUses(); const QList<CPlusPlus::Document::MacroUse> macros = doc->macroUses();
@@ -123,20 +122,20 @@ static QString quickTestName(const CPlusPlus::Document::Ptr &doc,
const QByteArray name = macro.macro().name(); const QByteArray name = macro.macro().name();
if (QuickTestUtils::isQuickTestMacro(name)) { if (QuickTestUtils::isQuickTestMacro(name)) {
CPlusPlus::Document::Block arg = macro.arguments().at(0); CPlusPlus::Document::Block arg = macro.arguments().at(0);
return QLatin1String(CppParser::getFileContent(doc->fileName()) return QLatin1String(getFileContent(doc->fileName())
.mid(int(arg.bytesBegin()), int(arg.bytesEnd() - arg.bytesBegin()))); .mid(int(arg.bytesBegin()), int(arg.bytesEnd() - arg.bytesBegin())));
} }
} }
// check for using quick_test_main() directly // check for using quick_test_main() directly
const QString fileName = doc->fileName(); const QString fileName = doc->fileName();
const QByteArray &fileContent = CppParser::getFileContent(fileName); const QByteArray &fileContent = getFileContent(fileName);
CPlusPlus::Document::Ptr document = snapshot.preprocessedDocument(fileContent, fileName); CPlusPlus::Document::Ptr document = m_cppSnapshot.preprocessedDocument(fileContent, fileName);
if (document.isNull()) if (document.isNull())
return QString(); return QString();
document->check(); document->check();
CPlusPlus::AST *ast = document->translationUnit()->ast(); CPlusPlus::AST *ast = document->translationUnit()->ast();
QuickTestAstVisitor astVisitor(document, snapshot); QuickTestAstVisitor astVisitor(document, m_cppSnapshot);
astVisitor.accept(ast); astVisitor.accept(ast);
return astVisitor.testBaseName(); return astVisitor.testBaseName();
} }
@@ -233,7 +232,7 @@ bool QuickTestParser::handleQtQuickTest(QFutureInterface<TestParseResultPtr> fut
ITestFramework *framework) ITestFramework *framework)
{ {
const CppTools::CppModelManager *modelManager = CppTools::CppModelManager::instance(); const CppTools::CppModelManager *modelManager = CppTools::CppModelManager::instance();
if (quickTestName(document, m_cppSnapshot).isEmpty()) if (quickTestName(document).isEmpty())
return false; return false;
const QString cppFileName = document->fileName(); const QString cppFileName = document->fileName();

View File

@@ -56,6 +56,7 @@ private:
CPlusPlus::Document::Ptr document, ITestFramework *framework); CPlusPlus::Document::Ptr document, ITestFramework *framework);
void handleDirectoryChanged(const QString &directory); void handleDirectoryChanged(const QString &directory);
void doUpdateWatchPaths(const QStringList &directories); void doUpdateWatchPaths(const QStringList &directories);
QString quickTestName(const CPlusPlus::Document::Ptr &doc) const;
QList<QmlJS::Document::Ptr> scanDirectoryForQuickTestQmlFiles(const QString &srcDir); QList<QmlJS::Document::Ptr> scanDirectoryForQuickTestQmlFiles(const QString &srcDir);
QmlJS::Snapshot m_qmlSnapshot; QmlJS::Snapshot m_qmlSnapshot;
QHash<QString, QString> m_proFilesForQmlFiles; QHash<QString, QString> m_proFilesForQmlFiles;