AutoTest: Unify handling of test tree items...

...and let specialized items handle its specialization by itself.

Change-Id: I988ce3c610bef68933b9102bb39ae4723add3a99
Reviewed-by: David Schulz <david.schulz@theqtcompany.com>
This commit is contained in:
Christian Stenger
2016-02-23 15:56:52 +01:00
parent 009eef4e0d
commit 36f6a5580f
10 changed files with 314 additions and 394 deletions

View File

@@ -428,23 +428,12 @@ static QMap<QString, TestCodeLocationList> checkForDataTags(const QString &fileN
/****** end of helpers ******/ /****** end of helpers ******/
static void handleQtQuickTest(QFutureInterface<TestParseResult> futureInterface, static void checkQmlDocumentForTestCode(QFutureInterface<TestParseResult> futureInterface,
CPlusPlus::Document::Ptr document) const QmlJS::Document::Ptr &qmlJSDoc,
const QString &proFile = QString())
{ {
const CppTools::CppModelManager *modelManager = CppTools::CppModelManager::instance();
if (quickTestName(document).isEmpty())
return;
const QString cppFileName = document->fileName();
const QString srcDir = quickTestSrcDir(modelManager, cppFileName);
if (srcDir.isEmpty())
return;
const QList<QmlJS::Document::Ptr> qmlDocs = scanDirectoryForQuickTestQmlFiles(srcDir);
foreach (const QmlJS::Document::Ptr &qmlJSDoc, qmlDocs) {
QmlJS::AST::Node *ast = qmlJSDoc->ast(); QmlJS::AST::Node *ast = qmlJSDoc->ast();
QTC_ASSERT(ast, continue); QTC_ASSERT(ast, return);
TestQmlVisitor qmlVisitor(qmlJSDoc); TestQmlVisitor qmlVisitor(qmlJSDoc);
QmlJS::AST::Node::accept(ast, &qmlVisitor); QmlJS::AST::Node::accept(ast, &qmlVisitor);
@@ -453,7 +442,7 @@ static void handleQtQuickTest(QFutureInterface<TestParseResult> futureInterface,
const QMap<QString, TestCodeLocationAndType> testFunctions = qmlVisitor.testFunctions(); const QMap<QString, TestCodeLocationAndType> testFunctions = qmlVisitor.testFunctions();
TestParseResult parseResult(TestTreeModel::QuickTest); TestParseResult parseResult(TestTreeModel::QuickTest);
parseResult.referencingFile = cppFileName; parseResult.proFile = proFile;
parseResult.functions = testFunctions; parseResult.functions = testFunctions;
if (!testCaseName.isEmpty()) { if (!testCaseName.isEmpty()) {
parseResult.fileName = tcLocationAndType.m_name; parseResult.fileName = tcLocationAndType.m_name;
@@ -463,6 +452,27 @@ static void handleQtQuickTest(QFutureInterface<TestParseResult> futureInterface,
} }
futureInterface.reportResult(parseResult); futureInterface.reportResult(parseResult);
} }
static void handleQtQuickTest(QFutureInterface<TestParseResult> futureInterface,
CPlusPlus::Document::Ptr document)
{
const CppTools::CppModelManager *modelManager = CppTools::CppModelManager::instance();
if (quickTestName(document).isEmpty())
return;
const QString cppFileName = document->fileName();
QList<CppTools::ProjectPart::Ptr> ppList = modelManager->projectPart(cppFileName);
QTC_ASSERT(!ppList.isEmpty(), return);
const QString &proFile = ppList.at(0)->projectFile;
const QString srcDir = quickTestSrcDir(modelManager, cppFileName);
if (srcDir.isEmpty())
return;
const QList<QmlJS::Document::Ptr> qmlDocs = scanDirectoryForQuickTestQmlFiles(srcDir);
foreach (const QmlJS::Document::Ptr &qmlJSDoc, qmlDocs)
checkQmlDocumentForTestCode(futureInterface, qmlJSDoc, proFile);
} }
static void handleGTest(QFutureInterface<TestParseResult> futureInterface, const QString &filePath) static void handleGTest(QFutureInterface<TestParseResult> futureInterface, const QString &filePath)
@@ -480,14 +490,14 @@ static void handleGTest(QFutureInterface<TestParseResult> futureInterface, const
const CppTools::CppModelManager *cppMM = CppTools::CppModelManager::instance(); const CppTools::CppModelManager *cppMM = CppTools::CppModelManager::instance();
QList<CppTools::ProjectPart::Ptr> ppList = cppMM->projectPart(filePath); QList<CppTools::ProjectPart::Ptr> ppList = cppMM->projectPart(filePath);
if (ppList.size()) if (ppList.size())
proFile = ppList.at(0)->projectFile; proFile = ppList.first()->projectFile;
foreach (const GTestCaseSpec &testSpec, result.keys()) { foreach (const GTestCaseSpec &testSpec, result.keys()) {
TestParseResult parseResult(TestTreeModel::GoogleTest); TestParseResult parseResult(TestTreeModel::GoogleTest);
parseResult.fileName = filePath; parseResult.fileName = filePath;
parseResult.testCaseName = testSpec.testCaseName; parseResult.testCaseName = testSpec.testCaseName;
parseResult.parameterized = testSpec.parameterized; parseResult.parameterized = testSpec.parameterized;
parseResult.referencingFile = proFile; parseResult.proFile = proFile;
parseResult.dataTagsOrTestSets.insert(QString(), result.value(testSpec)); parseResult.dataTagsOrTestSets.insert(QString(), result.value(testSpec));
futureInterface.reportResult(parseResult); futureInterface.reportResult(parseResult);
} }
@@ -495,7 +505,7 @@ static void handleGTest(QFutureInterface<TestParseResult> futureInterface, const
static void checkDocumentForTestCode(QFutureInterface<TestParseResult> futureInterface, static void checkDocumentForTestCode(QFutureInterface<TestParseResult> futureInterface,
CPlusPlus::Document::Ptr document, CPlusPlus::Document::Ptr document,
const QString &referencingFile = QString()) QMap<QString, QString> testCaseNames)
{ {
const QString fileName = document->fileName(); const QString fileName = document->fileName();
const CppTools::CppModelManager *modelManager = CppTools::CppModelManager::instance(); const CppTools::CppModelManager *modelManager = CppTools::CppModelManager::instance();
@@ -508,11 +518,13 @@ static void checkDocumentForTestCode(QFutureInterface<TestParseResult> futureInt
if (includesQtQuickTest(document, modelManager)) { if (includesQtQuickTest(document, modelManager)) {
handleQtQuickTest(futureInterface, document); handleQtQuickTest(futureInterface, document);
return; } else if (testCaseNames.contains(fileName) // if we do a reparse
} || (includesQtTest(document, modelManager)
&& qtTestLibDefined(modelManager, fileName))) {
if (includesQtTest(document, modelManager) && qtTestLibDefined(modelManager, fileName)) {
QString testCaseName(testClass(modelManager, document)); QString testCaseName(testClass(modelManager, document));
// we might be in a reparse without the original entry point with the QTest::qExec()
if (testCaseName.isEmpty())
testCaseName = testCaseNames.value(fileName);
if (!testCaseName.isEmpty()) { if (!testCaseName.isEmpty()) {
unsigned line = 0; unsigned line = 0;
unsigned column = 0; unsigned column = 0;
@@ -521,8 +533,6 @@ static void checkDocumentForTestCode(QFutureInterface<TestParseResult> futureInt
if (declaringDoc.isNull()) if (declaringDoc.isNull())
return; return;
const bool hasReferencingFile = declaringDoc->fileName() != document->fileName();
TestVisitor visitor(testCaseName); TestVisitor visitor(testCaseName);
visitor.accept(declaringDoc->globalNamespace()); visitor.accept(declaringDoc->globalNamespace());
const QMap<QString, TestCodeLocationAndType> testFunctions = visitor.privateSlots(); const QMap<QString, TestCodeLocationAndType> testFunctions = visitor.privateSlots();
@@ -530,7 +540,7 @@ static void checkDocumentForTestCode(QFutureInterface<TestParseResult> futureInt
QMap<QString, TestCodeLocationList> dataTags = QMap<QString, TestCodeLocationList> dataTags =
checkForDataTags(declaringDoc->fileName(), testFunctions); checkForDataTags(declaringDoc->fileName(), testFunctions);
if (hasReferencingFile) if (declaringDoc->fileName() != document->fileName())
dataTags.unite(checkForDataTags(document->fileName(), testFunctions)); dataTags.unite(checkForDataTags(document->fileName(), testFunctions));
TestParseResult parseResult(TestTreeModel::AutoTest); TestParseResult parseResult(TestTreeModel::AutoTest);
@@ -540,27 +550,13 @@ static void checkDocumentForTestCode(QFutureInterface<TestParseResult> futureInt
parseResult.column = column; parseResult.column = column;
parseResult.functions = testFunctions; parseResult.functions = testFunctions;
parseResult.dataTagsOrTestSets = dataTags; parseResult.dataTagsOrTestSets = dataTags;
if (hasReferencingFile) parseResult.proFile = projParts.first()->projectFile;
parseResult.referencingFile = fileName;
futureInterface.reportResult(parseResult); futureInterface.reportResult(parseResult);
return;
} }
} } else if (includesGTest(document, modelManager)) {
if (hasGTestNames(document))
if (includesGTest(document, modelManager)) {
if (hasGTestNames(document)) {
handleGTest(futureInterface, document->fileName()); handleGTest(futureInterface, document->fileName());
return;
}
}
// could not find the class to test, or QTest is not included and QT_TESTLIB_LIB defined
// maybe file is only a referenced file
if (!referencingFile.isEmpty()) {
CPlusPlus::Snapshot snapshot = modelManager->snapshot();
if (snapshot.contains(referencingFile))
checkDocumentForTestCode(futureInterface, snapshot.find(referencingFile).value());
} }
} }
@@ -569,21 +565,22 @@ static void checkDocumentForTestCode(QFutureInterface<TestParseResult> futureInt
static bool parsingHasFailed; static bool parsingHasFailed;
static void performParse(QFutureInterface<TestParseResult> &futureInterface, static void performParse(QFutureInterface<TestParseResult> &futureInterface,
const QStringList &list, const QMap<QString, QString> &referencingFiles) const QStringList &list, const QMap<QString, QString> testCaseNames)
{ {
int progressValue = 0; int progressValue = 0;
futureInterface.setProgressRange(0, list.size()); futureInterface.setProgressRange(0, list.size());
futureInterface.setProgressValue(progressValue); futureInterface.setProgressValue(progressValue);
CppTools::CppModelManager *cppMM = CppTools::CppModelManager::instance(); CppTools::CppModelManager *cppMM = CppTools::CppModelManager::instance();
CPlusPlus::Snapshot snapshot = cppMM->snapshot(); CPlusPlus::Snapshot snapshot = cppMM->snapshot();
QmlJS::Snapshot qmlSnapshot = QmlJSTools::Internal::ModelManager::instance()->snapshot();
foreach (const QString &file, list) { foreach (const QString &file, list) {
if (snapshot.contains(file)) { if (file.endsWith(QLatin1String(".qml"))) {
checkQmlDocumentForTestCode(futureInterface, qmlSnapshot.document(file));
} else if (snapshot.contains(file)) {
CPlusPlus::Document::Ptr doc = snapshot.find(file).value(); CPlusPlus::Document::Ptr doc = snapshot.find(file).value();
futureInterface.setProgressValue(++progressValue); futureInterface.setProgressValue(++progressValue);
const QString &referencingFile = referencingFiles.value(file); checkDocumentForTestCode(futureInterface, doc, testCaseNames);
checkDocumentForTestCode(futureInterface, doc,
list.contains(referencingFile) ? QString() : referencingFile);
} else { } else {
parsingHasFailed |= (CppTools::ProjectFile::classify(file) parsingHasFailed |= (CppTools::ProjectFile::classify(file)
!= CppTools::ProjectFile::Unclassified); != CppTools::ProjectFile::Unclassified);
@@ -617,10 +614,11 @@ void TestCodeParser::onCppDocumentUpdated(const CPlusPlus::Document::Ptr &docume
void TestCodeParser::onQmlDocumentUpdated(const QmlJS::Document::Ptr &document) void TestCodeParser::onQmlDocumentUpdated(const QmlJS::Document::Ptr &document)
{ {
const QString &fileName = document->fileName();
if (m_codeModelParsing) { if (m_codeModelParsing) {
if (!m_fullUpdatePostponed) { if (!m_fullUpdatePostponed) {
m_partialUpdatePostponed = true; m_partialUpdatePostponed = true;
m_postponedFiles.insert(document->fileName()); m_postponedFiles.insert(fileName);
} }
return; return;
} }
@@ -628,18 +626,12 @@ void TestCodeParser::onQmlDocumentUpdated(const QmlJS::Document::Ptr &document)
ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject(); ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject();
if (!project) if (!project)
return; return;
const QString fileName = document->fileName();
if (!project->files(ProjectExplorer::Project::AllFiles).contains(fileName)) { if (!project->files(ProjectExplorer::Project::AllFiles).contains(fileName)) {
// what if the file is not listed inside the pro file, but will be used anyway? // what if the file is not listed inside the pro file, but will be used anyway?
return; return;
} }
const CPlusPlus::Snapshot snapshot = CppTools::CppModelManager::instance()->snapshot();
const QString &referencingFile = m_model->referencingFiles().value(fileName); scanForTests(QStringList(fileName));
if (!referencingFile.isEmpty() && snapshot.contains(referencingFile)) {
qCDebug(LOG) << "calling scanForTests with cached referencing files"
<< "(onQmlDocumentUpdated)";
scanForTests(QStringList(referencingFile));
}
} }
void TestCodeParser::onStartupProjectChanged(ProjectExplorer::Project *project) void TestCodeParser::onStartupProjectChanged(ProjectExplorer::Project *project)
@@ -724,16 +716,20 @@ void TestCodeParser::scanForTests(const QStringList &fileList)
parsingHasFailed = false; parsingHasFailed = false;
QMap<QString, QString> referencingFiles = m_model->referencingFiles(); QMap<QString, QString> testCaseNames;
if (isFullParse) { if (isFullParse) {
// remove qml files as they will be found automatically by the referencing cpp file
list = Utils::filtered(list, [] (const QString &fn) {
return !fn.endsWith(QLatin1String(".qml"));
});
m_model->markAllForRemoval(); m_model->markAllForRemoval();
} else { } else {
testCaseNames = m_model->testCaseNamesForFiles(list);
foreach (const QString &filePath, list) foreach (const QString &filePath, list)
m_model->markForRemoval(filePath); m_model->markForRemoval(filePath);
} }
QFuture<TestParseResult> future QFuture<TestParseResult> future = Utils::runAsync(&performParse, list, testCaseNames);
= Utils::runAsync(&performParse, list, referencingFiles);
m_futureWatcher.setFuture(future); m_futureWatcher.setFuture(future);
if (list.size() > 5) { if (list.size() > 5) {
Core::ProgressManager::addTask(future, tr("Scanning for Tests"), Core::ProgressManager::addTask(future, tr("Scanning for Tests"),

View File

@@ -63,25 +63,7 @@ TestConfiguration::~TestConfiguration()
m_testCases.clear(); m_testCases.clear();
} }
void basicProjectInformation(Project *project, const QString &mainFilePath, QString *proFile, void completeBasicProjectInformation(Project *project, const QString &proFile, QString *displayName,
QString *displayName, Project **targetProject)
{
CppTools::CppModelManager *cppMM = CppTools::CppModelManager::instance();
QList<CppTools::ProjectPart::Ptr> projParts = cppMM->projectInfo(project).projectParts();
foreach (const CppTools::ProjectPart::Ptr &part, projParts) {
foreach (const CppTools::ProjectFile currentFile, part->files) {
if (currentFile.path == mainFilePath) {
*proFile = part->projectFile;
*displayName = part->displayName;
*targetProject = part->project;
return;
}
}
}
}
void basicProjectInformation(Project *project, const QString &proFile, QString *displayName,
Project **targetProject) Project **targetProject)
{ {
CppTools::CppModelManager *cppMM = CppTools::CppModelManager::instance(); CppTools::CppModelManager *cppMM = CppTools::CppModelManager::instance();
@@ -105,7 +87,7 @@ static bool isLocal(RunConfiguration *runConfiguration)
void TestConfiguration::completeTestInformation() void TestConfiguration::completeTestInformation()
{ {
QTC_ASSERT(!m_mainFilePath.isEmpty() || !m_proFile.isEmpty(), return); QTC_ASSERT(!m_proFile.isEmpty(), return);
Project *project = SessionManager::startupProject(); Project *project = SessionManager::startupProject();
if (!project) if (!project)
@@ -114,7 +96,6 @@ void TestConfiguration::completeTestInformation()
QString targetFile; QString targetFile;
QString targetName; QString targetName;
QString workDir; QString workDir;
QString proFile = m_proFile;
QString displayName; QString displayName;
QString buildDir; QString buildDir;
Project *targetProject = 0; Project *targetProject = 0;
@@ -123,10 +104,7 @@ void TestConfiguration::completeTestInformation()
bool guessedRunConfiguration = false; bool guessedRunConfiguration = false;
setProject(0); setProject(0);
if (m_proFile.isEmpty()) completeBasicProjectInformation(project, m_proFile, &displayName, &targetProject);
basicProjectInformation(project, m_mainFilePath, &proFile, &displayName, &targetProject);
else
basicProjectInformation(project, proFile, &displayName, &targetProject);
Target *target = project->activeTarget(); Target *target = project->activeTarget();
if (!target) if (!target)
@@ -135,7 +113,7 @@ void TestConfiguration::completeTestInformation()
BuildTargetInfoList appTargets = target->applicationTargets(); BuildTargetInfoList appTargets = target->applicationTargets();
foreach (const BuildTargetInfo &bti, appTargets.list) { foreach (const BuildTargetInfo &bti, appTargets.list) {
// some project manager store line/column information as well inside ProjectPart // some project manager store line/column information as well inside ProjectPart
if (bti.isValid() && proFile.startsWith(bti.projectFilePath.toString())) { if (bti.isValid() && m_proFile.startsWith(bti.projectFilePath.toString())) {
targetFile = Utils::HostOsInfo::withExecutableSuffix(bti.targetFilePath.toString()); targetFile = Utils::HostOsInfo::withExecutableSuffix(bti.targetFilePath.toString());
targetName = bti.targetName; targetName = bti.targetName;
break; break;
@@ -146,8 +124,8 @@ void TestConfiguration::completeTestInformation()
if (auto buildConfig = target->activeBuildConfiguration()) { if (auto buildConfig = target->activeBuildConfiguration()) {
const QString buildBase = buildConfig->buildDirectory().toString(); const QString buildBase = buildConfig->buildDirectory().toString();
const QString projBase = targetProject->projectDirectory().toString(); const QString projBase = targetProject->projectDirectory().toString();
if (proFile.startsWith(projBase)) if (m_proFile.startsWith(projBase))
buildDir = QFileInfo(buildBase + proFile.mid(projBase.length())).absolutePath(); buildDir = QFileInfo(buildBase + m_proFile.mid(projBase.length())).absolutePath();
} }
} }
@@ -180,7 +158,6 @@ void TestConfiguration::completeTestInformation()
} }
} }
setProFile(proFile);
setDisplayName(displayName); setDisplayName(displayName);
if (hasDesktopTarget) { if (hasDesktopTarget) {
@@ -215,11 +192,6 @@ void TestConfiguration::setTestCaseCount(int count)
m_testCaseCount = count; m_testCaseCount = count;
} }
void TestConfiguration::setMainFilePath(const QString &mainFile)
{
m_mainFilePath = mainFile;
}
void TestConfiguration::setTargetFile(const QString &targetFile) void TestConfiguration::setTargetFile(const QString &targetFile)
{ {
m_targetFile = targetFile; m_targetFile = targetFile;

View File

@@ -51,7 +51,6 @@ public:
void setTestCases(const QStringList &testCases); void setTestCases(const QStringList &testCases);
void setTestCaseCount(int count); void setTestCaseCount(int count);
void setMainFilePath(const QString &mainFile);
void setTargetFile(const QString &targetFile); void setTargetFile(const QString &targetFile);
void setTargetName(const QString &targetName); void setTargetName(const QString &targetName);
void setProFile(const QString &proFile); void setProFile(const QString &proFile);

View File

@@ -110,12 +110,9 @@ void TestNavigationWidget::contextMenuEvent(QContextMenuEvent *event)
// do not provide this menu entry for unnamed Quick Tests as it makes no sense // do not provide this menu entry for unnamed Quick Tests as it makes no sense
int type = index.data(TypeRole).toInt(); int type = index.data(TypeRole).toInt();
const QString &unnamed = tr(Constants::UNNAMED_QUICKTESTS); const QString &unnamed = tr(Constants::UNNAMED_QUICKTESTS);
if ((type == TestTreeItem::TestFunction && index.parent().data().toString() != unnamed) if ((type == TestTreeItem::TestFunctionOrSet && index.parent().data().toString() != unnamed)
|| (type == TestTreeItem::TestClass && index.data().toString() != unnamed) || (type == TestTreeItem::TestCase && index.data().toString() != unnamed)
|| (type == TestTreeItem::TestDataTag) || (type == TestTreeItem::TestDataTag)) {
|| (type == TestTreeItem::GTestCase)
|| (type == TestTreeItem::GTestCaseParameterized)
|| (type == TestTreeItem::GTestName)) {
runThisTest = new QAction(tr("Run This Test"), &menu); runThisTest = new QAction(tr("Run This Test"), &menu);
runThisTest->setEnabled(enabled); runThisTest->setEnabled(enabled);
connect(runThisTest, &QAction::triggered, connect(runThisTest, &QAction::triggered,
@@ -259,11 +256,8 @@ void TestNavigationWidget::onRunThisTestTriggered()
return; return;
TestTreeItem *item = static_cast<TestTreeItem *>(sourceIndex.internalPointer()); TestTreeItem *item = static_cast<TestTreeItem *>(sourceIndex.internalPointer());
if (item->type() == TestTreeItem::TestClass || item->type() == TestTreeItem::TestFunction if (item->type() == TestTreeItem::TestCase || item->type() == TestTreeItem::TestFunctionOrSet
|| item->type() == TestTreeItem::TestDataTag || item->type() == TestTreeItem::TestDataTag) {
|| item->type() == TestTreeItem::GTestCase
|| item->type() == TestTreeItem::GTestCaseParameterized
|| item->type() == TestTreeItem::GTestName) {
if (TestConfiguration *configuration = m_model->getTestConfiguration(item)) { if (TestConfiguration *configuration = m_model->getTestConfiguration(item)) {
TestRunner *runner = TestRunner::instance(); TestRunner *runner = TestRunner::instance();
runner->setSelectedTests( {configuration} ); runner->setSelectedTests( {configuration} );

View File

@@ -42,20 +42,9 @@ TestTreeItem::TestTreeItem(const QString &name, const QString &filePath, Type ty
m_filePath(filePath), m_filePath(filePath),
m_type(type), m_type(type),
m_line(0), m_line(0),
m_state(Enabled),
m_markedForRemoval(false) m_markedForRemoval(false)
{ {
switch (m_type) { m_checked = (m_type == TestCase || m_type == TestFunctionOrSet) ? Qt::Checked : Qt::Unchecked;
case TestClass:
case TestFunction:
case GTestCase:
case GTestCaseParameterized:
case GTestName:
m_checked = Qt::Checked;
break;
default:
m_checked = Qt::Unchecked;
}
} }
static QIcon testTreeIcon(TestTreeItem::Type type) static QIcon testTreeIcon(TestTreeItem::Type type)
@@ -66,8 +55,6 @@ static QIcon testTreeIcon(TestTreeItem::Type type)
QIcon(QLatin1String(":/images/func.png")), QIcon(QLatin1String(":/images/func.png")),
QIcon(QLatin1String(":/images/data.png")) QIcon(QLatin1String(":/images/data.png"))
}; };
if (type == TestTreeItem::GTestCase || type == TestTreeItem::GTestCaseParameterized)
return icons[1];
if (int(type) >= int(sizeof icons / sizeof *icons)) if (int(type) >= int(sizeof icons / sizeof *icons))
return icons[2]; return icons[2];
@@ -82,12 +69,10 @@ QVariant TestTreeItem::data(int /*column*/, int role) const
return QString(m_name + QObject::tr(" (none)")); return QString(m_name + QObject::tr(" (none)"));
else if (m_name.isEmpty()) else if (m_name.isEmpty())
return QObject::tr(Constants::UNNAMED_QUICKTESTS); return QObject::tr(Constants::UNNAMED_QUICKTESTS);
else if (m_type == GTestCaseParameterized)
return QString(m_name + QObject::tr(" [parameterized]"));
else else
return m_name; return m_name;
case Qt::ToolTipRole: case Qt::ToolTipRole:
if (m_type == TestClass && m_name.isEmpty()) { if (m_type == TestCase && m_name.isEmpty()) {
return QObject::tr("<p>Give all test cases a name to ensure correct behavior " return QObject::tr("<p>Give all test cases a name to ensure correct behavior "
"when running test cases and to be able to select them.</p>"); "when running test cases and to be able to select them.</p>");
} }
@@ -101,12 +86,9 @@ QVariant TestTreeItem::data(int /*column*/, int role) const
case TestSpecialFunction: case TestSpecialFunction:
case TestDataTag: case TestDataTag:
return QVariant(); return QVariant();
case TestClass: case TestCase:
case GTestCase:
case GTestCaseParameterized:
return m_name.isEmpty() ? QVariant() : checked(); return m_name.isEmpty() ? QVariant() : checked();
case TestFunction: case TestFunctionOrSet:
case GTestName:
if (parentItem() && parentItem()->name().isEmpty()) if (parentItem() && parentItem()->name().isEmpty())
return QVariant(); return QVariant();
return checked(); return checked();
@@ -123,17 +105,15 @@ QVariant TestTreeItem::data(int /*column*/, int role) const
case TestDataFunction: case TestDataFunction:
case TestSpecialFunction: case TestSpecialFunction:
return true; return true;
case TestClass: case TestCase:
return m_name.isEmpty(); return m_name.isEmpty();
case TestFunction: case TestFunctionOrSet:
return parentItem() ? parentItem()->name().isEmpty() : false; return parentItem() ? parentItem()->name().isEmpty() : false;
default: default:
return false; return false;
} }
case TypeRole: case TypeRole:
return m_type; return m_type;
case StateRole:
return (int)m_state;
} }
return QVariant(); return QVariant();
} }
@@ -171,22 +151,6 @@ bool TestTreeItem::modifyDataTagContent(const QString &fileName,
return hasBeenModified; return hasBeenModified;
} }
bool TestTreeItem::modifyGTestSetContent(const QString &fileName, const QString &referencingFile,
const TestCodeLocationAndType &location)
{
bool hasBeenModified = modifyFilePath(fileName);
if (m_referencingFile != referencingFile) {
m_referencingFile = referencingFile;
hasBeenModified = true;
}
hasBeenModified |= modifyLineAndColumn(location.m_line, location.m_column);
if (m_state != location.m_state) {
m_state = location.m_state;
hasBeenModified = true;
}
return hasBeenModified;
}
bool TestTreeItem::modifyLineAndColumn(unsigned line, unsigned column) bool TestTreeItem::modifyLineAndColumn(unsigned line, unsigned column)
{ {
bool hasBeenModified = false; bool hasBeenModified = false;
@@ -204,15 +168,12 @@ bool TestTreeItem::modifyLineAndColumn(unsigned line, unsigned column)
void TestTreeItem::setChecked(const Qt::CheckState checkState) void TestTreeItem::setChecked(const Qt::CheckState checkState)
{ {
switch (m_type) { switch (m_type) {
case TestFunction: case TestFunctionOrSet: {
case GTestName: {
m_checked = (checkState == Qt::Unchecked ? Qt::Unchecked : Qt::Checked); m_checked = (checkState == Qt::Unchecked ? Qt::Unchecked : Qt::Checked);
parentItem()->revalidateCheckState(); parentItem()->revalidateCheckState();
break; break;
} }
case TestClass: case TestCase: {
case GTestCase:
case GTestCaseParameterized: {
Qt::CheckState usedState = (checkState == Qt::Unchecked ? Qt::Unchecked : Qt::Checked); Qt::CheckState usedState = (checkState == Qt::Unchecked ? Qt::Unchecked : Qt::Checked);
for (int row = 0, count = childCount(); row < count; ++row) for (int row = 0, count = childCount(); row < count; ++row)
childItem(row)->setChecked(usedState); childItem(row)->setChecked(usedState);
@@ -226,11 +187,8 @@ void TestTreeItem::setChecked(const Qt::CheckState checkState)
Qt::CheckState TestTreeItem::checked() const Qt::CheckState TestTreeItem::checked() const
{ {
switch (m_type) { switch (m_type) {
case TestClass: case TestCase:
case TestFunction: case TestFunctionOrSet:
case GTestCase:
case GTestCaseParameterized:
case GTestName:
return m_checked; return m_checked;
case TestDataFunction: case TestDataFunction:
case TestSpecialFunction: case TestSpecialFunction:
@@ -271,11 +229,10 @@ TestTreeItem *TestTreeItem::findChildByName(const QString &name)
}); });
} }
TestTreeItem *TestTreeItem::findChildByFiles(const QString &filePath, TestTreeItem *TestTreeItem::findChildByFile(const QString &filePath)
const QString &referencingFile)
{ {
return findChildBy([filePath, referencingFile](const TestTreeItem *other) -> bool { return findChildBy([filePath](const TestTreeItem *other) -> bool {
return other->filePath() == filePath && other->referencingFile() == referencingFile; return other->filePath() == filePath;
}); });
} }
@@ -286,16 +243,6 @@ TestTreeItem *TestTreeItem::findChildByNameAndFile(const QString &name, const QS
}); });
} }
TestTreeItem *TestTreeItem::findChildByNameTypeAndFile(const QString &name, TestTreeItem::Type type,
const QString &referencingFile)
{
return findChildBy([name, type, referencingFile](const TestTreeItem *other) -> bool {
return other->referencingFile() == referencingFile
&& other->name() == name
&& other->type() == type;
});
}
void TestTreeItem::revalidateCheckState() void TestTreeItem::revalidateCheckState()
{ {
if (childCount() == 0) if (childCount() == 0)
@@ -352,9 +299,8 @@ TestTreeItem *TestTreeItem::findChildBy(CompareFunction compare)
AutoTestTreeItem *AutoTestTreeItem::createTestItem(const TestParseResult &result) AutoTestTreeItem *AutoTestTreeItem::createTestItem(const TestParseResult &result)
{ {
AutoTestTreeItem *item = new AutoTestTreeItem(result.testCaseName, result.fileName, AutoTestTreeItem *item = new AutoTestTreeItem(result.testCaseName, result.fileName, TestCase);
TestTreeItem::TestClass); item->setProFile(result.proFile);
item->setReferencingFile(result.referencingFile);
item->setLine(result.line); item->setLine(result.line);
item->setColumn(result.column); item->setColumn(result.column);
@@ -392,9 +338,8 @@ AutoTestTreeItem *AutoTestTreeItem::createDataTagItem(const QString &fileName,
QuickTestTreeItem *QuickTestTreeItem::createTestItem(const TestParseResult &result) QuickTestTreeItem *QuickTestTreeItem::createTestItem(const TestParseResult &result)
{ {
QuickTestTreeItem *item = new QuickTestTreeItem(result.testCaseName, result.fileName, QuickTestTreeItem *item = new QuickTestTreeItem(result.testCaseName, result.fileName, TestCase);
TestTreeItem::TestClass); item->setProFile(result.proFile);
item->setReferencingFile(result.referencingFile);
item->setLine(result.line); item->setLine(result.line);
item->setColumn(result.column); item->setColumn(result.column);
foreach (const QString &functionName, result.functions.keys()) foreach (const QString &functionName, result.functions.keys())
@@ -413,7 +358,7 @@ QuickTestTreeItem *QuickTestTreeItem::createFunctionItem(const QString &function
QuickTestTreeItem *QuickTestTreeItem::createUnnamedQuickTestItem(const TestParseResult &result) QuickTestTreeItem *QuickTestTreeItem::createUnnamedQuickTestItem(const TestParseResult &result)
{ {
QuickTestTreeItem *item = new QuickTestTreeItem(QString(), QString(), TestTreeItem::TestClass); QuickTestTreeItem *item = new QuickTestTreeItem(QString(), QString(), TestCase);
foreach (const QString &functionName, result.functions.keys()) foreach (const QString &functionName, result.functions.keys())
item->appendChild(createUnnamedQuickFunctionItem(functionName, result)); item->appendChild(createUnnamedQuickFunctionItem(functionName, result));
return item; return item;
@@ -426,15 +371,16 @@ QuickTestTreeItem *QuickTestTreeItem::createUnnamedQuickFunctionItem(const QStri
QuickTestTreeItem *item = new QuickTestTreeItem(functionName, location.m_name, location.m_type); QuickTestTreeItem *item = new QuickTestTreeItem(functionName, location.m_name, location.m_type);
item->setLine(location.m_line); item->setLine(location.m_line);
item->setColumn(location.m_column); item->setColumn(location.m_column);
item->setReferencingFile(result.referencingFile); item->setProFile(result.proFile);
return item; return item;
} }
GoogleTestTreeItem *GoogleTestTreeItem::createTestItem(const TestParseResult &result) GoogleTestTreeItem *GoogleTestTreeItem::createTestItem(const TestParseResult &result)
{ {
GoogleTestTreeItem *item = new GoogleTestTreeItem(result.testCaseName, QString(), GoogleTestTreeItem *item = new GoogleTestTreeItem(result.testCaseName, QString(), TestCase);
result.parameterized ? TestTreeItem::GTestCaseParameterized : TestTreeItem::GTestCase); item->setProFile(result.proFile);
item->setReferencingFile(result.referencingFile); if (result.parameterized)
item->setState(Parameterized);
foreach (const TestCodeLocationAndType &location, result.dataTagsOrTestSets.first()) foreach (const TestCodeLocationAndType &location, result.dataTagsOrTestSets.first())
item->appendChild(createTestSetItem(result, location)); item->appendChild(createTestSetItem(result, location));
return item; return item;
@@ -445,12 +391,55 @@ GoogleTestTreeItem *GoogleTestTreeItem::createTestSetItem(const TestParseResult
{ {
GoogleTestTreeItem *item = new GoogleTestTreeItem(location.m_name, result.fileName, GoogleTestTreeItem *item = new GoogleTestTreeItem(location.m_name, result.fileName,
location.m_type); location.m_type);
item->setState(location.m_state); item->setStates(location.m_state);
item->setLine(location.m_line); item->setLine(location.m_line);
item->setColumn(location.m_column); item->setColumn(location.m_column);
item->setReferencingFile(result.referencingFile); item->setProFile(result.proFile);
return item; return item;
} }
QVariant GoogleTestTreeItem::data(int column, int role) const
{
switch (role) {
case Qt::DisplayRole:
if (type() == TestCase) {
if (m_state & Parameterized)
return QString(name() + QObject::tr(" [parameterized]"));
return name();
}
break;
case StateRole:
return (int)m_state;
default:
break;
}
return TestTreeItem::data(column, role);
}
bool GoogleTestTreeItem::modifyTestSetContent(const QString &fileName,
const TestCodeLocationAndType &location)
{
bool hasBeenModified = modifyFilePath(fileName);
hasBeenModified |= modifyLineAndColumn(location.m_line, location.m_column);
if (m_state != location.m_state) {
m_state = location.m_state;
hasBeenModified = true;
}
return hasBeenModified;
}
TestTreeItem *GoogleTestTreeItem::findChildByNameStateAndFile(const QString &name,
GoogleTestTreeItem::TestStates state,
const QString &referencingFile)
{
return findChildBy([name, state, referencingFile](const TestTreeItem *other) -> bool {
GoogleTestTreeItem *gtestItem = const_cast<TestTreeItem *>(other)->asGoogleTestTreeItem();
return other->proFile() == referencingFile
&& other->name() == name
&& gtestItem->state() == state;
});
}
} // namespace Internal } // namespace Internal
} // namespace Autotest } // namespace Autotest

View File

@@ -57,25 +57,13 @@ public:
enum Type enum Type
{ {
Root, Root,
TestClass, TestCase,
TestFunction, TestFunctionOrSet,
TestDataTag, TestDataTag,
TestDataFunction, TestDataFunction,
TestSpecialFunction, TestSpecialFunction
GTestCase,
GTestCaseParameterized,
GTestName
}; };
enum TestState
{
Enabled = 0x00,
Disabled = 0x01,
};
Q_FLAGS(TestState)
Q_DECLARE_FLAGS(TestStates, TestState)
TestTreeItem(const QString &name = QString(), const QString &filePath = QString(), TestTreeItem(const QString &name = QString(), const QString &filePath = QString(),
Type type = Root); Type type = Root);
@@ -84,8 +72,6 @@ public:
bool modifyTestCaseContent(const QString &name, unsigned line, unsigned column); bool modifyTestCaseContent(const QString &name, unsigned line, unsigned column);
bool modifyTestFunctionContent(const TestCodeLocationAndType &location); bool modifyTestFunctionContent(const TestCodeLocationAndType &location);
bool modifyDataTagContent(const QString &fileName, const TestCodeLocationAndType &location); bool modifyDataTagContent(const QString &fileName, const TestCodeLocationAndType &location);
bool modifyGTestSetContent(const QString &fileName, const QString &referencingFile,
const TestCodeLocationAndType &location);
bool modifyLineAndColumn(unsigned line, unsigned column); bool modifyLineAndColumn(unsigned line, unsigned column);
const QString name() const { return m_name; } const QString name() const { return m_name; }
@@ -96,13 +82,11 @@ public:
unsigned line() const { return m_line; } unsigned line() const { return m_line; }
void setColumn(unsigned column) { m_column = column; } void setColumn(unsigned column) { m_column = column; }
unsigned column() const { return m_column; } unsigned column() const { return m_column; }
QString referencingFile() const { return m_referencingFile; } QString proFile() const { return m_proFile; }
void setReferencingFile(const QString &referencingFile) { m_referencingFile = referencingFile; } void setProFile(const QString &proFile) { m_proFile = proFile; }
void setChecked(const Qt::CheckState checked); void setChecked(const Qt::CheckState checked);
Qt::CheckState checked() const; Qt::CheckState checked() const;
Type type() const { return m_type; } Type type() const { return m_type; }
void setState(TestStates states) { m_state = states; }
TestStates state() const { return m_state; }
void markForRemoval(bool mark); void markForRemoval(bool mark);
void markForRemovalRecursively(bool mark); void markForRemovalRecursively(bool mark);
bool markedForRemoval() const { return m_markedForRemoval; } bool markedForRemoval() const { return m_markedForRemoval; }
@@ -110,48 +94,35 @@ public:
TestTreeItem *childItem(int row) const; TestTreeItem *childItem(int row) const;
TestTreeItem *findChildByName(const QString &name); TestTreeItem *findChildByName(const QString &name);
TestTreeItem *findChildByFiles(const QString &filePath, const QString &referencingFile); TestTreeItem *findChildByFile(const QString &filePath);
TestTreeItem *findChildByNameAndFile(const QString &name, const QString &filePath); TestTreeItem *findChildByNameAndFile(const QString &name, const QString &filePath);
TestTreeItem *findChildByNameTypeAndFile(const QString &name,
TestTreeItem::Type type, const QString &referencingFile);
virtual AutoTestTreeItem *asAutoTestTreeItem() { return 0; } virtual AutoTestTreeItem *asAutoTestTreeItem() { return 0; }
virtual QuickTestTreeItem *asQuickTestTreeItem() { return 0; } virtual QuickTestTreeItem *asQuickTestTreeItem() { return 0; }
virtual GoogleTestTreeItem *asGoogleTestTreeItem() { return 0; } virtual GoogleTestTreeItem *asGoogleTestTreeItem() { return 0; }
virtual const AutoTestTreeItem *asAutoTestTreeItem() const { return 0; }
virtual const QuickTestTreeItem *asQuickTestTreeItem() const { return 0; }
virtual const GoogleTestTreeItem *asGoogleTestTreeItem() const { return 0; }
protected:
bool modifyFilePath(const QString &filePath);
typedef std::function<bool(const TestTreeItem *)> CompareFunction;
TestTreeItem *findChildBy(CompareFunction compare);
private: private:
void revalidateCheckState(); void revalidateCheckState();
bool modifyFilePath(const QString &filePath);
bool modifyName(const QString &name); bool modifyName(const QString &name);
typedef std::function<bool(const TestTreeItem *)> CompareFunction;
TestTreeItem *findChildBy(CompareFunction compare);
QString m_name; QString m_name;
QString m_filePath; QString m_filePath;
Qt::CheckState m_checked; Qt::CheckState m_checked;
Type m_type; Type m_type;
unsigned m_line; unsigned m_line;
unsigned m_column; unsigned m_column;
QString m_referencingFile; QString m_proFile;
TestStates m_state;
bool m_markedForRemoval; bool m_markedForRemoval;
}; };
struct TestCodeLocationAndType {
QString m_name; // tag name for m_type == TEST_DATATAG, file name for other values
unsigned m_line;
unsigned m_column;
TestTreeItem::Type m_type;
TestTreeItem::TestStates m_state;
};
struct GTestCaseSpec
{
QString testCaseName;
bool parameterized;
};
typedef QVector<TestCodeLocationAndType> TestCodeLocationList; typedef QVector<TestCodeLocationAndType> TestCodeLocationList;
class AutoTestTreeItem : public TestTreeItem class AutoTestTreeItem : public TestTreeItem
@@ -161,6 +132,7 @@ public:
Type type = Root) : TestTreeItem(name, filePath, type) {} Type type = Root) : TestTreeItem(name, filePath, type) {}
virtual AutoTestTreeItem *asAutoTestTreeItem() override { return this; } virtual AutoTestTreeItem *asAutoTestTreeItem() override { return this; }
virtual const AutoTestTreeItem *asAutoTestTreeItem() const override { return this; }
static AutoTestTreeItem *createTestItem(const TestParseResult &result); static AutoTestTreeItem *createTestItem(const TestParseResult &result);
static AutoTestTreeItem *createFunctionItem(const QString &functionName, static AutoTestTreeItem *createFunctionItem(const QString &functionName,
@@ -177,6 +149,7 @@ public:
Type type = Root) : TestTreeItem(name, filePath, type) {} Type type = Root) : TestTreeItem(name, filePath, type) {}
virtual QuickTestTreeItem *asQuickTestTreeItem() override { return this; } virtual QuickTestTreeItem *asQuickTestTreeItem() override { return this; }
virtual const QuickTestTreeItem *asQuickTestTreeItem() const override { return this; }
static QuickTestTreeItem *createTestItem(const TestParseResult &result); static QuickTestTreeItem *createTestItem(const TestParseResult &result);
static QuickTestTreeItem *createFunctionItem(const QString &functionName, static QuickTestTreeItem *createFunctionItem(const QString &functionName,
@@ -189,15 +162,52 @@ public:
class GoogleTestTreeItem : public TestTreeItem class GoogleTestTreeItem : public TestTreeItem
{ {
public: public:
enum TestState
{
Enabled = 0x00,
Disabled = 0x01,
Parameterized = 0x02,
};
Q_FLAGS(TestState)
Q_DECLARE_FLAGS(TestStates, TestState)
GoogleTestTreeItem(const QString &name = QString(), const QString &filePath = QString(), GoogleTestTreeItem(const QString &name = QString(), const QString &filePath = QString(),
Type type = Root) : TestTreeItem(name, filePath, type) {} Type type = Root) : TestTreeItem(name, filePath, type), m_state(Enabled) {}
virtual GoogleTestTreeItem *asGoogleTestTreeItem() override { return this; } virtual GoogleTestTreeItem *asGoogleTestTreeItem() override { return this; }
virtual const GoogleTestTreeItem *asGoogleTestTreeItem() const override { return this; }
static GoogleTestTreeItem *createTestItem(const TestParseResult &result); static GoogleTestTreeItem *createTestItem(const TestParseResult &result);
static GoogleTestTreeItem *createTestSetItem(const TestParseResult &result, static GoogleTestTreeItem *createTestSetItem(const TestParseResult &result,
const TestCodeLocationAndType &location); const TestCodeLocationAndType &location);
QVariant data(int column, int role) const override;
void setStates(TestStates states) { m_state = states; }
void setState(TestState state) { m_state |= state; }
TestStates state() const { return m_state; }
bool modifyTestSetContent(const QString &fileName, const TestCodeLocationAndType &location);
TestTreeItem *findChildByNameStateAndFile(const QString &name,
GoogleTestTreeItem::TestStates state,
const QString &proFile);
private:
GoogleTestTreeItem::TestStates m_state;
};
struct TestCodeLocationAndType {
QString m_name; // tag name for m_type == TEST_DATATAG, file name for other values
unsigned m_line;
unsigned m_column;
TestTreeItem::Type m_type;
GoogleTestTreeItem::TestStates m_state;
};
struct GTestCaseSpec
{
QString testCaseName;
bool parameterized;
}; };
} // namespace Internal } // namespace Internal

View File

@@ -71,7 +71,7 @@ void TestTreeItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
} }
// paint disabled googletests in gray // paint disabled googletests in gray
if (index.data(StateRole).toInt() & TestTreeItem::Disabled) if (index.data(StateRole).toInt() & GoogleTestTreeItem::Disabled)
opt.palette.setColor(QPalette::Text, QColor(0xa0, 0xa0, 0xa0)); opt.palette.setColor(QPalette::Text, QColor(0xa0, 0xa0, 0xa0));
QStyledItemDelegate::paint(painter, opt, index); QStyledItemDelegate::paint(painter, opt, index);

View File

@@ -44,43 +44,11 @@
namespace Autotest { namespace Autotest {
namespace Internal { namespace Internal {
class ReferencingFilesFinder : public Utils::TreeItemVisitor
{
public:
ReferencingFilesFinder() {}
bool preVisit(Utils::TreeItem *item) override
{
// 0 = invisible root, 1 = main categories, 2 = test cases, 3 = test functions
return item->level() < 4;
}
void visit(Utils::TreeItem *item) override
{
// skip invisible root item
if (!item->parent())
return;
if (auto testItem = static_cast<TestTreeItem *>(item)) {
if (!testItem->filePath().isEmpty() && !testItem->referencingFile().isEmpty())
m_referencingFiles.insert(testItem->filePath(), testItem->referencingFile());
}
}
QMap<QString, QString> referencingFiles() const { return m_referencingFiles; }
private:
QMap<QString, QString> m_referencingFiles;
};
/***********************************************************************************************/
TestTreeModel::TestTreeModel(QObject *parent) : TestTreeModel::TestTreeModel(QObject *parent) :
TreeModel(parent), TreeModel(parent),
m_autoTestRootItem(new TestTreeItem(tr("Auto Tests"), QString(), TestTreeItem::Root)), m_autoTestRootItem(new AutoTestTreeItem(tr("Auto Tests"), QString(), TestTreeItem::Root)),
m_quickTestRootItem(new TestTreeItem(tr("Qt Quick Tests"), QString(), TestTreeItem::Root)), m_quickTestRootItem(new QuickTestTreeItem(tr("Qt Quick Tests"), QString(), TestTreeItem::Root)),
m_googleTestRootItem(new TestTreeItem(tr("Google Tests"), QString(), TestTreeItem::Root)), m_googleTestRootItem(new GoogleTestTreeItem(tr("Google Tests"), QString(), TestTreeItem::Root)),
m_parser(new TestCodeParser(this)), m_parser(new TestCodeParser(this)),
m_connectionsInitialized(false) m_connectionsInitialized(false)
{ {
@@ -174,14 +142,11 @@ bool TestTreeModel::setData(const QModelIndex &index, const QVariant &value, int
emit dataChanged(index, index); emit dataChanged(index, index);
if (role == Qt::CheckStateRole) { if (role == Qt::CheckStateRole) {
switch (item->type()) { switch (item->type()) {
case TestTreeItem::TestClass: case TestTreeItem::TestCase:
case TestTreeItem::GTestCase:
case TestTreeItem::GTestCaseParameterized:
if (item->childCount() > 0) if (item->childCount() > 0)
emit dataChanged(index.child(0, 0), index.child(item->childCount() - 1, 0)); emit dataChanged(index.child(0, 0), index.child(item->childCount() - 1, 0));
break; break;
case TestTreeItem::TestFunction: case TestTreeItem::TestFunctionOrSet:
case TestTreeItem::GTestName:
emit dataChanged(index.parent(), index.parent()); emit dataChanged(index.parent(), index.parent());
break; break;
default: // avoid warning regarding unhandled enum member default: // avoid warning regarding unhandled enum member
@@ -200,14 +165,11 @@ Qt::ItemFlags TestTreeModel::flags(const QModelIndex &index) const
TestTreeItem *item = static_cast<TestTreeItem *>(itemForIndex(index)); TestTreeItem *item = static_cast<TestTreeItem *>(itemForIndex(index));
switch(item->type()) { switch(item->type()) {
case TestTreeItem::TestClass: case TestTreeItem::TestCase:
case TestTreeItem::GTestCase:
case TestTreeItem::GTestCaseParameterized:
if (item->name().isEmpty()) if (item->name().isEmpty())
return Qt::ItemIsEnabled | Qt::ItemIsSelectable; return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsTristate | Qt::ItemIsUserCheckable; return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsTristate | Qt::ItemIsUserCheckable;
case TestTreeItem::TestFunction: case TestTreeItem::TestFunctionOrSet:
case TestTreeItem::GTestName:
if (item->parentItem()->name().isEmpty()) if (item->parentItem()->name().isEmpty())
return Qt::ItemIsEnabled | Qt::ItemIsSelectable; return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable; return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable;
@@ -241,55 +203,51 @@ QList<TestConfiguration *> TestTreeModel::getAllTestCases() const
TestConfiguration *tc = new TestConfiguration(child->name(), QStringList(), TestConfiguration *tc = new TestConfiguration(child->name(), QStringList(),
child->childCount()); child->childCount());
tc->setMainFilePath(child->filePath()); tc->setProFile(child->proFile());
tc->setProject(project); tc->setProject(project);
result << tc; result << tc;
} }
// get all Quick Tests // get all Quick Tests
QMap<QString, int> foundMains; QMap<QString, int> foundProFiles;
for (int row = 0, count = m_quickTestRootItem->childCount(); row < count; ++row) { for (int row = 0, count = m_quickTestRootItem->childCount(); row < count; ++row) {
const TestTreeItem *child = m_quickTestRootItem->childItem(row); const TestTreeItem *child = m_quickTestRootItem->childItem(row);
// unnamed Quick Tests must be handled separately // unnamed Quick Tests must be handled separately
if (child->name().isEmpty()) { if (child->name().isEmpty()) {
for (int childRow = 0, ccount = child->childCount(); childRow < ccount; ++ childRow) { for (int childRow = 0, ccount = child->childCount(); childRow < ccount; ++ childRow) {
const TestTreeItem *grandChild = child->childItem(childRow); const TestTreeItem *grandChild = child->childItem(childRow);
const QString mainFile = grandChild->referencingFile(); const QString &proFile = grandChild->proFile();
foundMains.insert(mainFile, foundMains.contains(mainFile) foundProFiles.insert(proFile, foundProFiles[proFile] + 1);
? foundMains.value(mainFile) + 1 : 1);
} }
continue; continue;
} }
// named Quick Test // named Quick Test
const QString mainFile = child->referencingFile(); const QString &proFile = child->proFile();
foundMains.insert(mainFile, foundMains.contains(mainFile) foundProFiles.insert(proFile, foundProFiles[proFile] + child->childCount());
? foundMains.value(mainFile) + child->childCount()
: child->childCount());
} }
// create TestConfiguration for each main // create TestConfiguration for each project file
foreach (const QString &mainFile, foundMains.keys()) { foreach (const QString &proFile, foundProFiles.keys()) {
TestConfiguration *tc = new TestConfiguration(QString(), QStringList(), TestConfiguration *tc = new TestConfiguration(QString(), QStringList(),
foundMains.value(mainFile)); foundProFiles.value(proFile));
tc->setMainFilePath(mainFile); tc->setProFile(proFile);
tc->setProject(project); tc->setProject(project);
result << tc; result << tc;
} }
foundMains.clear(); foundProFiles.clear();
// get all Google Tests // get all Google Tests
for (int row = 0, count = m_googleTestRootItem->childCount(); row < count; ++row) { for (int row = 0, count = m_googleTestRootItem->childCount(); row < count; ++row) {
const TestTreeItem *child = m_googleTestRootItem->childItem(row); const TestTreeItem *child = m_googleTestRootItem->childItem(row);
for (int childRow = 0, childCount = child->childCount(); childRow < childCount; ++childRow) { for (int childRow = 0, childCount = child->childCount(); childRow < childCount; ++childRow) {
const QString &proFilePath = child->childItem(childRow)->referencingFile(); const QString &proFilePath = child->childItem(childRow)->proFile();
foundMains.insert(proFilePath, foundMains.contains(proFilePath) foundProFiles.insert(proFilePath, foundProFiles[proFilePath] + 1);
? foundMains.value(proFilePath) + 1 : 1);
} }
} }
foreach (const QString &proFile, foundMains.keys()) { foreach (const QString &proFile, foundProFiles.keys()) {
TestConfiguration *tc = new TestConfiguration(QString(), QStringList(), TestConfiguration *tc = new TestConfiguration(QString(), QStringList(),
foundMains.value(proFile)); foundProFiles.value(proFile));
tc->setProFile(proFile); tc->setProFile(proFile);
tc->setProject(project); tc->setProject(project);
tc->setTestType(TestTypeGTest); tc->setTestType(TestTypeGTest);
@@ -316,7 +274,7 @@ QList<TestConfiguration *> TestTreeModel::getSelectedTests() const
continue; continue;
case Qt::Checked: case Qt::Checked:
testConfiguration = new TestConfiguration(child->name(), QStringList(), child->childCount()); testConfiguration = new TestConfiguration(child->name(), QStringList(), child->childCount());
testConfiguration->setMainFilePath(child->filePath()); testConfiguration->setProFile(child->proFile());
testConfiguration->setProject(project); testConfiguration->setProject(project);
result << testConfiguration; result << testConfiguration;
continue; continue;
@@ -332,7 +290,7 @@ QList<TestConfiguration *> TestTreeModel::getSelectedTests() const
} }
testConfiguration = new TestConfiguration(childName, testCases); testConfiguration = new TestConfiguration(childName, testCases);
testConfiguration->setMainFilePath(child->filePath()); testConfiguration->setProFile(child->proFile());
testConfiguration->setProject(project); testConfiguration->setProject(project);
result << testConfiguration; result << testConfiguration;
} }
@@ -342,24 +300,24 @@ QList<TestConfiguration *> TestTreeModel::getSelectedTests() const
// on and on and on... // on and on and on...
// TODO: do this later on for Auto Tests as well to support strange setups? or redo the model // TODO: do this later on for Auto Tests as well to support strange setups? or redo the model
QMap<QString, TestConfiguration *> foundMains; QMap<QString, TestConfiguration *> foundProFiles;
if (TestTreeItem *unnamed = unnamedQuickTests()) { if (TestTreeItem *unnamed = unnamedQuickTests()) {
for (int childRow = 0, ccount = unnamed->childCount(); childRow < ccount; ++ childRow) { for (int childRow = 0, ccount = unnamed->childCount(); childRow < ccount; ++ childRow) {
const TestTreeItem *grandChild = unnamed->childItem(childRow); const TestTreeItem *grandChild = unnamed->childItem(childRow);
const QString mainFile = grandChild->referencingFile(); const QString &proFile = grandChild->proFile();
if (foundMains.contains(mainFile)) { if (foundProFiles.contains(proFile)) {
QTC_ASSERT(testConfiguration, QTC_ASSERT(testConfiguration,
qWarning() << "Illegal state (unnamed Quick Test listed as named)"; qWarning() << "Illegal state (unnamed Quick Test listed as named)";
return QList<TestConfiguration *>()); return QList<TestConfiguration *>());
foundMains[mainFile]->setTestCaseCount(testConfiguration->testCaseCount() + 1); foundProFiles[proFile]->setTestCaseCount(testConfiguration->testCaseCount() + 1);
} else { } else {
testConfiguration = new TestConfiguration(QString(), QStringList()); testConfiguration = new TestConfiguration(QString(), QStringList());
testConfiguration->setTestCaseCount(1); testConfiguration->setTestCaseCount(1);
testConfiguration->setUnnamedOnly(true); testConfiguration->setUnnamedOnly(true);
testConfiguration->setMainFilePath(mainFile); testConfiguration->setProFile(proFile);
testConfiguration->setProject(project); testConfiguration->setProject(project);
foundMains.insert(mainFile, testConfiguration); foundProFiles.insert(proFile, testConfiguration);
} }
} }
} }
@@ -381,13 +339,13 @@ QList<TestConfiguration *> TestTreeModel::getSelectedTests() const
int grandChildCount = child->childCount(); int grandChildCount = child->childCount();
for (int grandChildRow = 0; grandChildRow < grandChildCount; ++grandChildRow) { for (int grandChildRow = 0; grandChildRow < grandChildCount; ++grandChildRow) {
const TestTreeItem *grandChild = child->childItem(grandChildRow); const TestTreeItem *grandChild = child->childItem(grandChildRow);
if (grandChild->type() != TestTreeItem::TestFunction) if (grandChild->type() != TestTreeItem::TestFunctionOrSet)
continue; continue;
testFunctions << child->name() + QLatin1String("::") + grandChild->name(); testFunctions << child->name() + QLatin1String("::") + grandChild->name();
} }
TestConfiguration *tc; TestConfiguration *tc;
if (foundMains.contains(child->referencingFile())) { if (foundProFiles.contains(child->proFile())) {
tc = foundMains[child->referencingFile()]; tc = foundProFiles[child->proFile()];
QStringList oldFunctions(tc->testCases()); QStringList oldFunctions(tc->testCases());
// if oldFunctions.size() is 0 this test configuration is used for at least one // if oldFunctions.size() is 0 this test configuration is used for at least one
// unnamed test case // unnamed test case
@@ -400,15 +358,15 @@ QList<TestConfiguration *> TestTreeModel::getSelectedTests() const
} }
} else { } else {
tc = new TestConfiguration(QString(), testFunctions); tc = new TestConfiguration(QString(), testFunctions);
tc->setMainFilePath(child->referencingFile()); tc->setProFile(child->proFile());
tc->setProject(project); tc->setProject(project);
foundMains.insert(child->referencingFile(), tc); foundProFiles.insert(child->proFile(), tc);
} }
break; break;
} }
} }
foreach (TestConfiguration *config, foundMains.values()) { foreach (TestConfiguration *config, foundProFiles.values()) {
if (!config->unnamedOnly()) if (!config->unnamedOnly())
result << config; result << config;
else else
@@ -419,18 +377,18 @@ QList<TestConfiguration *> TestTreeModel::getSelectedTests() const
QMap<QString, QStringList> proFilesWithEnabledTestSets; QMap<QString, QStringList> proFilesWithEnabledTestSets;
for (int row = 0, count = m_googleTestRootItem->childCount(); row < count; ++row) { for (int row = 0, count = m_googleTestRootItem->childCount(); row < count; ++row) {
const TestTreeItem *child = m_googleTestRootItem->childItem(row); const auto child = m_googleTestRootItem->childItem(row)->asGoogleTestTreeItem();
if (child->checked() == Qt::Unchecked) // add this test name to disabled list ? if (child->checked() == Qt::Unchecked) // add this test name to disabled list ?
continue; continue;
int grandChildCount = child->childCount(); int grandChildCount = child->childCount();
for (int grandChildRow = 0; grandChildRow < grandChildCount; ++grandChildRow) { for (int grandChildRow = 0; grandChildRow < grandChildCount; ++grandChildRow) {
const TestTreeItem *grandChild = child->childItem(grandChildRow); const TestTreeItem *grandChild = child->childItem(grandChildRow);
const QString &proFile = grandChild->referencingFile(); const QString &proFile = grandChild->proFile();
QStringList enabled = proFilesWithEnabledTestSets.value(proFile); QStringList enabled = proFilesWithEnabledTestSets.value(proFile);
if (grandChild->checked() == Qt::Checked) { if (grandChild->checked() == Qt::Checked) {
QString testSpecifier = child->name() + QLatin1Char('.') + grandChild->name(); QString testSpecifier = child->name() + QLatin1Char('.') + grandChild->name();
if (child->type() == TestTreeItem::GTestCaseParameterized) { if (child->state() & GoogleTestTreeItem::Parameterized) {
testSpecifier.prepend(QLatin1String("*/")); testSpecifier.prepend(QLatin1String("*/"));
testSpecifier.append(QLatin1String("/*")); testSpecifier.append(QLatin1String("/*"));
} }
@@ -460,8 +418,8 @@ TestConfiguration *TestTreeModel::getTestConfiguration(const TestTreeItem *item)
TestConfiguration *config = 0; TestConfiguration *config = 0;
switch (item->type()) { switch (item->type()) {
case TestTreeItem::TestClass: { case TestTreeItem::TestCase: {
if (item->parent() == m_quickTestRootItem) { if (item->asQuickTestTreeItem()) {
// Quick Test TestCase // Quick Test TestCase
QStringList testFunctions; QStringList testFunctions;
for (int row = 0, count = item->childCount(); row < count; ++row) { for (int row = 0, count = item->childCount(); row < count; ++row) {
@@ -469,29 +427,52 @@ TestConfiguration *TestTreeModel::getTestConfiguration(const TestTreeItem *item)
+ item->childItem(row)->name(); + item->childItem(row)->name();
} }
config = new TestConfiguration(QString(), testFunctions); config = new TestConfiguration(QString(), testFunctions);
config->setMainFilePath(item->referencingFile()); config->setProFile(item->proFile());
config->setProject(project); config->setProject(project);
} else { } else if (item->asAutoTestTreeItem()) {
// normal auto test // normal auto test
config = new TestConfiguration(item->name(), QStringList(), item->childCount()); config = new TestConfiguration(item->name(), QStringList(), item->childCount());
config->setMainFilePath(item->filePath()); config->setProFile(item->proFile());
config->setProject(project); config->setProject(project);
} else if (auto gtestItem = item->asGoogleTestTreeItem()) {
QString testSpecifier = item->name() + QLatin1String(".*");
if (gtestItem->state() & GoogleTestTreeItem::Parameterized)
testSpecifier.prepend(QLatin1String("*/"));
if (int childCount = item->childCount()) {
config = new TestConfiguration(QString(), QStringList(testSpecifier));
config->setTestCaseCount(childCount);
config->setProFile(item->proFile());
config->setProject(project);
config->setTestType(TestTypeGTest);
}
} }
break; break;
} }
case TestTreeItem::TestFunction: { case TestTreeItem::TestFunctionOrSet: {
const TestTreeItem *parent = item->parentItem(); TestTreeItem *parent = item->parentItem();
if (parent->parent() == m_quickTestRootItem) { if (parent->asQuickTestTreeItem()) {
// it's a Quick Test function of a named TestCase // it's a Quick Test function of a named TestCase
QStringList testFunction(parent->name() + QLatin1String("::") + item->name()); QStringList testFunction(parent->name() + QLatin1String("::") + item->name());
config = new TestConfiguration(QString(), testFunction); config = new TestConfiguration(QString(), testFunction);
config->setMainFilePath(parent->referencingFile()); config->setProFile(parent->proFile());
config->setProject(project); config->setProject(project);
} else { } else if (parent->asAutoTestTreeItem()){
// normal auto test // normal auto test
config = new TestConfiguration(parent->name(), QStringList() << item->name()); config = new TestConfiguration(parent->name(), QStringList() << item->name());
config->setMainFilePath(parent->filePath()); config->setProFile(parent->proFile());
config->setProject(project); config->setProject(project);
} else if (auto gtestParent = parent->asGoogleTestTreeItem()) {
QString testSpecifier = parent->name() + QLatin1Char('.') + item->name();
if (gtestParent->state() & GoogleTestTreeItem::Parameterized) {
testSpecifier.prepend(QLatin1String("*/"));
testSpecifier.append(QLatin1String("/*"));
}
config = new TestConfiguration(QString(), QStringList(testSpecifier));
config->setProFile(item->proFile());
config->setProject(project);
config->setTestType(TestTypeGTest);
} }
break; break;
} }
@@ -502,39 +483,10 @@ TestConfiguration *TestTreeModel::getTestConfiguration(const TestTreeItem *item)
return 0; return 0;
const QString functionWithTag = function->name() + QLatin1Char(':') + item->name(); const QString functionWithTag = function->name() + QLatin1Char(':') + item->name();
config = new TestConfiguration(parent->name(), QStringList() << functionWithTag); config = new TestConfiguration(parent->name(), QStringList() << functionWithTag);
config->setMainFilePath(parent->filePath()); config->setProFile(parent->proFile());
config->setProject(project); config->setProject(project);
break; break;
} }
case TestTreeItem::GTestCase:
case TestTreeItem::GTestCaseParameterized: {
QString testSpecifier = item->name() + QLatin1String(".*");
if (item->type() == TestTreeItem::GTestCaseParameterized)
testSpecifier.prepend(QLatin1String("*/"));
if (int childCount = item->childCount()) {
config = new TestConfiguration(QString(), QStringList(testSpecifier));
config->setTestCaseCount(childCount);
config->setProFile(item->childItem(0)->referencingFile());
config->setProject(project);
config->setTestType(TestTypeGTest);
}
break;
}
case TestTreeItem::GTestName: {
const TestTreeItem *parent = item->parentItem();
QString testSpecifier = parent->name() + QLatin1Char('.') + item->name();
if (parent->type() == TestTreeItem::GTestCaseParameterized) {
testSpecifier.prepend(QLatin1String("*/"));
testSpecifier.append(QLatin1String("/*"));
}
config = new TestConfiguration(QString(), QStringList(testSpecifier));
config->setProFile(item->referencingFile());
config->setProject(project);
config->setTestType(TestTypeGTest);
break;
}
// not supported items // not supported items
default: default:
return 0; return 0;
@@ -589,19 +541,16 @@ void TestTreeModel::markForRemoval(const QString &filePath)
TestTreeItem *root = rootItemForType(type); TestTreeItem *root = rootItemForType(type);
for (int childRow = root->childCount() - 1; childRow >= 0; --childRow) { for (int childRow = root->childCount() - 1; childRow >= 0; --childRow) {
TestTreeItem *child = root->childItem(childRow); TestTreeItem *child = root->childItem(childRow);
if (child->markedForRemoval())
continue;
// Qt + named Quick Tests // Qt + named Quick Tests
if (child->filePath() == filePath || child->referencingFile() == filePath) { if (child->filePath() == filePath) {
child->markForRemovalRecursively(true); child->markForRemoval(true);
} else { } else {
// unnamed Quick Tests and GTest and Qt Tests with separated source/header // unnamed Quick Tests and GTest and Qt Tests with separated source/header
int grandChildRow = child->childCount() - 1; int grandChildRow = child->childCount() - 1;
for ( ; grandChildRow >= 0; --grandChildRow) { for ( ; grandChildRow >= 0; --grandChildRow) {
TestTreeItem *grandChild = child->childItem(grandChildRow); TestTreeItem *grandChild = child->childItem(grandChildRow);
if (grandChild->filePath() == filePath if (grandChild->filePath() == filePath) {
|| grandChild->referencingFile() == filePath) { grandChild->markForRemoval(true);
grandChild->markForRemovalRecursively(true);
} }
} }
} }
@@ -621,6 +570,26 @@ void TestTreeModel::sweep()
emit testTreeModelChanged(); emit testTreeModelChanged();
} }
QMap<QString, QString> TestTreeModel::testCaseNamesForFiles(QStringList files)
{
QMap<QString, QString> result;
if (!m_autoTestRootItem)
return result;
for (int row = 0, count = m_autoTestRootItem->childCount(); row < count; ++row) {
const TestTreeItem *child = m_autoTestRootItem->childItem(row);
if (files.contains(child->filePath())) {
result.insert(child->filePath(), child->name());
}
for (int childRow = 0, children = child->childCount(); childRow < children; ++childRow) {
const TestTreeItem *grandChild = child->childItem(childRow);
if (files.contains(grandChild->filePath()))
result.insert(grandChild->filePath(), child->name());
}
}
return result;
}
/** /**
* @note after calling this function emit testTreeModelChanged() if it returns true * @note after calling this function emit testTreeModelChanged() if it returns true
*/ */
@@ -648,13 +617,6 @@ bool TestTreeModel::sweepChildren(TestTreeItem *item)
return hasChanged; return hasChanged;
} }
QMap<QString, QString> TestTreeModel::referencingFiles() const
{
ReferencingFilesFinder finder;
rootItem()->walkTree(&finder);
return finder.referencingFiles();
}
void TestTreeModel::onParseResultReady(const TestParseResult &result) void TestTreeModel::onParseResultReady(const TestParseResult &result)
{ {
switch (result.type) { switch (result.type) {
@@ -692,7 +654,7 @@ void TestTreeModel::handleParseResult(const TestParseResult &result)
QTC_ASSERT(false, return); // should never happen, just to avoid warning QTC_ASSERT(false, return); // should never happen, just to avoid warning
} }
TestTreeItem *toBeModified = root->findChildByFiles(result.fileName, result.referencingFile); TestTreeItem *toBeModified = root->findChildByFile(result.fileName);
// if there's no matching item, add the new one // if there's no matching item, add the new one
if (!toBeModified) { if (!toBeModified) {
if (result.type == AutoTest) if (result.type == AutoTest)
@@ -761,17 +723,18 @@ void TestTreeModel::handleUnnamedQuickParseResult(const TestParseResult &result)
func, result)); func, result));
continue; continue;
} }
functionItem->modifyLineAndColumn(result.line, result.column); functionItem->modifyLineAndColumn(location.m_line, location.m_column);
functionItem->markForRemoval(false); functionItem->markForRemoval(false);
} }
} }
void TestTreeModel::handleGTestParseResult(const TestParseResult &result) void TestTreeModel::handleGTestParseResult(const TestParseResult &result)
{ {
TestTreeItem::Type type = result.parameterized ? TestTreeItem::GTestCaseParameterized GoogleTestTreeItem::TestStates states = GoogleTestTreeItem::Enabled;
: TestTreeItem::GTestCase; if (result.parameterized)
TestTreeItem *toBeModified = m_googleTestRootItem->findChildByNameTypeAndFile( states |= GoogleTestTreeItem::Parameterized;
result.testCaseName, type, result.referencingFile); TestTreeItem *toBeModified = m_googleTestRootItem->findChildByNameStateAndFile(
result.testCaseName, states, result.proFile);
if (!toBeModified) { if (!toBeModified) {
m_googleTestRootItem->appendChild(GoogleTestTreeItem::createTestItem(result)); m_googleTestRootItem->appendChild(GoogleTestTreeItem::createTestItem(result));
return; return;
@@ -784,8 +747,8 @@ void TestTreeModel::handleGTestParseResult(const TestParseResult &result)
toBeModified->appendChild(GoogleTestTreeItem::createTestSetItem(result, location)); toBeModified->appendChild(GoogleTestTreeItem::createTestSetItem(result, location));
continue; continue;
} }
bool changed = testSetItem->modifyGTestSetContent(result.fileName, bool changed = testSetItem->asGoogleTestTreeItem()->modifyTestSetContent(
result.referencingFile, location); result.fileName, location);
testSetItem->markForRemoval(false); testSetItem->markForRemoval(false);
if (changed) if (changed)
emit dataChanged(indexForItem(testSetItem), indexForItem(testSetItem)); emit dataChanged(indexForItem(testSetItem), indexForItem(testSetItem));

View File

@@ -81,7 +81,7 @@ public:
void markAllForRemoval(); void markAllForRemoval();
void markForRemoval(const QString &filePath); void markForRemoval(const QString &filePath);
void sweep(); void sweep();
QMap<QString, QString> referencingFiles() const; QMap<QString, QString> testCaseNamesForFiles(QStringList files);
signals: signals:
void testTreeModelChanged(); void testTreeModelChanged();
@@ -104,9 +104,9 @@ private:
explicit TestTreeModel(QObject *parent = 0); explicit TestTreeModel(QObject *parent = 0);
void setupParsingConnections(); void setupParsingConnections();
TestTreeItem *m_autoTestRootItem; AutoTestTreeItem *m_autoTestRootItem;
TestTreeItem *m_quickTestRootItem; QuickTestTreeItem *m_quickTestRootItem;
TestTreeItem *m_googleTestRootItem; GoogleTestTreeItem *m_googleTestRootItem;
TestCodeParser *m_parser; TestCodeParser *m_parser;
bool m_connectionsInitialized; bool m_connectionsInitialized;
QAtomicInt m_refCounter; QAtomicInt m_refCounter;
@@ -151,7 +151,7 @@ struct TestParseResult
TestTreeModel::Type type; TestTreeModel::Type type;
QString fileName; QString fileName;
QString referencingFile; QString proFile;
QString testCaseName; QString testCaseName;
unsigned line = 0; unsigned line = 0;
unsigned column = 0; unsigned column = 0;

View File

@@ -94,8 +94,7 @@ bool TestVisitor::visit(CPlusPlus::Class *symbol)
else if (name.endsWith(QLatin1String("_data"))) else if (name.endsWith(QLatin1String("_data")))
locationAndType.m_type = TestTreeItem::TestDataFunction; locationAndType.m_type = TestTreeItem::TestDataFunction;
else else
locationAndType.m_type = TestTreeItem::TestFunction; locationAndType.m_type = TestTreeItem::TestFunctionOrSet;
locationAndType.m_state = TestTreeItem::Enabled;
m_privSlots.insert(name, locationAndType); m_privSlots.insert(name, locationAndType);
} }
} }
@@ -225,7 +224,6 @@ bool TestDataFunctionVisitor::visit(CPlusPlus::CallAST *ast)
locationAndType.m_column = column - 1; locationAndType.m_column = column - 1;
locationAndType.m_line = line; locationAndType.m_line = line;
locationAndType.m_type = TestTreeItem::TestDataTag; locationAndType.m_type = TestTreeItem::TestDataTag;
locationAndType.m_state = TestTreeItem::Enabled;
m_currentTags.append(locationAndType); m_currentTags.append(locationAndType);
} }
} }
@@ -302,7 +300,7 @@ bool TestQmlVisitor::visit(QmlJS::AST::UiObjectDefinition *ast)
m_testCaseLocation.m_name = m_currentDoc->fileName(); m_testCaseLocation.m_name = m_currentDoc->fileName();
m_testCaseLocation.m_line = sourceLocation.startLine; m_testCaseLocation.m_line = sourceLocation.startLine;
m_testCaseLocation.m_column = sourceLocation.startColumn - 1; m_testCaseLocation.m_column = sourceLocation.startColumn - 1;
m_testCaseLocation.m_type = TestTreeItem::TestClass; m_testCaseLocation.m_type = TestTreeItem::TestCase;
return true; return true;
} }
@@ -335,9 +333,8 @@ bool TestQmlVisitor::visit(QmlJS::AST::FunctionDeclaration *ast)
else if (name.endsWith(QLatin1String("_data"))) else if (name.endsWith(QLatin1String("_data")))
locationAndType.m_type = TestTreeItem::TestDataFunction; locationAndType.m_type = TestTreeItem::TestDataFunction;
else else
locationAndType.m_type = TestTreeItem::TestFunction; locationAndType.m_type = TestTreeItem::TestFunctionOrSet;
locationAndType.m_state = TestTreeItem::Enabled;
m_testFunctions.insert(name.toString(), locationAndType); m_testFunctions.insert(name.toString(), locationAndType);
} }
return false; return false;
@@ -389,9 +386,9 @@ bool GTestVisitor::visit(CPlusPlus::FunctionDefinitionAST *ast)
locationAndType.m_name = disabled ? testName.mid(9) : testName; locationAndType.m_name = disabled ? testName.mid(9) : testName;
locationAndType.m_line = line; locationAndType.m_line = line;
locationAndType.m_column = column - 1; locationAndType.m_column = column - 1;
locationAndType.m_type = TestTreeItem::GTestName; locationAndType.m_type = TestTreeItem::TestFunctionOrSet;
locationAndType.m_state = (disabled || disabledCase) ? TestTreeItem::Disabled locationAndType.m_state = (disabled || disabledCase) ? GoogleTestTreeItem::Disabled
: TestTreeItem::Enabled; : GoogleTestTreeItem::Enabled;
GTestCaseSpec spec; GTestCaseSpec spec;
spec.testCaseName = disabledCase ? testCaseName.mid(9) : testCaseName; spec.testCaseName = disabledCase ? testCaseName.mid(9) : testCaseName;
spec.parameterized = TestUtils::isGTestParameterized(prettyName); spec.parameterized = TestUtils::isGTestParameterized(prettyName);