Commit b58a10df authored by Christian Stenger's avatar Christian Stenger Committed by Christian Stenger

AutoTest: Split off TestParseResult...

...to allow different approaches for different test frameworks.

Change-Id: I16f101fb3f702a0db00cffe33e0d83cd4ea28c99
Reviewed-by: default avatarDavid Schulz <david.schulz@theqtcompany.com>
parent db71490b
......@@ -456,7 +456,7 @@ static bool checkQmlDocumentForTestCode(QFutureInterface<TestParseResultPtr> fut
const TestCodeLocationAndType tcLocationAndType = qmlVisitor.testCaseLocation();
const QMap<QString, TestCodeLocationAndType> testFunctions = qmlVisitor.testFunctions();
TestParseResultPtr parseResult(new TestParseResult(TestTreeModel::QuickTest));
QuickTestParseResult *parseResult = new QuickTestParseResult(TestTreeModel::QuickTest);
parseResult->proFile = proFile;
parseResult->functions = testFunctions;
if (!testCaseName.isEmpty()) {
......@@ -465,7 +465,7 @@ static bool checkQmlDocumentForTestCode(QFutureInterface<TestParseResultPtr> fut
parseResult->line = tcLocationAndType.m_line;
parseResult->column = tcLocationAndType.m_column;
}
futureInterface.reportResult(parseResult);
futureInterface.reportResult(TestParseResultPtr(parseResult));
return true;
}
......@@ -498,16 +498,16 @@ static bool handleQtTest(QFutureInterface<TestParseResultPtr> futureInterface,
foreach (const QString &file, files)
dataTags.unite(checkForDataTags(file));
TestParseResultPtr parseResult(new TestParseResult(TestTreeModel::AutoTest));
QtTestParseResult *parseResult = new QtTestParseResult(TestTreeModel::AutoTest);
parseResult->fileName = declaringDoc->fileName();
parseResult->testCaseName = testCaseName;
parseResult->line = line;
parseResult->column = column;
parseResult->functions = testFunctions;
parseResult->dataTagsOrTestSets = dataTags;
parseResult->dataTags = dataTags;
parseResult->proFile = modelManager->projectPart(fileName).first()->projectFile;
futureInterface.reportResult(parseResult);
futureInterface.reportResult(TestParseResultPtr(parseResult));
return true;
}
return false;
......@@ -555,15 +555,15 @@ static bool handleGTest(QFutureInterface<TestParseResultPtr> futureInterface, co
proFile = ppList.first()->projectFile;
foreach (const GTestCaseSpec &testSpec, result.keys()) {
TestParseResultPtr parseResult(new TestParseResult(TestTreeModel::GoogleTest));
GoogleTestParseResult *parseResult = new GoogleTestParseResult(TestTreeModel::GoogleTest);
parseResult->fileName = filePath;
parseResult->testCaseName = testSpec.testCaseName;
parseResult->parameterized = testSpec.parameterized;
parseResult->typed = testSpec.typed;
parseResult->disabled = testSpec.disabled;
parseResult->proFile = proFile;
parseResult->dataTagsOrTestSets.insert(QString(), result.value(testSpec));
futureInterface.reportResult(parseResult);
parseResult->testSets = result.value(testSpec);
futureInterface.reportResult(TestParseResultPtr(parseResult));
}
return !result.keys().isEmpty();
}
......
......@@ -43,8 +43,46 @@ class Id;
namespace Autotest {
namespace Internal {
struct TestCodeLocationAndType;
struct GTestCaseSpec;
class TestParseResult
{
public:
explicit TestParseResult(TestTreeModel::Type t = TestTreeModel::Invalid) : type(t) {}
virtual ~TestParseResult() {}
TestTreeModel::Type type;
QString fileName;
QString proFile;
QString testCaseName;
unsigned line = 0;
unsigned column = 0;
};
class QtTestParseResult : public TestParseResult
{
public:
QtTestParseResult(TestTreeModel::Type t = TestTreeModel::Invalid) : TestParseResult(t) {}
QMap<QString, TestCodeLocationAndType> functions;
QMap<QString, TestCodeLocationList> dataTags;
};
class QuickTestParseResult : public TestParseResult
{
public:
QuickTestParseResult(TestTreeModel::Type t = TestTreeModel::Invalid) : TestParseResult(t) {}
QMap<QString, TestCodeLocationAndType> functions;
};
class GoogleTestParseResult : public TestParseResult
{
public:
GoogleTestParseResult(TestTreeModel::Type t = TestTreeModel::Invalid) : TestParseResult(t) {}
bool parameterized = false;
bool typed = false;
bool disabled = false;
TestCodeLocationList testSets;
};
using TestParseResultPtr = QSharedPointer<TestParseResult>;
class TestCodeParser : public QObject
{
......@@ -106,3 +144,5 @@ private:
} // namespace Internal
} // Autotest
Q_DECLARE_METATYPE(Autotest::Internal::TestParseResultPtr)
......@@ -25,6 +25,7 @@
#include "autotestconstants.h"
#include "autotest_utils.h"
#include "testcodeparser.h"
#include "testconfiguration.h"
#include "testtreeitem.h"
#include "testtreemodel.h"
......@@ -282,16 +283,17 @@ TestTreeItem *TestTreeItem::findChildBy(CompareFunction compare)
AutoTestTreeItem *AutoTestTreeItem::createTestItem(const TestParseResult &result)
{
const QtTestParseResult &parseResult = static_cast<const QtTestParseResult &>(result);
AutoTestTreeItem *item = new AutoTestTreeItem(result.testCaseName, result.fileName, TestCase);
item->setProFile(result.proFile);
item->setLine(result.line);
item->setColumn(result.column);
item->setProFile(parseResult.proFile);
item->setLine(parseResult.line);
item->setColumn(parseResult.column);
foreach (const QString &functionName, result.functions.keys()) {
const TestCodeLocationAndType &locationAndType = result.functions.value(functionName);
foreach (const QString &functionName, parseResult.functions.keys()) {
const TestCodeLocationAndType &locationAndType = parseResult.functions.value(functionName);
const QString qualifiedName = result.testCaseName + QLatin1String("::") + functionName;
item->appendChild(createFunctionItem(functionName, locationAndType,
result.dataTagsOrTestSets.value(qualifiedName)));
parseResult.dataTags.value(qualifiedName)));
}
return item;
}
......@@ -467,12 +469,14 @@ QList<TestConfiguration *> AutoTestTreeItem::getSelectedTestConfigurations() con
QuickTestTreeItem *QuickTestTreeItem::createTestItem(const TestParseResult &result)
{
QuickTestTreeItem *item = new QuickTestTreeItem(result.testCaseName, result.fileName, TestCase);
const QuickTestParseResult &parseResult = static_cast<const QuickTestParseResult &>(result);
QuickTestTreeItem *item = new QuickTestTreeItem(parseResult.testCaseName, parseResult.fileName,
TestCase);
item->setProFile(result.proFile);
item->setLine(result.line);
item->setColumn(result.column);
foreach (const QString &functionName, result.functions.keys())
item->appendChild(createFunctionItem(functionName, result.functions.value(functionName)));
foreach (const QString &functionName, parseResult.functions.keys())
item->appendChild(createFunctionItem(functionName, parseResult.functions.value(functionName)));
return item;
}
......@@ -487,20 +491,22 @@ QuickTestTreeItem *QuickTestTreeItem::createFunctionItem(const QString &function
QuickTestTreeItem *QuickTestTreeItem::createUnnamedQuickTestItem(const TestParseResult &result)
{
const QuickTestParseResult &parseResult = static_cast<const QuickTestParseResult &>(result);
QuickTestTreeItem *item = new QuickTestTreeItem(QString(), QString(), TestCase);
foreach (const QString &functionName, result.functions.keys())
item->appendChild(createUnnamedQuickFunctionItem(functionName, result));
foreach (const QString &functionName, parseResult.functions.keys())
item->appendChild(createUnnamedQuickFunctionItem(functionName, parseResult));
return item;
}
QuickTestTreeItem *QuickTestTreeItem::createUnnamedQuickFunctionItem(const QString &functionName,
const TestParseResult &result)
{
const TestCodeLocationAndType &location = result.functions.value(functionName);
const QuickTestParseResult &parseResult = static_cast<const QuickTestParseResult &>(result);
const TestCodeLocationAndType &location = parseResult.functions.value(functionName);
QuickTestTreeItem *item = new QuickTestTreeItem(functionName, location.m_name, location.m_type);
item->setLine(location.m_line);
item->setColumn(location.m_column);
item->setProFile(result.proFile);
item->setProFile(parseResult.proFile);
return item;
}
......@@ -738,15 +744,16 @@ static QString gtestFilter(GoogleTestTreeItem::TestStates states)
GoogleTestTreeItem *GoogleTestTreeItem::createTestItem(const TestParseResult &result)
{
GoogleTestTreeItem *item = new GoogleTestTreeItem(result.testCaseName, QString(), TestCase);
item->setProFile(result.proFile);
if (result.parameterized)
const GoogleTestParseResult &parseResult = static_cast<const GoogleTestParseResult &>(result);
GoogleTestTreeItem *item = new GoogleTestTreeItem(parseResult.testCaseName, QString(), TestCase);
item->setProFile(parseResult.proFile);
if (parseResult.parameterized)
item->setState(Parameterized);
if (result.typed)
if (parseResult.typed)
item->setState(Typed);
if (result.disabled)
if (parseResult.disabled)
item->setState(Disabled);
foreach (const TestCodeLocationAndType &location, result.dataTagsOrTestSets.first())
foreach (const TestCodeLocationAndType &location, parseResult.testSets)
item->appendChild(createTestSetItem(result, location));
return item;
}
......
......@@ -47,7 +47,7 @@ struct TestCodeLocationAndType;
class AutoTestTreeItem;
class QuickTestTreeItem;
class GoogleTestTreeItem;
struct TestParseResult;
class TestParseResult;
class TestConfiguration;
class TestTreeItem : public Utils::TreeItem
......
......@@ -341,17 +341,12 @@ void TestTreeModel::onParseResultReady(const TestParseResultPtr result)
{
switch (result->type) {
case AutoTest:
handleParseResult(result);
handleQtParseResult(result);
break;
case QuickTest:
if (result->testCaseName.isEmpty()) {
handleUnnamedQuickParseResult(result);
break;
}
handleParseResult(result);
handleQuickParseResult(result);
break;
case GoogleTest:
QTC_ASSERT(result->dataTagsOrTestSets.size() == 1, return);
handleGTestParseResult(result);
break;
case Invalid:
......@@ -360,27 +355,12 @@ void TestTreeModel::onParseResultReady(const TestParseResultPtr result)
}
}
void TestTreeModel::handleParseResult(const TestParseResultPtr result)
void TestTreeModel::handleQtParseResult(const TestParseResultPtr result)
{
TestTreeItem *root;
switch (result->type) {
case AutoTest:
root = m_autoTestRootItem;
break;
case QuickTest:
root = m_quickTestRootItem;
break;
default:
QTC_ASSERT(false, return); // should never happen, just to avoid warning
}
TestTreeItem *toBeModified = root->findChildByFile(result->fileName);
TestTreeItem *toBeModified = m_autoTestRootItem->findChildByFile(result->fileName);
// if there's no matching item, add the new one
if (!toBeModified) {
if (result->type == AutoTest)
root->appendChild(AutoTestTreeItem::createTestItem(*result));
else
root->appendChild(QuickTestTreeItem::createTestItem(*result));
m_autoTestRootItem->appendChild(AutoTestTreeItem::createTestItem(*result));
return;
}
// else we have to check level by level.. first the current level...
......@@ -390,30 +370,26 @@ void TestTreeModel::handleParseResult(const TestParseResultPtr result)
if (changed)
emit dataChanged(indexForItem(toBeModified), indexForItem(toBeModified));
// ...now the functions
foreach (const QString &func, result->functions.keys()) {
const QtTestParseResult &parseResult = static_cast<const QtTestParseResult &>(*result);
foreach (const QString &func, parseResult.functions.keys()) {
TestTreeItem *functionItem = toBeModified->findChildByName(func);
// if there's no function matching, add the new one
if (!functionItem) {
const QString qualifiedName = result->testCaseName + QLatin1String("::") + func;
if (result->type == AutoTest) {
toBeModified->appendChild(AutoTestTreeItem::createFunctionItem(
func, result->functions.value(func),
result->dataTagsOrTestSets.value(qualifiedName)));
} else {
toBeModified->appendChild(QuickTestTreeItem::createFunctionItem(
func, result->functions.value(func)));
}
// if there's no function matching, add the new one
const QString qualifiedName = parseResult.testCaseName + QLatin1String("::") + func;
toBeModified->appendChild(AutoTestTreeItem::createFunctionItem(
func, parseResult.functions.value(func),
parseResult.dataTags.value(qualifiedName)));
continue;
}
// else we have to check level by level.. first the current level...
changed = functionItem->modifyTestFunctionContent(result->functions.value(func));
changed = functionItem->modifyTestFunctionContent(parseResult.functions.value(func));
functionItem->markForRemoval(false);
if (changed)
emit dataChanged(indexForItem(functionItem), indexForItem(functionItem));
// ...now the data tags - actually these are supported only for AutoTestTreeItem
const QString &funcFileName = result->functions.value(func).m_name;
const QString qualifiedFunctionName = result->testCaseName + QLatin1String("::") + func;
foreach (const TestCodeLocationAndType &location, result->dataTagsOrTestSets.value(qualifiedFunctionName)) {
// ...now the data tags
const QString &funcFileName = parseResult.functions.value(func).m_name;
const QString qualifiedFunctionName = parseResult.testCaseName + QLatin1String("::") + func;
foreach (const TestCodeLocationAndType &location, parseResult.dataTags.value(qualifiedFunctionName)) {
TestTreeItem *dataTagItem = functionItem->findChildByName(location.m_name);
if (!dataTagItem) {
functionItem->appendChild(AutoTestTreeItem::createDataTagItem(funcFileName, location));
......@@ -427,20 +403,59 @@ void TestTreeModel::handleParseResult(const TestParseResultPtr result)
}
}
void TestTreeModel::handleQuickParseResult(const TestParseResultPtr result)
{
if (result->testCaseName.isEmpty()) {
handleUnnamedQuickParseResult(result);
return;
}
TestTreeItem *toBeModified = m_quickTestRootItem->findChildByFile(result->fileName);
// if there's no matching item, add the new one
if (!toBeModified) {
m_quickTestRootItem->appendChild(QuickTestTreeItem::createTestItem(*result));
return;
}
// else we have to check level by level.. first the current level...
bool changed = toBeModified->modifyTestCaseContent(result->testCaseName, result->line,
result->column);
toBeModified->markForRemoval(false);
if (changed)
emit dataChanged(indexForItem(toBeModified), indexForItem(toBeModified));
// ...now the functions
const QuickTestParseResult &parseResult = static_cast<const QuickTestParseResult &>(*result);
foreach (const QString &func, parseResult.functions.keys()) {
TestTreeItem *functionItem = toBeModified->findChildByName(func);
if (!functionItem) {
// if there's no matching, add the new one
toBeModified->appendChild(QuickTestTreeItem::createFunctionItem(
func, parseResult.functions.value(func)));
continue;
}
// else we have to modify..
changed = functionItem->modifyTestFunctionContent(parseResult.functions.value(func));
functionItem->markForRemoval(false);
if (changed)
emit dataChanged(indexForItem(functionItem), indexForItem(functionItem));
}
}
void TestTreeModel::handleUnnamedQuickParseResult(const TestParseResultPtr result)
{
const QuickTestParseResult &parseResult = static_cast<const QuickTestParseResult &>(*result);
TestTreeItem *toBeModified = unnamedQuickTests();
if (!toBeModified) {
m_quickTestRootItem->appendChild(QuickTestTreeItem::createUnnamedQuickTestItem(*result));
m_quickTestRootItem->appendChild(QuickTestTreeItem::createUnnamedQuickTestItem(parseResult));
return;
}
// if we have already Unnamed Quick tests we might update them..
foreach (const QString &func, result->functions.keys()) {
const TestCodeLocationAndType &location = result->functions.value(func);
foreach (const QString &func, parseResult.functions.keys()) {
const TestCodeLocationAndType &location = parseResult.functions.value(func);
TestTreeItem *functionItem = toBeModified->findChildByNameAndFile(func, location.m_name);
if (!functionItem) {
toBeModified->appendChild(QuickTestTreeItem::createUnnamedQuickFunctionItem(
func, *result));
func, parseResult));
continue;
}
functionItem->modifyLineAndColumn(location);
......@@ -450,27 +465,30 @@ void TestTreeModel::handleUnnamedQuickParseResult(const TestParseResultPtr resul
void TestTreeModel::handleGTestParseResult(const TestParseResultPtr result)
{
const GoogleTestParseResult &parseResult = static_cast<const GoogleTestParseResult &>(*result);
QTC_ASSERT(!parseResult.testSets.isEmpty(), return);
GoogleTestTreeItem::TestStates states = GoogleTestTreeItem::Enabled;
if (result->parameterized)
if (parseResult.parameterized)
states |= GoogleTestTreeItem::Parameterized;
if (result->typed)
if (parseResult.typed)
states |= GoogleTestTreeItem::Typed;
TestTreeItem *toBeModified = m_googleTestRootItem->findChildByNameStateAndFile(
result->testCaseName, states, result->proFile);
parseResult.testCaseName, states, parseResult.proFile);
if (!toBeModified) {
m_googleTestRootItem->appendChild(GoogleTestTreeItem::createTestItem(*result));
m_googleTestRootItem->appendChild(GoogleTestTreeItem::createTestItem(parseResult));
return;
}
// if found nothing has to be updated as all relevant members are used to find the item
foreach (const TestCodeLocationAndType &location , result->dataTagsOrTestSets.first()) {
foreach (const TestCodeLocationAndType &location , parseResult.testSets) {
TestTreeItem *testSetItem = toBeModified->findChildByNameAndFile(location.m_name,
result->fileName);
parseResult.fileName);
if (!testSetItem) {
toBeModified->appendChild(GoogleTestTreeItem::createTestSetItem(*result, location));
toBeModified->appendChild(GoogleTestTreeItem::createTestSetItem(parseResult, location));
continue;
}
bool changed = static_cast<GoogleTestTreeItem *>(testSetItem)->modifyTestSetContent(
result->fileName, location);
parseResult.fileName, location);
testSetItem->markForRemoval(false);
if (changed)
emit dataChanged(indexForItem(testSetItem), indexForItem(testSetItem));
......
......@@ -38,7 +38,7 @@ namespace Autotest {
namespace Internal {
class TestCodeParser;
struct TestParseResult;
class TestParseResult;
using TestParseResultPtr = QSharedPointer<TestParseResult>;
......@@ -94,7 +94,8 @@ public slots:
private:
void onParseResultReady(const TestParseResultPtr result);
void handleParseResult(const TestParseResultPtr result);
void handleQtParseResult(const TestParseResultPtr result);
void handleQuickParseResult(const TestParseResultPtr result);
void handleUnnamedQuickParseResult(const TestParseResultPtr result);
void handleGTestParseResult(const TestParseResultPtr result);
void removeAllTestItems();
......@@ -149,25 +150,7 @@ private:
};
struct TestParseResult
{
TestParseResult(TestTreeModel::Type t = TestTreeModel::Invalid) : type(t) {}
TestTreeModel::Type type;
QString fileName;
QString proFile;
QString testCaseName;
unsigned line = 0;
unsigned column = 0;
bool parameterized = false;
bool typed = false;
bool disabled = false;
QMap<QString, TestCodeLocationAndType> functions;
QMap<QString, TestCodeLocationList> dataTagsOrTestSets;
};
} // namespace Internal
} // namespace Autotest
Q_DECLARE_METATYPE(Autotest::Internal::TestTreeModel::Type)
Q_DECLARE_METATYPE(Autotest::Internal::TestParseResultPtr)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment