forked from qt-creator/qt-creator
AutoTest: Use mark and sweep for parsing
This also removes caching from parser and the respective test info files are gone now as well. Change-Id: Ibcea68e446dea532d6addd2f16863738e497bca4 Reviewed-by: David Schulz <david.schulz@theqtcompany.com>
This commit is contained in:
@@ -11,7 +11,6 @@ SOURCES += \
|
||||
testtreemodel.cpp \
|
||||
testtreeitem.cpp \
|
||||
testvisitor.cpp \
|
||||
testinfo.cpp \
|
||||
testcodeparser.cpp \
|
||||
autotestplugin.cpp \
|
||||
testrunner.cpp \
|
||||
@@ -31,7 +30,6 @@ HEADERS += \
|
||||
testtreemodel.h \
|
||||
testtreeitem.h \
|
||||
testvisitor.h \
|
||||
testinfo.h \
|
||||
testcodeparser.h \
|
||||
autotestplugin.h \
|
||||
autotest_global.h \
|
||||
|
||||
@@ -40,8 +40,6 @@ QtcPlugin {
|
||||
"testcodeparser.h",
|
||||
"testconfiguration.cpp",
|
||||
"testconfiguration.h",
|
||||
"testinfo.cpp",
|
||||
"testinfo.h",
|
||||
"testnavigationwidget.cpp",
|
||||
"testnavigationwidget.h",
|
||||
"testresult.cpp",
|
||||
|
||||
@@ -105,11 +105,6 @@ void AutoTestUnitTests::testCodeParser()
|
||||
QCOMPARE(m_model->namedQuickTestsCount(), expectedNamedQuickTestsCount);
|
||||
QCOMPARE(m_model->unnamedQuickTestsCount(), expectedUnnamedQuickTestsCount);
|
||||
QCOMPARE(m_model->dataTagsCount(), expectedDataTagsCount);
|
||||
|
||||
QCOMPARE(m_model->parser()->autoTestsCount(), expectedAutoTestsCount);
|
||||
QCOMPARE(m_model->parser()->namedQuickTestsCount(), expectedNamedQuickTestsCount);
|
||||
QCOMPARE(m_model->parser()->unnamedQuickTestsCount(), expectedUnnamedQuickTestsCount);
|
||||
|
||||
}
|
||||
|
||||
void AutoTestUnitTests::testCodeParser_data()
|
||||
@@ -162,12 +157,6 @@ void AutoTestUnitTests::testCodeParserSwitchStartup()
|
||||
m_isQt4 ? 0 : expectedUnnamedQuickTestsCount.at(i));
|
||||
QCOMPARE(m_model->dataTagsCount(),
|
||||
expectedDataTagsCount.at(i));
|
||||
|
||||
QCOMPARE(m_model->parser()->autoTestsCount(), expectedAutoTestsCount.at(i));
|
||||
QCOMPARE(m_model->parser()->namedQuickTestsCount(),
|
||||
m_isQt4 ? 0 : expectedNamedQuickTestsCount.at(i));
|
||||
QCOMPARE(m_model->parser()->unnamedQuickTestsCount(),
|
||||
m_isQt4 ? 0 : expectedUnnamedQuickTestsCount.at(i));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -212,8 +201,6 @@ void AutoTestUnitTests::testCodeParserGTest()
|
||||
QVERIFY(parserSpy.wait(20000));
|
||||
|
||||
QCOMPARE(m_model->gtestNamesCount(), 6);
|
||||
// 11 == 3 + 2 + 2 + 2 + 1 + 1, see below
|
||||
QCOMPARE(m_model->parser()->gtestNamesAndSetsCount(), 11);
|
||||
|
||||
QMultiMap<QString, int> expectedNamesAndSets;
|
||||
expectedNamesAndSets.insert(QStringLiteral("FactorialTest"), 3);
|
||||
@@ -233,10 +220,6 @@ void AutoTestUnitTests::testCodeParserGTest()
|
||||
QCOMPARE(m_model->namedQuickTestsCount(), 0);
|
||||
QCOMPARE(m_model->unnamedQuickTestsCount(), 0);
|
||||
QCOMPARE(m_model->dataTagsCount(), 0);
|
||||
|
||||
QCOMPARE(m_model->parser()->autoTestsCount(), 0);
|
||||
QCOMPARE(m_model->parser()->namedQuickTestsCount(), 0);
|
||||
QCOMPARE(m_model->parser()->unnamedQuickTestsCount(), 0);
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
#include "autotestconstants.h"
|
||||
#include "autotest_utils.h"
|
||||
#include "testcodeparser.h"
|
||||
#include "testinfo.h"
|
||||
#include "testvisitor.h"
|
||||
|
||||
#include <coreplugin/editormanager/editormanager.h>
|
||||
@@ -84,7 +83,6 @@ TestCodeParser::TestCodeParser(TestTreeModel *parent)
|
||||
|
||||
TestCodeParser::~TestCodeParser()
|
||||
{
|
||||
clearCache();
|
||||
}
|
||||
|
||||
void TestCodeParser::setState(State state)
|
||||
@@ -145,7 +143,7 @@ void TestCodeParser::updateTestTree()
|
||||
|
||||
m_fullUpdatePostponed = false;
|
||||
|
||||
clearCache();
|
||||
emit aboutToPerformFullParse();
|
||||
qCDebug(LOG) << "calling scanForTests (updateTestTree)";
|
||||
scanForTests();
|
||||
}
|
||||
@@ -488,7 +486,7 @@ static TestTreeItem *constructGTestTreeItem(const QString &filePath, const GTest
|
||||
static bool parsingHasFailed;
|
||||
|
||||
void performParse(QFutureInterface<void> &futureInterface, const QStringList &list,
|
||||
const QMap<QString, TestCodeParser::ReferencingInfo> &referencingFiles,
|
||||
const QMap<QString, QString> &referencingFiles,
|
||||
TestCodeParser *testCodeParser)
|
||||
{
|
||||
int progressValue = 0;
|
||||
@@ -501,8 +499,9 @@ void performParse(QFutureInterface<void> &futureInterface, const QStringList &li
|
||||
if (snapshot.contains(file)) {
|
||||
CPlusPlus::Document::Ptr doc = snapshot.find(file).value();
|
||||
futureInterface.setProgressValue(++progressValue);
|
||||
const QString &referencingFile = referencingFiles.value(file);
|
||||
testCodeParser->checkDocumentForTestCode(doc,
|
||||
referencingFiles.value(file).referencingFile);
|
||||
list.contains(referencingFile) ? QString() : referencingFile);
|
||||
} else {
|
||||
parsingHasFailed |= (CppTools::ProjectFile::classify(file)
|
||||
!= CppTools::ProjectFile::Unclassified);
|
||||
@@ -520,10 +519,8 @@ void TestCodeParser::checkDocumentForTestCode(CPlusPlus::Document::Ptr document,
|
||||
|
||||
QList<CppTools::ProjectPart::Ptr> projParts = modelManager->projectPart(fileName);
|
||||
if (projParts.size())
|
||||
if (!projParts.at(0)->selectedForBuilding) {
|
||||
removeTestsIfNecessary(fileName);
|
||||
if (!projParts.at(0)->selectedForBuilding)
|
||||
return;
|
||||
}
|
||||
|
||||
if (includesQtQuickTest(document, modelManager)) {
|
||||
handleQtQuickTest(document);
|
||||
@@ -540,6 +537,8 @@ void TestCodeParser::checkDocumentForTestCode(CPlusPlus::Document::Ptr document,
|
||||
if (declaringDoc.isNull())
|
||||
return;
|
||||
|
||||
const bool hasReferencingFile = declaringDoc->fileName() != document->fileName();
|
||||
|
||||
TestVisitor visitor(testCaseName);
|
||||
visitor.accept(declaringDoc->globalNamespace());
|
||||
const QMap<QString, TestCodeLocationAndType> testFunctions = visitor.privateSlots();
|
||||
@@ -547,14 +546,16 @@ void TestCodeParser::checkDocumentForTestCode(CPlusPlus::Document::Ptr document,
|
||||
QMap<QString, TestCodeLocationList> dataTags =
|
||||
checkForDataTags(declaringDoc->fileName(), testFunctions);
|
||||
|
||||
if (declaringDoc->fileName() != document->fileName())
|
||||
if (hasReferencingFile)
|
||||
dataTags.unite(checkForDataTags(document->fileName(), testFunctions));
|
||||
|
||||
TestTreeItem *item = constructTestTreeItem(declaringDoc->fileName(), QString(),
|
||||
testCaseName, line, column, testFunctions,
|
||||
dataTags);
|
||||
if (hasReferencingFile)
|
||||
item->setReferencingFile(fileName);
|
||||
|
||||
updateModelAndCppDocMap(document, declaringDoc->fileName(), item);
|
||||
emit testItemCreated(item, TestTreeModel::AutoTest);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -570,12 +571,8 @@ void TestCodeParser::checkDocumentForTestCode(CPlusPlus::Document::Ptr document,
|
||||
// maybe file is only a referenced file
|
||||
if (!referencingFile.isEmpty()) {
|
||||
CPlusPlus::Snapshot snapshot = modelManager->snapshot();
|
||||
if (snapshot.contains(referencingFile)) {
|
||||
if (snapshot.contains(referencingFile))
|
||||
checkDocumentForTestCode(snapshot.find(referencingFile).value());
|
||||
} else { // no referencing file too, so this test case is no more a test case
|
||||
m_referencingFiles.remove(fileName);
|
||||
emit testItemsRemoved(fileName, TestTreeModel::AutoTest);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -602,19 +599,28 @@ void TestCodeParser::handleQtQuickTest(CPlusPlus::Document::Ptr document)
|
||||
const TestCodeLocationAndType tcLocationAndType = qmlVisitor.testCaseLocation();
|
||||
const QMap<QString, TestCodeLocationAndType> testFunctions = qmlVisitor.testFunctions();
|
||||
|
||||
TestTreeItem *testTreeItem;
|
||||
if (testCaseName.isEmpty()) {
|
||||
updateUnnamedQuickTests(qmlJSDoc->fileName(), cppFileName, testFunctions);
|
||||
continue;
|
||||
} // end of handling test cases without name property
|
||||
testTreeItem = new TestTreeItem(QString(), QString(), TestTreeItem::TestClass);
|
||||
|
||||
// construct new/modified TestTreeItem
|
||||
TestTreeItem *testTreeItem
|
||||
= constructTestTreeItem(tcLocationAndType.m_name, cppFileName, testCaseName,
|
||||
tcLocationAndType.m_line, tcLocationAndType.m_column,
|
||||
testFunctions);
|
||||
foreach (const QString &functionName, testFunctions.keys()) {
|
||||
const TestCodeLocationAndType locationAndType = testFunctions.value(functionName);
|
||||
TestTreeItem *testFunction = new TestTreeItem(functionName, locationAndType.m_name,
|
||||
locationAndType.m_type);
|
||||
testFunction->setLine(locationAndType.m_line);
|
||||
testFunction->setColumn(locationAndType.m_column);
|
||||
testFunction->setMainFile(cppFileName);
|
||||
testFunction->setReferencingFile(cppFileName);
|
||||
testTreeItem->appendChild(testFunction);
|
||||
}
|
||||
|
||||
// update model and internal map
|
||||
updateModelAndQuickDocMap(qmlJSDoc, cppFileName, testTreeItem);
|
||||
} else {
|
||||
testTreeItem = constructTestTreeItem(tcLocationAndType.m_name, cppFileName,
|
||||
testCaseName, tcLocationAndType.m_line,
|
||||
tcLocationAndType.m_column, testFunctions);
|
||||
testTreeItem->setReferencingFile(cppFileName);
|
||||
}
|
||||
emit testItemCreated(testTreeItem, TestTreeModel::QuickTest);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -629,7 +635,17 @@ void TestCodeParser::handleGTest(const QString &filePath)
|
||||
visitor.accept(ast);
|
||||
|
||||
QMap<GTestCaseSpec, TestCodeLocationList> result = visitor.gtestFunctions();
|
||||
updateGTests(document, result);
|
||||
QString proFile;
|
||||
const CppTools::CppModelManager *cppMM = CppTools::CppModelManager::instance();
|
||||
QList<CppTools::ProjectPart::Ptr> ppList = cppMM->projectPart(filePath);
|
||||
if (ppList.size())
|
||||
proFile = ppList.at(0)->projectFile;
|
||||
|
||||
foreach (const GTestCaseSpec &testSpec, result.keys()) {
|
||||
TestTreeItem *item = constructGTestTreeItem(filePath, testSpec, proFile,
|
||||
result.value(testSpec));
|
||||
emit testItemCreated(item, TestTreeModel::GoogleTest);
|
||||
}
|
||||
}
|
||||
|
||||
void TestCodeParser::onCppDocumentUpdated(const CPlusPlus::Document::Ptr &document)
|
||||
@@ -672,34 +688,23 @@ void TestCodeParser::onQmlDocumentUpdated(const QmlJS::Document::Ptr &document)
|
||||
return;
|
||||
}
|
||||
const CPlusPlus::Snapshot snapshot = CppTools::CppModelManager::instance()->snapshot();
|
||||
if (m_referencingFiles.contains(fileName)) {
|
||||
const ReferencingInfo &refInfo = m_referencingFiles.value(fileName);
|
||||
if (refInfo.type == TestTreeModel::QuickTest
|
||||
&& snapshot.contains(refInfo.referencingFile)) {
|
||||
if (!refInfo.referencingFile.isEmpty()) {
|
||||
QMap<QString, QString> referencingFiles = m_model->referencingFiles();
|
||||
if (referencingFiles.contains(fileName)) {
|
||||
const QString &referencingFile = referencingFiles.value(fileName);
|
||||
if (!referencingFile.isEmpty() && snapshot.contains(referencingFile)) {
|
||||
qCDebug(LOG) << "calling scanForTests with cached referencing files"
|
||||
<< "(onQmlDocumentUpdated)";
|
||||
scanForTests(QStringList(refInfo.referencingFile));
|
||||
scanForTests(QStringList(referencingFile));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m_unnamedQuickDocList.size() == 0)
|
||||
return;
|
||||
|
||||
// special case of having unnamed TestCases
|
||||
const QString &mainFile = m_model->getMainFileForUnnamedQuickTest(fileName);
|
||||
if (!mainFile.isEmpty() && snapshot.contains(mainFile)) {
|
||||
qCDebug(LOG) << "calling scanForTests with mainfile (onQmlDocumentUpdated)";
|
||||
scanForTests(QStringList(mainFile));
|
||||
}
|
||||
}
|
||||
|
||||
void TestCodeParser::onStartupProjectChanged(ProjectExplorer::Project *)
|
||||
{
|
||||
if (m_parserState == FullParse || m_parserState == PartialParse) {
|
||||
Core::ProgressManager::instance()->cancelTasks(Constants::TASK_PARSE);
|
||||
} else {
|
||||
clearCache();
|
||||
emit aboutToPerformFullParse();
|
||||
emitUpdateTestTree();
|
||||
}
|
||||
}
|
||||
@@ -714,12 +719,6 @@ void TestCodeParser::onProjectPartsUpdated(ProjectExplorer::Project *project)
|
||||
emitUpdateTestTree();
|
||||
}
|
||||
|
||||
void TestCodeParser::removeFiles(const QStringList &files)
|
||||
{
|
||||
foreach (const QString &file, files)
|
||||
removeTestsIfNecessary(file);
|
||||
}
|
||||
|
||||
bool TestCodeParser::postponed(const QStringList &fileList)
|
||||
{
|
||||
switch (m_parserState) {
|
||||
@@ -786,13 +785,20 @@ void TestCodeParser::scanForTests(const QStringList &fileList)
|
||||
}
|
||||
|
||||
parsingHasFailed = false;
|
||||
|
||||
QMap<QString, QString> referencingFiles = m_model->referencingFiles();
|
||||
if (isSmallChange) { // no need to do this async or should we do this always async?
|
||||
foreach (const QString &filePath, list)
|
||||
m_model->markForRemoval(filePath);
|
||||
|
||||
CppTools::CppModelManager *cppMM = CppTools::CppModelManager::instance();
|
||||
CPlusPlus::Snapshot snapshot = cppMM->snapshot();
|
||||
foreach (const QString &file, list) {
|
||||
if (snapshot.contains(file)) {
|
||||
CPlusPlus::Document::Ptr doc = snapshot.find(file).value();
|
||||
checkDocumentForTestCode(doc, m_referencingFiles.value(file).referencingFile);
|
||||
const QString &referencingFile = referencingFiles.value(file);
|
||||
checkDocumentForTestCode(doc, list.contains(referencingFile) ? QString()
|
||||
: referencingFile);
|
||||
} else {
|
||||
parsingHasFailed |= (CppTools::ProjectFile::classify(file)
|
||||
!= CppTools::ProjectFile::Unclassified);
|
||||
@@ -802,7 +808,9 @@ void TestCodeParser::scanForTests(const QStringList &fileList)
|
||||
return;
|
||||
}
|
||||
|
||||
QFuture<void> future = Utils::runAsync<void>(&performParse, list, m_referencingFiles, this);
|
||||
m_model->markAllForRemoval();
|
||||
|
||||
QFuture<void> future = Utils::runAsync<void>(&performParse, list, referencingFiles, this);
|
||||
Core::FutureProgress *progress
|
||||
= Core::ProgressManager::addTask(future, isFullParse ? tr("Scanning for Tests")
|
||||
: tr("Refreshing Tests List"),
|
||||
@@ -813,53 +821,6 @@ void TestCodeParser::scanForTests(const QStringList &fileList)
|
||||
emit parsingStarted();
|
||||
}
|
||||
|
||||
void TestCodeParser::clearCache()
|
||||
{
|
||||
m_referencingFiles.clear();
|
||||
m_unnamedQuickDocList.clear();
|
||||
m_gtestDocList.clear();
|
||||
emit cacheCleared();
|
||||
}
|
||||
|
||||
void TestCodeParser::removeTestsIfNecessary(const QString &fileName)
|
||||
{
|
||||
// check if this file was listed before and remove if necessary (switched config,...)
|
||||
if (m_referencingFiles.contains(fileName)
|
||||
&& m_referencingFiles.value(fileName).type == TestTreeModel::AutoTest) {
|
||||
m_referencingFiles.remove(fileName);
|
||||
emit testItemsRemoved(fileName, TestTreeModel::AutoTest);
|
||||
} else if (m_referencingFiles.contains(fileName)
|
||||
&& m_referencingFiles.value(fileName).type == TestTreeModel::GoogleTest) {
|
||||
m_referencingFiles.remove(fileName);
|
||||
emit testItemsRemoved(fileName, TestTreeModel::GoogleTest);
|
||||
} else { // handle Qt Quick Tests
|
||||
QList<QString> toBeRemoved;
|
||||
foreach (const QString &file, m_referencingFiles.keys()) {
|
||||
if (file == fileName
|
||||
&& m_referencingFiles.value(file).type == TestTreeModel::QuickTest) {
|
||||
toBeRemoved.append(file);
|
||||
continue;
|
||||
}
|
||||
const ReferencingInfo &refInfo = m_referencingFiles.value(file);
|
||||
if (refInfo.type == TestTreeModel::QuickTest && refInfo.referencingFile == fileName)
|
||||
toBeRemoved.append(file);
|
||||
}
|
||||
foreach (const QString &file, toBeRemoved) {
|
||||
m_referencingFiles.remove(file);
|
||||
emit testItemsRemoved(file, TestTreeModel::QuickTest);
|
||||
}
|
||||
// unnamed Quick Tests must be handled separately
|
||||
if (fileName.endsWith(QLatin1String(".qml"))) {
|
||||
removeUnnamedQuickTestsByName(fileName);
|
||||
} else {
|
||||
QSet<QString> filePaths;
|
||||
m_model->qmlFilesForMainFile(fileName, &filePaths);
|
||||
foreach (const QString &file, filePaths)
|
||||
removeUnnamedQuickTestsByName(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TestCodeParser::onTaskStarted(Core::Id type)
|
||||
{
|
||||
if (type == CppTools::Constants::TASK_INDEX)
|
||||
@@ -936,175 +897,5 @@ void TestCodeParser::onPartialParsingFinished()
|
||||
}
|
||||
}
|
||||
|
||||
void TestCodeParser::updateUnnamedQuickTests(const QString &fileName, const QString &mainFile,
|
||||
const QMap<QString, TestCodeLocationAndType> &functions)
|
||||
{
|
||||
// if this test case was named before remove it
|
||||
m_referencingFiles.remove(fileName);
|
||||
emit testItemsRemoved(fileName, TestTreeModel::QuickTest);
|
||||
|
||||
removeUnnamedQuickTestsByName(fileName);
|
||||
foreach (const QString &functionName, functions.keys()) {
|
||||
UnnamedQuickTestInfo info(functionName, fileName);
|
||||
m_unnamedQuickDocList.append(info);
|
||||
}
|
||||
|
||||
emit unnamedQuickTestsUpdated(mainFile, functions);
|
||||
}
|
||||
|
||||
void TestCodeParser::updateModelAndCppDocMap(CPlusPlus::Document::Ptr document,
|
||||
const QString &declaringFile, TestTreeItem *testItem)
|
||||
{
|
||||
const CppTools::CppModelManager *cppMM = CppTools::CppModelManager::instance();
|
||||
const QString fileName = document->fileName();
|
||||
const QString testCaseName = testItem->name();
|
||||
QString proFile;
|
||||
const QList<CppTools::ProjectPart::Ptr> ppList = cppMM->projectPart(fileName);
|
||||
if (ppList.size())
|
||||
proFile = ppList.at(0)->projectFile;
|
||||
|
||||
if (m_referencingFiles.contains(fileName)
|
||||
&& m_referencingFiles.value(fileName).type == TestTreeModel::AutoTest) {
|
||||
QStringList files = { fileName };
|
||||
if (fileName != declaringFile)
|
||||
files << declaringFile;
|
||||
foreach (const QString &file, files) {
|
||||
const bool setReferencingFile = (files.size() == 2 && file == declaringFile);
|
||||
ReferencingInfo testInfo;
|
||||
if (setReferencingFile) {
|
||||
testInfo.referencingFile = fileName;
|
||||
testItem->setReferencingFile(fileName);
|
||||
}
|
||||
testInfo.type = TestTreeModel::AutoTest;
|
||||
m_referencingFiles.insert(file, testInfo);
|
||||
}
|
||||
emit testItemModified(testItem, TestTreeModel::AutoTest, files);
|
||||
} else {
|
||||
if (declaringFile != fileName)
|
||||
testItem->setReferencingFile(fileName);
|
||||
emit testItemCreated(testItem, TestTreeModel::AutoTest);
|
||||
ReferencingInfo testInfo;
|
||||
testInfo.type = TestTreeModel::AutoTest;
|
||||
m_referencingFiles.insert(fileName, testInfo);
|
||||
if (declaringFile != fileName) {
|
||||
testInfo.referencingFile = fileName;
|
||||
m_referencingFiles.insert(declaringFile, testInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TestCodeParser::updateModelAndQuickDocMap(QmlJS::Document::Ptr document,
|
||||
const QString &referencingFile,
|
||||
TestTreeItem *testItem)
|
||||
{
|
||||
const CppTools::CppModelManager *cppMM = CppTools::CppModelManager::instance();
|
||||
const QString fileName = document->fileName();
|
||||
QString proFile;
|
||||
QList<CppTools::ProjectPart::Ptr> ppList = cppMM->projectPart(referencingFile);
|
||||
if (ppList.size())
|
||||
proFile = ppList.at(0)->projectFile;
|
||||
|
||||
if (m_referencingFiles.contains(fileName)
|
||||
&& m_referencingFiles.value(fileName).type == TestTreeModel::QuickTest) {
|
||||
ReferencingInfo testInfo;
|
||||
testInfo.referencingFile = referencingFile;
|
||||
testInfo.type = TestTreeModel::QuickTest;
|
||||
testItem->setReferencingFile(referencingFile);
|
||||
emit testItemModified(testItem, TestTreeModel::QuickTest, { fileName });
|
||||
m_referencingFiles.insert(fileName, testInfo);
|
||||
} else {
|
||||
// if it was formerly unnamed remove the respective items
|
||||
removeUnnamedQuickTestsByName(fileName);
|
||||
|
||||
const QString &filePath = testItem->filePath();
|
||||
ReferencingInfo testInfo;
|
||||
testInfo.referencingFile = referencingFile;
|
||||
testInfo.type = TestTreeModel::QuickTest;
|
||||
testItem->setReferencingFile(referencingFile);
|
||||
emit testItemCreated(testItem, TestTreeModel::QuickTest);
|
||||
m_referencingFiles.insert(filePath, testInfo);
|
||||
}
|
||||
}
|
||||
|
||||
void TestCodeParser::updateGTests(const CPlusPlus::Document::Ptr &doc,
|
||||
const QMap<GTestCaseSpec, TestCodeLocationList> &tests)
|
||||
{
|
||||
const QString &fileName = doc->fileName();
|
||||
removeGTestsByName(fileName);
|
||||
|
||||
QString proFile;
|
||||
const CppTools::CppModelManager *cppMM = CppTools::CppModelManager::instance();
|
||||
QList<CppTools::ProjectPart::Ptr> ppList = cppMM->projectPart(fileName);
|
||||
if (ppList.size())
|
||||
proFile = ppList.at(0)->projectFile;
|
||||
|
||||
foreach (const GTestCaseSpec &testSpec, tests.keys()) {
|
||||
TestTreeItem *item = constructGTestTreeItem(fileName, testSpec, proFile, tests.value(testSpec));
|
||||
ReferencingInfo testInfo;
|
||||
testInfo.type = TestTreeModel::GoogleTest;
|
||||
|
||||
foreach (const TestCodeLocationAndType &testSet, tests.value(testSpec)) {
|
||||
GTestInfo gtestInfo(testSpec.testCaseName, testSet.m_name, fileName);
|
||||
if (testSet.m_state & TestTreeItem::Disabled)
|
||||
gtestInfo.setEnabled(false);
|
||||
m_gtestDocList.append(gtestInfo);
|
||||
}
|
||||
emit testItemCreated(item, TestTreeModel::GoogleTest);
|
||||
m_referencingFiles.insert(fileName, testInfo);
|
||||
}
|
||||
}
|
||||
|
||||
void TestCodeParser::removeUnnamedQuickTestsByName(const QString &fileName)
|
||||
{
|
||||
for (int i = m_unnamedQuickDocList.size() - 1; i >= 0; --i) {
|
||||
if (m_unnamedQuickDocList.at(i).fileName() == fileName)
|
||||
m_unnamedQuickDocList.removeAt(i);
|
||||
}
|
||||
emit unnamedQuickTestsRemoved(fileName);
|
||||
}
|
||||
|
||||
void TestCodeParser::removeGTestsByName(const QString &fileName)
|
||||
{
|
||||
for (int i = m_gtestDocList.size() - 1; i >= 0; --i)
|
||||
if (m_gtestDocList.at(i).fileName() == fileName)
|
||||
m_gtestDocList.removeAt(i);
|
||||
|
||||
emit gTestsRemoved(fileName);
|
||||
}
|
||||
|
||||
#ifdef WITH_TESTS
|
||||
int TestCodeParser::autoTestsCount() const
|
||||
{
|
||||
int count = 0;
|
||||
foreach (const QString &file, m_referencingFiles.keys()) {
|
||||
const ReferencingInfo &refInfo = m_referencingFiles.value(file);
|
||||
if (refInfo.type == TestTreeModel::AutoTest && refInfo.referencingFile.isEmpty())
|
||||
++count;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
int TestCodeParser::namedQuickTestsCount() const
|
||||
{
|
||||
int count = 0;
|
||||
foreach (const QString &file, m_referencingFiles.keys()) {
|
||||
const ReferencingInfo &refInfo = m_referencingFiles.value(file);
|
||||
if (refInfo.type == TestTreeModel::QuickTest)
|
||||
++count;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
int TestCodeParser::unnamedQuickTestsCount() const
|
||||
{
|
||||
return m_unnamedQuickDocList.size();
|
||||
}
|
||||
|
||||
int TestCodeParser::gtestNamesAndSetsCount() const
|
||||
{
|
||||
return m_gtestDocList.size();
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Autotest
|
||||
|
||||
@@ -44,8 +44,6 @@ namespace Autotest {
|
||||
namespace Internal {
|
||||
|
||||
struct TestCodeLocationAndType;
|
||||
class UnnamedQuickTestInfo;
|
||||
class GTestInfo;
|
||||
struct GTestCaseSpec;
|
||||
|
||||
class TestCodeParser : public QObject
|
||||
@@ -65,29 +63,9 @@ public:
|
||||
State state() const { return m_parserState; }
|
||||
void setDirty() { m_dirty = true; }
|
||||
|
||||
#ifdef WITH_TESTS
|
||||
int autoTestsCount() const;
|
||||
int namedQuickTestsCount() const;
|
||||
int unnamedQuickTestsCount() const;
|
||||
int gtestNamesAndSetsCount() const;
|
||||
#endif
|
||||
|
||||
// FIXME remove me again
|
||||
struct ReferencingInfo
|
||||
{
|
||||
QString referencingFile;
|
||||
TestTreeModel::Type type;
|
||||
};
|
||||
|
||||
signals:
|
||||
void cacheCleared();
|
||||
void aboutToPerformFullParse();
|
||||
void testItemCreated(TestTreeItem *item, TestTreeModel::Type type);
|
||||
void testItemModified(TestTreeItem *tItem, TestTreeModel::Type type, const QStringList &file);
|
||||
void testItemsRemoved(const QString &filePath, TestTreeModel::Type type);
|
||||
void unnamedQuickTestsUpdated(const QString &mainFile,
|
||||
const QMap<QString, TestCodeLocationAndType> &functions);
|
||||
void unnamedQuickTestsRemoved(const QString &filePath);
|
||||
void gTestsRemoved(const QString &filePath);
|
||||
void parsingStarted();
|
||||
void parsingFinished();
|
||||
void parsingFailed();
|
||||
@@ -105,34 +83,18 @@ public slots:
|
||||
void onQmlDocumentUpdated(const QmlJS::Document::Ptr &document);
|
||||
void onStartupProjectChanged(ProjectExplorer::Project *);
|
||||
void onProjectPartsUpdated(ProjectExplorer::Project *project);
|
||||
void removeFiles(const QStringList &files);
|
||||
|
||||
private:
|
||||
bool postponed(const QStringList &fileList);
|
||||
void scanForTests(const QStringList &fileList = QStringList());
|
||||
void clearCache();
|
||||
void removeTestsIfNecessary(const QString &fileName);
|
||||
|
||||
void onTaskStarted(Core::Id type);
|
||||
void onAllTasksFinished(Core::Id type);
|
||||
void onFinished();
|
||||
void onPartialParsingFinished();
|
||||
void updateUnnamedQuickTests(const QString &fileName, const QString &mainFile,
|
||||
const QMap<QString, TestCodeLocationAndType> &functions);
|
||||
void updateModelAndCppDocMap(CPlusPlus::Document::Ptr document,
|
||||
const QString &declaringFile, TestTreeItem *testItem);
|
||||
void updateModelAndQuickDocMap(QmlJS::Document::Ptr document,
|
||||
const QString &referencingFile, TestTreeItem *testItem);
|
||||
void updateGTests(const CPlusPlus::Document::Ptr &doc,
|
||||
const QMap<GTestCaseSpec, TestCodeLocationList> &tests);
|
||||
void removeUnnamedQuickTestsByName(const QString &fileName);
|
||||
void removeGTestsByName(const QString &fileName);
|
||||
|
||||
TestTreeModel *m_model;
|
||||
|
||||
QMap<QString, ReferencingInfo> m_referencingFiles;
|
||||
QList<UnnamedQuickTestInfo> m_unnamedQuickDocList;
|
||||
QList<GTestInfo> m_gtestDocList;
|
||||
bool m_codeModelParsing;
|
||||
bool m_fullUpdatePostponed;
|
||||
bool m_partialUpdatePostponed;
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "testinfo.h"
|
||||
|
||||
namespace Autotest {
|
||||
namespace Internal {
|
||||
|
||||
UnnamedQuickTestInfo::UnnamedQuickTestInfo(const QString &function, const QString &fileName)
|
||||
: m_function(function),
|
||||
m_fileName(fileName)
|
||||
{
|
||||
}
|
||||
|
||||
GTestInfo::GTestInfo(const QString &caseName, const QString &setName, const QString &file)
|
||||
: m_caseName(caseName),
|
||||
m_setName(setName),
|
||||
m_fileName(file),
|
||||
m_enabled(true)
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Autotest
|
||||
@@ -1,73 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef TESTINFO_H
|
||||
#define TESTINFO_H
|
||||
|
||||
#include <QStringList>
|
||||
|
||||
namespace Autotest {
|
||||
namespace Internal {
|
||||
|
||||
class UnnamedQuickTestInfo {
|
||||
public:
|
||||
explicit UnnamedQuickTestInfo(const QString &function = QString(),
|
||||
const QString& fileName = QString());
|
||||
~UnnamedQuickTestInfo() {}
|
||||
|
||||
const QString function() const { return m_function; }
|
||||
void setFunction(const QString &function) { m_function = function; }
|
||||
const QString fileName() const { return m_fileName; }
|
||||
void setFileName(const QString &fileName) { m_fileName = fileName; }
|
||||
|
||||
private:
|
||||
QString m_function;
|
||||
QString m_fileName;
|
||||
};
|
||||
|
||||
class GTestInfo {
|
||||
public:
|
||||
explicit GTestInfo(const QString &caseName, const QString &setName, const QString &file);
|
||||
|
||||
const QString caseName() const { return m_caseName; }
|
||||
void setCaseName(const QString &caseName) { m_caseName = caseName; }
|
||||
const QString setName() const { return m_setName; }
|
||||
void setSetName(const QString &setName) { m_setName = setName; }
|
||||
const QString fileName() const { return m_fileName; }
|
||||
void setFileName(const QString &fileName) { m_fileName = fileName; }
|
||||
bool isEnabled() const { return m_enabled; }
|
||||
void setEnabled(bool enabled) { m_enabled = enabled; }
|
||||
|
||||
private:
|
||||
QString m_caseName;
|
||||
QString m_setName;
|
||||
QString m_fileName;
|
||||
bool m_enabled;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Autotest
|
||||
|
||||
#endif // TESTINFO_H
|
||||
@@ -86,33 +86,14 @@ TestTreeModel::TestTreeModel(QObject *parent) :
|
||||
rootItem()->appendChild(m_quickTestRootItem);
|
||||
rootItem()->appendChild(m_googleTestRootItem);
|
||||
|
||||
connect(m_parser, &TestCodeParser::cacheCleared, this,
|
||||
connect(m_parser, &TestCodeParser::aboutToPerformFullParse, this,
|
||||
&TestTreeModel::removeAllTestItems, Qt::QueuedConnection);
|
||||
connect(m_parser, &TestCodeParser::testItemCreated,
|
||||
this, &TestTreeModel::addTestTreeItem, Qt::QueuedConnection);
|
||||
connect(m_parser, &TestCodeParser::testItemModified,
|
||||
this, &TestTreeModel::modifyTestTreeItem, Qt::QueuedConnection);
|
||||
connect(m_parser, &TestCodeParser::testItemsRemoved,
|
||||
this, &TestTreeModel::removeTestTreeItems, Qt::QueuedConnection);
|
||||
connect(m_parser, &TestCodeParser::unnamedQuickTestsUpdated,
|
||||
this, &TestTreeModel::updateUnnamedQuickTest, Qt::QueuedConnection);
|
||||
connect(m_parser, &TestCodeParser::unnamedQuickTestsRemoved,
|
||||
this, &TestTreeModel::removeUnnamedQuickTests, Qt::QueuedConnection);
|
||||
connect(m_parser, &TestCodeParser::gTestsRemoved,
|
||||
this, &TestTreeModel::removeGTests, Qt::QueuedConnection);
|
||||
|
||||
// CppTools::CppModelManagerInterface *cppMM = CppTools::CppModelManagerInterface::instance();
|
||||
// if (cppMM) {
|
||||
// // replace later on by
|
||||
// // cppMM->registerAstProcessor([this](const CplusPlus::Document::Ptr &doc,
|
||||
// // const CPlusPlus::Snapshot &snapshot) {
|
||||
// // checkForQtTestStuff(doc, snapshot);
|
||||
// // });
|
||||
// connect(cppMM, SIGNAL(documentUpdated(CPlusPlus::Document::Ptr)),
|
||||
// this, SLOT(checkForQtTestStuff(CPlusPlus::Document::Ptr)),
|
||||
// Qt::DirectConnection);
|
||||
|
||||
// }
|
||||
connect(m_parser, &TestCodeParser::parsingFinished,
|
||||
this, &TestTreeModel::sweep, Qt::QueuedConnection);
|
||||
connect(m_parser, &TestCodeParser::parsingFailed,
|
||||
this, &TestTreeModel::sweep, Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
static TestTreeModel *m_instance = 0;
|
||||
@@ -148,7 +129,7 @@ void TestTreeModel::enableParsing()
|
||||
connect(cppMM, &CppTools::CppModelManager::documentUpdated,
|
||||
m_parser, &TestCodeParser::onCppDocumentUpdated, Qt::QueuedConnection);
|
||||
connect(cppMM, &CppTools::CppModelManager::aboutToRemoveFiles,
|
||||
m_parser, &TestCodeParser::removeFiles, Qt::QueuedConnection);
|
||||
this, &TestTreeModel::removeFiles, Qt::QueuedConnection);
|
||||
connect(cppMM, &CppTools::CppModelManager::projectPartsUpdated,
|
||||
m_parser, &TestCodeParser::onProjectPartsUpdated);
|
||||
|
||||
@@ -156,7 +137,7 @@ void TestTreeModel::enableParsing()
|
||||
connect(qmlJsMM, &QmlJS::ModelManagerInterface::documentUpdated,
|
||||
m_parser, &TestCodeParser::onQmlDocumentUpdated, Qt::QueuedConnection);
|
||||
connect(qmlJsMM, &QmlJS::ModelManagerInterface::aboutToRemoveFiles,
|
||||
m_parser, &TestCodeParser::removeFiles, Qt::QueuedConnection);
|
||||
this, &TestTreeModel::removeFiles, Qt::QueuedConnection);
|
||||
m_connectionsInitialized = true;
|
||||
}
|
||||
|
||||
@@ -541,38 +522,6 @@ TestConfiguration *TestTreeModel::getTestConfiguration(const TestTreeItem *item)
|
||||
return config;
|
||||
}
|
||||
|
||||
QString TestTreeModel::getMainFileForUnnamedQuickTest(const QString &qmlFile) const
|
||||
{
|
||||
const TestTreeItem *unnamed = unnamedQuickTests();
|
||||
const int count = unnamed ? unnamed->childCount() : 0;
|
||||
for (int row = 0; row < count; ++row) {
|
||||
const TestTreeItem *child = unnamed->childItem(row);
|
||||
if (qmlFile == child->filePath())
|
||||
return child->mainFile();
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
void TestTreeModel::qmlFilesForMainFile(const QString &mainFile, QSet<QString> *filePaths) const
|
||||
{
|
||||
const TestTreeItem *unnamed = unnamedQuickTests();
|
||||
if (!unnamed)
|
||||
return;
|
||||
for (int row = 0, count = unnamed->childCount(); row < count; ++row) {
|
||||
const TestTreeItem *child = unnamed->childItem(row);
|
||||
if (child->mainFile() == mainFile)
|
||||
filePaths->insert(child->filePath());
|
||||
}
|
||||
}
|
||||
|
||||
QList<QString> TestTreeModel::getUnnamedQuickTestFunctions() const
|
||||
{
|
||||
const TestTreeItem *unnamed = unnamedQuickTests();
|
||||
if (unnamed)
|
||||
return unnamed->getChildNames();
|
||||
return QList<QString>();
|
||||
}
|
||||
|
||||
bool TestTreeModel::hasUnnamedQuickTests() const
|
||||
{
|
||||
for (int row = 0, count = m_quickTestRootItem->childCount(); row < count; ++row)
|
||||
@@ -591,36 +540,11 @@ TestTreeItem *TestTreeModel::unnamedQuickTests() const
|
||||
return 0;
|
||||
}
|
||||
|
||||
void TestTreeModel::removeUnnamedQuickTests(const QString &filePath)
|
||||
void TestTreeModel::removeFiles(const QStringList &files)
|
||||
{
|
||||
TestTreeItem *unnamedQT = unnamedQuickTests();
|
||||
if (!unnamedQT)
|
||||
return;
|
||||
|
||||
for (int childRow = unnamedQT->childCount() - 1; childRow >= 0; --childRow) {
|
||||
TestTreeItem *child = unnamedQT->childItem(childRow);
|
||||
if (filePath == child->filePath())
|
||||
delete takeItem(child);
|
||||
}
|
||||
|
||||
if (unnamedQT->childCount() == 0)
|
||||
delete takeItem(unnamedQT);
|
||||
emit testTreeModelChanged();
|
||||
}
|
||||
|
||||
void TestTreeModel::removeGTests(const QString &filePath)
|
||||
{
|
||||
for (int childRow = m_googleTestRootItem->childCount() - 1; childRow >= 0; --childRow) {
|
||||
TestTreeItem *child = m_googleTestRootItem->childItem(childRow);
|
||||
for (int grandChildRow = child->childCount() - 1; grandChildRow >= 0; --grandChildRow) {
|
||||
TestTreeItem *grandChild = child->childItem(grandChildRow);
|
||||
if (filePath == grandChild->filePath())
|
||||
delete takeItem(grandChild);
|
||||
}
|
||||
if (child->childCount() == 0)
|
||||
delete takeItem(child);
|
||||
}
|
||||
emit testTreeModelChanged();
|
||||
foreach (const QString &file, files)
|
||||
markForRemoval(file);
|
||||
sweep();
|
||||
}
|
||||
|
||||
void TestTreeModel::markAllForRemoval()
|
||||
@@ -711,80 +635,61 @@ QMap<QString, QString> TestTreeModel::referencingFiles() const
|
||||
return finder.referencingFiles();
|
||||
}
|
||||
|
||||
void TestTreeModel::addTestTreeItem(TestTreeItem *item, TestTreeModel::Type type)
|
||||
TestTreeItem *TestTreeModel::findTestTreeItemByContent(TestTreeItem *item, TestTreeItem *parent,
|
||||
Type type)
|
||||
{
|
||||
TestTreeItem *parent = rootItemForType(type);
|
||||
if (type == TestTreeModel::GoogleTest) {
|
||||
// check if there's already an item with the same test name...
|
||||
TestTreeItem *toBeUpdated = 0;
|
||||
for (int row = 0, count = parent->childCount(); row < count; ++row) {
|
||||
TestTreeItem *current = parent->childItem(row);
|
||||
if (current->name() == item->name() && current->type() == item->type()) {
|
||||
toBeUpdated = current;
|
||||
if (current->name() != item->name())
|
||||
continue;
|
||||
|
||||
switch (type) {
|
||||
case AutoTest:
|
||||
if (current->filePath() == item->filePath())
|
||||
return current;
|
||||
break;
|
||||
case QuickTest:
|
||||
if (current->filePath() == item->filePath() && current->mainFile() == item->mainFile())
|
||||
return current;
|
||||
break;
|
||||
case GoogleTest:
|
||||
if (current->type() == item->type())
|
||||
return current;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// ...if so we have, to update this one instead of adding a new item
|
||||
if (toBeUpdated) {
|
||||
for (int row = 0, count = item->childCount(); row < count; ++row)
|
||||
toBeUpdated->appendChild(new TestTreeItem(*item->childItem(row)));
|
||||
delete item;
|
||||
} else {
|
||||
parent->appendChild(item);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void TestTreeModel::addTestTreeItem(TestTreeItem *item, Type type)
|
||||
{
|
||||
TestTreeItem *parent = rootItemForType(type);
|
||||
TestTreeItem *toBeUpdated = findTestTreeItemByContent(item, parent, type);
|
||||
const int count = item->childCount();
|
||||
if (toBeUpdated) {
|
||||
if (!toBeUpdated->markedForRemoval()) {
|
||||
for (int row = 0; row < count; ++row)
|
||||
toBeUpdated->appendChild(new TestTreeItem(*item->childItem(row)));
|
||||
} else {
|
||||
for (int childRow = count - 1; childRow >= 0; --childRow) {
|
||||
TestTreeItem *childItem = item->childItem(childRow);
|
||||
TestTreeItem *origChild = findTestTreeItemByContent(childItem, toBeUpdated, type);
|
||||
if (origChild) {
|
||||
QModelIndex toBeModifiedIndex = indexForItem(origChild);
|
||||
modifyTestSubtree(toBeModifiedIndex, childItem);
|
||||
} else {
|
||||
toBeUpdated->insertChild(qMin(count, toBeUpdated->childCount()),
|
||||
new TestTreeItem(*childItem));
|
||||
}
|
||||
}
|
||||
}
|
||||
delete item;
|
||||
} else {
|
||||
parent->appendChild(item);
|
||||
}
|
||||
emit testTreeModelChanged();
|
||||
}
|
||||
|
||||
void TestTreeModel::updateUnnamedQuickTest(const QString &mainFile,
|
||||
const QMap<QString, TestCodeLocationAndType> &functions)
|
||||
{
|
||||
if (functions.isEmpty())
|
||||
return;
|
||||
|
||||
if (!hasUnnamedQuickTests())
|
||||
addTestTreeItem(new TestTreeItem(QString(), QString(), TestTreeItem::TestClass), QuickTest);
|
||||
|
||||
TestTreeItem *unnamed = unnamedQuickTests();
|
||||
foreach (const QString &functionName, functions.keys()) {
|
||||
const TestCodeLocationAndType locationAndType = functions.value(functionName);
|
||||
TestTreeItem *testFunction = new TestTreeItem(functionName, locationAndType.m_name,
|
||||
locationAndType.m_type);
|
||||
testFunction->setLine(locationAndType.m_line);
|
||||
testFunction->setColumn(locationAndType.m_column);
|
||||
testFunction->setMainFile(mainFile);
|
||||
unnamed->appendChild(testFunction);
|
||||
}
|
||||
}
|
||||
|
||||
void TestTreeModel::modifyTestTreeItem(TestTreeItem *item, TestTreeModel::Type type, const QStringList &files)
|
||||
{
|
||||
QModelIndex index = rootIndexForType(type);
|
||||
TestTreeItem *parent = rootItemForType(type);
|
||||
if (files.isEmpty()) {
|
||||
if (TestTreeItem *unnamed = unnamedQuickTests()) {
|
||||
if (unnamed == item) // no need to update or delete
|
||||
return;
|
||||
|
||||
index = indexForItem(unnamed);
|
||||
modifyTestSubtree(index, item);
|
||||
}
|
||||
} else {
|
||||
for (int row = 0; row < parent->childCount(); ++row) {
|
||||
if (files.contains(parent->childItem(row)->filePath())) {
|
||||
index = index.child(row, 0);
|
||||
modifyTestSubtree(index, item);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// item was created as temporary, destroy it if it won't get destroyed by its parent
|
||||
if (!item->parent())
|
||||
delete item;
|
||||
}
|
||||
|
||||
void TestTreeModel::removeAllTestItems()
|
||||
{
|
||||
m_autoTestRootItem->removeChildren();
|
||||
@@ -793,21 +698,6 @@ void TestTreeModel::removeAllTestItems()
|
||||
emit testTreeModelChanged();
|
||||
}
|
||||
|
||||
void TestTreeModel::removeTestTreeItems(const QString &filePath, Type type)
|
||||
{
|
||||
bool removed = false;
|
||||
const TestTreeItem *rootItem = rootItemForType(type);
|
||||
for (int row = rootItem->childCount() - 1; row >= 0; --row) {
|
||||
TestTreeItem *childItem = rootItem->childItem(row);
|
||||
if (filePath == childItem->filePath()) {
|
||||
delete takeItem(childItem);
|
||||
removed = true;
|
||||
}
|
||||
}
|
||||
if (removed)
|
||||
emit testTreeModelChanged();
|
||||
}
|
||||
|
||||
TestTreeItem *TestTreeModel::rootItemForType(TestTreeModel::Type type)
|
||||
{
|
||||
switch (type) {
|
||||
@@ -821,19 +711,6 @@ TestTreeItem *TestTreeModel::rootItemForType(TestTreeModel::Type type)
|
||||
QTC_ASSERT(false, return 0);
|
||||
}
|
||||
|
||||
QModelIndex TestTreeModel::rootIndexForType(TestTreeModel::Type type)
|
||||
{
|
||||
switch (type) {
|
||||
case AutoTest:
|
||||
return index(0, 0);
|
||||
case QuickTest:
|
||||
return index(1, 0);
|
||||
case GoogleTest:
|
||||
return index(2, 0);
|
||||
}
|
||||
QTC_ASSERT(false, return QModelIndex());
|
||||
}
|
||||
|
||||
void TestTreeModel::modifyTestSubtree(QModelIndex &toBeModifiedIndex, const TestTreeItem *newItem)
|
||||
{
|
||||
if (!toBeModifiedIndex.isValid())
|
||||
|
||||
@@ -64,9 +64,6 @@ public:
|
||||
QList<TestConfiguration *> getAllTestCases() const;
|
||||
QList<TestConfiguration *> getSelectedTests() const;
|
||||
TestConfiguration *getTestConfiguration(const TestTreeItem *item) const;
|
||||
QString getMainFileForUnnamedQuickTest(const QString &qmlFile) const;
|
||||
void qmlFilesForMainFile(const QString &mainFile, QSet<QString> *filePaths) const;
|
||||
QList<QString> getUnnamedQuickTestFunctions() const;
|
||||
bool hasUnnamedQuickTests() const;
|
||||
|
||||
#ifdef WITH_TESTS
|
||||
@@ -90,18 +87,14 @@ public slots:
|
||||
|
||||
private:
|
||||
void addTestTreeItem(TestTreeItem *item, Type type);
|
||||
void updateUnnamedQuickTest(const QString &mainFile,
|
||||
const QMap<QString, TestCodeLocationAndType> &functions);
|
||||
void modifyTestTreeItem(TestTreeItem *item, Type type, const QStringList &file);
|
||||
void removeAllTestItems();
|
||||
void removeTestTreeItems(const QString &filePath, Type type);
|
||||
void removeUnnamedQuickTests(const QString &filePath);
|
||||
void removeGTests(const QString &filePath);
|
||||
bool sweepChildren(TestTreeItem *item);
|
||||
void removeFiles(const QStringList &files);
|
||||
void markForRemoval(const QString &filePath, Type type);
|
||||
void sweepChildren(TestTreeItem *item);
|
||||
TestTreeItem *findTestTreeItemByContent(TestTreeItem *item, TestTreeItem *parent, Type type);
|
||||
|
||||
TestTreeItem *unnamedQuickTests() const;
|
||||
TestTreeItem *rootItemForType(Type type);
|
||||
QModelIndex rootIndexForType(Type type);
|
||||
|
||||
explicit TestTreeModel(QObject *parent = 0);
|
||||
void modifyTestSubtree(QModelIndex &toBeModifiedIndex, const TestTreeItem *newItem);
|
||||
|
||||
Reference in New Issue
Block a user