Move file versioning functions out of DatabaseInterface

They don't need to be member functions, and needing a pointer to an
instance of that interface is awkward.

The function names have also changed to reflect that they're not
specific to the masterlists.
This commit is contained in:
Oliver Hamlet
2021-09-23 13:31:34 +01:00
parent 5ce0df0f03
commit e5a229e09f
10 changed files with 295 additions and 248 deletions
+23
View File
@@ -28,6 +28,7 @@
#include "api/game/game.h"
#include "api/helpers/logging.h"
#include "api/helpers/git.h"
namespace fs = std::filesystem;
@@ -97,4 +98,26 @@ LOOT_API std::shared_ptr<GameInterface> CreateGameHandle(
return std::make_shared<Game>(game, resolvedGamePath, resolvedGameLocalPath);
}
bool UpdateFile(const std::filesystem::path& masterlistPath,
const std::string& remoteURL,
const std::string& remoteBranch) {
if (!std::filesystem::is_directory(masterlistPath.parent_path()))
throw std::invalid_argument("The path \"" + masterlistPath.u8string() +
"\" does not have a valid parent directory.");
return git::UpdateFile(masterlistPath, remoteURL, remoteBranch);
}
FileRevision GetFileRevision(
const std::filesystem::path& masterlistPath,
const bool getShortID) {
return git::GetVersionInfo(masterlistPath, getShortID);
}
bool IsLatestFile(
const std::filesystem::path& masterlist_path,
const std::string& branch) {
return git::IsLatest(masterlist_path, branch);
}
}
-27
View File
@@ -95,33 +95,6 @@ void ApiDatabase::WriteUserMetadata(const std::filesystem::path& outputFile,
userlist_.Save(outputFile);
}
////////////////////////////////////
// LOOT Functionality Functions
////////////////////////////////////
bool ApiDatabase::UpdateMasterlist(const std::filesystem::path& masterlistPath,
const std::string& remoteURL,
const std::string& remoteBranch) {
if (!std::filesystem::is_directory(masterlistPath.parent_path()))
throw std::invalid_argument("The path \"" +
masterlistPath.u8string() +
"\" does not have a valid parent directory.");
return git::UpdateFile(masterlistPath, remoteURL, remoteBranch);
}
FileRevision ApiDatabase::GetMasterlistRevision(
const std::filesystem::path& masterlistPath,
const bool getShortID) const {
return git::GetVersionInfo(masterlistPath, getShortID);
}
bool ApiDatabase::IsLatestMasterlist(
const std::filesystem::path& masterlist_path,
const std::string& branch) const {
return git::IsLatest(masterlist_path, branch);
}
//////////////////////////
// DB Access Functions
//////////////////////////
-12
View File
@@ -31,7 +31,6 @@
#include "api/game/game_cache.h"
#include "api/game/load_order_handler.h"
#include "api/helpers/git.h"
#include "api/metadata/condition_evaluator.h"
#include "api/metadata_list.h"
#include "loot/database_interface.h"
@@ -52,17 +51,6 @@ struct ApiDatabase : public DatabaseInterface {
void WriteMinimalList(const std::filesystem::path& outputFile,
const bool overwrite) const;
bool UpdateMasterlist(const std::filesystem::path& masterlist_path,
const std::string& remote_url,
const std::string& remote_branch);
FileRevision GetMasterlistRevision(
const std::filesystem::path& masterlist_path,
const bool get_short_id) const;
bool IsLatestMasterlist(const std::filesystem::path& masterlist_path,
const std::string& branch) const;
std::vector<std::string> GetKnownBashTags() const;
std::vector<Message> GetGeneralMessages(
@@ -273,144 +273,6 @@ TEST_P(DatabaseInterfaceTest, writeUserMetadataShouldShouldWriteUserMetadata) {
EXPECT_FALSE(GetFileContent(minimalOutputPath_).empty());
}
TEST_P(DatabaseInterfaceTest,
updateMasterlistShouldThrowIfTheMasterlistPathGivenIsInvalid) {
EXPECT_THROW(db_->UpdateMasterlist("//\?", url_, branch_), std::exception);
}
TEST_P(DatabaseInterfaceTest,
updateMasterlistShouldThrowIfTheMasterlistPathGivenIsEmpty) {
EXPECT_THROW(db_->UpdateMasterlist("", url_, branch_), std::invalid_argument);
}
TEST_P(DatabaseInterfaceTest,
updateMasterlistShouldThrowIfTheRepositoryUrlGivenCannotBeFound) {
EXPECT_THROW(db_->UpdateMasterlist(
masterlistPath,
"https://github.com/loot/oblivion-does-not-exist.git",
branch_),
std::system_error);
}
TEST_P(DatabaseInterfaceTest,
updateMasterlistShouldThrowIfTheRepositoryUrlGivenIsEmpty) {
EXPECT_THROW(db_->UpdateMasterlist(masterlistPath, "", branch_),
std::invalid_argument);
}
TEST_P(DatabaseInterfaceTest,
updateMasterlistShouldThrowIfTheRepositoryBranchGivenCannotBeFound) {
EXPECT_THROW(db_->UpdateMasterlist(masterlistPath, url_, "missing-branch"),
std::system_error);
}
TEST_P(DatabaseInterfaceTest,
updateMasterlistShouldThrowIfTheRepositoryBranchGivenIsEmpty) {
EXPECT_THROW(db_->UpdateMasterlist(masterlistPath, url_, ""),
std::invalid_argument);
}
TEST_P(
DatabaseInterfaceTest,
updateMasterlistShouldSucceedIfPassedValidParametersAndOutputTrueIfTheMasterlistWasUpdated) {
bool updated = false;
EXPECT_NO_THROW(updated =
db_->UpdateMasterlist(masterlistPath, url_, branch_));
EXPECT_TRUE(updated);
EXPECT_TRUE(std::filesystem::exists(masterlistPath));
}
TEST_P(
DatabaseInterfaceTest,
updateMasterlistShouldSucceedIfCalledRepeatedlyButOnlyOutputTrueForTheFirstCall) {
bool updated = false;
EXPECT_NO_THROW(updated =
db_->UpdateMasterlist(masterlistPath, url_, branch_));
EXPECT_TRUE(updated);
EXPECT_NO_THROW(updated =
db_->UpdateMasterlist(masterlistPath, url_, branch_));
EXPECT_FALSE(updated);
EXPECT_TRUE(std::filesystem::exists(masterlistPath));
}
TEST_P(DatabaseInterfaceTest,
getMasterlistRevisionShouldThrowIfNoMasterlistIsPresent) {
FileRevision revision;
EXPECT_THROW(revision = db_->GetMasterlistRevision(masterlistPath, false),
FileAccessError);
EXPECT_TRUE(revision.id.empty());
EXPECT_TRUE(revision.date.empty());
EXPECT_FALSE(revision.is_modified);
}
TEST_P(
DatabaseInterfaceTest,
getMasterlistRevisionShouldThrowIfANonVersionControlledMasterlistIsPresent) {
ASSERT_NO_THROW(GenerateMasterlist());
FileRevision revision;
EXPECT_THROW(revision = db_->GetMasterlistRevision(masterlistPath, false),
GitStateError);
EXPECT_TRUE(revision.id.empty());
EXPECT_TRUE(revision.date.empty());
EXPECT_FALSE(revision.is_modified);
}
TEST_P(
DatabaseInterfaceTest,
getMasterlistRevisionShouldOutputLongStringsAndBooleanFalseIfAVersionControlledMasterlistIsPresentAndGetShortIdParameterIsFalse) {
ASSERT_NO_THROW(db_->UpdateMasterlist(masterlistPath, url_, branch_));
FileRevision revision;
EXPECT_NO_THROW(revision = db_->GetMasterlistRevision(masterlistPath, false));
EXPECT_EQ(40, revision.id.length());
EXPECT_EQ(10, revision.date.length());
EXPECT_FALSE(revision.is_modified);
}
TEST_P(
DatabaseInterfaceTest,
getMasterlistRevisionShouldOutputShortStringsAndBooleanFalseIfAVersionControlledMasterlistIsPresentAndGetShortIdParameterIsTrue) {
ASSERT_NO_THROW(db_->UpdateMasterlist(masterlistPath, url_, branch_));
FileRevision revision;
EXPECT_NO_THROW(revision = db_->GetMasterlistRevision(masterlistPath, false));
EXPECT_GE(size_t(40), revision.id.length());
EXPECT_LE(size_t(7), revision.id.length());
EXPECT_EQ(10, revision.date.length());
EXPECT_FALSE(revision.is_modified);
}
TEST_P(
DatabaseInterfaceTest,
getMasterlistRevisionShouldSucceedIfAnEditedVersionControlledMasterlistIsPresent) {
ASSERT_NO_THROW(db_->UpdateMasterlist(masterlistPath, url_, branch_));
ASSERT_NO_THROW(GenerateMasterlist());
FileRevision revision;
EXPECT_NO_THROW(revision = db_->GetMasterlistRevision(masterlistPath, false));
EXPECT_EQ(40, revision.id.length());
EXPECT_EQ(10, revision.date.length());
EXPECT_TRUE(revision.is_modified);
}
TEST_P(
DatabaseInterfaceTest,
isLatestMasterlistShouldReturnFalseIfTheCurrentRevisionIsNotTheLatestRevisionInTheGivenBranch) {
ASSERT_NO_THROW(db_->UpdateMasterlist(masterlistPath, url_, oldBranch_));
EXPECT_FALSE(db_->IsLatestMasterlist(masterlistPath, branch_));
}
TEST_P(
DatabaseInterfaceTest,
isLatestMasterlistShouldReturnTrueIfTheCurrentRevisionIsTheLatestRevisioninTheGivenBranch) {
ASSERT_NO_THROW(db_->UpdateMasterlist(masterlistPath, url_, branch_));
EXPECT_TRUE(db_->IsLatestMasterlist(masterlistPath, branch_));
}
TEST_P(DatabaseInterfaceTest,
getGroupsShouldReturnAllGroupsListedInTheLoadedMetadata) {
ASSERT_NO_THROW(GenerateMasterlist());
@@ -0,0 +1,196 @@
/* LOOT
A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and
Fallout: New Vegas.
Copyright (C) 2014-2016 WrinklyNinja
This file is part of LOOT.
LOOT is free software: you can redistribute
it and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
LOOT is distributed in the hope that it will
be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with LOOT. If not, see
<https://www.gnu.org/licenses/>.
*/
#ifndef LOOT_TESTS_API_INTERFACE_FILE_VERSIONING_TEST
#define LOOT_TESTS_API_INTERFACE_FILE_VERSIONING_TEST
#include "loot/api.h"
#include "tests/api/interface/api_game_operations_test.h"
namespace loot {
namespace test {
class FileVersioningTest : public ApiGameOperationsTest {
protected:
FileVersioningTest() :
url_("./testing-metadata.git"),
branch_("master"),
oldBranch_("old-branch") {}
const std::string url_;
const std::string branch_;
const std::string oldBranch_;
};
// Pass an empty first argument, as it's a prefix for the test instantation,
// but we only have the one so no prefix is necessary.
INSTANTIATE_TEST_SUITE_P(,
FileVersioningTest,
::testing::Values(GameType::tes4,
GameType::tes5,
GameType::fo3,
GameType::fonv,
GameType::fo4,
GameType::tes5se));
TEST_P(FileVersioningTest,
updateFileShouldThrowIfTheMasterlistPathGivenIsInvalid) {
EXPECT_THROW(UpdateFile("//\?", url_, branch_), std::exception);
}
TEST_P(FileVersioningTest,
updateFileShouldThrowIfTheMasterlistPathGivenIsEmpty) {
EXPECT_THROW(UpdateFile("", url_, branch_), std::invalid_argument);
}
TEST_P(FileVersioningTest,
updateFileShouldThrowIfTheRepositoryUrlGivenCannotBeFound) {
EXPECT_THROW(UpdateFile(
masterlistPath,
"https://github.com/loot/oblivion-does-not-exist.git",
branch_),
std::system_error);
}
TEST_P(FileVersioningTest,
updateFileShouldThrowIfTheRepositoryUrlGivenIsEmpty) {
EXPECT_THROW(UpdateFile(masterlistPath, "", branch_),
std::invalid_argument);
}
TEST_P(FileVersioningTest,
updateFileShouldThrowIfTheRepositoryBranchGivenCannotBeFound) {
EXPECT_THROW(UpdateFile(masterlistPath, url_, "missing-branch"),
std::system_error);
}
TEST_P(FileVersioningTest,
updateFileShouldThrowIfTheRepositoryBranchGivenIsEmpty) {
EXPECT_THROW(UpdateFile(masterlistPath, url_, ""),
std::invalid_argument);
}
TEST_P(
FileVersioningTest,
updateFileShouldSucceedIfPassedValidParametersAndOutputTrueIfTheMasterlistWasUpdated) {
bool updated = false;
EXPECT_NO_THROW(updated =
UpdateFile(masterlistPath, url_, branch_));
EXPECT_TRUE(updated);
EXPECT_TRUE(std::filesystem::exists(masterlistPath));
}
TEST_P(
FileVersioningTest,
updateFileShouldSucceedIfCalledRepeatedlyButOnlyOutputTrueForTheFirstCall) {
bool updated = false;
EXPECT_NO_THROW(updated =
UpdateFile(masterlistPath, url_, branch_));
EXPECT_TRUE(updated);
EXPECT_NO_THROW(updated =
UpdateFile(masterlistPath, url_, branch_));
EXPECT_FALSE(updated);
EXPECT_TRUE(std::filesystem::exists(masterlistPath));
}
TEST_P(FileVersioningTest,
getFileRevisionShouldThrowIfNoMasterlistIsPresent) {
FileRevision revision;
EXPECT_THROW(revision = GetFileRevision(masterlistPath, false),
FileAccessError);
EXPECT_TRUE(revision.id.empty());
EXPECT_TRUE(revision.date.empty());
EXPECT_FALSE(revision.is_modified);
}
TEST_P(
FileVersioningTest,
getFileRevisionShouldThrowIfANonVersionControlledMasterlistIsPresent) {
ASSERT_NO_THROW(GenerateMasterlist());
FileRevision revision;
EXPECT_THROW(revision = GetFileRevision(masterlistPath, false),
GitStateError);
EXPECT_TRUE(revision.id.empty());
EXPECT_TRUE(revision.date.empty());
EXPECT_FALSE(revision.is_modified);
}
TEST_P(
FileVersioningTest,
getFileRevisionShouldOutputLongStringsAndBooleanFalseIfAVersionControlledMasterlistIsPresentAndGetShortIdParameterIsFalse) {
ASSERT_NO_THROW(UpdateFile(masterlistPath, url_, branch_));
FileRevision revision;
EXPECT_NO_THROW(revision = GetFileRevision(masterlistPath, false));
EXPECT_EQ(40, revision.id.length());
EXPECT_EQ(10, revision.date.length());
EXPECT_FALSE(revision.is_modified);
}
TEST_P(
FileVersioningTest,
getFileRevisionShouldOutputShortStringsAndBooleanFalseIfAVersionControlledMasterlistIsPresentAndGetShortIdParameterIsTrue) {
ASSERT_NO_THROW(UpdateFile(masterlistPath, url_, branch_));
FileRevision revision;
EXPECT_NO_THROW(revision = GetFileRevision(masterlistPath, false));
EXPECT_GE(size_t(40), revision.id.length());
EXPECT_LE(size_t(7), revision.id.length());
EXPECT_EQ(10, revision.date.length());
EXPECT_FALSE(revision.is_modified);
}
TEST_P(
FileVersioningTest,
getFileRevisionShouldSucceedIfAnEditedVersionControlledMasterlistIsPresent) {
ASSERT_NO_THROW(UpdateFile(masterlistPath, url_, branch_));
ASSERT_NO_THROW(GenerateMasterlist());
FileRevision revision;
EXPECT_NO_THROW(revision = GetFileRevision(masterlistPath, false));
EXPECT_EQ(40, revision.id.length());
EXPECT_EQ(10, revision.date.length());
EXPECT_TRUE(revision.is_modified);
}
TEST_P(
FileVersioningTest,
isLatestFileShouldReturnFalseIfTheCurrentRevisionIsNotTheLatestRevisionInTheGivenBranch) {
ASSERT_NO_THROW(UpdateFile(masterlistPath, url_, oldBranch_));
EXPECT_FALSE(IsLatestFile(masterlistPath, branch_));
}
TEST_P(
FileVersioningTest,
isLatestFileShouldReturnTrueIfTheCurrentRevisionIsTheLatestRevisioninTheGivenBranch) {
ASSERT_NO_THROW(UpdateFile(masterlistPath, url_, branch_));
EXPECT_TRUE(IsLatestFile(masterlistPath, branch_));
}
}
}
#endif
+1
View File
@@ -27,6 +27,7 @@
#include "loot/api.h"
#include "tests/api/interface/create_game_handle_test.h"
#include "tests/api/interface/database_interface_test.h"
#include "tests/api/interface/file_versioning_test.h"
#include "tests/api/interface/game_interface_test.h"
#include "tests/api/interface/is_compatible_test.h"