forked from qt-creator/qt-creator
AutoTest: Fix handling of cpp files for Quick tests
Modifying C++ files of Quick tests had been ignored as they normally have little impact. But nevertheless this behavior is wrong and could lead to unexpected behavior later on if no complete rescan had been done and even with a rescan there could have been some cached artifacts. Fix this by tracking the paths of the C++ files that hold the main() or the respective macro to be able to handle changes of these files correctly as well. Task-number: QTCREATORBUG-20746 Change-Id: Iec860aa63ffd167511efdbf63a6ffa369f094edf Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
@@ -212,7 +212,7 @@ static bool checkQmlDocumentForQuickTestCode(QFutureInterface<TestParseResultPtr
|
|||||||
|
|
||||||
bool QuickTestParser::handleQtQuickTest(QFutureInterface<TestParseResultPtr> futureInterface,
|
bool QuickTestParser::handleQtQuickTest(QFutureInterface<TestParseResultPtr> futureInterface,
|
||||||
CPlusPlus::Document::Ptr document,
|
CPlusPlus::Document::Ptr document,
|
||||||
const Core::Id &id) const
|
const Core::Id &id)
|
||||||
{
|
{
|
||||||
const CppTools::CppModelManager *modelManager = CppTools::CppModelManager::instance();
|
const CppTools::CppModelManager *modelManager = CppTools::CppModelManager::instance();
|
||||||
if (quickTestName(document).isEmpty())
|
if (quickTestName(document).isEmpty())
|
||||||
@@ -223,7 +223,7 @@ bool QuickTestParser::handleQtQuickTest(QFutureInterface<TestParseResultPtr> fut
|
|||||||
if (ppList.isEmpty()) // happens if shutting down while parsing
|
if (ppList.isEmpty()) // happens if shutting down while parsing
|
||||||
return false;
|
return false;
|
||||||
const QString &proFile = ppList.at(0)->projectFile;
|
const QString &proFile = ppList.at(0)->projectFile;
|
||||||
|
m_mainCppFiles.insert(cppFileName, proFile);
|
||||||
const QString srcDir = quickTestSrcDir(modelManager, cppFileName);
|
const QString srcDir = quickTestSrcDir(modelManager, cppFileName);
|
||||||
if (srcDir.isEmpty())
|
if (srcDir.isEmpty())
|
||||||
return false;
|
return false;
|
||||||
@@ -306,8 +306,21 @@ QuickTestParser::~QuickTestParser()
|
|||||||
void QuickTestParser::init(const QStringList &filesToParse, bool fullParse)
|
void QuickTestParser::init(const QStringList &filesToParse, bool fullParse)
|
||||||
{
|
{
|
||||||
m_qmlSnapshot = QmlJSTools::Internal::ModelManager::instance()->snapshot();
|
m_qmlSnapshot = QmlJSTools::Internal::ModelManager::instance()->snapshot();
|
||||||
if (!fullParse) // in a full parse we get the correct entry points by the respective main
|
if (!fullParse) {
|
||||||
|
// in a full parse we get the correct entry points by the respective main
|
||||||
m_proFilesForQmlFiles = QuickTestUtils::proFilesForQmlFiles(id(), filesToParse);
|
m_proFilesForQmlFiles = QuickTestUtils::proFilesForQmlFiles(id(), filesToParse);
|
||||||
|
// get rid of cached main cpp files that are going to get processed anyhow
|
||||||
|
for (const QString &file : filesToParse) {
|
||||||
|
if (m_mainCppFiles.contains(file)) {
|
||||||
|
m_mainCppFiles.remove(file);
|
||||||
|
if (m_mainCppFiles.isEmpty())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// get rid of all cached main cpp files
|
||||||
|
m_mainCppFiles.clear();
|
||||||
|
}
|
||||||
CppParser::init(filesToParse, fullParse);
|
CppParser::init(filesToParse, fullParse);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -336,5 +349,10 @@ bool QuickTestParser::processDocument(QFutureInterface<TestParseResultPtr> futur
|
|||||||
return handleQtQuickTest(futureInterface, document, id());
|
return handleQtQuickTest(futureInterface, document, id());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString QuickTestParser::projectFileForMainCppFile(const QString &fileName) const
|
||||||
|
{
|
||||||
|
return m_mainCppFiles.contains(fileName) ? m_mainCppFiles.value(fileName) : QString();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace Autotest
|
} // namespace Autotest
|
||||||
|
@@ -51,11 +51,12 @@ public:
|
|||||||
void release() override;
|
void release() override;
|
||||||
bool processDocument(QFutureInterface<TestParseResultPtr> futureInterface,
|
bool processDocument(QFutureInterface<TestParseResultPtr> futureInterface,
|
||||||
const QString &fileName) override;
|
const QString &fileName) override;
|
||||||
|
QString projectFileForMainCppFile(const QString &fileName) const;
|
||||||
signals:
|
signals:
|
||||||
void updateWatchPaths(const QStringList &directories) const;
|
void updateWatchPaths(const QStringList &directories) const;
|
||||||
private:
|
private:
|
||||||
bool handleQtQuickTest(QFutureInterface<TestParseResultPtr> futureInterface,
|
bool handleQtQuickTest(QFutureInterface<TestParseResultPtr> futureInterface,
|
||||||
CPlusPlus::Document::Ptr document, const Core::Id &id) const;
|
CPlusPlus::Document::Ptr document, const Core::Id &id);
|
||||||
void handleDirectoryChanged(const QString &directory);
|
void handleDirectoryChanged(const QString &directory);
|
||||||
void doUpdateWatchPaths(const QStringList &directories);
|
void doUpdateWatchPaths(const QStringList &directories);
|
||||||
QList<QmlJS::Document::Ptr> scanDirectoryForQuickTestQmlFiles(const QString &srcDir) const;
|
QList<QmlJS::Document::Ptr> scanDirectoryForQuickTestQmlFiles(const QString &srcDir) const;
|
||||||
@@ -63,6 +64,7 @@ private:
|
|||||||
QHash<QString, QString> m_proFilesForQmlFiles;
|
QHash<QString, QString> m_proFilesForQmlFiles;
|
||||||
QFileSystemWatcher m_directoryWatcher;
|
QFileSystemWatcher m_directoryWatcher;
|
||||||
QMap<QString, QMap<QString, QDateTime> > m_watchedFiles;
|
QMap<QString, QMap<QString, QDateTime> > m_watchedFiles;
|
||||||
|
QMap<QString, QString> m_mainCppFiles;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#include "quicktesttreeitem.h"
|
#include "quicktesttreeitem.h"
|
||||||
#include "quicktestconfiguration.h"
|
#include "quicktestconfiguration.h"
|
||||||
|
#include "quicktestframework.h"
|
||||||
#include "quicktestparser.h"
|
#include "quicktestparser.h"
|
||||||
#include "../testframeworkmanager.h"
|
#include "../testframeworkmanager.h"
|
||||||
|
|
||||||
@@ -426,6 +427,23 @@ QSet<QString> QuickTestTreeItem::internalTargets() const
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QuickTestTreeItem::markForRemovalRecursively(const QString &filePath)
|
||||||
|
{
|
||||||
|
static const Core::Id id = Core::Id(Constants::FRAMEWORK_PREFIX).withSuffix(
|
||||||
|
QuickTest::Constants::FRAMEWORK_NAME);
|
||||||
|
TestTreeItem::markForRemovalRecursively(filePath);
|
||||||
|
auto parser = dynamic_cast<QuickTestParser *>(TestFrameworkManager::instance()
|
||||||
|
->testParserForTestFramework(id));
|
||||||
|
const QString proFile = parser->projectFileForMainCppFile(filePath);
|
||||||
|
if (!proFile.isEmpty()) {
|
||||||
|
TestTreeItem *root = TestFrameworkManager::instance()->rootNodeForTestFramework(id);
|
||||||
|
root->forAllChildren([proFile](TestTreeItem *it) {
|
||||||
|
if (it->proFile() == proFile)
|
||||||
|
it->markForRemoval(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TestTreeItem *QuickTestTreeItem::unnamedQuickTests() const
|
TestTreeItem *QuickTestTreeItem::unnamedQuickTests() const
|
||||||
{
|
{
|
||||||
if (type() != Root)
|
if (type() != Root)
|
||||||
|
@@ -54,6 +54,7 @@ public:
|
|||||||
bool removeOnSweepIfEmpty() const override;
|
bool removeOnSweepIfEmpty() const override;
|
||||||
TestTreeItem *createParentGroupNode() const override;
|
TestTreeItem *createParentGroupNode() const override;
|
||||||
QSet<QString> internalTargets() const override;
|
QSet<QString> internalTargets() const override;
|
||||||
|
void markForRemovalRecursively(const QString &filePath) override;
|
||||||
private:
|
private:
|
||||||
TestTreeItem *unnamedQuickTests() const;
|
TestTreeItem *unnamedQuickTests() const;
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user