forked from qt-creator/qt-creator
AutoTest: Prefer ITestParser to ITestFramework in TestCodeParser
Preserves the level of abstraction. Change-Id: I01354fc8fcdf846dd2ef2a20fce12f6e9c4756b2 Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
@@ -108,7 +108,7 @@ void TestCodeParser::setState(State state)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestCodeParser::syncTestFrameworks(const QList<ITestFramework *> &frameworks)
|
void TestCodeParser::syncTestFrameworks(const QList<ITestParser *> &parsers)
|
||||||
{
|
{
|
||||||
if (m_parserState != Idle) {
|
if (m_parserState != Idle) {
|
||||||
// there's a running parse
|
// there's a running parse
|
||||||
@@ -116,13 +116,8 @@ void TestCodeParser::syncTestFrameworks(const QList<ITestFramework *> &framework
|
|||||||
m_postponedFiles.clear();
|
m_postponedFiles.clear();
|
||||||
Core::ProgressManager::cancelTasks(Constants::TASK_PARSE);
|
Core::ProgressManager::cancelTasks(Constants::TASK_PARSE);
|
||||||
}
|
}
|
||||||
m_testCodeParsers.clear();
|
qCDebug(LOG) << "Setting" << parsers << "as current parsers";
|
||||||
qCDebug(LOG) << "Setting" << frameworks << "as current parsers";
|
m_testCodeParsers = parsers;
|
||||||
for (ITestFramework *framework : frameworks) {
|
|
||||||
ITestParser *testParser = framework->testParser();
|
|
||||||
QTC_ASSERT(testParser, continue); // buildsystem based frameworks have no code parser
|
|
||||||
m_testCodeParsers.append(testParser);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestCodeParser::emitUpdateTestTree(ITestParser *parser)
|
void TestCodeParser::emitUpdateTestTree(ITestParser *parser)
|
||||||
@@ -130,7 +125,7 @@ void TestCodeParser::emitUpdateTestTree(ITestParser *parser)
|
|||||||
if (m_testCodeParsers.isEmpty())
|
if (m_testCodeParsers.isEmpty())
|
||||||
return;
|
return;
|
||||||
if (parser)
|
if (parser)
|
||||||
m_updateParsers.insert(parser->framework());
|
m_updateParsers.insert(parser);
|
||||||
else
|
else
|
||||||
m_updateParsers.clear();
|
m_updateParsers.clear();
|
||||||
if (m_singleShotScheduled) {
|
if (m_singleShotScheduled) {
|
||||||
@@ -143,18 +138,18 @@ void TestCodeParser::emitUpdateTestTree(ITestParser *parser)
|
|||||||
QTimer::singleShot(1000, this, [this]() { updateTestTree(m_updateParsers); });
|
QTimer::singleShot(1000, this, [this]() { updateTestTree(m_updateParsers); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestCodeParser::updateTestTree(const QSet<ITestFramework *> &frameworks)
|
void TestCodeParser::updateTestTree(const QSet<ITestParser *> &parsers)
|
||||||
{
|
{
|
||||||
m_singleShotScheduled = false;
|
m_singleShotScheduled = false;
|
||||||
if (m_codeModelParsing) {
|
if (m_codeModelParsing) {
|
||||||
m_fullUpdatePostponed = true;
|
m_fullUpdatePostponed = true;
|
||||||
m_partialUpdatePostponed = false;
|
m_partialUpdatePostponed = false;
|
||||||
m_postponedFiles.clear();
|
m_postponedFiles.clear();
|
||||||
if (frameworks.isEmpty()) {
|
if (parsers.isEmpty()) {
|
||||||
m_updateParsers.clear();
|
m_updateParsers.clear();
|
||||||
} else {
|
} else {
|
||||||
for (ITestFramework *framework : frameworks)
|
for (ITestParser *parser : parsers)
|
||||||
m_updateParsers.insert(framework);
|
m_updateParsers.insert(parser);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -164,9 +159,11 @@ void TestCodeParser::updateTestTree(const QSet<ITestFramework *> &frameworks)
|
|||||||
|
|
||||||
m_fullUpdatePostponed = false;
|
m_fullUpdatePostponed = false;
|
||||||
qCDebug(LOG) << "calling scanForTests (updateTestTree)";
|
qCDebug(LOG) << "calling scanForTests (updateTestTree)";
|
||||||
TestFrameworks sortedFrameworks = Utils::toList(frameworks);
|
QList<ITestParser *> sortedParsers = Utils::toList(parsers);
|
||||||
Utils::sort(sortedFrameworks, &ITestFramework::priority);
|
Utils::sort(sortedParsers, [](const ITestParser *lhs, const ITestParser *rhs) {
|
||||||
scanForTests(QStringList(), sortedFrameworks);
|
return lhs->framework()->priority() < rhs->framework()->priority();
|
||||||
|
});
|
||||||
|
scanForTests(QStringList(), sortedParsers);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****** threaded parsing stuff *******/
|
/****** threaded parsing stuff *******/
|
||||||
@@ -296,7 +293,7 @@ static void parseFileForTests(const QList<ITestParser *> &parsers,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestCodeParser::scanForTests(const QStringList &fileList, const QList<ITestFramework *> &parsers)
|
void TestCodeParser::scanForTests(const QStringList &fileList, const QList<ITestParser *> &parsers)
|
||||||
{
|
{
|
||||||
if (m_parserState == Shutdown || m_testCodeParsers.isEmpty())
|
if (m_parserState == Shutdown || m_testCodeParsers.isEmpty())
|
||||||
return;
|
return;
|
||||||
@@ -337,18 +334,16 @@ void TestCodeParser::scanForTests(const QStringList &fileList, const QList<ITest
|
|||||||
return !fn.endsWith(".qml");
|
return !fn.endsWith(".qml");
|
||||||
});
|
});
|
||||||
if (!parsers.isEmpty()) {
|
if (!parsers.isEmpty()) {
|
||||||
for (ITestFramework *framework : parsers) {
|
for (ITestParser *parser : parsers) {
|
||||||
QTC_ASSERT(framework->testParser(), continue); // mark only frameworks with a parser
|
parser->framework()->rootNode()->markForRemovalRecursively(true);
|
||||||
framework->rootNode()->markForRemovalRecursively(true);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
emit requestRemoveAllFrameworkItems();
|
emit requestRemoveAllFrameworkItems();
|
||||||
}
|
}
|
||||||
} else if (!parsers.isEmpty()) {
|
} else if (!parsers.isEmpty()) {
|
||||||
for (ITestFramework *framework : parsers) {
|
for (ITestParser *parser: parsers) {
|
||||||
for (const QString &filePath : qAsConst(list)) {
|
for (const QString &filePath : qAsConst(list)) {
|
||||||
QTC_ASSERT(framework->testParser(), continue);
|
parser->framework()->rootNode()->markForRemovalRecursively(filePath);
|
||||||
framework->rootNode()->markForRemovalRecursively(filePath);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -359,9 +354,7 @@ void TestCodeParser::scanForTests(const QStringList &fileList, const QList<ITest
|
|||||||
QTC_ASSERT(!(isFullParse && list.isEmpty()), onFinished(); return);
|
QTC_ASSERT(!(isFullParse && list.isEmpty()), onFinished(); return);
|
||||||
|
|
||||||
// use only a single parser or all current active?
|
// use only a single parser or all current active?
|
||||||
const QList<ITestParser *> codeParsers
|
const QList<ITestParser *> codeParsers = parsers.isEmpty() ? m_testCodeParsers : parsers;
|
||||||
= parsers.isEmpty() ? m_testCodeParsers
|
|
||||||
: Utils::transform(parsers, &ITestFramework::testParser);
|
|
||||||
qCDebug(LOG) << QDateTime::currentDateTime().toString("hh:mm:ss.zzz") << "StartParsing";
|
qCDebug(LOG) << QDateTime::currentDateTime().toString("hh:mm:ss.zzz") << "StartParsing";
|
||||||
for (ITestParser *parser : codeParsers)
|
for (ITestParser *parser : codeParsers)
|
||||||
parser->init(list, isFullParse);
|
parser->init(list, isFullParse);
|
||||||
|
|||||||
@@ -43,8 +43,6 @@ namespace ProjectExplorer { class Project; }
|
|||||||
|
|
||||||
namespace Autotest {
|
namespace Autotest {
|
||||||
|
|
||||||
class ITestFramework;
|
|
||||||
|
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
class TestCodeParser : public QObject
|
class TestCodeParser : public QObject
|
||||||
@@ -64,7 +62,7 @@ public:
|
|||||||
State state() const { return m_parserState; }
|
State state() const { return m_parserState; }
|
||||||
bool isParsing() const { return m_parserState == PartialParse || m_parserState == FullParse; }
|
bool isParsing() const { return m_parserState == PartialParse || m_parserState == FullParse; }
|
||||||
void setDirty() { m_dirty = true; }
|
void setDirty() { m_dirty = true; }
|
||||||
void syncTestFrameworks(const QList<ITestFramework *> &frameworks);
|
void syncTestFrameworks(const QList<ITestParser *> &parsers);
|
||||||
#ifdef WITH_TESTS
|
#ifdef WITH_TESTS
|
||||||
bool furtherParsingExpected() const
|
bool furtherParsingExpected() const
|
||||||
{ return m_singleShotScheduled || m_fullUpdatePostponed || m_partialUpdatePostponed; }
|
{ return m_singleShotScheduled || m_fullUpdatePostponed || m_partialUpdatePostponed; }
|
||||||
@@ -81,7 +79,7 @@ signals:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
void emitUpdateTestTree(ITestParser *parser = nullptr);
|
void emitUpdateTestTree(ITestParser *parser = nullptr);
|
||||||
void updateTestTree(const QSet<ITestFramework *> &frameworks = {});
|
void updateTestTree(const QSet<ITestParser *> &parsers = {});
|
||||||
void onCppDocumentUpdated(const CPlusPlus::Document::Ptr &document);
|
void onCppDocumentUpdated(const CPlusPlus::Document::Ptr &document);
|
||||||
void onQmlDocumentUpdated(const QmlJS::Document::Ptr &document);
|
void onQmlDocumentUpdated(const QmlJS::Document::Ptr &document);
|
||||||
void onStartupProjectChanged(ProjectExplorer::Project *project);
|
void onStartupProjectChanged(ProjectExplorer::Project *project);
|
||||||
@@ -91,7 +89,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
bool postponed(const QStringList &fileList);
|
bool postponed(const QStringList &fileList);
|
||||||
void scanForTests(const QStringList &fileList = QStringList(),
|
void scanForTests(const QStringList &fileList = QStringList(),
|
||||||
const QList<ITestFramework *> &parserIds = {});
|
const QList<ITestParser *> &parsers = {});
|
||||||
|
|
||||||
// qml files must be handled slightly different
|
// qml files must be handled slightly different
|
||||||
void onDocumentUpdated(const QString &fileName, bool isQmlFile = false);
|
void onDocumentUpdated(const QString &fileName, bool isQmlFile = false);
|
||||||
@@ -117,7 +115,7 @@ private:
|
|||||||
QFutureWatcher<TestParseResultPtr> m_futureWatcher;
|
QFutureWatcher<TestParseResultPtr> m_futureWatcher;
|
||||||
QList<ITestParser *> m_testCodeParsers; // ptrs are still owned by TestFrameworkManager
|
QList<ITestParser *> m_testCodeParsers; // ptrs are still owned by TestFrameworkManager
|
||||||
QTimer m_reparseTimer;
|
QTimer m_reparseTimer;
|
||||||
QSet<ITestFramework *> m_updateParsers;
|
QSet<ITestParser *> m_updateParsers;
|
||||||
QThreadPool *m_threadPool = nullptr;
|
QThreadPool *m_threadPool = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -321,9 +321,10 @@ void TestTreeModel::synchronizeTestFrameworks()
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto sortedParsers = Utils::transform(sorted, &ITestFramework::testParser);
|
||||||
// pre-check to avoid further processing when frameworks are unchanged
|
// pre-check to avoid further processing when frameworks are unchanged
|
||||||
Utils::TreeItem *invisibleRoot = rootItem();
|
Utils::TreeItem *invisibleRoot = rootItem();
|
||||||
QSet<ITestFramework *> newlyAdded;
|
QSet<ITestParser *> newlyAdded;
|
||||||
QList<ITestTreeItem *> oldFrameworkRoots;
|
QList<ITestTreeItem *> oldFrameworkRoots;
|
||||||
for (Utils::TreeItem *oldFrameworkRoot : *invisibleRoot)
|
for (Utils::TreeItem *oldFrameworkRoot : *invisibleRoot)
|
||||||
oldFrameworkRoots.append(static_cast<ITestTreeItem *>(oldFrameworkRoot));
|
oldFrameworkRoots.append(static_cast<ITestTreeItem *>(oldFrameworkRoot));
|
||||||
@@ -331,11 +332,11 @@ void TestTreeModel::synchronizeTestFrameworks()
|
|||||||
for (ITestTreeItem *oldFrameworkRoot : oldFrameworkRoots)
|
for (ITestTreeItem *oldFrameworkRoot : oldFrameworkRoots)
|
||||||
takeItem(oldFrameworkRoot); // do NOT delete the ptr is still held by TestFrameworkManager
|
takeItem(oldFrameworkRoot); // do NOT delete the ptr is still held by TestFrameworkManager
|
||||||
|
|
||||||
for (ITestFramework *framework : qAsConst(sorted)) {
|
for (ITestParser *parser : sortedParsers) {
|
||||||
TestTreeItem *frameworkRootNode = framework->rootNode();
|
TestTreeItem *frameworkRootNode = parser->framework()->rootNode();
|
||||||
invisibleRoot->appendChild(frameworkRootNode);
|
invisibleRoot->appendChild(frameworkRootNode);
|
||||||
if (!oldFrameworkRoots.removeOne(frameworkRootNode))
|
if (!oldFrameworkRoots.removeOne(frameworkRootNode))
|
||||||
newlyAdded.insert(framework);
|
newlyAdded.insert(parser);
|
||||||
}
|
}
|
||||||
for (ITestTreeItem *oldFrameworkRoot : oldFrameworkRoots) {
|
for (ITestTreeItem *oldFrameworkRoot : oldFrameworkRoots) {
|
||||||
if (oldFrameworkRoot->testBase()->type() == ITestBase::Framework)
|
if (oldFrameworkRoot->testBase()->type() == ITestBase::Framework)
|
||||||
@@ -344,7 +345,7 @@ void TestTreeModel::synchronizeTestFrameworks()
|
|||||||
invisibleRoot->appendChild(oldFrameworkRoot);
|
invisibleRoot->appendChild(oldFrameworkRoot);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_parser->syncTestFrameworks(sorted);
|
m_parser->syncTestFrameworks(sortedParsers);
|
||||||
if (!newlyAdded.isEmpty())
|
if (!newlyAdded.isEmpty())
|
||||||
m_parser->updateTestTree(newlyAdded);
|
m_parser->updateTestTree(newlyAdded);
|
||||||
emit updatedActiveFrameworks(invisibleRoot->childCount());
|
emit updatedActiveFrameworks(invisibleRoot->childCount());
|
||||||
|
|||||||
Reference in New Issue
Block a user