forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/master' into 4.2
Change-Id: I96904f9c65b6c25bb4e04ca34e2d1acb27b8dd58
This commit is contained in:
40
tests/unit/unittest/clangcompareoperators.h
Normal file
40
tests/unit/unittest/clangcompareoperators.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <clang-c/Index.h>
|
||||
|
||||
inline
|
||||
bool operator==(const CXSourceLocation &first, const CXSourceLocation &second)
|
||||
{
|
||||
return clang_equalLocations(first, second);
|
||||
}
|
||||
|
||||
inline
|
||||
bool operator==(const CXSourceRange &first, const CXSourceRange &second)
|
||||
{
|
||||
return clang_equalRanges(first, second);
|
||||
}
|
||||
@@ -25,8 +25,11 @@
|
||||
|
||||
#include "googletest.h"
|
||||
|
||||
#include <clangclock.h>
|
||||
#include <clangfilepath.h>
|
||||
#include <clangtranslationunitupdater.h>
|
||||
#include <clangtranslationunits.h>
|
||||
#include <clangtranslationunit.h>
|
||||
#include <commandlinearguments.h>
|
||||
#include <diagnosticset.h>
|
||||
#include <highlightingmarks.h>
|
||||
@@ -45,9 +48,10 @@
|
||||
|
||||
#include <QTemporaryFile>
|
||||
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
||||
using ClangBackEnd::Clock;
|
||||
using ClangBackEnd::Duration;
|
||||
using ClangBackEnd::FileContainer;
|
||||
using ClangBackEnd::FilePath;
|
||||
using ClangBackEnd::Document;
|
||||
@@ -56,6 +60,8 @@ using ClangBackEnd::ProjectPart;
|
||||
using ClangBackEnd::ProjectPartContainer;
|
||||
using ClangBackEnd::Documents;
|
||||
using ClangBackEnd::TranslationUnitUpdateResult;
|
||||
using ClangBackEnd::TranslationUnit;
|
||||
using ClangBackEnd::TranslationUnits;
|
||||
|
||||
using testing::IsNull;
|
||||
using testing::NotNull;
|
||||
@@ -161,7 +167,7 @@ TEST_F(Document, LastCommandLineArgumentIsFilePath)
|
||||
TEST_F(Document, TimeStampForProjectPartChangeIsUpdatedAsNewCxTranslationUnitIsGenerated)
|
||||
{
|
||||
auto lastChangeTimePoint = document.lastProjectPartChangeTimePoint();
|
||||
std::this_thread::sleep_for(std::chrono::steady_clock::duration(1));
|
||||
std::this_thread::sleep_for(Duration(1));
|
||||
|
||||
document.parse();
|
||||
|
||||
@@ -173,7 +179,7 @@ TEST_F(Document, TimeStampForProjectPartChangeIsUpdatedAsProjectPartIsCleared)
|
||||
ProjectPart projectPart = document.projectPart();
|
||||
document.parse();
|
||||
auto lastChangeTimePoint = document.lastProjectPartChangeTimePoint();
|
||||
std::this_thread::sleep_for(std::chrono::steady_clock::duration(1));
|
||||
std::this_thread::sleep_for(Duration(1));
|
||||
|
||||
projectPart.clear();
|
||||
document.parse();
|
||||
@@ -330,8 +336,9 @@ TEST_F(Document, IncorporateUpdaterResultResetsDirtyness)
|
||||
{
|
||||
document.setDirtyIfDependencyIsMet(document.filePath());
|
||||
TranslationUnitUpdateResult result;
|
||||
result.reparseTimePoint = std::chrono::steady_clock::now();
|
||||
result.reparseTimePoint = Clock::now();
|
||||
result.needsToBeReparsedChangeTimePoint = document.isNeededReparseChangeTimePoint();
|
||||
result.translationUnitId = document.translationUnit().id();
|
||||
|
||||
document.incorporateUpdaterResult(result);
|
||||
|
||||
@@ -341,8 +348,9 @@ TEST_F(Document, IncorporateUpdaterResultResetsDirtyness)
|
||||
TEST_F(Document, IncorporateUpdaterResultDoesNotResetDirtynessIfItWasChanged)
|
||||
{
|
||||
TranslationUnitUpdateResult result;
|
||||
result.reparseTimePoint = std::chrono::steady_clock::now();
|
||||
result.needsToBeReparsedChangeTimePoint = std::chrono::steady_clock::now();
|
||||
result.reparseTimePoint = Clock::now();
|
||||
result.needsToBeReparsedChangeTimePoint = Clock::now();
|
||||
result.translationUnitId = document.translationUnit().id();
|
||||
document.setDirtyIfDependencyIsMet(document.filePath());
|
||||
|
||||
document.incorporateUpdaterResult(result);
|
||||
@@ -350,6 +358,25 @@ TEST_F(Document, IncorporateUpdaterResultDoesNotResetDirtynessIfItWasChanged)
|
||||
ASSERT_TRUE(document.isNeedingReparse());
|
||||
}
|
||||
|
||||
TEST_F(Document, IncorporateUpdaterResultUpdatesTranslationUnitsReparseTimePoint)
|
||||
{
|
||||
TranslationUnits &translationUnits = document.translationUnits();
|
||||
const TranslationUnit initialTranslationUnit = translationUnits.get();
|
||||
translationUnits.updateParseTimePoint(initialTranslationUnit.id(), Clock::now());
|
||||
const TranslationUnit alternativeTranslationUnit = translationUnits.createAndAppend();
|
||||
translationUnits.updateParseTimePoint(alternativeTranslationUnit.id(), Clock::now());
|
||||
TranslationUnitUpdateResult result;
|
||||
result.reparseTimePoint = Clock::now();
|
||||
result.needsToBeReparsedChangeTimePoint = Clock::now();
|
||||
result.translationUnitId = initialTranslationUnit.id();
|
||||
document.setDirtyIfDependencyIsMet(document.filePath());
|
||||
ASSERT_THAT(translationUnits.get().id(), Eq(alternativeTranslationUnit.id()));
|
||||
|
||||
document.incorporateUpdaterResult(result);
|
||||
|
||||
ASSERT_THAT(translationUnits.get().id(), Eq(initialTranslationUnit.id()));
|
||||
}
|
||||
|
||||
void Document::SetUp()
|
||||
{
|
||||
projects.createOrUpdate({ProjectPartContainer(projectPartId)});
|
||||
|
||||
128
tests/unit/unittest/clangdocumentprocessor-test.cpp
Normal file
128
tests/unit/unittest/clangdocumentprocessor-test.cpp
Normal file
@@ -0,0 +1,128 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "clangiasyncjob.h"
|
||||
#include "dummyclangipcclient.h"
|
||||
#include "processevents-utilities.h"
|
||||
|
||||
#include <clangdocument.h>
|
||||
#include <clangdocumentprocessor.h>
|
||||
#include <clangdocuments.h>
|
||||
#include <clangjobrequest.h>
|
||||
#include <clangjobs.h>
|
||||
#include <projects.h>
|
||||
#include <unsavedfiles.h>
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include <gmock/gmock-matchers.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include "gtest-qt-printing.h"
|
||||
|
||||
using namespace ClangBackEnd;
|
||||
|
||||
namespace {
|
||||
|
||||
class DocumentProcessor : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
void SetUp() override;
|
||||
void TearDown() override;
|
||||
|
||||
ClangBackEnd::JobRequest createJobRequest(ClangBackEnd::JobRequest::Type type) const;
|
||||
|
||||
bool waitUntilAllJobsFinished(int timeOutInMs = 10000) const;
|
||||
|
||||
protected:
|
||||
ClangBackEnd::ProjectParts projects;
|
||||
ClangBackEnd::UnsavedFiles unsavedFiles;
|
||||
ClangBackEnd::Documents documents{projects, unsavedFiles};
|
||||
ClangBackEnd::Document document;
|
||||
|
||||
DummyIpcClient dummyIpcClient;
|
||||
|
||||
Utf8String filePath{Utf8StringLiteral(TESTDATA_DIR"/translationunits.cpp")};
|
||||
Utf8String projectPartId{Utf8StringLiteral("/path/to/projectfile")};
|
||||
|
||||
ClangBackEnd::DocumentProcessor documentProcessor{document,
|
||||
documents,
|
||||
unsavedFiles,
|
||||
projects,
|
||||
dummyIpcClient};
|
||||
};
|
||||
|
||||
TEST_F(DocumentProcessor, ProcessEmpty)
|
||||
{
|
||||
const JobRequests jobsStarted = documentProcessor.process();
|
||||
|
||||
ASSERT_THAT(jobsStarted.size(), 0);
|
||||
}
|
||||
|
||||
TEST_F(DocumentProcessor, ProcessSingleJob)
|
||||
{
|
||||
const JobRequest jobRequest = createJobRequest(JobRequest::Type::UpdateDocumentAnnotations);
|
||||
documentProcessor.addJob(jobRequest);
|
||||
|
||||
const JobRequests jobsStarted = documentProcessor.process();
|
||||
|
||||
ASSERT_THAT(jobsStarted.size(), 1);
|
||||
}
|
||||
|
||||
void DocumentProcessor::SetUp()
|
||||
{
|
||||
projects.createOrUpdate({ProjectPartContainer(projectPartId)});
|
||||
|
||||
const QVector<FileContainer> fileContainer{FileContainer(filePath, projectPartId)};
|
||||
document = documents.create(fileContainer).front();
|
||||
documents.setVisibleInEditors({filePath});
|
||||
documents.setUsedByCurrentEditor(filePath);
|
||||
}
|
||||
|
||||
void DocumentProcessor::TearDown()
|
||||
{
|
||||
ASSERT_TRUE(waitUntilAllJobsFinished()); // QFuture/QFutureWatcher is implemented with events
|
||||
}
|
||||
|
||||
JobRequest DocumentProcessor::createJobRequest(JobRequest::Type type) const
|
||||
{
|
||||
JobRequest jobRequest;
|
||||
jobRequest.type = type;
|
||||
jobRequest.requirements = JobRequest::requirementsForType(type);
|
||||
jobRequest.filePath = filePath;
|
||||
jobRequest.projectPartId = projectPartId;
|
||||
jobRequest.unsavedFilesChangeTimePoint = unsavedFiles.lastChangeTimePoint();
|
||||
jobRequest.documentRevision = document.documentRevision();
|
||||
jobRequest.projectChangeTimePoint = projects.project(projectPartId).lastChangeTimePoint();
|
||||
|
||||
return jobRequest;
|
||||
}
|
||||
|
||||
bool DocumentProcessor::waitUntilAllJobsFinished(int timeOutInMs) const
|
||||
{
|
||||
const auto noJobsRunningAnymore = [this](){ return documentProcessor.runningJobs().isEmpty(); };
|
||||
|
||||
return ProcessEventUtilities::processEventsUntilTrue(noJobsRunningAnymore, timeOutInMs);
|
||||
}
|
||||
|
||||
} // anonymous
|
||||
194
tests/unit/unittest/clangdocumentprocessors-test.cpp
Normal file
194
tests/unit/unittest/clangdocumentprocessors-test.cpp
Normal file
@@ -0,0 +1,194 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "clangiasyncjob.h"
|
||||
#include "dummyclangipcclient.h"
|
||||
#include "processevents-utilities.h"
|
||||
|
||||
#include <clangdocument.h>
|
||||
#include <clangdocumentprocessor.h>
|
||||
#include <clangdocumentprocessors.h>
|
||||
#include <clangdocuments.h>
|
||||
#include <clangexceptions.h>
|
||||
#include <clangjobrequest.h>
|
||||
#include <clangjobs.h>
|
||||
#include <projects.h>
|
||||
#include <unsavedfiles.h>
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include <gmock/gmock-matchers.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include "gtest-qt-printing.h"
|
||||
|
||||
using testing::Eq;
|
||||
|
||||
using namespace ClangBackEnd;
|
||||
|
||||
namespace {
|
||||
|
||||
class DocumentProcessors : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
void SetUp() override;
|
||||
void TearDown() override;
|
||||
|
||||
ClangBackEnd::JobRequest createJobRequest(ClangBackEnd::JobRequest::Type type) const;
|
||||
|
||||
bool waitUntilAllJobsFinished(int timeOutInMs = 10000) const;
|
||||
|
||||
protected:
|
||||
ClangBackEnd::ProjectParts projects;
|
||||
ClangBackEnd::UnsavedFiles unsavedFiles;
|
||||
ClangBackEnd::Documents documents{projects, unsavedFiles};
|
||||
ClangBackEnd::Document document;
|
||||
|
||||
DummyIpcClient dummyIpcClient;
|
||||
|
||||
Utf8String filePath{Utf8StringLiteral(TESTDATA_DIR"/translationunits.cpp")};
|
||||
Utf8String projectPartId{Utf8StringLiteral("/path/to/projectfile")};
|
||||
|
||||
ClangBackEnd::JobRequest jobRequest;
|
||||
ClangBackEnd::JobContext jobContext;
|
||||
|
||||
ClangBackEnd::DocumentProcessors documentProcessors{documents,
|
||||
unsavedFiles,
|
||||
projects,
|
||||
dummyIpcClient};
|
||||
};
|
||||
|
||||
TEST_F(DocumentProcessors, HasNoItemsInitially)
|
||||
{
|
||||
ASSERT_TRUE(documentProcessors.processors().empty());
|
||||
}
|
||||
|
||||
TEST_F(DocumentProcessors, CreateAddsADocumentProcessor)
|
||||
{
|
||||
documentProcessors.create(document);
|
||||
|
||||
ASSERT_THAT(documentProcessors.processors().size(), Eq(1));
|
||||
}
|
||||
|
||||
TEST_F(DocumentProcessors, CreateReturnsDocumentProcessor)
|
||||
{
|
||||
const DocumentProcessor documentProcessor = documentProcessors.create(document);
|
||||
|
||||
ASSERT_THAT(documentProcessor.document(), Eq(document));
|
||||
}
|
||||
|
||||
TEST_F(DocumentProcessors, CreateThrowsForAlreadyExisting)
|
||||
{
|
||||
documentProcessors.create(document);
|
||||
|
||||
ASSERT_THROW(documentProcessors.create(document),
|
||||
ClangBackEnd::DocumentProcessorAlreadyExists);
|
||||
}
|
||||
|
||||
TEST_F(DocumentProcessors, Access)
|
||||
{
|
||||
documentProcessors.create(document);
|
||||
|
||||
const DocumentProcessor documentProcessor = documentProcessors.processor(document);
|
||||
|
||||
ASSERT_THAT(documentProcessor.document(), Eq(document));
|
||||
}
|
||||
|
||||
TEST_F(DocumentProcessors, AccessThrowsForNotExisting)
|
||||
{
|
||||
ASSERT_THROW(documentProcessors.processor(document),
|
||||
ClangBackEnd::DocumentProcessorDoesNotExist);
|
||||
}
|
||||
|
||||
TEST_F(DocumentProcessors, Remove)
|
||||
{
|
||||
documentProcessors.create(document);
|
||||
|
||||
documentProcessors.remove(document);
|
||||
|
||||
ASSERT_TRUE(documentProcessors.processors().empty());
|
||||
}
|
||||
|
||||
TEST_F(DocumentProcessors, RemoveThrowsForNotExisting)
|
||||
{
|
||||
ASSERT_THROW(documentProcessors.remove(document),
|
||||
ClangBackEnd::DocumentProcessorDoesNotExist);
|
||||
}
|
||||
|
||||
TEST_F(DocumentProcessors, ProcessEmpty)
|
||||
{
|
||||
documentProcessors.create(document);
|
||||
|
||||
const JobRequests jobsStarted = documentProcessors.process();
|
||||
|
||||
ASSERT_TRUE(jobsStarted.isEmpty());
|
||||
}
|
||||
|
||||
TEST_F(DocumentProcessors, ProcessSingle)
|
||||
{
|
||||
DocumentProcessor documentProcessor = documentProcessors.create(document);
|
||||
const JobRequest jobRequest = createJobRequest(JobRequest::Type::UpdateDocumentAnnotations);
|
||||
documentProcessor.addJob(jobRequest);
|
||||
|
||||
const JobRequests jobsStarted = documentProcessors.process();
|
||||
|
||||
ASSERT_THAT(jobsStarted.size(), 1);
|
||||
}
|
||||
|
||||
void DocumentProcessors::SetUp()
|
||||
{
|
||||
projects.createOrUpdate({ProjectPartContainer(projectPartId)});
|
||||
|
||||
const QVector<FileContainer> fileContainer{FileContainer(filePath, projectPartId)};
|
||||
document = documents.create(fileContainer).front();
|
||||
documents.setVisibleInEditors({filePath});
|
||||
documents.setUsedByCurrentEditor(filePath);
|
||||
}
|
||||
|
||||
void DocumentProcessors::TearDown()
|
||||
{
|
||||
ASSERT_TRUE(waitUntilAllJobsFinished()); // QFuture/QFutureWatcher is implemented with events
|
||||
}
|
||||
|
||||
JobRequest DocumentProcessors::createJobRequest(JobRequest::Type type) const
|
||||
{
|
||||
JobRequest jobRequest;
|
||||
jobRequest.type = type;
|
||||
jobRequest.requirements = JobRequest::requirementsForType(type);
|
||||
jobRequest.filePath = filePath;
|
||||
jobRequest.projectPartId = projectPartId;
|
||||
jobRequest.unsavedFilesChangeTimePoint = unsavedFiles.lastChangeTimePoint();
|
||||
jobRequest.documentRevision = document.documentRevision();
|
||||
jobRequest.projectChangeTimePoint = projects.project(projectPartId).lastChangeTimePoint();
|
||||
|
||||
return jobRequest;
|
||||
}
|
||||
|
||||
bool DocumentProcessors::waitUntilAllJobsFinished(int timeOutInMs) const
|
||||
{
|
||||
const auto noJobsRunningAnymore = [this](){ return documentProcessors.runningJobs().isEmpty(); };
|
||||
|
||||
return ProcessEventUtilities::processEventsUntilTrue(noJobsRunningAnymore, timeOutInMs);
|
||||
}
|
||||
|
||||
} // anonymous
|
||||
@@ -43,6 +43,7 @@ using ClangBackEnd::ProjectPartContainer;
|
||||
using testing::IsNull;
|
||||
using testing::NotNull;
|
||||
using testing::Gt;
|
||||
using testing::Eq;
|
||||
using testing::Not;
|
||||
using testing::Contains;
|
||||
|
||||
@@ -158,6 +159,18 @@ TEST_F(Documents, UpdateSingle)
|
||||
IsDocument(filePath, projectPartId, 75u));
|
||||
}
|
||||
|
||||
TEST_F(Documents, UpdateReturnsUpdatedDocument)
|
||||
{
|
||||
ClangBackEnd::FileContainer createFileContainer(filePath, projectPartId, Utf8StringVector(), 74u);
|
||||
ClangBackEnd::FileContainer updateFileContainer(filePath, Utf8String(), Utf8StringVector(), 75u);
|
||||
documents.create({createFileContainer});
|
||||
|
||||
const std::vector<Document> updatedDocuments = documents.update({updateFileContainer});
|
||||
|
||||
ASSERT_THAT(updatedDocuments.size(), Eq(1u));
|
||||
ASSERT_THAT(updatedDocuments.front().documentRevision(), Eq(75u));
|
||||
}
|
||||
|
||||
TEST_F(Documents, UpdateMultiple)
|
||||
{
|
||||
ClangBackEnd::FileContainer fileContainer(filePath, projectPartId, Utf8StringVector(), 74u);
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <highlightingmarkcontainer.h>
|
||||
#include <clangcodemodelclientproxy.h>
|
||||
#include <clangcodemodelserverproxy.h>
|
||||
#include <clangtranslationunits.h>
|
||||
#include <requestdocumentannotations.h>
|
||||
#include <clangexceptions.h>
|
||||
|
||||
@@ -41,6 +42,7 @@
|
||||
#include <cmbunregisterprojectsforeditormessage.h>
|
||||
#include <cmbunregistertranslationunitsforeditormessage.h>
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QFile>
|
||||
|
||||
using testing::Property;
|
||||
@@ -135,6 +137,8 @@ protected:
|
||||
void completeCodeInFileA();
|
||||
void completeCodeInFileB();
|
||||
|
||||
bool isSupportiveTranslationUnitInitialized(const Utf8String &filePath);
|
||||
|
||||
void expectDocumentAnnotationsChanged(int count);
|
||||
void expectCompletion(const CodeCompletion &completion);
|
||||
void expectCompletionFromFileA();
|
||||
@@ -286,6 +290,64 @@ TEST_F(ClangClangCodeModelServer, SetCurrentAndVisibleEditor)
|
||||
ASSERT_TRUE(functionDocument.isVisibleInEditor());
|
||||
}
|
||||
|
||||
TEST_F(ClangClangCodeModelServer, StartCompletionJobFirstOnEditThatTriggersCompletion)
|
||||
{
|
||||
registerProjectAndFile(filePathA, 2);
|
||||
ASSERT_TRUE(waitUntilAllJobsFinished());
|
||||
expectCompletionFromFileA();
|
||||
|
||||
updateUnsavedContent(filePathA, unsavedContent(filePathAUnsavedVersion2), 1);
|
||||
completeCodeInFileA();
|
||||
|
||||
const QList<Jobs::RunningJob> jobs = clangServer.runningJobsForTestsOnly();
|
||||
ASSERT_THAT(jobs.size(), Eq(1));
|
||||
ASSERT_THAT(jobs.first().jobRequest.type, Eq(JobRequest::Type::CompleteCode));
|
||||
}
|
||||
|
||||
TEST_F(ClangClangCodeModelServer, SupportiveTranslationUnitNotInitializedAfterRegister)
|
||||
{
|
||||
registerProjectAndFile(filePathA, 1);
|
||||
|
||||
ASSERT_TRUE(waitUntilAllJobsFinished());
|
||||
ASSERT_FALSE(isSupportiveTranslationUnitInitialized(filePathA));
|
||||
}
|
||||
|
||||
TEST_F(ClangClangCodeModelServer, SupportiveTranslationUnitIsSetupAfterFirstEdit)
|
||||
{
|
||||
registerProjectAndFile(filePathA, 2);
|
||||
ASSERT_TRUE(waitUntilAllJobsFinished());
|
||||
|
||||
updateUnsavedContent(filePathA, unsavedContent(filePathAUnsavedVersion2), 1);
|
||||
|
||||
ASSERT_TRUE(waitUntilAllJobsFinished());
|
||||
ASSERT_TRUE(isSupportiveTranslationUnitInitialized(filePathA));
|
||||
}
|
||||
|
||||
TEST_F(ClangClangCodeModelServer, DoNotRunDuplicateJobs)
|
||||
{
|
||||
registerProjectAndFile(filePathA, 3);
|
||||
ASSERT_TRUE(waitUntilAllJobsFinished());
|
||||
updateUnsavedContent(filePathA, unsavedContent(filePathAUnsavedVersion2), 1);
|
||||
ASSERT_TRUE(waitUntilAllJobsFinished());
|
||||
ASSERT_TRUE(isSupportiveTranslationUnitInitialized(filePathA));
|
||||
updateUnsavedContent(filePathA, unsavedContent(filePathAUnsavedVersion2), 2);
|
||||
QCoreApplication::processEvents(); // adds + runs a job
|
||||
updateVisibilty(Utf8String(), Utf8String());
|
||||
|
||||
updateVisibilty(filePathA, filePathA); // triggers adding + runnings job on next processevents()
|
||||
}
|
||||
|
||||
TEST_F(ClangClangCodeModelServer, OpenDocumentAndEdit)
|
||||
{
|
||||
registerProjectAndFile(filePathA, 4);
|
||||
ASSERT_TRUE(waitUntilAllJobsFinished());
|
||||
|
||||
for (unsigned revision = 1; revision <= 3; ++revision) {
|
||||
updateUnsavedContent(filePathA, unsavedContent(filePathAUnsavedVersion2), revision);
|
||||
ASSERT_TRUE(waitUntilAllJobsFinished());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(ClangClangCodeModelServer, IsNotCurrentCurrentAndVisibleEditorAnymore)
|
||||
{
|
||||
registerProjectAndFilesAndWaitForFinished();
|
||||
@@ -323,8 +385,8 @@ void ClangClangCodeModelServer::TearDown()
|
||||
bool ClangClangCodeModelServer::waitUntilAllJobsFinished(int timeOutInMs)
|
||||
{
|
||||
const auto noJobsRunningAnymore = [this]() {
|
||||
return clangServer.jobsForTestOnly().runningJobs() == 0
|
||||
&& clangServer.jobsForTestOnly().queue().size() == 0
|
||||
return clangServer.runningJobsForTestsOnly().isEmpty()
|
||||
&& clangServer.queueSizeForTestsOnly() == 0
|
||||
&& !clangServer.isTimerRunningForTestOnly();
|
||||
};
|
||||
|
||||
@@ -411,6 +473,16 @@ void ClangClangCodeModelServer::completeCodeInFileB()
|
||||
completeCode(filePathB, 35, 1);
|
||||
}
|
||||
|
||||
bool ClangClangCodeModelServer::isSupportiveTranslationUnitInitialized(const Utf8String &filePath)
|
||||
{
|
||||
Document document = clangServer.documentsForTestOnly().document(filePath, projectPartId);
|
||||
DocumentProcessor documentProcessor = clangServer.documentProcessors().processor(document);
|
||||
|
||||
return document.translationUnits().size() == 2
|
||||
&& documentProcessor.hasSupportiveTranslationUnit()
|
||||
&& documentProcessor.isSupportiveTranslationUnitInitialized();
|
||||
}
|
||||
|
||||
void ClangClangCodeModelServer::expectCompletion(const CodeCompletion &completion)
|
||||
{
|
||||
EXPECT_CALL(mockClangCodeModelClient,
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
|
||||
#include <clangdocument.h>
|
||||
#include <clangdocuments.h>
|
||||
#include <clangtranslationunit.h>
|
||||
#include <clangtranslationunits.h>
|
||||
#include <clangjobs.h>
|
||||
#include <filecontainer.h>
|
||||
#include <projectpart.h>
|
||||
@@ -60,7 +62,9 @@ protected:
|
||||
Utf8String createTranslationUnitForDeletedFile();
|
||||
|
||||
JobRequest createJobRequest(const Utf8String &filePath,
|
||||
JobRequest::Type type) const;
|
||||
JobRequest::Type type,
|
||||
PreferredTranslationUnit preferredTranslationUnit
|
||||
= PreferredTranslationUnit::RecentlyParsed) const;
|
||||
|
||||
void updateDocumentRevision();
|
||||
void updateUnsavedFiles();
|
||||
@@ -91,6 +95,29 @@ TEST_F(JobQueue, AddJob)
|
||||
ASSERT_THAT(jobQueue.queue().size(), Eq(1));
|
||||
}
|
||||
|
||||
TEST_F(JobQueue, DoNotAddDuplicate)
|
||||
{
|
||||
const JobRequest request = createJobRequest(filePath1,
|
||||
JobRequest::Type::UpdateDocumentAnnotations);
|
||||
jobQueue.add(request);
|
||||
|
||||
const bool added = jobQueue.add(request);
|
||||
|
||||
ASSERT_FALSE(added);
|
||||
}
|
||||
|
||||
TEST_F(JobQueue, DoNotAddDuplicateForWhichAJobIsAlreadyRunning)
|
||||
{
|
||||
jobQueue.setIsJobRunningForJobRequestHandler([](const JobRequest &) {
|
||||
return true;
|
||||
});
|
||||
|
||||
const bool added = jobQueue.add(createJobRequest(filePath1,
|
||||
JobRequest::Type::UpdateDocumentAnnotations));
|
||||
|
||||
ASSERT_FALSE(added);
|
||||
}
|
||||
|
||||
TEST_F(JobQueue, ProcessEmpty)
|
||||
{
|
||||
jobQueue.processQueue();
|
||||
@@ -111,7 +138,7 @@ TEST_F(JobQueue, ProcessSingleJob)
|
||||
TEST_F(JobQueue, ProcessUntilEmpty)
|
||||
{
|
||||
jobQueue.add(createJobRequest(filePath1, JobRequest::Type::UpdateDocumentAnnotations));
|
||||
jobQueue.add(createJobRequest(filePath1, JobRequest::Type::UpdateDocumentAnnotations));
|
||||
jobQueue.add(createJobRequest(filePath1, JobRequest::Type::CreateInitialDocumentPreamble));
|
||||
|
||||
JobRequests jobsToRun;
|
||||
ASSERT_THAT(jobQueue.size(), Eq(2));
|
||||
@@ -231,7 +258,7 @@ TEST_F(JobQueue, PrioritizeCurrentDocumentOverVisible)
|
||||
TEST_F(JobQueue, RunNothingForNotCurrentOrVisibleDocument)
|
||||
{
|
||||
jobQueue.add(createJobRequest(filePath1, JobRequest::Type::UpdateDocumentAnnotations));
|
||||
jobQueue.add(createJobRequest(filePath1, JobRequest::Type::UpdateDocumentAnnotations));
|
||||
jobQueue.add(createJobRequest(filePath1, JobRequest::Type::CreateInitialDocumentPreamble));
|
||||
documents.setVisibleInEditors({});
|
||||
documents.setUsedByCurrentEditor(Utf8StringLiteral("aNonExistingFilePath"));
|
||||
|
||||
@@ -240,10 +267,10 @@ TEST_F(JobQueue, RunNothingForNotCurrentOrVisibleDocument)
|
||||
ASSERT_THAT(jobsToRun.size(), Eq(0));
|
||||
}
|
||||
|
||||
TEST_F(JobQueue, RunOnlyOneJobPerDocumentIfMultipleAreInQueue)
|
||||
TEST_F(JobQueue, RunOnlyOneJobPerTranslationUnitIfMultipleAreInQueue)
|
||||
{
|
||||
jobQueue.add(createJobRequest(filePath1, JobRequest::Type::UpdateDocumentAnnotations));
|
||||
jobQueue.add(createJobRequest(filePath1, JobRequest::Type::UpdateDocumentAnnotations));
|
||||
jobQueue.add(createJobRequest(filePath1, JobRequest::Type::CreateInitialDocumentPreamble));
|
||||
|
||||
const JobRequests jobsToRun = jobQueue.processQueue();
|
||||
|
||||
@@ -251,12 +278,30 @@ TEST_F(JobQueue, RunOnlyOneJobPerDocumentIfMultipleAreInQueue)
|
||||
ASSERT_THAT(jobQueue.size(), Eq(1));
|
||||
}
|
||||
|
||||
TEST_F(JobQueue, DoNotRunJobForDocumentThatIsBeingProcessed)
|
||||
TEST_F(JobQueue, RunJobsForDistinctTranslationUnits)
|
||||
{
|
||||
const TranslationUnit initialTu = document.translationUnit();
|
||||
document.translationUnits().updateParseTimePoint(initialTu.id(), std::chrono::steady_clock::now());
|
||||
const TranslationUnit alternativeTu = document.translationUnits().createAndAppend();
|
||||
document.translationUnits().updateParseTimePoint(alternativeTu.id(), std::chrono::steady_clock::now());
|
||||
jobQueue.add(createJobRequest(filePath1,
|
||||
JobRequest::Type::UpdateDocumentAnnotations,
|
||||
PreferredTranslationUnit::RecentlyParsed));
|
||||
jobQueue.add(createJobRequest(filePath1,
|
||||
JobRequest::Type::UpdateDocumentAnnotations,
|
||||
PreferredTranslationUnit::PreviouslyParsed));
|
||||
|
||||
const JobRequests jobsToRun = jobQueue.processQueue();
|
||||
|
||||
ASSERT_THAT(jobsToRun.size(), Eq(2));
|
||||
ASSERT_THAT(jobQueue.size(), Eq(0));
|
||||
}
|
||||
TEST_F(JobQueue, DoNotRunJobForTranslationUnittThatIsBeingProcessed)
|
||||
{
|
||||
jobQueue.add(createJobRequest(filePath1, JobRequest::Type::UpdateDocumentAnnotations));
|
||||
jobQueue.add(createJobRequest(filePath1, JobRequest::Type::UpdateDocumentAnnotations));
|
||||
jobQueue.add(createJobRequest(filePath1, JobRequest::Type::CreateInitialDocumentPreamble));
|
||||
JobRequests jobsToRun = jobQueue.processQueue();
|
||||
jobQueue.setIsJobRunningHandler([](const Utf8String &, const Utf8String &) {
|
||||
jobQueue.setIsJobRunningForTranslationUnitHandler([](const Utf8String &) {
|
||||
return true;
|
||||
});
|
||||
|
||||
@@ -397,8 +442,10 @@ Utf8String JobQueue::createTranslationUnitForDeletedFile()
|
||||
return temporaryFilePath;
|
||||
}
|
||||
|
||||
JobRequest JobQueue::createJobRequest(const Utf8String &filePath,
|
||||
JobRequest::Type type) const
|
||||
JobRequest JobQueue::createJobRequest(
|
||||
const Utf8String &filePath,
|
||||
JobRequest::Type type,
|
||||
PreferredTranslationUnit preferredTranslationUnit) const
|
||||
{
|
||||
JobRequest jobRequest;
|
||||
jobRequest.type = type;
|
||||
@@ -407,6 +454,7 @@ JobRequest JobQueue::createJobRequest(const Utf8String &filePath,
|
||||
jobRequest.projectPartId = projectPartId;
|
||||
jobRequest.unsavedFilesChangeTimePoint = unsavedFiles.lastChangeTimePoint();
|
||||
jobRequest.documentRevision = document.documentRevision();
|
||||
jobRequest.preferredTranslationUnit = preferredTranslationUnit;
|
||||
jobRequest.projectChangeTimePoint = projects.project(projectPartId).lastChangeTimePoint();
|
||||
|
||||
return jobRequest;
|
||||
|
||||
@@ -79,7 +79,7 @@ TEST_F(Jobs, ProcessEmptyQueue)
|
||||
const JobRequests jobsStarted = jobs.process();
|
||||
|
||||
ASSERT_THAT(jobsStarted.size(), Eq(0));
|
||||
ASSERT_THAT(jobs.runningJobs(), Eq(0));
|
||||
ASSERT_TRUE(jobs.runningJobs().isEmpty());
|
||||
}
|
||||
|
||||
TEST_F(Jobs, ProcessQueueWithSingleJob)
|
||||
@@ -89,7 +89,7 @@ TEST_F(Jobs, ProcessQueueWithSingleJob)
|
||||
const JobRequests jobsStarted = jobs.process();
|
||||
|
||||
ASSERT_THAT(jobsStarted.size(), Eq(1));
|
||||
ASSERT_THAT(jobs.runningJobs(), Eq(1));
|
||||
ASSERT_THAT(jobs.runningJobs().size(), Eq(1));
|
||||
}
|
||||
|
||||
TEST_F(Jobs, ProcessQueueUntilEmpty)
|
||||
@@ -108,7 +108,7 @@ TEST_F(Jobs, IsJobRunning)
|
||||
jobs.add(createJobRequest(filePath1, JobRequest::Type::UpdateDocumentAnnotations));
|
||||
jobs.process();
|
||||
|
||||
const bool isJobRunning = jobs.isJobRunning(filePath1, projectPartId);
|
||||
const bool isJobRunning = jobs.isJobRunningForTranslationUnit(document.translationUnit().id());
|
||||
|
||||
ASSERT_TRUE(isJobRunning);
|
||||
}
|
||||
@@ -130,7 +130,7 @@ void Jobs::TearDown()
|
||||
|
||||
bool Jobs::waitUntilAllJobsFinished(int timeOutInMs) const
|
||||
{
|
||||
const auto noJobsRunningAnymore = [this](){ return jobs.runningJobs() == 0; };
|
||||
const auto noJobsRunningAnymore = [this](){ return jobs.runningJobs().isEmpty(); };
|
||||
|
||||
return ProcessEventUtilities::processEventsUntilTrue(noJobsRunningAnymore, timeOutInMs);
|
||||
}
|
||||
@@ -138,7 +138,7 @@ bool Jobs::waitUntilAllJobsFinished(int timeOutInMs) const
|
||||
bool Jobs::waitUntilJobChainFinished(int timeOutInMs) const
|
||||
{
|
||||
const auto noJobsRunningAnymore = [this]() {
|
||||
return jobs.runningJobs() == 0 && jobs.queue().isEmpty();
|
||||
return jobs.runningJobs().isEmpty() && jobs.queue().isEmpty();
|
||||
};
|
||||
|
||||
return ProcessEventUtilities::processEventsUntilTrue(noJobsRunningAnymore, timeOutInMs);
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "clangasyncjob-base.h"
|
||||
|
||||
#include <clangparsesupportivetranslationunitjob.h>
|
||||
#include <clangtranslationunits.h>
|
||||
|
||||
using namespace ClangBackEnd;
|
||||
|
||||
using testing::Eq;
|
||||
using testing::Not;
|
||||
using testing::_;
|
||||
|
||||
namespace {
|
||||
|
||||
class ParseSupportiveTranslationUnitJob : public ClangAsyncJobTest
|
||||
{
|
||||
protected:
|
||||
void SetUp() override { BaseSetUp(JobRequest::Type::ParseSupportiveTranslationUnit, job); }
|
||||
|
||||
TimePoint parseTimePointOfDocument();
|
||||
|
||||
protected:
|
||||
ClangBackEnd::ParseSupportiveTranslationUnitJob job;
|
||||
};
|
||||
|
||||
TEST_F(ParseSupportiveTranslationUnitJob, PrepareAsyncRun)
|
||||
{
|
||||
job.setContext(jobContext);
|
||||
|
||||
ASSERT_TRUE(job.prepareAsyncRun());
|
||||
}
|
||||
|
||||
TEST_F(ParseSupportiveTranslationUnitJob, RunAsync)
|
||||
{
|
||||
job.setContext(jobContext);
|
||||
job.prepareAsyncRun();
|
||||
|
||||
job.runAsync();
|
||||
|
||||
ASSERT_TRUE(waitUntilJobFinished(job));
|
||||
}
|
||||
|
||||
TEST_F(ParseSupportiveTranslationUnitJob, DoNotIncorporateUpdaterResult)
|
||||
{
|
||||
const TimePoint parseTimePointBefore = parseTimePointOfDocument();
|
||||
job.setContext(jobContext);
|
||||
job.prepareAsyncRun();
|
||||
|
||||
job.runAsync();
|
||||
|
||||
ASSERT_TRUE(waitUntilJobFinished(job));
|
||||
ASSERT_THAT(parseTimePointOfDocument(), Eq(parseTimePointBefore));
|
||||
}
|
||||
|
||||
TimePoint ParseSupportiveTranslationUnitJob::parseTimePointOfDocument()
|
||||
{
|
||||
const Utf8String translationUnitId = document.translationUnit().id();
|
||||
|
||||
return document.translationUnits().parseTimePoint(translationUnitId);
|
||||
}
|
||||
|
||||
} // anonymous
|
||||
@@ -0,0 +1,109 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "clangasyncjob-base.h"
|
||||
|
||||
#include <clangreparsesupportivetranslationunitjob.h>
|
||||
#include <clangtranslationunits.h>
|
||||
|
||||
using namespace ClangBackEnd;
|
||||
|
||||
using testing::Eq;
|
||||
using testing::Not;
|
||||
using testing::_;
|
||||
|
||||
namespace {
|
||||
|
||||
class ReparseSupportiveTranslationUnitJob : public ClangAsyncJobTest
|
||||
{
|
||||
protected:
|
||||
void SetUp() override { BaseSetUp(JobRequest::Type::ReparseSupportiveTranslationUnit, job); }
|
||||
|
||||
TimePoint parseTimePointOfDocument();
|
||||
void parse();
|
||||
|
||||
protected:
|
||||
ClangBackEnd::ReparseSupportiveTranslationUnitJob job;
|
||||
};
|
||||
|
||||
TEST_F(ReparseSupportiveTranslationUnitJob, PrepareAsyncRun)
|
||||
{
|
||||
job.setContext(jobContext);
|
||||
|
||||
ASSERT_TRUE(job.prepareAsyncRun());
|
||||
}
|
||||
|
||||
TEST_F(ReparseSupportiveTranslationUnitJob, RunAsync)
|
||||
{
|
||||
parse();
|
||||
job.setContext(jobContext);
|
||||
job.prepareAsyncRun();
|
||||
|
||||
job.runAsync();
|
||||
|
||||
ASSERT_TRUE(waitUntilJobFinished(job));
|
||||
}
|
||||
|
||||
TEST_F(ReparseSupportiveTranslationUnitJob, IncorporateUpdaterResult)
|
||||
{
|
||||
parse();
|
||||
const TimePoint parseTimePointBefore = parseTimePointOfDocument();
|
||||
job.setContext(jobContext);
|
||||
job.prepareAsyncRun();
|
||||
|
||||
job.runAsync();
|
||||
|
||||
ASSERT_TRUE(waitUntilJobFinished(job));
|
||||
ASSERT_THAT(parseTimePointOfDocument(), Not(Eq(parseTimePointBefore)));
|
||||
}
|
||||
|
||||
TEST_F(ReparseSupportiveTranslationUnitJob, DoNotIncorporateUpdaterResultIfDocumentWasClosed)
|
||||
{
|
||||
parse();
|
||||
const TimePoint parseTimePointBefore = parseTimePointOfDocument();
|
||||
job.setContext(jobContext);
|
||||
job.prepareAsyncRun();
|
||||
|
||||
job.runAsync();
|
||||
documents.remove({FileContainer{filePath, projectPartId}});
|
||||
|
||||
ASSERT_TRUE(waitUntilJobFinished(job));
|
||||
ASSERT_THAT(parseTimePointOfDocument(), Eq(parseTimePointBefore));
|
||||
}
|
||||
|
||||
TimePoint ReparseSupportiveTranslationUnitJob::parseTimePointOfDocument()
|
||||
{
|
||||
const Utf8String translationUnitId = document.translationUnit().id();
|
||||
|
||||
return document.translationUnits().parseTimePoint(translationUnitId);
|
||||
}
|
||||
|
||||
void ReparseSupportiveTranslationUnitJob::parse()
|
||||
{
|
||||
projects.createOrUpdate({ProjectPartContainer{projectPartId, Utf8StringVector()}});
|
||||
document.parse();
|
||||
}
|
||||
|
||||
} // anonymous
|
||||
@@ -0,0 +1,262 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "dummyclangipcclient.h"
|
||||
#include "processevents-utilities.h"
|
||||
|
||||
#include <clangbackend_global.h>
|
||||
#include <clangdocuments.h>
|
||||
#include <clangexceptions.h>
|
||||
#include <clangsupportivetranslationunitinitializer.cpp>
|
||||
#include <clangtranslationunit.h>
|
||||
#include <clangtranslationunits.h>
|
||||
#include <projects.h>
|
||||
#include <utf8string.h>
|
||||
|
||||
#include <clang-c/Index.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include <gmock/gmock-matchers.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include "gtest-qt-printing.h"
|
||||
|
||||
using namespace ClangBackEnd;
|
||||
|
||||
using testing::Eq;
|
||||
|
||||
namespace {
|
||||
|
||||
class Data {
|
||||
public:
|
||||
Data()
|
||||
{
|
||||
projects.createOrUpdate({ProjectPartContainer(projectPartId)});
|
||||
|
||||
const QVector<FileContainer> fileContainer{FileContainer(filePath, projectPartId)};
|
||||
document = documents.create(fileContainer).front();
|
||||
documents.setVisibleInEditors({filePath});
|
||||
documents.setUsedByCurrentEditor(filePath);
|
||||
|
||||
const auto isDocumentClosed = [this](const Utf8String &filePath,
|
||||
const Utf8String &projectPartId) {
|
||||
return !documents.hasDocument(filePath, projectPartId);
|
||||
};
|
||||
const auto jobRequestCreator = [this](const Document &document,
|
||||
JobRequest::Type type,
|
||||
PreferredTranslationUnit preferredTranslationUnit) {
|
||||
return createJobRequest(document, type, preferredTranslationUnit);
|
||||
};
|
||||
initializer.reset(new ClangBackEnd::SupportiveTranslationUnitInitializer{document, jobs});
|
||||
initializer->setIsDocumentClosedChecker(isDocumentClosed);
|
||||
initializer->setJobRequestCreator(jobRequestCreator);
|
||||
}
|
||||
|
||||
JobRequest createJobRequest(const Document &document,
|
||||
JobRequest::Type type,
|
||||
PreferredTranslationUnit preferredTranslationUnit) const
|
||||
{
|
||||
JobRequest jobRequest;
|
||||
jobRequest.type = type;
|
||||
jobRequest.requirements = JobRequest::requirementsForType(type);
|
||||
jobRequest.filePath = document.filePath();
|
||||
jobRequest.projectPartId = document.projectPartId();
|
||||
jobRequest.unsavedFilesChangeTimePoint = unsavedFiles.lastChangeTimePoint();
|
||||
jobRequest.documentRevision = document.documentRevision();
|
||||
jobRequest.preferredTranslationUnit = preferredTranslationUnit;
|
||||
const ProjectPart &projectPart = projects.project(document.projectPartId());
|
||||
jobRequest.projectChangeTimePoint = projectPart.lastChangeTimePoint();
|
||||
|
||||
return jobRequest;
|
||||
}
|
||||
|
||||
public:
|
||||
Utf8String filePath{Utf8StringLiteral(TESTDATA_DIR"/translationunits.cpp")};
|
||||
Utf8String projectPartId{Utf8StringLiteral("/path/to/projectfile")};
|
||||
|
||||
ProjectParts projects;
|
||||
UnsavedFiles unsavedFiles;
|
||||
Documents documents{projects, unsavedFiles};
|
||||
Document document;
|
||||
DummyIpcClient dummyClientInterface;
|
||||
|
||||
Jobs jobs{documents, unsavedFiles, projects, dummyClientInterface};
|
||||
|
||||
std::unique_ptr<ClangBackEnd::SupportiveTranslationUnitInitializer> initializer;
|
||||
};
|
||||
|
||||
class SupportiveTranslationUnitInitializer : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
void parse();
|
||||
Jobs::RunningJob createRunningJob(JobRequest::Type type) const;
|
||||
|
||||
void assertNoJobIsRunningAndEmptyQueue();
|
||||
void assertSingleJobRunningAndEmptyQueue();
|
||||
|
||||
bool waitUntilJobChainFinished(int timeOutInMs = 10000) const;
|
||||
|
||||
protected:
|
||||
Data d;
|
||||
|
||||
Utf8String &filePath{d.filePath};
|
||||
Utf8String &projectPartId{d.projectPartId};
|
||||
|
||||
ProjectParts projects{d.projects};
|
||||
Document &document{d.document};
|
||||
Documents &documents{d.documents};
|
||||
Jobs &jobs{d.jobs};
|
||||
ClangBackEnd::SupportiveTranslationUnitInitializer &initializer{*d.initializer};
|
||||
};
|
||||
|
||||
TEST_F(SupportiveTranslationUnitInitializer, HasInitiallyNotInitializedState)
|
||||
{
|
||||
ASSERT_THAT(initializer.state(), Eq(ClangBackEnd::SupportiveTranslationUnitInitializer::State::NotInitialized));
|
||||
}
|
||||
|
||||
TEST_F(SupportiveTranslationUnitInitializer, StartInitializingAbortsIfDocumentIsClosed)
|
||||
{
|
||||
documents.remove({FileContainer(filePath, projectPartId)});
|
||||
|
||||
initializer.startInitializing();
|
||||
|
||||
assertNoJobIsRunningAndEmptyQueue();
|
||||
ASSERT_THAT(initializer.state(), Eq(ClangBackEnd::SupportiveTranslationUnitInitializer::State::Aborted));
|
||||
}
|
||||
|
||||
TEST_F(SupportiveTranslationUnitInitializer, StartInitializingAddsTranslationUnit)
|
||||
{
|
||||
initializer.startInitializing();
|
||||
|
||||
ASSERT_THAT(document.translationUnits().size(), Eq(2));
|
||||
ASSERT_FALSE(document.translationUnits().areAllTranslationUnitsParsed());
|
||||
}
|
||||
|
||||
TEST_F(SupportiveTranslationUnitInitializer, StartInitializingStartsJob)
|
||||
{
|
||||
initializer.startInitializing();
|
||||
|
||||
assertSingleJobRunningAndEmptyQueue();
|
||||
const Jobs::RunningJob runningJob = jobs.runningJobs().first();
|
||||
ASSERT_THAT(runningJob.jobRequest.type, JobRequest::Type::ParseSupportiveTranslationUnit);
|
||||
}
|
||||
|
||||
TEST_F(SupportiveTranslationUnitInitializer, CheckIfParseJobFinishedAbortsIfDocumentIsClosed)
|
||||
{
|
||||
documents.remove({FileContainer(filePath, projectPartId)});
|
||||
initializer.setState(ClangBackEnd::SupportiveTranslationUnitInitializer::State::WaitingForParseJob);
|
||||
const Jobs::RunningJob runningJob = createRunningJob(JobRequest::Type::ParseSupportiveTranslationUnit);
|
||||
|
||||
initializer.checkIfParseJobFinished(runningJob);
|
||||
|
||||
assertNoJobIsRunningAndEmptyQueue();
|
||||
ASSERT_THAT(initializer.state(), Eq(ClangBackEnd::SupportiveTranslationUnitInitializer::State::Aborted));
|
||||
}
|
||||
|
||||
TEST_F(SupportiveTranslationUnitInitializer, CheckIfParseJobFinishedStartsJob)
|
||||
{
|
||||
parse();
|
||||
initializer.setState(ClangBackEnd::SupportiveTranslationUnitInitializer::State::WaitingForParseJob);
|
||||
Jobs::RunningJob runningJob = createRunningJob(JobRequest::Type::ParseSupportiveTranslationUnit);
|
||||
|
||||
initializer.checkIfParseJobFinished(runningJob);
|
||||
jobs.process();
|
||||
|
||||
assertSingleJobRunningAndEmptyQueue();
|
||||
runningJob = jobs.runningJobs().first();
|
||||
ASSERT_THAT(runningJob.jobRequest.type, JobRequest::Type::ReparseSupportiveTranslationUnit);
|
||||
}
|
||||
|
||||
TEST_F(SupportiveTranslationUnitInitializer, CheckIfReparseJobFinishedAbortsIfDocumentIsClosed)
|
||||
{
|
||||
documents.remove({FileContainer(filePath, projectPartId)});
|
||||
initializer.setState(ClangBackEnd::SupportiveTranslationUnitInitializer::State::WaitingForReparseJob);
|
||||
const Jobs::RunningJob runningJob = createRunningJob(JobRequest::Type::ReparseSupportiveTranslationUnit);
|
||||
|
||||
initializer.checkIfReparseJobFinished(runningJob);
|
||||
|
||||
assertNoJobIsRunningAndEmptyQueue();
|
||||
ASSERT_THAT(initializer.state(), Eq(ClangBackEnd::SupportiveTranslationUnitInitializer::State::Aborted));
|
||||
}
|
||||
|
||||
TEST_F(SupportiveTranslationUnitInitializer, CheckIfReparseJobFinishedStartsJob)
|
||||
{
|
||||
parse();
|
||||
initializer.setState(ClangBackEnd::SupportiveTranslationUnitInitializer::State::WaitingForReparseJob);
|
||||
Jobs::RunningJob runningJob = createRunningJob(JobRequest::Type::ReparseSupportiveTranslationUnit);
|
||||
|
||||
initializer.checkIfReparseJobFinished(runningJob);
|
||||
jobs.process();
|
||||
|
||||
assertNoJobIsRunningAndEmptyQueue();
|
||||
ASSERT_THAT(initializer.state(), Eq(ClangBackEnd::SupportiveTranslationUnitInitializer::State::Initialized));
|
||||
}
|
||||
|
||||
TEST_F(SupportiveTranslationUnitInitializer, FullRun)
|
||||
{
|
||||
parse();
|
||||
initializer.startInitializing();
|
||||
|
||||
waitUntilJobChainFinished();
|
||||
ASSERT_THAT(initializer.state(), Eq(ClangBackEnd::SupportiveTranslationUnitInitializer::State::Initialized));
|
||||
}
|
||||
|
||||
void SupportiveTranslationUnitInitializer::parse()
|
||||
{
|
||||
projects.createOrUpdate({ProjectPartContainer{projectPartId, Utf8StringVector()}});
|
||||
document.parse();
|
||||
}
|
||||
|
||||
Jobs::RunningJob SupportiveTranslationUnitInitializer::createRunningJob(JobRequest::Type type) const
|
||||
{
|
||||
const JobRequest jobRequest = d.createJobRequest(document,
|
||||
type,
|
||||
PreferredTranslationUnit::LastUninitialized);
|
||||
return Jobs::RunningJob{jobRequest, Utf8String(), QFuture<void>()};
|
||||
}
|
||||
|
||||
void SupportiveTranslationUnitInitializer::assertNoJobIsRunningAndEmptyQueue()
|
||||
{
|
||||
ASSERT_TRUE(jobs.runningJobs().isEmpty());
|
||||
ASSERT_TRUE(jobs.queue().isEmpty());
|
||||
}
|
||||
|
||||
void SupportiveTranslationUnitInitializer::assertSingleJobRunningAndEmptyQueue()
|
||||
{
|
||||
ASSERT_THAT(jobs.runningJobs().size(), Eq(1));
|
||||
ASSERT_TRUE(jobs.queue().isEmpty());
|
||||
}
|
||||
|
||||
bool SupportiveTranslationUnitInitializer::waitUntilJobChainFinished(int timeOutInMs) const
|
||||
{
|
||||
const auto noJobsRunningAnymore = [this]() {
|
||||
return jobs.runningJobs().isEmpty() && jobs.queue().isEmpty();
|
||||
};
|
||||
|
||||
return ProcessEventUtilities::processEventsUntilTrue(noJobsRunningAnymore, timeOutInMs);
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
197
tests/unit/unittest/clangtranslationunit-test.cpp
Normal file
197
tests/unit/unittest/clangtranslationunit-test.cpp
Normal file
@@ -0,0 +1,197 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <clangtranslationunit.h>
|
||||
#include <clangtranslationunitupdater.h>
|
||||
#include <diagnosticcontainer.h>
|
||||
#include <utf8string.h>
|
||||
|
||||
#include <clang-c/Index.h>
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include <gmock/gmock-matchers.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include "gtest-qt-printing.h"
|
||||
|
||||
using ClangBackEnd::DiagnosticContainer;
|
||||
using ClangBackEnd::TranslationUnit;
|
||||
using ClangBackEnd::TranslationUnitUpdateInput;
|
||||
using ClangBackEnd::TranslationUnitUpdateResult;
|
||||
|
||||
using testing::ContainerEq;
|
||||
using testing::Eq;
|
||||
|
||||
namespace {
|
||||
|
||||
class TranslationUnit : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
void SetUp() override;
|
||||
void TearDown() override;
|
||||
|
||||
void parse();
|
||||
void reparse();
|
||||
|
||||
DiagnosticContainer createDiagnostic(const QString &text,
|
||||
ClangBackEnd::DiagnosticSeverity severity,
|
||||
uint line,
|
||||
uint column,
|
||||
const QString &filePath) const;
|
||||
QVector<DiagnosticContainer> diagnosticsFromMainFile() const;
|
||||
QVector<DiagnosticContainer> errorDiagnosticsFromHeaders() const;
|
||||
|
||||
protected:
|
||||
Utf8String sourceFilePath = Utf8StringLiteral(TESTDATA_DIR"/diagnostic_erroneous_source.cpp");
|
||||
Utf8String headerFilePath = Utf8StringLiteral(TESTDATA_DIR"/diagnostic_erroneous_header.h");
|
||||
CXIndex cxIndex = nullptr;
|
||||
CXTranslationUnit cxTranslationUnit = nullptr;
|
||||
::TranslationUnit translationUnit{Utf8String(), sourceFilePath, cxIndex, cxTranslationUnit};
|
||||
|
||||
DiagnosticContainer extractedFirstHeaderErrorDiagnostic;
|
||||
QVector<DiagnosticContainer> extractedMainFileDiagnostics;
|
||||
};
|
||||
|
||||
TEST_F(TranslationUnit, HasExpectedMainFileDiagnostics)
|
||||
{
|
||||
translationUnit.extractDiagnostics(extractedFirstHeaderErrorDiagnostic,
|
||||
extractedMainFileDiagnostics);
|
||||
|
||||
ASSERT_THAT(extractedMainFileDiagnostics, ContainerEq(diagnosticsFromMainFile()));
|
||||
}
|
||||
|
||||
TEST_F(TranslationUnit, HasExpectedMainFileDiagnosticsAfterReparse)
|
||||
{
|
||||
reparse();
|
||||
|
||||
translationUnit.extractDiagnostics(extractedFirstHeaderErrorDiagnostic,
|
||||
extractedMainFileDiagnostics);
|
||||
|
||||
ASSERT_THAT(extractedMainFileDiagnostics, ContainerEq(diagnosticsFromMainFile()));
|
||||
}
|
||||
|
||||
TEST_F(TranslationUnit, HasErrorDiagnosticsInHeaders)
|
||||
{
|
||||
translationUnit.extractDiagnostics(extractedFirstHeaderErrorDiagnostic,
|
||||
extractedMainFileDiagnostics);
|
||||
|
||||
ASSERT_THAT(extractedFirstHeaderErrorDiagnostic,
|
||||
Eq(errorDiagnosticsFromHeaders().first()));
|
||||
}
|
||||
|
||||
TEST_F(TranslationUnit, HasErrorDiagnosticsInHeadersAfterReparse)
|
||||
{
|
||||
reparse();
|
||||
|
||||
translationUnit.extractDiagnostics(extractedFirstHeaderErrorDiagnostic,
|
||||
extractedMainFileDiagnostics);
|
||||
|
||||
ASSERT_THAT(extractedFirstHeaderErrorDiagnostic,
|
||||
Eq(errorDiagnosticsFromHeaders().first()));
|
||||
}
|
||||
|
||||
void TranslationUnit::SetUp()
|
||||
{
|
||||
parse();
|
||||
}
|
||||
|
||||
void TranslationUnit::TearDown()
|
||||
{
|
||||
clang_disposeTranslationUnit(cxTranslationUnit);
|
||||
clang_disposeIndex(cxIndex);
|
||||
}
|
||||
|
||||
void TranslationUnit::parse()
|
||||
{
|
||||
TranslationUnitUpdateInput parseInput;
|
||||
parseInput.filePath = sourceFilePath;
|
||||
parseInput.parseNeeded = true;
|
||||
const TranslationUnitUpdateResult parseResult = translationUnit.update(parseInput);
|
||||
ASSERT_TRUE(parseResult.hasParsed());
|
||||
}
|
||||
|
||||
void TranslationUnit::reparse()
|
||||
{
|
||||
TranslationUnitUpdateInput parseInput;
|
||||
parseInput.filePath = sourceFilePath;
|
||||
parseInput.reparseNeeded = true;
|
||||
const TranslationUnitUpdateResult parseResult = translationUnit.update(parseInput);
|
||||
ASSERT_TRUE(parseResult.hasReparsed());
|
||||
}
|
||||
|
||||
DiagnosticContainer TranslationUnit::createDiagnostic(const QString &text,
|
||||
ClangBackEnd::DiagnosticSeverity severity,
|
||||
uint line,
|
||||
uint column,
|
||||
const QString &filePath) const
|
||||
{
|
||||
return DiagnosticContainer(
|
||||
text,
|
||||
Utf8StringLiteral(""),
|
||||
{},
|
||||
severity,
|
||||
{filePath, line, column},
|
||||
{},
|
||||
{},
|
||||
{}
|
||||
);
|
||||
}
|
||||
|
||||
QVector<ClangBackEnd::DiagnosticContainer> TranslationUnit::diagnosticsFromMainFile() const
|
||||
{
|
||||
return {
|
||||
createDiagnostic(
|
||||
QStringLiteral("warning: enumeration value 'Three' not handled in switch"),
|
||||
ClangBackEnd::DiagnosticSeverity::Warning,
|
||||
7,
|
||||
13,
|
||||
sourceFilePath),
|
||||
createDiagnostic(
|
||||
QStringLiteral("error: void function 'g' should not return a value"),
|
||||
ClangBackEnd::DiagnosticSeverity::Error,
|
||||
15,
|
||||
5,
|
||||
sourceFilePath),
|
||||
createDiagnostic(
|
||||
QStringLiteral("warning: using the result of an assignment as a condition without parentheses"),
|
||||
ClangBackEnd::DiagnosticSeverity::Warning,
|
||||
21,
|
||||
11,
|
||||
sourceFilePath),
|
||||
};
|
||||
}
|
||||
|
||||
QVector<ClangBackEnd::DiagnosticContainer> TranslationUnit::errorDiagnosticsFromHeaders() const
|
||||
{
|
||||
return {
|
||||
createDiagnostic(
|
||||
QStringLiteral("error: C++ requires a type specifier for all declarations"),
|
||||
ClangBackEnd::DiagnosticSeverity::Error,
|
||||
11,
|
||||
1,
|
||||
headerFilePath),
|
||||
};
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
153
tests/unit/unittest/clangtranslationunits-test.cpp
Normal file
153
tests/unit/unittest/clangtranslationunits-test.cpp
Normal file
@@ -0,0 +1,153 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <clangbackend_global.h>
|
||||
#include <clangexceptions.h>
|
||||
#include <clangtranslationunit.h>
|
||||
#include <clangtranslationunits.h>
|
||||
#include <utf8string.h>
|
||||
|
||||
#include <clang-c/Index.h>
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include <gmock/gmock-matchers.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include "gtest-qt-printing.h"
|
||||
|
||||
using ClangBackEnd::Clock;
|
||||
using ClangBackEnd::TranslationUnit;
|
||||
using ClangBackEnd::TranslationUnits;
|
||||
using ClangBackEnd::TranslationUnitDoesNotExist;
|
||||
using ClangBackEnd::PreferredTranslationUnit;
|
||||
|
||||
using testing::Eq;
|
||||
|
||||
namespace {
|
||||
|
||||
class TranslationUnits : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
Utf8String someFilePath = Utf8StringLiteral("someFilePath");
|
||||
ClangBackEnd::TranslationUnits translationUnits{someFilePath};
|
||||
};
|
||||
|
||||
TEST_F(TranslationUnits, CreatedUnitIsNull)
|
||||
{
|
||||
TranslationUnit translationUnit = translationUnits.createAndAppend();
|
||||
|
||||
ASSERT_TRUE(translationUnit.isNull());
|
||||
}
|
||||
|
||||
TEST_F(TranslationUnits, GetThrowsForNotExisting)
|
||||
{
|
||||
ASSERT_THROW(translationUnits.get(), TranslationUnitDoesNotExist);
|
||||
}
|
||||
|
||||
TEST_F(TranslationUnits, GetForSingleTranslationUnit)
|
||||
{
|
||||
const TranslationUnit created = translationUnits.createAndAppend();
|
||||
|
||||
const TranslationUnit queried = translationUnits.get();
|
||||
|
||||
ASSERT_THAT(queried.id(), Eq(created.id()));
|
||||
}
|
||||
|
||||
TEST_F(TranslationUnits, GetFirstForMultipleTranslationUnits)
|
||||
{
|
||||
const TranslationUnit created1 = translationUnits.createAndAppend();
|
||||
translationUnits.createAndAppend();
|
||||
|
||||
const TranslationUnit queried = translationUnits.get();
|
||||
|
||||
ASSERT_THAT(queried.id(), Eq(created1.id()));
|
||||
}
|
||||
|
||||
TEST_F(TranslationUnits, GetFirstForMultipleTranslationUnitsAndOnlyFirstParsed)
|
||||
{
|
||||
const TranslationUnit created1 = translationUnits.createAndAppend();
|
||||
translationUnits.updateParseTimePoint(created1.id(), Clock::now());
|
||||
translationUnits.createAndAppend();
|
||||
|
||||
const TranslationUnit queried = translationUnits.get();
|
||||
|
||||
ASSERT_THAT(queried.id(), Eq(created1.id()));
|
||||
}
|
||||
|
||||
TEST_F(TranslationUnits, GetFirstForMultipleTranslationUnitsAndOnlySecondParsed)
|
||||
{
|
||||
const TranslationUnit created1 = translationUnits.createAndAppend();
|
||||
const TranslationUnit created2 = translationUnits.createAndAppend();
|
||||
translationUnits.updateParseTimePoint(created2.id(), Clock::now());
|
||||
|
||||
const TranslationUnit queried = translationUnits.get();
|
||||
|
||||
ASSERT_THAT(queried.id(), Eq(created1.id()));
|
||||
}
|
||||
|
||||
TEST_F(TranslationUnits, GetLastUnitializedForMultipleTranslationUnits)
|
||||
{
|
||||
const TranslationUnit created1 = translationUnits.createAndAppend();
|
||||
translationUnits.updateParseTimePoint(created1.id(), Clock::now());
|
||||
const TranslationUnit created2 = translationUnits.createAndAppend();
|
||||
|
||||
const TranslationUnit queried = translationUnits.get(PreferredTranslationUnit::LastUninitialized);
|
||||
|
||||
ASSERT_THAT(queried.id(), Eq(created2.id()));
|
||||
}
|
||||
|
||||
TEST_F(TranslationUnits, GetRecentForMultipleTranslationUnits)
|
||||
{
|
||||
const TranslationUnit created1 = translationUnits.createAndAppend();
|
||||
translationUnits.updateParseTimePoint(created1.id(), Clock::now());
|
||||
const TranslationUnit created2 = translationUnits.createAndAppend();
|
||||
translationUnits.updateParseTimePoint(created2.id(), Clock::now());
|
||||
|
||||
const TranslationUnit queried = translationUnits.get(PreferredTranslationUnit::RecentlyParsed);
|
||||
|
||||
ASSERT_THAT(queried.id(), Eq(created2.id()));
|
||||
}
|
||||
|
||||
TEST_F(TranslationUnits, GetPreviousForMultipleTranslationUnits)
|
||||
{
|
||||
const TranslationUnit created1 = translationUnits.createAndAppend();
|
||||
translationUnits.updateParseTimePoint(created1.id(), Clock::now());
|
||||
const TranslationUnit created2 = translationUnits.createAndAppend();
|
||||
translationUnits.updateParseTimePoint(created2.id(), Clock::now());
|
||||
|
||||
const TranslationUnit queried = translationUnits.get(PreferredTranslationUnit::PreviouslyParsed);
|
||||
|
||||
ASSERT_THAT(queried.id(), Eq(created1.id()));
|
||||
}
|
||||
|
||||
TEST_F(TranslationUnits, UpdateThrowsForNotExisting)
|
||||
{
|
||||
ClangBackEnd::TranslationUnits otherTranslationUnits{someFilePath};
|
||||
const TranslationUnit translationUnit = otherTranslationUnits.createAndAppend();
|
||||
|
||||
ASSERT_THROW(translationUnits.updateParseTimePoint(translationUnit.id(), Clock::now()),
|
||||
TranslationUnitDoesNotExist);
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
@@ -97,7 +97,7 @@ TEST_F(UpdateDocumentAnnotationsJob, DontSendAnnotationsIfDocumentRevisionChange
|
||||
|
||||
TEST_F(UpdateDocumentAnnotationsJob, UpdatesTranslationUnit)
|
||||
{
|
||||
const time_point timePointBefore = document.lastProjectPartChangeTimePoint();
|
||||
const TimePoint timePointBefore = document.lastProjectPartChangeTimePoint();
|
||||
const QSet<Utf8String> dependendOnFilesBefore = document.dependedFilePaths();
|
||||
job.setContext(jobContext);
|
||||
job.prepareAsyncRun();
|
||||
|
||||
@@ -277,6 +277,7 @@ TEST_F(ClientServerInProcess, SendDocumentAnnotationsChangedMessage)
|
||||
|
||||
ClangBackEnd::DocumentAnnotationsChangedMessage message(fileContainer,
|
||||
{diagnostic},
|
||||
{},
|
||||
{highlightingMark},
|
||||
QVector<SourceRangeContainer>());
|
||||
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
|
||||
#include "googletest.h"
|
||||
|
||||
#include "clangcompareoperators.h"
|
||||
|
||||
#include <clangdocument.h>
|
||||
#include <clangdocuments.h>
|
||||
#include <clangstring.h>
|
||||
@@ -68,6 +70,7 @@ struct Data {
|
||||
{},
|
||||
documents};
|
||||
TranslationUnit translationUnit{filePath,
|
||||
filePath,
|
||||
document.translationUnit().cxIndex(),
|
||||
document.translationUnit().cxTranslationUnit()};
|
||||
};
|
||||
@@ -84,6 +87,8 @@ protected:
|
||||
const TranslationUnit &translationUnit = d->translationUnit;
|
||||
};
|
||||
|
||||
|
||||
|
||||
TEST_F(Cursor, CreateNullCursor)
|
||||
{
|
||||
::Cursor cursor;
|
||||
@@ -488,21 +493,21 @@ TEST_F(Cursor, HasNotFinaAttributeInClass)
|
||||
TEST_F(Cursor, HasOutputValues)
|
||||
{
|
||||
auto callExpressionCursor = translationUnit.cursorAt(117, 19);
|
||||
auto outputArgumentExpectedCursor = translationUnit.cursorAt(117, 20);
|
||||
auto outputArgumentExpectedSourceLocation = translationUnit.cursorAt(117, 20).cxSourceRange();
|
||||
|
||||
auto outputArguments = callExpressionCursor.outputArguments();
|
||||
auto outputArgumentLocations = callExpressionCursor.outputArgumentRanges();
|
||||
|
||||
ASSERT_THAT(outputArguments.size(), 1);
|
||||
ASSERT_THAT(outputArguments[0], outputArgumentExpectedCursor);
|
||||
ASSERT_THAT(outputArgumentLocations.size(), 2);
|
||||
ASSERT_THAT(outputArgumentLocations[0], outputArgumentExpectedSourceLocation);
|
||||
}
|
||||
|
||||
TEST_F(Cursor, HasOnlyInputValues)
|
||||
{
|
||||
auto callExpressionCursor = translationUnit.cursorAt(118, 18);
|
||||
|
||||
auto outputArguments = callExpressionCursor.outputArguments();
|
||||
auto outputArgumentLocations = callExpressionCursor.outputArgumentRanges();
|
||||
|
||||
ASSERT_THAT(outputArguments, IsEmpty());
|
||||
ASSERT_THAT(outputArgumentLocations, IsEmpty());
|
||||
}
|
||||
|
||||
TEST_F(Cursor, ArgumentCountIsZero)
|
||||
@@ -747,58 +752,58 @@ TEST_F(Cursor, PointerIsNotRefencingConstant)
|
||||
ASSERT_FALSE(argument.isReferencingConstant());
|
||||
}
|
||||
|
||||
TEST_F(Cursor, PointerIsOutputParameter)
|
||||
TEST_F(Cursor, PointerIsOutputArgument)
|
||||
{
|
||||
auto callExpressionCursor = translationUnit.cursorAt(127, 13);
|
||||
|
||||
auto argument = callExpressionCursor.type().argument(0);
|
||||
|
||||
ASSERT_TRUE(argument.isOutputParameter());
|
||||
ASSERT_TRUE(argument.isOutputArgument());
|
||||
}
|
||||
|
||||
TEST_F(Cursor, ConstantReferenceIsNotOutputParameter)
|
||||
TEST_F(Cursor, ConstantReferenceIsNotOutputArgument)
|
||||
{
|
||||
auto callExpressionCursor = translationUnit.cursorAt(125, 26);
|
||||
|
||||
auto argument = callExpressionCursor.type().argument(0);
|
||||
|
||||
ASSERT_FALSE(argument.isOutputParameter());
|
||||
ASSERT_FALSE(argument.isOutputArgument());
|
||||
}
|
||||
|
||||
TEST_F(Cursor, PointerToConstantIsNotOutputParameter)
|
||||
TEST_F(Cursor, PointerToConstantIsNotOutputArgument)
|
||||
{
|
||||
auto callExpressionCursor = translationUnit.cursorAt(126, 20);
|
||||
|
||||
auto argument = callExpressionCursor.type().argument(0);
|
||||
|
||||
ASSERT_FALSE(argument.isOutputParameter()) << argument.isConstant() << argument.pointeeType().isConstant();
|
||||
ASSERT_FALSE(argument.isOutputArgument()) << argument.isConstant() << argument.pointeeType().isConstant();
|
||||
}
|
||||
|
||||
TEST_F(Cursor, ConstantPointerIsNotOutputParameter)
|
||||
TEST_F(Cursor, ConstantPointerIsNotOutputArgument)
|
||||
{
|
||||
auto callExpressionCursor = translationUnit.cursorAt(128, 21);
|
||||
|
||||
auto argument = callExpressionCursor.type().argument(0);
|
||||
|
||||
ASSERT_TRUE(argument.isOutputParameter());
|
||||
ASSERT_TRUE(argument.isOutputArgument());
|
||||
}
|
||||
|
||||
TEST_F(Cursor, ReferenceIsOutputParameter)
|
||||
TEST_F(Cursor, ReferenceIsOutputArgument)
|
||||
{
|
||||
auto callExpressionCursor = translationUnit.cursorAt(124, 21);
|
||||
|
||||
auto argument = callExpressionCursor.type().argument(0);
|
||||
|
||||
ASSERT_TRUE(argument.isOutputParameter());
|
||||
ASSERT_TRUE(argument.isOutputArgument());
|
||||
}
|
||||
|
||||
TEST_F(Cursor, ConstReferenceIsNotOutputParameter)
|
||||
TEST_F(Cursor, ConstReferenceIsNotOutputArgument)
|
||||
{
|
||||
auto callExpressionCursor = translationUnit.cursorAt(125, 26);
|
||||
|
||||
auto argument = callExpressionCursor.type().argument(0);
|
||||
|
||||
ASSERT_FALSE(argument.isOutputParameter());
|
||||
ASSERT_FALSE(argument.isOutputArgument());
|
||||
}
|
||||
|
||||
Data *Cursor::d;
|
||||
|
||||
@@ -278,12 +278,12 @@ void FinalClass::FinalClassThisCall()
|
||||
}
|
||||
|
||||
|
||||
void OutputParameter(int &one, const int &two, int *three=0);
|
||||
void OutputArgument(int &one, const int &two, int *three=0);
|
||||
|
||||
void f12()
|
||||
void f12b()
|
||||
{
|
||||
int One;
|
||||
OutputParameter(One, 2);
|
||||
OutputArgument(One, 2);
|
||||
}
|
||||
|
||||
#include <highlightingmarks.h>
|
||||
@@ -445,3 +445,83 @@ struct LambdaTester
|
||||
lambda(var2);
|
||||
}
|
||||
};
|
||||
|
||||
void NonConstReferenceArgument(int &argument);
|
||||
|
||||
void f22()
|
||||
{
|
||||
int x = 1;
|
||||
|
||||
NonConstReferenceArgument(x);
|
||||
}
|
||||
|
||||
void ConstReferenceArgument(const int &argument);
|
||||
|
||||
void f23()
|
||||
{
|
||||
int x = 1;
|
||||
|
||||
ConstReferenceArgument(x);
|
||||
}
|
||||
|
||||
void RValueReferenceArgument(int &&argument);
|
||||
|
||||
void f24()
|
||||
{
|
||||
int x = 1;
|
||||
|
||||
RValueReferenceArgument(static_cast<int&&>(x));
|
||||
}
|
||||
|
||||
void NonConstPointerArgument(int *argument);
|
||||
|
||||
void f25()
|
||||
{
|
||||
int *x;
|
||||
|
||||
NonConstPointerArgument(x);
|
||||
}
|
||||
|
||||
void ConstPointerArgument(const int *argument);
|
||||
|
||||
void f26()
|
||||
{
|
||||
int *x;
|
||||
|
||||
ConstPointerArgument(x);
|
||||
}
|
||||
|
||||
void NonConstReferenceArgumentCallInsideCall(int x, int &argument);
|
||||
int GetArgument(int x);
|
||||
|
||||
void f27()
|
||||
{
|
||||
int x = 1;
|
||||
|
||||
NonConstReferenceArgumentCallInsideCall(GetArgument(x), x);
|
||||
}
|
||||
|
||||
void f28(int &Reference)
|
||||
{
|
||||
NonConstReferenceArgument(Reference);
|
||||
}
|
||||
|
||||
void f29()
|
||||
{
|
||||
int x;
|
||||
|
||||
NonConstPointerArgument(&x);
|
||||
}
|
||||
|
||||
struct NonConstPointerArgumentAsMemberOfClass
|
||||
{
|
||||
int member;
|
||||
};
|
||||
|
||||
void f30()
|
||||
{
|
||||
NonConstPointerArgumentAsMemberOfClass instance;
|
||||
|
||||
NonConstReferenceArgument(instance.member);
|
||||
}
|
||||
|
||||
|
||||
@@ -107,10 +107,11 @@ struct Data {
|
||||
Utf8String filePath{Utf8StringLiteral(TESTDATA_DIR"/highlightingmarks.cpp")};
|
||||
Document document{filePath,
|
||||
ProjectPart(Utf8StringLiteral("projectPartId"),
|
||||
{Utf8StringLiteral("-std=c++14")}),
|
||||
{Utf8StringLiteral("-std=c++14"), Utf8StringLiteral("-I" TESTDATA_DIR)}),
|
||||
{},
|
||||
documents};
|
||||
TranslationUnit translationUnit{filePath,
|
||||
filePath,
|
||||
document.translationUnit().cxIndex(),
|
||||
document.translationUnit().cxTranslationUnit()};
|
||||
};
|
||||
@@ -958,6 +959,106 @@ TEST_F(HighlightingMarks, TypeDefDeclarationUsage)
|
||||
ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Type));
|
||||
}
|
||||
|
||||
TEST_F(HighlightingMarks, NonConstReferenceArgument)
|
||||
{
|
||||
const auto infos = translationUnit.highlightingMarksInRange(sourceRange(455, 35));
|
||||
|
||||
infos[1];
|
||||
|
||||
ASSERT_THAT(infos[2],
|
||||
HasTwoTypes(HighlightingType::LocalVariable, HighlightingType::OutputArgument));
|
||||
}
|
||||
|
||||
TEST_F(HighlightingMarks, ConstReferenceArgument)
|
||||
{
|
||||
const auto infos = translationUnit.highlightingMarksInRange(sourceRange(464, 32));
|
||||
|
||||
infos[1];
|
||||
|
||||
ASSERT_THAT(infos[2],
|
||||
HasOnlyType(HighlightingType::LocalVariable));
|
||||
}
|
||||
|
||||
TEST_F(HighlightingMarks, RValueReferenceArgument)
|
||||
{
|
||||
const auto infos = translationUnit.highlightingMarksInRange(sourceRange(473, 52));
|
||||
|
||||
infos[1];
|
||||
|
||||
ASSERT_THAT(infos[8],
|
||||
HasOnlyType(HighlightingType::LocalVariable));
|
||||
}
|
||||
|
||||
TEST_F(HighlightingMarks, NonConstPointerArgument)
|
||||
{
|
||||
const auto infos = translationUnit.highlightingMarksInRange(sourceRange(482, 33));
|
||||
|
||||
infos[1];
|
||||
|
||||
ASSERT_THAT(infos[2],
|
||||
HasTwoTypes(HighlightingType::LocalVariable, HighlightingType::OutputArgument));
|
||||
}
|
||||
|
||||
TEST_F(HighlightingMarks, ConstPointerArgument)
|
||||
{
|
||||
const auto infos = translationUnit.highlightingMarksInRange(sourceRange(491, 30));
|
||||
|
||||
infos[1];
|
||||
|
||||
ASSERT_THAT(infos[2],
|
||||
HasOnlyType(HighlightingType::LocalVariable));
|
||||
}
|
||||
|
||||
TEST_F(HighlightingMarks, NonConstReferenceArgumentCallInsideCall)
|
||||
{
|
||||
const auto infos = translationUnit.highlightingMarksInRange(sourceRange(501, 64));
|
||||
infos[1];
|
||||
|
||||
infos[3];
|
||||
|
||||
ASSERT_THAT(infos[7],
|
||||
HasTwoTypes(HighlightingType::LocalVariable, HighlightingType::OutputArgument));
|
||||
}
|
||||
|
||||
TEST_F(HighlightingMarks, OutputArgumentsAreEmptyAfterIteration)
|
||||
{
|
||||
const auto infos = translationUnit.highlightingMarksInRange(sourceRange(501, 63));
|
||||
|
||||
for (const auto &info : infos ) {}
|
||||
|
||||
ASSERT_TRUE(infos.currentOutputArgumentRangesAreEmpty());
|
||||
}
|
||||
|
||||
TEST_F(HighlightingMarks, NonConstReferenceArgumentFromFunctionParameter)
|
||||
{
|
||||
const auto infos = translationUnit.highlightingMarksInRange(sourceRange(506, 42));
|
||||
|
||||
infos[1];
|
||||
|
||||
ASSERT_THAT(infos[2],
|
||||
HasTwoTypes(HighlightingType::LocalVariable, HighlightingType::OutputArgument));
|
||||
}
|
||||
|
||||
TEST_F(HighlightingMarks, NonConstPointerArgumentAsExpression)
|
||||
{
|
||||
const auto infos = translationUnit.highlightingMarksInRange(sourceRange(513, 33));
|
||||
|
||||
infos[1];
|
||||
|
||||
ASSERT_THAT(infos[3],
|
||||
HasTwoTypes(HighlightingType::LocalVariable, HighlightingType::OutputArgument));
|
||||
}
|
||||
|
||||
TEST_F(HighlightingMarks, NonConstPointerArgumentAsMemberOfClass)
|
||||
{
|
||||
const auto infos = translationUnit.highlightingMarksInRange(sourceRange(525, 46));
|
||||
|
||||
infos[1];
|
||||
|
||||
ASSERT_THAT(infos[4],
|
||||
HasTwoTypes(HighlightingType::Field, HighlightingType::OutputArgument));
|
||||
}
|
||||
|
||||
TEST_F(HighlightingMarks, DISABLED_EnumerationTypeDef)
|
||||
{
|
||||
const auto infos = translationUnit.highlightingMarksInRange(sourceRange(424, 41));
|
||||
|
||||
@@ -25,12 +25,12 @@
|
||||
|
||||
#include "googletest.h"
|
||||
|
||||
#include <clangclock.h>
|
||||
#include <projectpart.h>
|
||||
#include <clangexceptions.h>
|
||||
#include <projects.h>
|
||||
#include <utf8stringvector.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
||||
using testing::ElementsAre;
|
||||
@@ -82,7 +82,7 @@ TEST(ProjectPart, TimeStampIsUpdatedAsArgumentChanged)
|
||||
{
|
||||
ClangBackEnd::ProjectPart project(Utf8StringLiteral("/tmp/blah.pro"));
|
||||
auto lastChangeTimePoint = project.lastChangeTimePoint();
|
||||
std::this_thread::sleep_for(std::chrono::steady_clock::duration(1));
|
||||
std::this_thread::sleep_for(ClangBackEnd::Duration(1));
|
||||
|
||||
project.setArguments(Utf8StringVector({Utf8StringLiteral("-O"), Utf8StringLiteral("-fast")}));
|
||||
|
||||
@@ -163,7 +163,7 @@ TEST(ProjectPart, ProjectPartIsClearedAfterRemove)
|
||||
projects.createOrUpdate({projectContainer});
|
||||
ClangBackEnd::ProjectPart project = *projects.findProjectPart(projectContainer.projectPartId());
|
||||
const auto lastChangeTimePoint = project.lastChangeTimePoint();
|
||||
std::this_thread::sleep_for(std::chrono::steady_clock::duration(1));
|
||||
std::this_thread::sleep_for(ClangBackEnd::Duration(1));
|
||||
|
||||
projects.remove({projectContainer.projectPartId()});
|
||||
|
||||
|
||||
@@ -186,6 +186,7 @@ TEST_F(ReadAndWriteMessageBlock, CompareDocumentAnnotationsChangedMessage)
|
||||
|
||||
CompareMessage(ClangBackEnd::DocumentAnnotationsChangedMessage(fileContainer,
|
||||
{diagnostic},
|
||||
{},
|
||||
{highlightingMark},
|
||||
QVector<ClangBackEnd::SourceRangeContainer>()));
|
||||
}
|
||||
|
||||
@@ -99,6 +99,7 @@ struct Data {
|
||||
{},
|
||||
documents};
|
||||
TranslationUnit translationUnit{filePath,
|
||||
filePath,
|
||||
document.translationUnit().cxIndex(),
|
||||
document.translationUnit().cxTranslationUnit()};
|
||||
};
|
||||
|
||||
@@ -103,6 +103,7 @@ struct Data {
|
||||
Utf8StringVector(),
|
||||
documents};
|
||||
TranslationUnit translationUnit{filePath,
|
||||
filePath,
|
||||
document.translationUnit().cxIndex(),
|
||||
document.translationUnit().cxTranslationUnit()};
|
||||
|
||||
|
||||
@@ -25,14 +25,18 @@
|
||||
|
||||
#include "googletest.h"
|
||||
|
||||
#include <clangclock.h>
|
||||
#include <clangtranslationunitupdater.h>
|
||||
|
||||
#include <clang-c/Index.h>
|
||||
|
||||
using ClangBackEnd::Clock;
|
||||
using ClangBackEnd::TimePoint;
|
||||
using ClangBackEnd::TranslationUnitUpdater;
|
||||
using ClangBackEnd::TranslationUnitUpdateInput;
|
||||
using ClangBackEnd::TranslationUnitUpdateResult;
|
||||
|
||||
using testing::Eq;
|
||||
using testing::Gt;
|
||||
|
||||
namespace {
|
||||
@@ -42,7 +46,8 @@ class TranslationUnitUpdater : public ::testing::Test
|
||||
protected:
|
||||
void TearDown() override;
|
||||
|
||||
::TranslationUnitUpdater createUpdater(const TranslationUnitUpdateInput &input);
|
||||
::TranslationUnitUpdater createUpdater(const TranslationUnitUpdateInput &input,
|
||||
const Utf8String &translationUnitId = Utf8String());
|
||||
|
||||
enum ReparseMode { SetReparseNeeded, DoNotSetReparseNeeded };
|
||||
TranslationUnitUpdateInput createInput(ReparseMode reparseMode = DoNotSetReparseNeeded);
|
||||
@@ -73,10 +78,20 @@ TEST_F(TranslationUnitUpdater, ReparsesIfNeeded)
|
||||
ASSERT_TRUE(result.hasReparsed());
|
||||
}
|
||||
|
||||
TEST_F(TranslationUnitUpdater, PropagatesTranslationUnitId)
|
||||
{
|
||||
const Utf8String translationUnitId = Utf8StringLiteral("myId");
|
||||
::TranslationUnitUpdater updater = createUpdater(createInput(SetReparseNeeded), translationUnitId);
|
||||
|
||||
TranslationUnitUpdateResult result = updater.update(::TranslationUnitUpdater::UpdateMode::AsNeeded);
|
||||
|
||||
ASSERT_THAT(result.translationUnitId, Eq(translationUnitId));
|
||||
}
|
||||
|
||||
TEST_F(TranslationUnitUpdater, UpdatesParseTimePoint)
|
||||
{
|
||||
::TranslationUnitUpdater updater = createUpdater(createInput());
|
||||
const std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
|
||||
const TimePoint now = Clock::now();
|
||||
|
||||
TranslationUnitUpdateResult result = updater.update(::TranslationUnitUpdater::UpdateMode::AsNeeded);
|
||||
|
||||
@@ -111,9 +126,10 @@ void TranslationUnitUpdater::TearDown()
|
||||
}
|
||||
|
||||
::TranslationUnitUpdater
|
||||
TranslationUnitUpdater::createUpdater(const TranslationUnitUpdateInput &input)
|
||||
TranslationUnitUpdater::createUpdater(const TranslationUnitUpdateInput &input,
|
||||
const Utf8String &translationUnitId)
|
||||
{
|
||||
return ::TranslationUnitUpdater(cxIndex, cxTranslationUnit, input);
|
||||
return ::TranslationUnitUpdater(translationUnitId, cxIndex, cxTranslationUnit, input);
|
||||
}
|
||||
|
||||
TranslationUnitUpdateInput
|
||||
|
||||
@@ -49,13 +49,20 @@ SOURCES += \
|
||||
clangdiagnosticfilter-test.cpp \
|
||||
clangdocuments-test.cpp \
|
||||
clangdocument-test.cpp \
|
||||
clangdocumentprocessor-test.cpp \
|
||||
clangdocumentprocessors-test.cpp \
|
||||
clangfixitoperation-test.cpp \
|
||||
clangipcserver-test.cpp \
|
||||
clangisdiagnosticrelatedtolocation-test.cpp \
|
||||
clangjobqueue-test.cpp \
|
||||
clangjobs-test.cpp \
|
||||
clangparsesupportivetranslationunitjobtest.cpp \
|
||||
clangreparsesupportivetranslationunitjobtest.cpp \
|
||||
clangrequestdocumentannotationsjob-test.cpp \
|
||||
clangsupportivetranslationunitinitializertest.cpp \
|
||||
clangstring-test.cpp \
|
||||
clangtranslationunit-test.cpp \
|
||||
clangtranslationunits-test.cpp \
|
||||
clangupdatedocumentannotationsjob-test.cpp \
|
||||
codecompletionsextractor-test.cpp \
|
||||
codecompletion-test.cpp \
|
||||
@@ -111,6 +118,7 @@ HEADERS += \
|
||||
chunksreportedmonitor.h \
|
||||
clangasyncjob-base.h \
|
||||
diagnosticcontainer-matcher.h \
|
||||
clangcompareoperators.h \
|
||||
dummyclangipcclient.h \
|
||||
mockclangcodemodelclient.h \
|
||||
mockclangcodemodelserver.h
|
||||
|
||||
Reference in New Issue
Block a user