From 83f0caa68e472ca12283d3f80418737334e5db48 Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Sun, 29 Jan 2017 17:43:30 +0000 Subject: [PATCH] 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. --- CMakeLists.txt | 10 +- include/loot/api.h | 16 +-- include/loot/database_interface.h | 29 +--- include/loot/game_interface.h | 101 ++++++++++++++ src/api/api.cpp | 10 +- src/api/api_database.cpp | 24 +--- src/api/api_database.h | 8 +- src/api/game.cpp | 76 +++++++++++ src/api/game.h | 58 ++++++++ src/tests/api/api_game_operations_test.h | 6 +- ...abase_test.h => create_game_handle_test.h} | 46 +++---- src/tests/api/database_interface_test.h | 40 +----- src/tests/api/game_interface_test.h | 126 ++++++++++++++++++ src/tests/api/main.cpp | 3 +- 14 files changed, 418 insertions(+), 135 deletions(-) create mode 100644 include/loot/game_interface.h create mode 100644 src/api/game.cpp create mode 100644 src/api/game.h rename src/tests/api/{create_database_test.h => create_game_handle_test.h} (58%) create mode 100644 src/tests/api/game_interface_test.h diff --git a/CMakeLists.txt b/CMakeLists.txt index bdd39c9b..9e26a64a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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") diff --git a/include/loot/api.h b/include/loot/api.h index 528f3166..33ba78ce 100644 --- a/include/loot/api.h +++ b/include/loot/api.h @@ -29,7 +29,7 @@ #include #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 CreateDatabase(const GameType game, - const std::string& game_path = "", - const std::string& game_local_path = ""); +LOOT_API std::shared_ptr CreateGameHandle(const GameType game, + const std::string& game_path = "", + const std::string& game_local_path = ""); } #endif diff --git a/include/loot/database_interface.h b/include/loot/database_interface.h index e91f98f9..dee22058 100644 --- a/include/loot/database_interface.h +++ b/include/loot/database_interface.h @@ -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 SortPlugins(const std::vector& 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 diff --git a/include/loot/game_interface.h b/include/loot/game_interface.h new file mode 100644 index 00000000..868b69bf --- /dev/null +++ b/include/loot/game_interface.h @@ -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 + . + */ +#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 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 SortPlugins(const std::vector& 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 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& loadOrder) = 0; +}; +} + +#endif diff --git a/src/api/api.cpp b/src/api/api.cpp index 1b7f5136..128f57b6 100644 --- a/src/api/api.cpp +++ b/src/api/api.cpp @@ -27,7 +27,7 @@ #include #include -#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 CreateDatabase(const GameType game, - const std::string& gamePath, - const std::string& gameLocalPath) { +LOOT_API std::shared_ptr 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 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(game, resolvedGamePath, resolvedGameLocalPath); + return std::make_shared(game, resolvedGamePath, resolvedGameLocalPath); } } diff --git a/src/api/api_database.cpp b/src/api/api_database.cpp index b439f70b..ae24d41e 100644 --- a/src/api/api_database.cpp +++ b/src/api/api_database.cpp @@ -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 ApiDatabase::SortPlugins(const std::vector& 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 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, diff --git a/src/api/api_database.h b/src/api/api_database.h index cf42a3a5..09a30a1f 100644 --- a/src/api/api_database.h +++ b/src/api/api_database.h @@ -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_; diff --git a/src/api/game.cpp b/src/api/game.cpp new file mode 100644 index 00000000..425e0b6a --- /dev/null +++ b/src/api/game.cpp @@ -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 + . + */ + +#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(game_); +} + +std::shared_ptr Game::GetDatabase() { + return database_; +} + +void Game::IdentifyMainMasterFile(const std::string& masterFile) { + masterFile_ = masterFile; +} + +std::vector Game::SortPlugins(const std::vector& plugins) { + game_.LoadPlugins(plugins, masterFile_, false); + + //Sort plugins into their load order. + PluginSorter sorter; + auto list = sorter.Sort(game_, LanguageCode::english); + + std::vector 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 Game::GetLoadOrder() { + return game_.GetLoadOrder(); +} + +void Game::SetLoadOrder(const std::vector& loadOrder) { + game_.SetLoadOrder(loadOrder); +} +} +} diff --git a/src/api/game.h b/src/api/game.h new file mode 100644 index 00000000..92713a67 --- /dev/null +++ b/src/api/game.h @@ -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 + . + */ + +#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 GetDatabase(); + + void IdentifyMainMasterFile(const std::string& masterFile); + + std::vector SortPlugins(const std::vector& plugins); + + bool IsPluginActive(const std::string& plugin); + + std::vector GetLoadOrder(); + + void SetLoadOrder(const std::vector& loadOrder); +private: + loot::Game game_; + std::shared_ptr database_; + + std::string masterFile_; +}; +} +} +#endif diff --git a/src/tests/api/api_game_operations_test.h b/src/tests/api/api_game_operations_test.h index 4a0d1228..77ebeb89 100644 --- a/src/tests/api/api_game_operations_test.h +++ b/src/tests/api/api_game_operations_test.h @@ -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 db_; + std::shared_ptr handle_; const boost::filesystem::path masterlistPath; diff --git a/src/tests/api/create_database_test.h b/src/tests/api/create_game_handle_test.h similarity index 58% rename from src/tests/api/create_database_test.h rename to src/tests/api/create_game_handle_test.h index 6415c104..84fcbb23 100644 --- a/src/tests/api/create_database_test.h +++ b/src/tests/api/create_game_handle_test.h @@ -22,8 +22,8 @@ along with LOOT. If not, see . */ -#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 db_; + std::shared_ptr 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_); } } } diff --git a/src/tests/api/database_interface_test.h b/src/tests/api/database_interface_test.h index d0446ee1..d8254808 100644 --- a/src/tests/api/database_interface_test.h +++ b/src/tests/api/database_interface_test.h @@ -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 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 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 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); } diff --git a/src/tests/api/game_interface_test.h b/src/tests/api/game_interface_test.h new file mode 100644 index 00000000..6fd1c655 --- /dev/null +++ b/src/tests/api/game_interface_test.h @@ -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 +. +*/ + +#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 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 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 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 diff --git a/src/tests/api/main.cpp b/src/tests/api/main.cpp index 7748fff9..3a70fe5f 100644 --- a/src/tests/api/main.cpp +++ b/src/tests/api/main.cpp @@ -24,8 +24,9 @@ #include -#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