Add GameInterface to API

DatabaseInterface is now accessed through it, and IdentifyMainMasterFile
and SortPlugins have moved to it. GameInterface also deals with load
order access.

This is obviously a breaking change, but it's a cleaner structure than
just continuing to stuff everything in DatabaseInterface, and there
needs to be some relation between GameInterface and it.
This commit is contained in:
Oliver Hamlet
2017-02-06 18:02:18 +00:00
parent 2ef78a7743
commit 83f0caa68e
14 changed files with 418 additions and 135 deletions
+7 -3
View File
@@ -289,7 +289,8 @@ set (LOOT_GUI_HEADERS "${CMAKE_SOURCE_DIR}/src/gui/editor_message.h"
set (LOOT_API_SRC "${CMAKE_BINARY_DIR}/generated/loot_version.cpp"
"${CMAKE_SOURCE_DIR}/src/api/api.cpp"
"${CMAKE_SOURCE_DIR}/src/api/api_database.cpp")
"${CMAKE_SOURCE_DIR}/src/api/api_database.cpp"
"${CMAKE_SOURCE_DIR}/src/api/game.cpp")
set (LOOT_API_HEADERS "${CMAKE_SOURCE_DIR}/include/loot/api.h"
"${CMAKE_SOURCE_DIR}/include/loot/api_decorator.h"
@@ -302,13 +303,15 @@ set (LOOT_API_HEADERS "${CMAKE_SOURCE_DIR}/include/loot/api.h"
"${CMAKE_SOURCE_DIR}/include/loot/exception/git_state_error.h"
"${CMAKE_SOURCE_DIR}/include/loot/enum/game_type.h"
"${CMAKE_SOURCE_DIR}/include/loot/enum/language_code.h"
"${CMAKE_SOURCE_DIR}/include/loot/game_interface.h"
"${CMAKE_SOURCE_DIR}/include/loot/loot_version.h"
"${CMAKE_SOURCE_DIR}/include/loot/struct/masterlist_info.h"
"${CMAKE_SOURCE_DIR}/include/loot/enum/message_type.h"
"${CMAKE_SOURCE_DIR}/include/loot/enum/plugin_cleanliness.h"
"${CMAKE_SOURCE_DIR}/include/loot/struct/plugin_tags.h"
"${CMAKE_SOURCE_DIR}/include/loot/struct/simple_message.h"
"${CMAKE_SOURCE_DIR}/src/api/api_database.h")
"${CMAKE_SOURCE_DIR}/src/api/api_database.h"
"${CMAKE_SOURCE_DIR}/src/api/game.h")
set (LOOT_TESTS_SRC "${CMAKE_SOURCE_DIR}/src/tests/backend/main.cpp")
@@ -341,8 +344,9 @@ set (LOOT_TESTS_HEADERS "${CMAKE_SOURCE_DIR}/src/tests/backend/game/game_test.h"
set(LOOT_API_TESTS_SRC "${CMAKE_SOURCE_DIR}/src/tests/api/main.cpp")
set(LOOT_API_TESTS_HEADERS "${CMAKE_SOURCE_DIR}/src/tests/api/api_game_operations_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/create_database_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/create_game_handle_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/database_interface_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/game_interface_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/is_compatible_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/common_game_test_fixture.h")
+8 -8
View File
@@ -29,7 +29,7 @@
#include <memory>
#include "loot/api_decorator.h"
#include "loot/database_interface.h"
#include "loot/game_interface.h"
#include "loot/exception/error_categories.h"
#include "loot/exception/condition_syntax_error.h"
#include "loot/exception/cyclic_interaction_error.h"
@@ -70,9 +70,9 @@ LOOT_API bool IsCompatible(const unsigned int major,
/**@{*/
/**
* @brief Initialise a new database handle.
* @details Creates a handle for a database, which is then used by all
* database functions.
* @brief Initialise a new game handle.
* @details Creates a handle for a game, which is then used by all
* game-specific functions.
* @param game
* A game code for which to create the handle.
* @param game_path
@@ -86,11 +86,11 @@ LOOT_API bool IsCompatible(const unsigned int major,
* attempt to look up the path that `%%LOCALAPPDATA%` corresponds to.
* This parameter is provided so that systems lacking that environmental
* variable (eg. Linux) can still use the API.
* @returns The new database handle.
* @returns The new game handle.
*/
LOOT_API std::shared_ptr<DatabaseInterface> CreateDatabase(const GameType game,
const std::string& game_path = "",
const std::string& game_local_path = "");
LOOT_API std::shared_ptr<GameInterface> CreateGameHandle(const GameType game,
const std::string& game_path = "",
const std::string& game_local_path = "");
}
#endif
+1 -28
View File
@@ -90,33 +90,6 @@ public:
virtual void WriteMinimalList(const std::string& outputFile,
const bool overwrite) = 0;
/**
* @}
* @name Sorting
* @{
*/
/**
* @brief Identify the game's main master file.
* @details When sorting, LOOT always only loads the headers of the game's
* main master file as a performance optimisation.
*/
virtual void IdentifyMainMasterFile(const std::string& masterFile) = 0;
/**
* @brief Calculates a new load order for the game's installed plugins
* (including inactive plugins) and outputs the sorted order.
* @details Pulls metadata from the masterlist and userlist if they are
* loaded, and reads the contents of each plugin. No changes are
* applied to the load order used by the game. This function does
* not load or evaluate the masterlist or userlist.
* @param plugins
* A vector of filenames of the plugins to sort.
* @returns A vector of the given plugin filenames in their sorted load
* order.
*/
virtual std::vector<std::string> SortPlugins(const std::vector<std::string>& plugins) = 0;
/**
* @}
* @name Masterlist Update
@@ -223,7 +196,7 @@ public:
virtual PluginMetadata GetPluginUserMetadata(const std::string& plugin) = 0;
/**
* @brief Sets a plugin's user metadata, overwriting any existing user
* @brief Sets a plugin's user metadata, overwriting any existing user
* metadata.
* @param plugin
* The user metadata you want to set, with plugin.Name() being the
+101
View File
@@ -0,0 +1,101 @@
/* LOOT
A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and
Fallout: New Vegas.
Copyright (C) 2012-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_GAME_INTERFACE
#define LOOT_GAME_INTERFACE
#include "loot/database_interface.h"
namespace loot {
/** @brief The interface provided for accessing game-specific functionality. */
class GameInterface {
public:
/**
* @name Metadata Access
* @{
*/
/**
* @brief Get the database interface used for accessing metadata-related
* functionality.
* @returns A shared pointer to the game's DatabaseInterface
*/
virtual std::shared_ptr<DatabaseInterface> GetDatabase() = 0;
/**
* @}
* @name Sorting
* @{
*/
/**
* @brief Identify the game's main master file.
* @details When sorting, LOOT always only loads the headers of the game's
* main master file as a performance optimisation.
*/
virtual void IdentifyMainMasterFile(const std::string& masterFile) = 0;
/**
* @brief Calculates a new load order for the game's installed plugins
* (including inactive plugins) and outputs the sorted order.
* @details Pulls metadata from the masterlist and userlist if they are
* loaded, and reads the contents of each plugin. No changes are
* applied to the load order used by the game. This function does
* not load or evaluate the masterlist or userlist.
* @param plugins
* A vector of filenames of the plugins to sort.
* @returns A vector of the given plugin filenames in their sorted load
* order.
*/
virtual std::vector<std::string> SortPlugins(const std::vector<std::string>& plugins) = 0;
/**
* @}
* @name Load Order Interaction
* @{
*/
/**
* @brief Check if a plugin is active.
* @param plugin
* The filename of the plugin for which to check the active state.
* @returns True if the plugin is active, false otherwise.
*/
virtual bool IsPluginActive(const std::string& plugin) = 0;
/**
* @brief Get the current load order.
* @returns A vector of plugin filenames in their load order.
*/
virtual std::vector<std::string> GetLoadOrder() = 0;
/**
* @brief Set the game's load order.
* @param loadOrder
* A vector of plugin filenames sorted in the load order to set.
*/
virtual void SetLoadOrder(const std::vector<std::string>& loadOrder) = 0;
};
}
#endif
+5 -5
View File
@@ -27,7 +27,7 @@
#include <boost/filesystem.hpp>
#include <boost/log/core.hpp>
#include "api/api_database.h"
#include "api/game.h"
namespace fs = boost::filesystem;
@@ -46,9 +46,9 @@ LOOT_API bool IsCompatible(const unsigned int versionMajor, const unsigned int v
return versionMinor == loot::LootVersion::minor;
}
LOOT_API std::shared_ptr<DatabaseInterface> CreateDatabase(const GameType game,
const std::string& gamePath,
const std::string& gameLocalPath) {
LOOT_API std::shared_ptr<GameInterface> CreateGameHandle(const GameType game,
const std::string& gamePath,
const std::string& gameLocalPath) {
// Set the locale to get UTF-8 conversions working correctly.
std::locale::global(boost::locale::generator().generate(""));
boost::filesystem::path::imbue(std::locale());
@@ -65,6 +65,6 @@ LOOT_API std::shared_ptr<DatabaseInterface> CreateDatabase(const GameType game,
if (!gameLocalPath.empty() && !fs::is_directory(resolvedGameLocalPath))
throw std::invalid_argument("Given game path \"" + gameLocalPath + "\" does not resolve to a valid directory.");
return std::make_shared<ApiDatabase>(game, resolvedGamePath, resolvedGameLocalPath);
return std::make_shared<api::Game>(game, resolvedGamePath, resolvedGameLocalPath);
}
}
+1 -23
View File
@@ -35,10 +35,7 @@
#include "backend/plugin/plugin_sorter.h"
namespace loot {
ApiDatabase::ApiDatabase(const GameType game, const std::string& gamePath, const std::string& gameLocalDataPath)
: game_(game, gamePath, gameLocalDataPath) {
game_.Init();
}
ApiDatabase::ApiDatabase(Game& game) : game_(game) {}
///////////////////////////////////
// Database Loading Functions
@@ -94,29 +91,10 @@ void ApiDatabase::WriteUserMetadata(const std::string& outputFile, const bool ov
game_.GetUserlist().Save(outputFile);
}
void ApiDatabase::IdentifyMainMasterFile(const std::string& masterFile) {
masterFile_ = masterFile;
}
////////////////////////////////////
// LOOT Functionality Functions
////////////////////////////////////
std::vector<std::string> ApiDatabase::SortPlugins(const std::vector<std::string>& plugins) {
// Always reload all the plugins.
game_.LoadPlugins(plugins, masterFile_, false);
//Sort plugins into their load order.
PluginSorter sorter;
auto list = sorter.Sort(game_, LanguageCode::english);
std::vector<std::string> loadOrder(list.size());
std::transform(begin(list), end(list), begin(loadOrder), [](const Plugin& plugin) {
return plugin.Name();
});
return loadOrder;
}
bool ApiDatabase::UpdateMasterlist(const std::string& masterlistPath,
const std::string& remoteURL,
+2 -6
View File
@@ -34,9 +34,7 @@
namespace loot {
struct ApiDatabase : public DatabaseInterface {
ApiDatabase(const GameType clientGame,
const std::string& gamePath = "",
const std::string& gameLocalDataPath = "");
ApiDatabase(Game& game);
void LoadLists(const std::string& masterlist_path,
const std::string& userlist_path = "");
@@ -81,9 +79,7 @@ struct ApiDatabase : public DatabaseInterface {
PluginCleanliness GetPluginCleanliness(const std::string& plugin);
private:
Game game_;
std::string masterFile_;
Game& game_;
Masterlist unevaluatedMasterlist_;
MetadataList unevaluatedUserlist_;
+76
View File
@@ -0,0 +1,76 @@
/* LOOT
A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and
Fallout: New Vegas.
Copyright (C) 2013-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/>.
*/
#include "api/game.h"
#include "api/api_database.h"
#include "backend/plugin/plugin_sorter.h"
namespace loot {
namespace api {
Game::Game(const GameType gameType,
const std::string& gamePath,
const std::string& gameLocalDataPath)
: game_(gameType, gamePath, gameLocalDataPath) {
game_.Init();
database_ = std::make_shared<ApiDatabase>(game_);
}
std::shared_ptr<DatabaseInterface> Game::GetDatabase() {
return database_;
}
void Game::IdentifyMainMasterFile(const std::string& masterFile) {
masterFile_ = masterFile;
}
std::vector<std::string> Game::SortPlugins(const std::vector<std::string>& plugins) {
game_.LoadPlugins(plugins, masterFile_, false);
//Sort plugins into their load order.
PluginSorter sorter;
auto list = sorter.Sort(game_, LanguageCode::english);
std::vector<std::string> loadOrder(list.size());
std::transform(begin(list), end(list), begin(loadOrder), [](const Plugin& plugin) {
return plugin.Name();
});
return loadOrder;
}
bool Game::IsPluginActive(const std::string& plugin) {
return game_.IsPluginActive(plugin);
}
std::vector<std::string> Game::GetLoadOrder() {
return game_.GetLoadOrder();
}
void Game::SetLoadOrder(const std::vector<std::string>& loadOrder) {
game_.SetLoadOrder(loadOrder);
}
}
}
+58
View File
@@ -0,0 +1,58 @@
/* LOOT
A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and
Fallout: New Vegas.
Copyright (C) 2013-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_API_GAME
#define LOOT_API_GAME
#include "backend/game/game.h"
#include "loot/game_interface.h"
namespace loot {
namespace api {
class Game : public GameInterface {
public:
Game(const GameType clientGame,
const std::string& gamePath = "",
const std::string& gameLocalDataPath = "");
std::shared_ptr<DatabaseInterface> GetDatabase();
void IdentifyMainMasterFile(const std::string& masterFile);
std::vector<std::string> SortPlugins(const std::vector<std::string>& plugins);
bool IsPluginActive(const std::string& plugin);
std::vector<std::string> GetLoadOrder();
void SetLoadOrder(const std::vector<std::string>& loadOrder);
private:
loot::Game game_;
std::shared_ptr<DatabaseInterface> database_;
std::string masterFile_;
};
}
}
#endif
+3 -3
View File
@@ -34,7 +34,7 @@ namespace test {
class ApiGameOperationsTest : public CommonGameTestFixture {
protected:
ApiGameOperationsTest() :
db_(nullptr),
handle_(nullptr),
masterlistPath(localPath / "masterlist.yaml"),
noteMessage("Do not clean ITM records, they are intentional and required for the mod to function."),
warningMessage("Check you are using v2+. If not, Update. v1 has a severe bug with the Mystic Emporium disappearing."),
@@ -46,7 +46,7 @@ protected:
ASSERT_FALSE(boost::filesystem::exists(masterlistPath));
db_ = CreateDatabase(GetParam(), dataPath.parent_path().string(), localPath.string());
handle_ = CreateGameHandle(GetParam(), dataPath.parent_path().string(), localPath.string());
}
virtual void TearDown() {
@@ -111,7 +111,7 @@ protected:
masterlist.close();
}
std::shared_ptr<DatabaseInterface> db_;
std::shared_ptr<GameInterface> handle_;
const boost::filesystem::path masterlistPath;
@@ -22,8 +22,8 @@ along with LOOT. If not, see
<https://www.gnu.org/licenses/>.
*/
#ifndef LOOT_TESTS_API_CREATE_DATABASE_TEST
#define LOOT_TESTS_API_CREATE_DATABASE_TEST
#ifndef LOOT_TESTS_API_CREATE_GAME_HANDLE_TEST
#define LOOT_TESTS_API_CREATE_GAME_HANDLE_TEST
#include "loot/api.h"
@@ -33,10 +33,10 @@ along with LOOT. If not, see
namespace loot {
namespace test {
class CreateDatabaseTest : public CommonGameTestFixture {
class CreateGameHandleTest : public CommonGameTestFixture {
protected:
CreateDatabaseTest() :
db_(nullptr),
CreateGameHandleTest() :
handle_(nullptr),
gamePathSymlink(dataPath.parent_path().string() + "symlink"),
localPathSymlink(localPath.string() + "symlink") {}
@@ -54,7 +54,7 @@ protected:
boost::filesystem::remove(localPathSymlink);
}
std::shared_ptr<DatabaseInterface> db_;
std::shared_ptr<GameInterface> handle_;
const boost::filesystem::path gamePathSymlink;
const boost::filesystem::path localPathSymlink;
@@ -63,7 +63,7 @@ protected:
// 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_CASE_P(,
CreateDatabaseTest,
CreateGameHandleTest,
::testing::Values(
GameType::tes4,
GameType::tes5,
@@ -72,37 +72,37 @@ INSTANTIATE_TEST_CASE_P(,
GameType::fo4,
GameType::tes5se));
TEST_P(CreateDatabaseTest, shouldSucceedIfPassedValidParametersWithRelativePaths) {
EXPECT_NO_THROW(db_ = CreateDatabase(GetParam(), dataPath.parent_path().string(), localPath.string()));
EXPECT_NE(nullptr, db_);
TEST_P(CreateGameHandleTest, shouldSucceedIfPassedValidParametersWithRelativePaths) {
EXPECT_NO_THROW(handle_ = CreateGameHandle(GetParam(), dataPath.parent_path().string(), localPath.string()));
EXPECT_NE(nullptr, handle_);
}
TEST_P(CreateDatabaseTest, shouldSucceedIfPassedValidParametersWithAbsolutePaths) {
TEST_P(CreateGameHandleTest, shouldSucceedIfPassedValidParametersWithAbsolutePaths) {
boost::filesystem::path game = boost::filesystem::current_path() / dataPath.parent_path();
boost::filesystem::path local = boost::filesystem::current_path() / localPath;
EXPECT_NO_THROW(db_ = CreateDatabase(GetParam(), dataPath.parent_path().string(), localPath.string()));
EXPECT_NE(nullptr, db_);
EXPECT_NO_THROW(handle_ = CreateGameHandle(GetParam(), dataPath.parent_path().string(), localPath.string()));
EXPECT_NE(nullptr, handle_);
}
TEST_P(CreateDatabaseTest, shouldThrowIfPassedAGamePathThatDoesNotExist) {
EXPECT_THROW(CreateDatabase(GetParam(), missingPath.string(), localPath.string()), std::invalid_argument);
TEST_P(CreateGameHandleTest, shouldThrowIfPassedAGamePathThatDoesNotExist) {
EXPECT_THROW(CreateGameHandle(GetParam(), missingPath.string(), localPath.string()), std::invalid_argument);
}
TEST_P(CreateDatabaseTest, shouldThrowIfPassedALocalPathThatDoesNotExist) {
EXPECT_THROW(CreateDatabase(GetParam(), dataPath.parent_path().string(), missingPath.string()), std::invalid_argument);
TEST_P(CreateGameHandleTest, shouldThrowIfPassedALocalPathThatDoesNotExist) {
EXPECT_THROW(CreateGameHandle(GetParam(), dataPath.parent_path().string(), missingPath.string()), std::invalid_argument);
}
#ifdef _WIN32
TEST_P(CreateDatabaseTest, shouldReturnOkIfPassedAnEmptyLocalPathString) {
EXPECT_NO_THROW(db_ = CreateDatabase(GetParam(), dataPath.parent_path().string(), ""));
EXPECT_NE(nullptr, db_);
TEST_P(CreateGameHandleTest, shouldReturnOkIfPassedAnEmptyLocalPathString) {
EXPECT_NO_THROW(handle_ = CreateGameHandle(GetParam(), dataPath.parent_path().string(), ""));
EXPECT_NE(nullptr, handle_);
}
#endif
TEST_P(CreateDatabaseTest, shouldReturnOkIfPassedGameAndLocalPathSymlinks) {
EXPECT_NO_THROW(db_ = CreateDatabase(GetParam(), gamePathSymlink.string(), localPathSymlink.string()));
EXPECT_NE(nullptr, db_);
TEST_P(CreateGameHandleTest, shouldReturnOkIfPassedGameAndLocalPathSymlinks) {
EXPECT_NO_THROW(handle_ = CreateGameHandle(GetParam(), gamePathSymlink.string(), localPathSymlink.string()));
EXPECT_NE(nullptr, handle_);
}
}
}
+5 -35
View File
@@ -34,6 +34,7 @@ namespace test {
class DatabaseInterfaceTest : public ApiGameOperationsTest {
protected:
DatabaseInterfaceTest() :
db_(nullptr),
userlistPath_(localPath / "userlist.yaml"),
url_("https://github.com/loot/testing-metadata.git"),
branch_("master"),
@@ -43,6 +44,8 @@ protected:
void SetUp() {
ApiGameOperationsTest::SetUp();
db_ = handle_->GetDatabase();
ASSERT_FALSE(boost::filesystem::exists(minimalOutputPath_));
}
@@ -119,6 +122,8 @@ protected:
const std::string url_;
const std::string branch_;
const std::string generalUserlistMessage;
std::shared_ptr<DatabaseInterface> db_;
};
// Pass an empty first argument, as it's a prefix for the test instantation,
@@ -222,41 +227,6 @@ TEST_P(DatabaseInterfaceTest, writeUserMetadataShouldShouldWriteUserMetadata) {
EXPECT_FALSE(GetFileContent(minimalOutputPath_).empty());
}
TEST_P(DatabaseInterfaceTest, sortPluginsShouldSucceedIfPassedValidArguments) {
std::vector<std::string> expectedOrder = {
masterFile,
blankEsm,
blankMasterDependentEsm,
blankDifferentEsm,
blankDifferentMasterDependentEsm,
blankMasterDependentEsp,
blankDifferentMasterDependentEsp,
blankEsp,
blankPluginDependentEsp,
blankDifferentEsp,
blankDifferentPluginDependentEsp,
};
ASSERT_NO_THROW(GenerateMasterlist());
ASSERT_NO_THROW(db_->LoadLists(masterlistPath.string(), ""));
std::vector<std::string> actualOrder = db_->SortPlugins({
blankEsp,
blankPluginDependentEsp,
blankDifferentMasterDependentEsm,
blankMasterDependentEsp,
blankDifferentMasterDependentEsp,
blankDifferentEsp,
blankDifferentPluginDependentEsp,
masterFile,
blankEsm,
blankMasterDependentEsm,
blankDifferentEsm,
});
ASSERT_EQ(expectedOrder, actualOrder);
}
TEST_P(DatabaseInterfaceTest, updateMasterlistShouldThrowIfTheMasterlistPathGivenIsInvalid) {
EXPECT_THROW(db_->UpdateMasterlist(";//\?", url_, branch_), std::invalid_argument);
}
+126
View File
@@ -0,0 +1,126 @@
/* 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_GAME_INTERFACE_TEST
#define LOOT_TESTS_API_GAME_INTERFACE_TEST
#include "loot/api.h"
#include "tests/api/api_game_operations_test.h"
namespace loot {
namespace test {
class GameInterfaceTest : public ApiGameOperationsTest {};
// 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_CASE_P(,
GameInterfaceTest,
::testing::Values(
GameType::tes4,
GameType::tes5,
GameType::fo3,
GameType::fonv,
GameType::fo4,
GameType::tes5se));
TEST_P(GameInterfaceTest, sortPluginsShouldSucceedIfPassedValidArguments) {
std::vector<std::string> expectedOrder = {
masterFile,
blankEsm,
blankMasterDependentEsm,
blankDifferentEsm,
blankDifferentMasterDependentEsm,
blankMasterDependentEsp,
blankDifferentMasterDependentEsp,
blankEsp,
blankPluginDependentEsp,
blankDifferentEsp,
blankDifferentPluginDependentEsp,
};
ASSERT_NO_THROW(GenerateMasterlist());
ASSERT_NO_THROW(handle_->GetDatabase()->LoadLists(masterlistPath.string(), ""));
std::vector<std::string> actualOrder = handle_->SortPlugins({
blankEsp,
blankPluginDependentEsp,
blankDifferentMasterDependentEsm,
blankMasterDependentEsp,
blankDifferentMasterDependentEsp,
blankDifferentEsp,
blankDifferentPluginDependentEsp,
masterFile,
blankEsm,
blankMasterDependentEsm,
blankDifferentEsm,
});
EXPECT_EQ(expectedOrder, actualOrder);
}
TEST_P(GameInterfaceTest, isPluginActiveShouldReturnFalseIfTheGivenPluginIsNotActive) {
EXPECT_TRUE(handle_->IsPluginActive(blankEsm));
}
TEST_P(GameInterfaceTest, isPluginActiveShouldReturnTrueIfTheGivenPluginIsActive) {
EXPECT_FALSE(handle_->IsPluginActive(blankEsp));
}
TEST_P(GameInterfaceTest, getLoadOrderShouldReturnTheCurrentLoadOrder) {
ASSERT_EQ(getLoadOrder(), handle_->GetLoadOrder());
}
TEST_P(GameInterfaceTest, setLoadOrderShouldSetTheLoadOrder) {
std::vector<std::string> loadOrder({
masterFile,
blankEsm,
blankMasterDependentEsm,
blankDifferentEsm,
blankDifferentMasterDependentEsm,
blankDifferentEsp,
blankDifferentPluginDependentEsp,
blankEsp,
blankMasterDependentEsp,
blankDifferentMasterDependentEsp,
blankPluginDependentEsp,
});
EXPECT_NO_THROW(handle_->SetLoadOrder(loadOrder));
EXPECT_EQ(loadOrder, handle_->GetLoadOrder());
if (GetParam() == GameType::fo4 || GetParam() == GameType::tes5se)
loadOrder.erase(std::begin(loadOrder));
EXPECT_EQ(loadOrder, getLoadOrder());
}
}
}
#endif
+2 -1
View File
@@ -24,8 +24,9 @@
#include <gtest/gtest.h>
#include "tests/api/create_database_test.h"
#include "tests/api/create_game_handle_test.h"
#include "tests/api/database_interface_test.h"
#include "tests/api/game_interface_test.h"
#include "tests/api/is_compatible_test.h"
#include <boost/log/core.hpp>