forked from qt-creator/qt-creator
We optimal indexer is only reindexing if the index would be changed. This patch is a step in that direction. We only reindex now if the file or project has changed. It fixes some typos too. Task-number: QTCREATORBUG-21150 Change-Id: I6ea1c13282fbcd70253b9b2939aed37580dbd160 Reviewed-by: Ivan Donchevskii <ivan.donchevskii@qt.io>
528 lines
23 KiB
C++
528 lines
23 KiB
C++
/****************************************************************************
|
|
**
|
|
** Copyright (C) 2018 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 "googletest.h"
|
|
|
|
#include "mocksqlitedatabase.h"
|
|
|
|
#include <builddependenciesstorage.h>
|
|
#include <projectpartsstorage.h>
|
|
#include <refactoringdatabaseinitializer.h>
|
|
#include <sqlitedatabase.h>
|
|
#include <sqlitereadstatement.h>
|
|
#include <sqlitewritestatement.h>
|
|
#include <symbolstorage.h>
|
|
namespace {
|
|
|
|
using ClangBackEnd::FilePathId;
|
|
using ClangBackEnd::IncludeSearchPath;
|
|
using ClangBackEnd::IncludeSearchPaths;
|
|
using ClangBackEnd::IncludeSearchPathType;
|
|
using ClangBackEnd::ProjectPartId;
|
|
using ClangBackEnd::ProjectPartIds;
|
|
|
|
class Data
|
|
{
|
|
protected:
|
|
ClangBackEnd::ProjectPartContainer projectPart1{1,
|
|
{"-m32"},
|
|
{{"FOO", "1", 1}},
|
|
{{"/include", 1, IncludeSearchPathType::System}},
|
|
{{"/home/yi", 2, IncludeSearchPathType::User}},
|
|
{1, 2},
|
|
{3, 4},
|
|
Utils::Language::Cxx,
|
|
Utils::LanguageVersion::CXX14,
|
|
Utils::LanguageExtension::Microsoft};
|
|
ClangBackEnd::ProjectPartContainer projectPart2{2,
|
|
{"-m64"},
|
|
{{"BAR", "2", 1}},
|
|
{{"/usr/include", 1, IncludeSearchPathType::System}},
|
|
{{"/home/er", 2, IncludeSearchPathType::User}},
|
|
{5, 6},
|
|
{7, 8},
|
|
Utils::Language::C,
|
|
Utils::LanguageVersion::C11,
|
|
Utils::LanguageExtension::Gnu};
|
|
};
|
|
|
|
class ProjectPartsStorage : public testing::Test, public Data
|
|
{
|
|
using Storage = ClangBackEnd::ProjectPartsStorage<MockSqliteDatabase>;
|
|
|
|
protected:
|
|
ProjectPartsStorage()
|
|
{
|
|
ON_CALL(fetchProjectPartByIdStatement, valueReturnProjectPartContainer(Eq(1)))
|
|
.WillByDefault(Return(projectPart1));
|
|
ON_CALL(fetchProjectPartByIdStatement, valueReturnProjectPartContainer(Eq(2)))
|
|
.WillByDefault(Return(projectPart2));
|
|
ON_CALL(fetchProjectPartsHeadersByIdStatement, valuesReturnFilePathIds(_, Eq(1)))
|
|
.WillByDefault(Return(projectPart1.headerPathIds));
|
|
ON_CALL(fetchProjectPartsHeadersByIdStatement, valuesReturnFilePathIds(_, Eq(2)))
|
|
.WillByDefault(Return(projectPart2.headerPathIds));
|
|
ON_CALL(fetchProjectPartsSourcesByIdStatement, valuesReturnFilePathIds(_, Eq(1)))
|
|
.WillByDefault(Return(projectPart1.sourcePathIds));
|
|
ON_CALL(fetchProjectPartsSourcesByIdStatement, valuesReturnFilePathIds(_, Eq(2)))
|
|
.WillByDefault(Return(projectPart2.sourcePathIds));
|
|
}
|
|
NiceMock<MockSqliteDatabase> mockDatabase;
|
|
Storage storage{mockDatabase};
|
|
MockSqliteReadStatement &fetchProjectPartIdStatement = storage.fetchProjectPartIdStatement;
|
|
MockSqliteWriteStatement &insertProjectPartNameStatement = storage.insertProjectPartNameStatement;
|
|
MockSqliteReadStatement &fetchProjectPartNameStatement = storage.fetchProjectPartNameStatement;
|
|
MockSqliteReadStatement &fetchProjectPartsStatement = storage.fetchProjectPartsStatement;
|
|
MockSqliteReadStatement &fetchProjectPartByIdStatement = storage.fetchProjectPartByIdStatement;
|
|
MockSqliteWriteStatement &updateProjectPartStatement = storage.updateProjectPartStatement;
|
|
MockSqliteReadStatement &getProjectPartArtefactsBySourceId = storage.getProjectPartArtefactsBySourceId;
|
|
MockSqliteReadStatement &getProjectPartArtefactsByProjectPartId = storage.getProjectPartArtefactsByProjectPartId;
|
|
MockSqliteWriteStatement &deleteProjectPartsHeadersByIdStatement = storage.deleteProjectPartsHeadersByIdStatement;
|
|
MockSqliteWriteStatement &deleteProjectPartsSourcesByIdStatement = storage.deleteProjectPartsSourcesByIdStatement;
|
|
MockSqliteWriteStatement &insertProjectPartsHeadersStatement = storage.insertProjectPartsHeadersStatement;
|
|
MockSqliteWriteStatement &insertProjectPartsSourcesStatement = storage.insertProjectPartsSourcesStatement;
|
|
MockSqliteReadStatement &fetchProjectPartsHeadersByIdStatement = storage.fetchProjectPartsHeadersByIdStatement;
|
|
MockSqliteReadStatement &fetchProjectPartsSourcesByIdStatement = storage.fetchProjectPartsSourcesByIdStatement;
|
|
MockSqliteReadStatement &fetchProjectPrecompiledHeaderPathStatement = storage.fetchProjectPrecompiledHeaderPathStatement;
|
|
MockSqliteWriteStatement &resetDependentIndexingTimeStampsStatement = storage.resetDependentIndexingTimeStampsStatement;
|
|
IncludeSearchPaths systemIncludeSearchPaths{{"/includes", 1, IncludeSearchPathType::BuiltIn},
|
|
{"/other/includes", 2, IncludeSearchPathType::System}};
|
|
IncludeSearchPaths projectIncludeSearchPaths{{"/project/includes", 1, IncludeSearchPathType::User},
|
|
{"/other/project/includes",
|
|
2,
|
|
IncludeSearchPathType::User}};
|
|
Utils::SmallString systemIncludeSearchPathsText{R"([["/includes",1,2],["/other/includes",2,3]])"};
|
|
Utils::SmallString projectIncludeSearchPathsText{
|
|
R"([["/project/includes",1,1],["/other/project/includes",2,1]])"};
|
|
ClangBackEnd::ProjectPartArtefact artefact{R"(["-DFOO"])",
|
|
R"([["FOO","1",1]])",
|
|
systemIncludeSearchPathsText,
|
|
projectIncludeSearchPathsText,
|
|
74,
|
|
Utils::Language::Cxx,
|
|
Utils::LanguageVersion::CXX11,
|
|
Utils::LanguageExtension::None};
|
|
};
|
|
|
|
TEST_F(ProjectPartsStorage, CallsFetchProjectIdWithNonExistingProjectPartName)
|
|
{
|
|
InSequence s;
|
|
|
|
EXPECT_CALL(mockDatabase, deferredBegin());
|
|
EXPECT_CALL(fetchProjectPartIdStatement,
|
|
valueReturnProjectPartId(TypedEq<Utils::SmallStringView>("test")));
|
|
EXPECT_CALL(insertProjectPartNameStatement, write(TypedEq<Utils::SmallStringView>("test")));
|
|
EXPECT_CALL(mockDatabase, commit());
|
|
|
|
storage.fetchProjectPartId("test");
|
|
}
|
|
|
|
TEST_F(ProjectPartsStorage, CallsFetchProjectIdWithExistingProjectPart)
|
|
{
|
|
InSequence s;
|
|
|
|
EXPECT_CALL(mockDatabase, deferredBegin());
|
|
EXPECT_CALL(fetchProjectPartIdStatement,
|
|
valueReturnProjectPartId(TypedEq<Utils::SmallStringView>("test")))
|
|
.WillOnce(Return(Utils::optional<ProjectPartId>{20}));
|
|
EXPECT_CALL(insertProjectPartNameStatement, write(TypedEq<Utils::SmallStringView>("test"))).Times(0);
|
|
EXPECT_CALL(mockDatabase, commit());
|
|
|
|
storage.fetchProjectPartId("test");
|
|
}
|
|
|
|
TEST_F(ProjectPartsStorage, CallsFetchProjectIdWithBusyDatabaset)
|
|
{
|
|
InSequence s;
|
|
|
|
EXPECT_CALL(mockDatabase, deferredBegin());
|
|
EXPECT_CALL(fetchProjectPartIdStatement,
|
|
valueReturnProjectPartId(TypedEq<Utils::SmallStringView>("test")));
|
|
EXPECT_CALL(insertProjectPartNameStatement, write(TypedEq<Utils::SmallStringView>("test")))
|
|
.WillOnce(Throw(Sqlite::StatementIsBusy("busy")));
|
|
EXPECT_CALL(mockDatabase, rollback());
|
|
EXPECT_CALL(mockDatabase, deferredBegin());
|
|
EXPECT_CALL(fetchProjectPartIdStatement,
|
|
valueReturnProjectPartId(TypedEq<Utils::SmallStringView>("test")));
|
|
EXPECT_CALL(insertProjectPartNameStatement, write(TypedEq<Utils::SmallStringView>("test")));
|
|
EXPECT_CALL(mockDatabase, commit());
|
|
|
|
storage.fetchProjectPartId("test");
|
|
}
|
|
|
|
TEST_F(ProjectPartsStorage, FetchProjectIdWithNonExistingProjectPartName)
|
|
{
|
|
ON_CALL(fetchProjectPartIdStatement,
|
|
valueReturnProjectPartId(TypedEq<Utils::SmallStringView>("test")))
|
|
.WillByDefault(Return(Utils::optional<ProjectPartId>{}));
|
|
ON_CALL(mockDatabase, lastInsertedRowId()).WillByDefault(Return(21));
|
|
|
|
auto id = storage.fetchProjectPartId("test");
|
|
|
|
ASSERT_THAT(id.projectPathId, 21);
|
|
}
|
|
|
|
TEST_F(ProjectPartsStorage, FetchProjectIdWithNonExistingProjectPartNameAndIsBusy)
|
|
{
|
|
InSequence s;
|
|
EXPECT_CALL(fetchProjectPartIdStatement,
|
|
valueReturnProjectPartId(TypedEq<Utils::SmallStringView>("test")))
|
|
.WillOnce(Throw(Sqlite::StatementIsBusy("busy")));
|
|
EXPECT_CALL(fetchProjectPartIdStatement,
|
|
valueReturnProjectPartId(TypedEq<Utils::SmallStringView>("test")))
|
|
.WillOnce(Return(ClangBackEnd::ProjectPartId{21}));
|
|
ON_CALL(mockDatabase, lastInsertedRowId()).WillByDefault(Return(21));
|
|
|
|
auto id = storage.fetchProjectPartId("test");
|
|
|
|
ASSERT_THAT(id.projectPathId, 21);
|
|
}
|
|
|
|
TEST_F(ProjectPartsStorage, FetchProjectIdWithExistingProjectPartName)
|
|
{
|
|
ON_CALL(fetchProjectPartIdStatement,
|
|
valueReturnProjectPartId(TypedEq<Utils::SmallStringView>("test")))
|
|
.WillByDefault(Return(Utils::optional<ProjectPartId>{20}));
|
|
|
|
auto id = storage.fetchProjectPartId("test");
|
|
|
|
ASSERT_THAT(id.projectPathId, 20);
|
|
}
|
|
|
|
TEST_F(ProjectPartsStorage, FetchProjectPartName)
|
|
{
|
|
InSequence s;
|
|
|
|
EXPECT_CALL(mockDatabase, deferredBegin());
|
|
EXPECT_CALL(fetchProjectPartNameStatement, valueReturnPathString(TypedEq<int>(12)))
|
|
.WillOnce(Return(Utils::optional<Utils::PathString>{"test"}));
|
|
EXPECT_CALL(mockDatabase, commit());
|
|
|
|
storage.fetchProjectPartName(12);
|
|
}
|
|
|
|
TEST_F(ProjectPartsStorage, FetchProjectPartNameStatementIsBusy)
|
|
{
|
|
InSequence s;
|
|
|
|
EXPECT_CALL(mockDatabase, deferredBegin());
|
|
EXPECT_CALL(fetchProjectPartNameStatement, valueReturnPathString(TypedEq<int>(12)))
|
|
.WillOnce(Throw(Sqlite::StatementIsBusy{""}));
|
|
EXPECT_CALL(mockDatabase, rollback());
|
|
EXPECT_CALL(mockDatabase, deferredBegin());
|
|
EXPECT_CALL(fetchProjectPartNameStatement, valueReturnPathString(TypedEq<int>(12)))
|
|
.WillOnce(Return(Utils::optional<Utils::PathString>{"test"}));
|
|
EXPECT_CALL(mockDatabase, commit());
|
|
|
|
storage.fetchProjectPartName(12);
|
|
}
|
|
|
|
TEST_F(ProjectPartsStorage, FetchProjectParts)
|
|
{
|
|
InSequence s;
|
|
|
|
EXPECT_CALL(mockDatabase, deferredBegin());
|
|
EXPECT_CALL(fetchProjectPartsStatement, valuesReturnProjectPartContainers(4096));
|
|
EXPECT_CALL(mockDatabase, commit());
|
|
|
|
storage.fetchProjectParts();
|
|
}
|
|
|
|
TEST_F(ProjectPartsStorage, FetchProjectPartsByIds)
|
|
{
|
|
InSequence s;
|
|
|
|
EXPECT_CALL(mockDatabase, deferredBegin());
|
|
EXPECT_CALL(fetchProjectPartByIdStatement, valueReturnProjectPartContainer(Eq(1)));
|
|
EXPECT_CALL(fetchProjectPartsHeadersByIdStatement, valuesReturnFilePathIds(1024, Eq(1)));
|
|
EXPECT_CALL(fetchProjectPartsSourcesByIdStatement, valuesReturnFilePathIds(1024, Eq(1)));
|
|
EXPECT_CALL(fetchProjectPrecompiledHeaderPathStatement, valueReturnSmallString(Eq(1)));
|
|
EXPECT_CALL(fetchProjectPartByIdStatement, valueReturnProjectPartContainer(Eq(2)));
|
|
EXPECT_CALL(fetchProjectPartsHeadersByIdStatement, valuesReturnFilePathIds(1024, Eq(2)));
|
|
EXPECT_CALL(fetchProjectPartsSourcesByIdStatement, valuesReturnFilePathIds(1024, Eq(2)));
|
|
EXPECT_CALL(fetchProjectPrecompiledHeaderPathStatement, valueReturnSmallString(Eq(2)));
|
|
EXPECT_CALL(mockDatabase, commit());
|
|
|
|
storage.fetchProjectParts({1, 2});
|
|
}
|
|
|
|
TEST_F(ProjectPartsStorage, FetchProjectPartsByIdsIsBusy)
|
|
{
|
|
InSequence s;
|
|
|
|
EXPECT_CALL(mockDatabase, deferredBegin());
|
|
EXPECT_CALL(fetchProjectPartByIdStatement, valueReturnProjectPartContainer(Eq(1)));
|
|
EXPECT_CALL(fetchProjectPartByIdStatement, valueReturnProjectPartContainer(Eq(2)))
|
|
.WillOnce(Throw(Sqlite::StatementIsBusy{""}));
|
|
EXPECT_CALL(mockDatabase, rollback());
|
|
EXPECT_CALL(mockDatabase, deferredBegin());
|
|
EXPECT_CALL(fetchProjectPartByIdStatement, valueReturnProjectPartContainer(Eq(1)));
|
|
EXPECT_CALL(fetchProjectPartByIdStatement, valueReturnProjectPartContainer(Eq(2)));
|
|
EXPECT_CALL(mockDatabase, commit());
|
|
|
|
storage.fetchProjectParts({1, 2});
|
|
}
|
|
|
|
TEST_F(ProjectPartsStorage, FetchProjectPartsByIdsHasPrecompiledNullOptional)
|
|
{
|
|
ON_CALL(fetchProjectPrecompiledHeaderPathStatement, valueReturnSmallString(Eq(1)))
|
|
.WillByDefault(Return(Utils::optional<Utils::SmallString>{}));
|
|
|
|
auto projectParts = storage.fetchProjectParts({1});
|
|
|
|
ASSERT_FALSE(projectParts.front().hasPrecompiledHeader);
|
|
}
|
|
|
|
TEST_F(ProjectPartsStorage, FetchProjectPartsByIdsHasPrecompiledEmptyString)
|
|
{
|
|
ON_CALL(fetchProjectPrecompiledHeaderPathStatement, valueReturnSmallString(Eq(1)))
|
|
.WillByDefault(Return(Utils::optional<Utils::SmallString>{""}));
|
|
|
|
auto projectParts = storage.fetchProjectParts({1});
|
|
|
|
ASSERT_FALSE(projectParts.front().hasPrecompiledHeader);
|
|
}
|
|
|
|
TEST_F(ProjectPartsStorage, FetchProjectPartsByIdsHasPrecompiledStringWithContent)
|
|
{
|
|
ON_CALL(fetchProjectPrecompiledHeaderPathStatement, valueReturnSmallString(Eq(1)))
|
|
.WillByDefault(Return(Utils::optional<Utils::SmallString>{"/some/path"}));
|
|
|
|
auto projectParts = storage.fetchProjectParts({1});
|
|
|
|
ASSERT_TRUE(projectParts.front().hasPrecompiledHeader);
|
|
}
|
|
|
|
TEST_F(ProjectPartsStorage, FetchProjectPartsByIdsHasMissingId)
|
|
{
|
|
auto projectParts = storage.fetchProjectParts({1, 2, 3});
|
|
|
|
ASSERT_THAT(projectParts, ElementsAre(projectPart1, projectPart2));
|
|
}
|
|
|
|
TEST_F(ProjectPartsStorage, ConvertStringsToJson)
|
|
{
|
|
Utils::SmallStringVector strings{"foo", "bar", "foo"};
|
|
|
|
auto jsonText = storage.toJson(strings);
|
|
|
|
ASSERT_THAT(jsonText, Eq("[\"foo\",\"bar\",\"foo\"]"));
|
|
}
|
|
|
|
TEST_F(ProjectPartsStorage, UpdateProjectParts)
|
|
{
|
|
InSequence sequence;
|
|
|
|
EXPECT_CALL(mockDatabase, immediateBegin());
|
|
EXPECT_CALL(updateProjectPartStatement,
|
|
write(TypedEq<int>(1),
|
|
TypedEq<Utils::SmallStringView>(R"(["-m32"])"),
|
|
TypedEq<Utils::SmallStringView>(R"([["FOO","1",1]])"),
|
|
TypedEq<Utils::SmallStringView>(R"([["/include",1,3]])"),
|
|
TypedEq<Utils::SmallStringView>(R"([["/home/yi",2,1]])"),
|
|
2,
|
|
35,
|
|
2));
|
|
EXPECT_CALL(deleteProjectPartsHeadersByIdStatement, write(TypedEq<int>(1)));
|
|
EXPECT_CALL(insertProjectPartsHeadersStatement, write(TypedEq<int>(1), TypedEq<int>(1)));
|
|
EXPECT_CALL(insertProjectPartsHeadersStatement, write(TypedEq<int>(1), TypedEq<int>(2)));
|
|
EXPECT_CALL(deleteProjectPartsSourcesByIdStatement, write(TypedEq<int>(1)));
|
|
EXPECT_CALL(insertProjectPartsSourcesStatement, write(TypedEq<int>(1), TypedEq<int>(3)));
|
|
EXPECT_CALL(insertProjectPartsSourcesStatement, write(TypedEq<int>(1), TypedEq<int>(4)));
|
|
EXPECT_CALL(updateProjectPartStatement,
|
|
write(TypedEq<int>(2),
|
|
TypedEq<Utils::SmallStringView>(R"(["-m64"])"),
|
|
TypedEq<Utils::SmallStringView>(R"([["BAR","2",1]])"),
|
|
TypedEq<Utils::SmallStringView>(R"([["/usr/include",1,3]])"),
|
|
TypedEq<Utils::SmallStringView>(R"([["/home/er",2,1]])"),
|
|
1,
|
|
3,
|
|
1));
|
|
EXPECT_CALL(deleteProjectPartsHeadersByIdStatement, write(TypedEq<int>(2)));
|
|
EXPECT_CALL(insertProjectPartsHeadersStatement, write(TypedEq<int>(2), TypedEq<int>(5)));
|
|
EXPECT_CALL(insertProjectPartsHeadersStatement, write(TypedEq<int>(2), TypedEq<int>(6)));
|
|
EXPECT_CALL(deleteProjectPartsSourcesByIdStatement, write(TypedEq<int>(2)));
|
|
EXPECT_CALL(insertProjectPartsSourcesStatement, write(TypedEq<int>(2), TypedEq<int>(7)));
|
|
EXPECT_CALL(insertProjectPartsSourcesStatement, write(TypedEq<int>(2), TypedEq<int>(8)));
|
|
EXPECT_CALL(mockDatabase, commit());
|
|
|
|
storage.updateProjectParts({projectPart1, projectPart2});
|
|
}
|
|
|
|
TEST_F(ProjectPartsStorage, UpdateProjectPartsIsBusy)
|
|
{
|
|
InSequence sequence;
|
|
|
|
EXPECT_CALL(mockDatabase, immediateBegin()).WillOnce(Throw(Sqlite::StatementIsBusy{""}));
|
|
EXPECT_CALL(mockDatabase, immediateBegin());
|
|
EXPECT_CALL(updateProjectPartStatement,
|
|
write(TypedEq<int>(1),
|
|
TypedEq<Utils::SmallStringView>(R"(["-m32"])"),
|
|
TypedEq<Utils::SmallStringView>(R"([["FOO","1",1]])"),
|
|
TypedEq<Utils::SmallStringView>(R"([["/include",1,3]])"),
|
|
TypedEq<Utils::SmallStringView>(R"([["/home/yi",2,1]])"),
|
|
2,
|
|
35,
|
|
2));
|
|
EXPECT_CALL(mockDatabase, commit());
|
|
|
|
storage.updateProjectParts({projectPart1});
|
|
}
|
|
|
|
TEST_F(ProjectPartsStorage, FetchProjectPartArtefactBySourceIdCallsValueInStatement)
|
|
{
|
|
EXPECT_CALL(getProjectPartArtefactsBySourceId, valueReturnProjectPartArtefact(1))
|
|
.WillRepeatedly(Return(artefact));
|
|
|
|
storage.fetchProjectPartArtefact(FilePathId{1});
|
|
}
|
|
|
|
TEST_F(ProjectPartsStorage, FetchProjectPartArtefactBySourceIdReturnArtefact)
|
|
{
|
|
EXPECT_CALL(getProjectPartArtefactsBySourceId, valueReturnProjectPartArtefact(1))
|
|
.WillRepeatedly(Return(artefact));
|
|
|
|
auto result = storage.fetchProjectPartArtefact(FilePathId{1});
|
|
|
|
ASSERT_THAT(result, Eq(artefact));
|
|
}
|
|
|
|
TEST_F(ProjectPartsStorage, FetchProjectPartArtefactByProjectPartIdCallsValueInStatement)
|
|
{
|
|
EXPECT_CALL(getProjectPartArtefactsByProjectPartId, valueReturnProjectPartArtefact(74))
|
|
.WillRepeatedly(Return(artefact));
|
|
|
|
storage.fetchProjectPartArtefact(ProjectPartId{74});
|
|
}
|
|
|
|
TEST_F(ProjectPartsStorage, FetchProjectPartArtefactByProjectPartIdReturnArtefact)
|
|
{
|
|
EXPECT_CALL(getProjectPartArtefactsByProjectPartId, valueReturnProjectPartArtefact(74))
|
|
.WillRepeatedly(Return(artefact));
|
|
|
|
auto result = storage.fetchProjectPartArtefact(ProjectPartId{74});
|
|
|
|
ASSERT_THAT(result, Eq(artefact));
|
|
}
|
|
|
|
TEST_F(ProjectPartsStorage, ResetDependentIndexingTimeStamps)
|
|
{
|
|
InSequence s;
|
|
|
|
EXPECT_CALL(mockDatabase, immediateBegin());
|
|
EXPECT_CALL(resetDependentIndexingTimeStampsStatement, write(TypedEq<int>(3)));
|
|
EXPECT_CALL(resetDependentIndexingTimeStampsStatement, write(TypedEq<int>(4)));
|
|
EXPECT_CALL(resetDependentIndexingTimeStampsStatement, write(TypedEq<int>(7)));
|
|
EXPECT_CALL(resetDependentIndexingTimeStampsStatement, write(TypedEq<int>(8)));
|
|
EXPECT_CALL(mockDatabase, commit());
|
|
|
|
storage.resetIndexingTimeStamps({projectPart1, projectPart2});
|
|
}
|
|
|
|
TEST_F(ProjectPartsStorage, ResetDependentIndexingTimeStampsIsBusy)
|
|
{
|
|
InSequence s;
|
|
|
|
EXPECT_CALL(mockDatabase, immediateBegin()).WillOnce(Throw(Sqlite::StatementIsBusy{""}));
|
|
EXPECT_CALL(mockDatabase, immediateBegin());
|
|
EXPECT_CALL(resetDependentIndexingTimeStampsStatement, write(TypedEq<int>(3)));
|
|
EXPECT_CALL(resetDependentIndexingTimeStampsStatement, write(TypedEq<int>(4)));
|
|
EXPECT_CALL(resetDependentIndexingTimeStampsStatement, write(TypedEq<int>(7)));
|
|
EXPECT_CALL(resetDependentIndexingTimeStampsStatement, write(TypedEq<int>(8)));
|
|
EXPECT_CALL(mockDatabase, commit());
|
|
|
|
storage.resetIndexingTimeStamps({projectPart1, projectPart2});
|
|
}
|
|
|
|
class ProjectPartsStorageSlow : public testing::Test, public Data
|
|
{
|
|
using Storage = ClangBackEnd::ProjectPartsStorage<Sqlite::Database>;
|
|
|
|
protected:
|
|
Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory};
|
|
ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> databaseInitializer{database};
|
|
Storage storage{database};
|
|
ClangBackEnd::SymbolStorage<> symbolStorage{database};
|
|
ClangBackEnd::BuildDependenciesStorage<> buildDependenciesStorage{database};
|
|
};
|
|
|
|
TEST_F(ProjectPartsStorageSlow, FetchProjectPartName)
|
|
{
|
|
auto id = storage.fetchProjectPartId("test");
|
|
|
|
auto name = storage.fetchProjectPartName(id);
|
|
|
|
ASSERT_THAT(name, "test");
|
|
}
|
|
|
|
TEST_F(ProjectPartsStorageSlow, FetchNonExistingProjectPartName)
|
|
{
|
|
ASSERT_THROW(storage.fetchProjectPartName(ClangBackEnd::ProjectPartId{1}),
|
|
ClangBackEnd::ProjectPartDoesNotExists);
|
|
}
|
|
|
|
TEST_F(ProjectPartsStorageSlow, FetchProjectPartId)
|
|
{
|
|
auto first = storage.fetchProjectPartId("test");
|
|
|
|
auto second = storage.fetchProjectPartId("test");
|
|
|
|
ASSERT_THAT(first, Eq(second));
|
|
}
|
|
|
|
TEST_F(ProjectPartsStorageSlow, FetchProjectParts)
|
|
{
|
|
projectPart1.projectPartId = storage.fetchProjectPartId("project1");
|
|
projectPart2.projectPartId = storage.fetchProjectPartId("project2");
|
|
storage.updateProjectParts({projectPart1, projectPart2});
|
|
|
|
auto projectParts = storage.fetchProjectParts(
|
|
{projectPart1.projectPartId, projectPart2.projectPartId});
|
|
|
|
ASSERT_THAT(projectParts, ElementsAre(projectPart1, projectPart2));
|
|
}
|
|
|
|
TEST_F(ProjectPartsStorageSlow, ResetDependentIndexingTimeStamps)
|
|
{
|
|
symbolStorage.insertOrUpdateIndexingTimeStamps({1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 34);
|
|
buildDependenciesStorage.insertOrUpdateSourceDependencies(
|
|
{{3, 1}, {4, 1}, {1, 2}, {7, 5}, {8, 6}, {6, 5}, {9, 10}});
|
|
|
|
storage.resetIndexingTimeStamps({projectPart1, projectPart2});
|
|
|
|
ASSERT_THAT(symbolStorage.fetchIndexingTimeStamps(),
|
|
ElementsAre(SourceTimeStamp{1, 0},
|
|
SourceTimeStamp{2, 0},
|
|
SourceTimeStamp{3, 0},
|
|
SourceTimeStamp{4, 0},
|
|
SourceTimeStamp{5, 0},
|
|
SourceTimeStamp{6, 0},
|
|
SourceTimeStamp{7, 0},
|
|
SourceTimeStamp{8, 0},
|
|
SourceTimeStamp{9, 34},
|
|
SourceTimeStamp{10, 34}));
|
|
}
|
|
|
|
} // namespace
|