diff --git a/kdevplatform/tests/testfile.cpp b/kdevplatform/tests/testfile.cpp --- a/kdevplatform/tests/testfile.cpp +++ b/kdevplatform/tests/testfile.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -123,6 +124,25 @@ TestFile::~TestFile() { + IDocument* document = ICore::self()->documentController()->documentForUrl(d->url.toUrl()); + if (document) { + document->close(KDevelop::IDocument::Discard); + } + + auto backgroundParser = ICore::self()->languageController()->backgroundParser(); + backgroundParser->removeDocument(d->url, this); + if (backgroundParser->parseJobForDocument(d->url)) { + bool finished = false; + connect(backgroundParser, &BackgroundParser::parseJobFinished, this, [this, &finished](KDevelop::ParseJob* job) { + if (job->document() == d->url) { + finished = true; + } + }); + if (backgroundParser->parseJobForDocument(d->url)) { + QTRY_VERIFY(finished); + } + } + if (d->topContext && !d->keepDUChainData) { DUChainWriteLocker lock; DUChain::self()->removeDocumentChain(d->topContext.data()); diff --git a/plugins/clang/tests/test_duchain.cpp b/plugins/clang/tests/test_duchain.cpp --- a/plugins/clang/tests/test_duchain.cpp +++ b/plugins/clang/tests/test_duchain.cpp @@ -113,6 +113,11 @@ void TestDUChain::cleanup() { + // Tests should not leave the background parser running such that they do + // not affect subsequent tests. This assert also helps avoiding parse jobs being + // started on TestFiles which were already destructed. + Q_ASSERT(ICore::self()->languageController()->backgroundParser()->isIdle()); + Q_ASSERT(ICore::self()->documentController()->openDocuments().isEmpty()); if (m_provider) { IDefinesAndIncludesManager::manager()->unregisterBackgroundProvider(m_provider.data()); } @@ -428,6 +433,7 @@ file.parse(TopDUContext::Features(TopDUContext::AllDeclarationsContextsAndUses | TopDUContext::ForceUpdateRecursive)); } + file.waitForParsed(500); } void TestDUChain::testReparseError() @@ -448,6 +454,7 @@ file.parse(TopDUContext::Features(TopDUContext::AllDeclarationsContextsAndUses | TopDUContext::ForceUpdateRecursive)); } + file.waitForParsed(500); } void TestDUChain::testTemplate() @@ -658,6 +665,7 @@ file.parse(TopDUContext::Features(TopDUContext::AllDeclarationsContextsAndUses | TopDUContext::ForceUpdateRecursive)); } + file.waitForParsed(500); } void TestDUChain::testReparseBaseClassesTemplates() @@ -687,6 +695,7 @@ file.parse(TopDUContext::Features(TopDUContext::AllDeclarationsContextsAndUses | TopDUContext::ForceUpdateRecursive)); } + file.waitForParsed(500); } void TestDUChain::testGetInheriters_data() @@ -982,22 +991,32 @@ auto documentController = ICore::self()->documentController(); // open first document (no activation) - auto doc = documentController->openDocument(file1.url().toUrl(), KTextEditor::Range::invalid(), {IDocumentController::DoNotActivate}); - QVERIFY(doc); + auto doc1 = documentController->openDocument(file1.url().toUrl(), KTextEditor::Range::invalid(), {IDocumentController::DoNotActivate}); + QVERIFY(doc1); QVERIFY(backgroundParser->isQueued(file1.url())); QCOMPARE(backgroundParser->priorityForDocument(file1.url()), (int)BackgroundParser::NormalPriority); // open second document, activate - doc = documentController->openDocument(file2.url().toUrl()); - QVERIFY(doc); + auto doc2 = documentController->openDocument(file2.url().toUrl()); + QVERIFY(doc2); QVERIFY(backgroundParser->isQueued(file2.url())); QCOMPARE(backgroundParser->priorityForDocument(file2.url()), (int)BackgroundParser::BestPriority); // open third document, activate, too - doc = documentController->openDocument(file3.url().toUrl()); - QVERIFY(doc); + auto doc3 = documentController->openDocument(file3.url().toUrl()); + QVERIFY(doc3); QVERIFY(backgroundParser->isQueued(file3.url())); QCOMPARE(backgroundParser->priorityForDocument(file3.url()), (int)BackgroundParser::BestPriority); + + // Wait for the parsing to finish to avoid errors like "error: error reading '/tmp/testfile_SD1554.cpp'" + // due to the TestFiles getting removed. + file1.parseAndWait(); + file2.parseAndWait(); + file3.parseAndWait(); + + doc1->close(KDevelop::IDocument::Discard); + doc2->close(KDevelop::IDocument::Discard); + doc3->close(KDevelop::IDocument::Discard); } void TestDUChain::testSystemIncludes()