mirror of
https://github.com/loot/libloot.git
synced 2026-07-27 14:16:01 -07:00
Turn the C API into a C++ API
This commit is contained in:
+17
-19
@@ -224,21 +224,29 @@ set (LOOT_GUI_HEADERS "${CMAKE_SOURCE_DIR}/src/gui/loot_handler.h"
|
||||
"${CMAKE_SOURCE_DIR}/src/gui/query_handler.h"
|
||||
"${CMAKE_SOURCE_DIR}/src/gui/resource.h")
|
||||
|
||||
set (LOOT_API_SRC "${CMAKE_SOURCE_DIR}/src/api/api.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/api/loot_db.cpp")
|
||||
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")
|
||||
|
||||
set (LOOT_API_HEADERS "${CMAKE_SOURCE_DIR}/include/loot/api.h"
|
||||
"${CMAKE_SOURCE_DIR}/src/api/loot_db.h")
|
||||
"${CMAKE_SOURCE_DIR}/include/loot/database_interface.h"
|
||||
"${CMAKE_SOURCE_DIR}/include/loot/game_type.h"
|
||||
"${CMAKE_SOURCE_DIR}/include/loot/language_code.h"
|
||||
"${CMAKE_SOURCE_DIR}/include/loot/loot_version.h"
|
||||
"${CMAKE_SOURCE_DIR}/include/loot/masterlist_info.h"
|
||||
"${CMAKE_SOURCE_DIR}/include/loot/message_type.h"
|
||||
"${CMAKE_SOURCE_DIR}/include/loot/plugin_cleanliness.h"
|
||||
"${CMAKE_SOURCE_DIR}/include/loot/plugin_message.h"
|
||||
"${CMAKE_SOURCE_DIR}/include/loot/plugin_tags.h"
|
||||
"${CMAKE_SOURCE_DIR}/src/api/api_database.h")
|
||||
|
||||
set (LOOT_VALIDATOR_SRC "${CMAKE_SOURCE_DIR}/src/validator/main.cpp")
|
||||
|
||||
set (LOOT_TESTS_SRC "${CMAKE_SOURCE_DIR}/src/api/loot_db.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/tests/backend/main.cpp")
|
||||
set (LOOT_TESTS_SRC "${CMAKE_SOURCE_DIR}/src/tests/backend/main.cpp")
|
||||
|
||||
set (LOOT_TESTS_HEADERS # Testing this here rather than as part of the API tests
|
||||
# because it tests internal code and requires internal
|
||||
# linking.
|
||||
"${CMAKE_SOURCE_DIR}/src/tests/api/loot_db_test.h"
|
||||
"${CMAKE_SOURCE_DIR}/src/tests/backend/app/loot_paths_test.h"
|
||||
"${CMAKE_SOURCE_DIR}/src/tests/backend/app/loot_settings_test.h"
|
||||
"${CMAKE_SOURCE_DIR}/src/tests/backend/app/loot_state_test.h"
|
||||
@@ -272,19 +280,9 @@ set (LOOT_TESTS_HEADERS # Testing this here rather than as part of the API tests
|
||||
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/loot_apply_load_order_test.h"
|
||||
"${CMAKE_SOURCE_DIR}/src/tests/api/loot_create_db_test.h"
|
||||
"${CMAKE_SOURCE_DIR}/src/tests/api/loot_eval_lists_test.h"
|
||||
"${CMAKE_SOURCE_DIR}/src/tests/api/loot_get_dirty_info_test.h"
|
||||
"${CMAKE_SOURCE_DIR}/src/tests/api/loot_get_masterlist_revision_test.h"
|
||||
"${CMAKE_SOURCE_DIR}/src/tests/api/loot_get_plugin_messages_test.h"
|
||||
"${CMAKE_SOURCE_DIR}/src/tests/api/loot_get_plugin_tags_test.h"
|
||||
"${CMAKE_SOURCE_DIR}/src/tests/api/loot_get_tag_map_test.h"
|
||||
"${CMAKE_SOURCE_DIR}/src/tests/api/loot_load_lists_test.h"
|
||||
"${CMAKE_SOURCE_DIR}/src/tests/api/loot_sort_plugins_test.h"
|
||||
"${CMAKE_SOURCE_DIR}/src/tests/api/loot_update_masterlist_test.h"
|
||||
"${CMAKE_SOURCE_DIR}/src/tests/api/loot_write_minimal_list_test.h"
|
||||
"${CMAKE_SOURCE_DIR}/src/tests/api/test_api.h"
|
||||
"${CMAKE_SOURCE_DIR}/src/tests/api/create_database_test.h"
|
||||
"${CMAKE_SOURCE_DIR}/src/tests/api/database_interface_test.h"
|
||||
"${CMAKE_SOURCE_DIR}/src/tests/api/is_compatible_test.h"
|
||||
"${CMAKE_SOURCE_DIR}/src/tests/common_game_test_fixture.h")
|
||||
|
||||
source_group("Header Files\\backend" FILES ${LOOT_HEADERS})
|
||||
|
||||
+58
-529
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,270 @@
|
||||
/* 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_DATABASE_INTERFACE
|
||||
#define LOOT_DATABASE_INTERFACE
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "loot/language_code.h"
|
||||
#include "loot/masterlist_info.h"
|
||||
#include "loot/plugin_cleanliness.h"
|
||||
#include "loot/plugin_message.h"
|
||||
#include "loot/plugin_tags.h"
|
||||
|
||||
namespace loot {
|
||||
class DatabaseInterface {
|
||||
public:
|
||||
/**********************************************************************//**
|
||||
* @name Database Loading Functions
|
||||
*************************************************************************/
|
||||
/**@{*/
|
||||
|
||||
/**
|
||||
* @brief Loads the masterlist and userlist from the paths specified.
|
||||
* @details Can be called multiple times, each time replacing the
|
||||
* previously-loaded data.
|
||||
* @param masterlist_path
|
||||
* A string containing the relative or absolute path to the masterlist
|
||||
* file that should be loaded.
|
||||
* @param userlist_path
|
||||
* A string containing the relative or absolute path to the userlist
|
||||
* file that should be loaded, or `NULL`. If `NULL`, no userlist will
|
||||
* be loaded.
|
||||
*/
|
||||
virtual void LoadLists(const std::string& masterlist_path,
|
||||
const std::string& userlist_path) = 0;
|
||||
|
||||
/**
|
||||
* @brief Evaluates all conditions and regular expression metadata
|
||||
* entries.
|
||||
* @details Repeated calls re-evaluate the metadata from scratch. This
|
||||
* function affects the output of all the database access
|
||||
* functions.
|
||||
* @param language
|
||||
* The language code that is used for message language comparisons.
|
||||
*/
|
||||
virtual void EvalLists(const LanguageCode language) = 0;
|
||||
|
||||
/**********************************************************************//**
|
||||
* @name LOOT Functionality Functions
|
||||
*************************************************************************/
|
||||
/**@{*/
|
||||
|
||||
/**
|
||||
* @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 db
|
||||
* The database the function acts on.
|
||||
* @param sortedPlugins
|
||||
* A pointer to an array of plugin filenames in their sorted load
|
||||
* order.
|
||||
* @param numPlugins
|
||||
* A pointer to the size of the outputted array.
|
||||
* @returns A return code.
|
||||
*/
|
||||
virtual std::vector<std::string> SortPlugins() = 0;
|
||||
|
||||
/**
|
||||
* @brief Applies the given load order.
|
||||
* @param db
|
||||
* The database the function acts on.
|
||||
* @param loadOrder
|
||||
* An array of plugin filenames in the load order to be set.
|
||||
* @param numPlugins
|
||||
* The size of the inputted array.
|
||||
* @returns A return code.
|
||||
*/
|
||||
virtual void ApplyLoadOrder(const std::vector<std::string>& loadOrder) = 0;
|
||||
|
||||
/**
|
||||
* @brief Update the given masterlist.
|
||||
* @details Uses Git to update the given masterlist to a given remote.
|
||||
* If the masterlist doesn't exist, this will create it. This
|
||||
* function also initialises a Git repository in the given
|
||||
* masterlist's parent folder. If the masterlist was not already
|
||||
* up-to-date, it will be re-loaded, but not re-evaluated.
|
||||
*
|
||||
* If a Git repository is already present, it will be used to
|
||||
* perform a diff-only update, but if for any reason a
|
||||
* fast-forward merge update is not possible, the existing
|
||||
* repository will be deleted and a new repository cloned from
|
||||
* the given remote.
|
||||
* @param db
|
||||
* The database the function acts on.
|
||||
* @param masterlistPath
|
||||
* A string containing the relative or absolute path to the masterlist
|
||||
* file that should be updated. The filename must match the filename
|
||||
* of the masterlist file in the given remote repository, otherwise it
|
||||
* will not be updated correctly. Although LOOT itself expects this
|
||||
* filename to be "masterlist.yaml", the API does not check for any
|
||||
* specific filename.
|
||||
* @param remoteURL
|
||||
* The URL of the remote from which to fetch updates. This can also be
|
||||
* a relative or absolute path to a local repository.
|
||||
* @param remoteBranch
|
||||
* The branch of the remote from which to apply updates. LOOT's
|
||||
* official masterlists are versioned using separate branches for each
|
||||
* new version of the masterlist syntax, so if you're using them,
|
||||
* check their repositories to see which is the latest release branch.
|
||||
* @param updated
|
||||
* `true` if the masterlist was updated. `false` if no update was
|
||||
* necessary, ie. it was already up-to-date. If `true`, the masterlist
|
||||
* will have been re-loaded, but will need to be re-evaluated
|
||||
* separately.
|
||||
* @returns A return code.
|
||||
*/
|
||||
virtual bool UpdateMasterlist(const std::string& masterlist_path,
|
||||
const std::string& remote_url,
|
||||
const std::string& remote_branch) = 0;
|
||||
|
||||
/**
|
||||
* @brief Get the given masterlist's revision.
|
||||
* @details Getting a masterlist's revision is only possible if it is
|
||||
* found inside a local Git repository.
|
||||
* @param db
|
||||
* The database the function acts on.
|
||||
* @param masterlistPath
|
||||
* A string containing the relative or absolute path to the masterlist
|
||||
* file that should be queried.
|
||||
* @param getShortID
|
||||
* If `true`, the shortest unique hexadecimal revision hash that is at
|
||||
* least 7 characters long will be outputted. Otherwise, the full 40
|
||||
* character hash will be outputted.
|
||||
* @param revisionID
|
||||
* A pointer to a string containing the outputted revision hash for
|
||||
* the masterlist. If the masterlist doesn't exist, or there is no Git
|
||||
* repository at its location, this will be `NULL`.
|
||||
* @param revisionDate
|
||||
* A pointer to a string containing the ISO 8601 formatted revision
|
||||
* date, ie. YYYY-MM-DD. If the masterlist doesn't exist, or there is
|
||||
* no Git repository at its location, this will be `NULL`.
|
||||
* @param isModified
|
||||
* A pointer to a boolean that is `true` if the masterlist has been
|
||||
* edited since the outputted revision, or `false` if it is at exactly
|
||||
* the revision given.
|
||||
* @returns A return code.
|
||||
*/
|
||||
virtual MasterlistInfo GetMasterlistRevision(const std::string& masterlist_path,
|
||||
const bool get_short_id) = 0;
|
||||
|
||||
/**@}*/
|
||||
/**********************************************************************//**
|
||||
* @name Database Access Functions
|
||||
*************************************************************************/
|
||||
/**@{*/
|
||||
|
||||
/**
|
||||
* @brief Outputs the Bash Tags suggested for addition and removal by the
|
||||
* database for the given plugin.
|
||||
* @details loot_get_tag_map() must be called before this to ensure that
|
||||
* the Bash Tag UIDs outputted by this function can be matched up
|
||||
* to name strings.
|
||||
* @param db
|
||||
* The database the function acts on.
|
||||
* @param plugin
|
||||
* The filename of the plugin to look up Bash Tag suggestions for.
|
||||
* @param tags_added
|
||||
* A pointer to the outputted array of UIDs of the Bash Tags suggested
|
||||
* for addition to the specified plugin. `NULL` if no Bash Tag
|
||||
* additions are suggested.
|
||||
* @param numTags_added
|
||||
* A pointer to the size of the tags_added array. `0` if `tags_added`
|
||||
* is `NULL`.
|
||||
* @param tags_removed
|
||||
* A pointer to the outputted array of UIDs of the Bash Tags suggested
|
||||
* for removal from the specified plugin. `NULL` if no Bash Tag
|
||||
* removals are suggested.
|
||||
* @param numTags_removed
|
||||
* A pointer to the size of the `tags_removed` array. `0` if
|
||||
* `tags_removed` is `null`.
|
||||
* @param userlistModified
|
||||
* `true` if the Bash Tag suggestions were modified by the data in the
|
||||
* userlist, `false` otherwise.
|
||||
* @returns A return code.
|
||||
*/
|
||||
virtual PluginTags GetPluginTags(const std::string& plugin) = 0;
|
||||
|
||||
/**
|
||||
* @brief Outputs the messages associated with the given plugin in the
|
||||
* database.
|
||||
* @param db
|
||||
* The database the function acts on.
|
||||
* @param plugin
|
||||
* The filename of the plugin to look up messages for.
|
||||
* @param messages
|
||||
* A pointer to the outputted array of messages associated with the
|
||||
* specified plugin, given as loot_message structures. `NULL` if the
|
||||
* plugin has no messages associated with it.
|
||||
* @param numMessages
|
||||
* A pointer to the size of the outputted array. If no messages are
|
||||
* outputted, this will be `0`.
|
||||
* @returns A return code.
|
||||
*/
|
||||
virtual std::vector<PluginMessage> GetPluginMessages(const std::string& plugin) = 0;
|
||||
|
||||
/**
|
||||
* @brief Determines the database's knowledge of a plugin's dirtiness.
|
||||
* @details Outputs whether the plugin should be cleaned or not, or if
|
||||
* no data is available. The mechanism used to determine that
|
||||
* a plugin should not be cleaned is not very reliable, and is
|
||||
* likely to fail if `loot_eval_lists()` was called with a
|
||||
* language other than English. As such, some plugins that should
|
||||
* not be cleaned may have the `loot_needs_cleaning_unknown`
|
||||
* code outputted.
|
||||
* @param db
|
||||
* The database the function acts on.
|
||||
* @param plugin
|
||||
* The plugin to look up dirty status information for.
|
||||
* @param needsCleaning
|
||||
* A pointer to a plugin cleanliness code.
|
||||
* @returns A return code.
|
||||
*/
|
||||
virtual PluginCleanliness GetPluginCleanliness(const std::string& plugin) = 0;
|
||||
|
||||
/**
|
||||
* @brief Writes a minimal metadata file that only contains plugins with
|
||||
* Bash Tag suggestions and/or dirty info, plus the suggestions and
|
||||
* info themselves.
|
||||
* @param db
|
||||
* The database the function acts on.
|
||||
* @param outputFile
|
||||
* The path to which the file shall be written.
|
||||
* @param overwrite
|
||||
* If `false` and `outputFile` already exists, no data will be
|
||||
* written. Otherwise, data will be written.
|
||||
* @returns A return code.
|
||||
*/
|
||||
virtual void WriteMinimalList(const std::string& outputFile,
|
||||
const bool overwrite) = 0;
|
||||
|
||||
/**@}*/
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,37 @@
|
||||
/* 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_MASTERLIST_INFO
|
||||
#define LOOT_MASTERLIST_INFO
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace loot {
|
||||
struct MasterlistInfo {
|
||||
std::string revision_id;
|
||||
std::string revision_date;
|
||||
bool is_modified;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,36 @@
|
||||
/* 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_PLUGIN_CLEANLINESS
|
||||
#define LOOT_PLUGIN_CLEANLINESS
|
||||
|
||||
namespace loot {
|
||||
enum struct PluginCleanliness : unsigned int {
|
||||
clean,
|
||||
dirty,
|
||||
do_not_clean,
|
||||
unknown,
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,50 @@
|
||||
/* 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_PLUGIN_MESSAGE
|
||||
#define LOOT_PLUGIN_MESSAGE
|
||||
|
||||
#include "loot/message_type.h"
|
||||
|
||||
namespace loot {
|
||||
/**
|
||||
* @brief A structure that holds the type of a message and the message
|
||||
* string itself.
|
||||
*/
|
||||
class PluginMessage {
|
||||
public:
|
||||
/**
|
||||
* @var type
|
||||
* The type of the message, specified using one of the message
|
||||
* type codes.
|
||||
* @var text
|
||||
* The message string, which may be formatted using
|
||||
* [GitHub Flavored Markdown]
|
||||
* (https://help.github.com/articles/github-flavored-markdown).
|
||||
*/
|
||||
MessageType type;
|
||||
std::string text;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,38 @@
|
||||
/* 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_PLUGIN_TAGS
|
||||
#define LOOT_PLUGIN_TAGS
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
namespace loot {
|
||||
struct PluginTags {
|
||||
std::set<std::string> added;
|
||||
std::set<std::string> removed;
|
||||
bool userlist_modified;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
+12
-600
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,255 @@
|
||||
/* 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/api_database.h"
|
||||
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "backend/error.h"
|
||||
#include "backend/game/game.h"
|
||||
#include "backend/plugin/plugin_sorter.h"
|
||||
|
||||
namespace loot {
|
||||
ApiDatabase::ApiDatabase(const GameType game, const std::string& gamePath, const std::string& gameLocalDataPath)
|
||||
: game_(Game(GameType(game))) {
|
||||
game_.SetGamePath(gamePath);
|
||||
game_.Init(false, gameLocalDataPath);
|
||||
}
|
||||
|
||||
///////////////////////////////////
|
||||
// Database Loading Functions
|
||||
///////////////////////////////////
|
||||
|
||||
void ApiDatabase::LoadLists(const std::string& masterlistPath,
|
||||
const std::string& userlistPath) {
|
||||
Masterlist temp;
|
||||
MetadataList userTemp;
|
||||
|
||||
if (boost::filesystem::exists(masterlistPath)) {
|
||||
temp.Load(masterlistPath);
|
||||
} else {
|
||||
throw Error(Error::Code::path_not_found, std::string("The given masterlist path does not exist: ") + masterlistPath);
|
||||
}
|
||||
|
||||
if (!userlistPath.empty()) {
|
||||
if (boost::filesystem::exists(userlistPath)) {
|
||||
userTemp.Load(userlistPath);
|
||||
} else {
|
||||
throw Error(Error::Code::path_not_found, std::string("The given userlist path does not exist: ") + userlistPath);
|
||||
}
|
||||
}
|
||||
|
||||
game_.GetMasterlist() = temp;
|
||||
unevaluatedMasterlist_ = temp;
|
||||
game_.GetUserlist() = userTemp;
|
||||
unevaluatedUserlist_ = userTemp;
|
||||
}
|
||||
|
||||
void ApiDatabase::EvalLists(const LanguageCode language) {
|
||||
// Clear caches before evaluating conditions.
|
||||
game_.ClearCachedConditions();
|
||||
|
||||
Masterlist temp = unevaluatedMasterlist_;
|
||||
MetadataList userTemp = unevaluatedUserlist_;
|
||||
|
||||
// Refresh active plugins before evaluating conditions.
|
||||
temp.EvalAllConditions(game_, Language(LanguageCode(language)).GetCode());
|
||||
userTemp.EvalAllConditions(game_, Language(LanguageCode(language)).GetCode());
|
||||
|
||||
game_.GetMasterlist() = temp;
|
||||
game_.GetUserlist() = userTemp;
|
||||
}
|
||||
|
||||
////////////////////////////////////
|
||||
// LOOT Functionality Functions
|
||||
////////////////////////////////////
|
||||
|
||||
std::vector<std::string> ApiDatabase::SortPlugins() {
|
||||
// Always reload all the plugins.
|
||||
game_.LoadPlugins(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;
|
||||
}
|
||||
|
||||
void ApiDatabase::ApplyLoadOrder(const std::vector<std::string>& loadOrder) {
|
||||
game_.SetLoadOrder(loadOrder);
|
||||
}
|
||||
|
||||
bool ApiDatabase::UpdateMasterlist(const std::string& masterlistPath,
|
||||
const std::string& remoteURL,
|
||||
const std::string& remoteBranch) {
|
||||
if (!boost::filesystem::is_directory(boost::filesystem::path(masterlistPath).parent_path()))
|
||||
throw Error(Error::Code::invalid_args, "Given masterlist path \"" + std::string(masterlistPath) + "\" does not have a valid parent directory.");
|
||||
|
||||
Masterlist masterlist;
|
||||
return masterlist.Update(masterlistPath, remoteURL, remoteBranch);
|
||||
}
|
||||
|
||||
MasterlistInfo ApiDatabase::GetMasterlistRevision(const std::string& masterlistPath,
|
||||
const bool getShortID) {
|
||||
MasterlistInfo apiMasterlistInfo;
|
||||
apiMasterlistInfo.is_modified = false;
|
||||
try {
|
||||
Masterlist::Info info = Masterlist::GetInfo(masterlistPath, getShortID);
|
||||
|
||||
if (boost::ends_with(info.revision, " (edited)")) {
|
||||
apiMasterlistInfo.revision_id = info.revision.substr(0, info.revision.length() - 9);
|
||||
apiMasterlistInfo.revision_date = info.date.substr(0, info.date.length() - 9);
|
||||
apiMasterlistInfo.is_modified = true;
|
||||
} else {
|
||||
apiMasterlistInfo.revision_id = info.revision;
|
||||
apiMasterlistInfo.revision_date = info.date;
|
||||
apiMasterlistInfo.is_modified = false;
|
||||
}
|
||||
} catch (Error &e) {
|
||||
if (e.code() != Error::Code::ok)
|
||||
throw;
|
||||
}
|
||||
|
||||
return apiMasterlistInfo;
|
||||
}
|
||||
|
||||
//////////////////////////
|
||||
// DB Access Functions
|
||||
//////////////////////////
|
||||
|
||||
PluginTags ApiDatabase::GetPluginTags(const std::string& plugin) {
|
||||
PluginTags tags;
|
||||
|
||||
PluginMetadata pluginMetadata = game_.GetMasterlist().FindPlugin(PluginMetadata(plugin));
|
||||
for (const auto &tag : pluginMetadata.Tags()) {
|
||||
if (tag.IsAddition())
|
||||
tags.added.insert(tag.Name());
|
||||
else
|
||||
tags.removed.insert(tag.Name());
|
||||
}
|
||||
|
||||
pluginMetadata = game_.GetUserlist().FindPlugin(PluginMetadata(plugin));
|
||||
tags.userlist_modified = !pluginMetadata.Tags().empty();
|
||||
for (const auto &tag : pluginMetadata.Tags()) {
|
||||
if (tag.IsAddition())
|
||||
tags.added.insert(tag.Name());
|
||||
else
|
||||
tags.removed.insert(tag.Name());
|
||||
}
|
||||
|
||||
return tags;
|
||||
}
|
||||
|
||||
std::vector<PluginMessage> ApiDatabase::GetPluginMessages(const std::string& plugin) {
|
||||
std::vector<PluginMessage> messages;
|
||||
|
||||
PluginMetadata pluginMetadata = game_.GetMasterlist().FindPlugin(PluginMetadata(plugin));
|
||||
for (const auto& message : pluginMetadata.Messages()) {
|
||||
PluginMessage pluginMessage;
|
||||
pluginMessage.type = message.GetType();
|
||||
pluginMessage.text = message.GetText();
|
||||
messages.push_back(pluginMessage);
|
||||
}
|
||||
|
||||
pluginMetadata = game_.GetUserlist().FindPlugin(PluginMetadata(plugin));
|
||||
for (const auto& message : pluginMetadata.Messages()) {
|
||||
PluginMessage pluginMessage;
|
||||
pluginMessage.type = message.GetType();
|
||||
pluginMessage.text = message.GetText();
|
||||
messages.push_back(pluginMessage);
|
||||
}
|
||||
|
||||
return messages;
|
||||
}
|
||||
|
||||
PluginCleanliness ApiDatabase::GetPluginCleanliness(const std::string& plugin) {
|
||||
// Is there any dirty info? Testing for applicability happens in loot_eval_lists().
|
||||
if (!game_.GetMasterlist().FindPlugin(PluginMetadata(plugin)).DirtyInfo().empty()
|
||||
|| !game_.GetUserlist().FindPlugin(PluginMetadata(plugin)).DirtyInfo().empty()) {
|
||||
return PluginCleanliness::dirty;
|
||||
}
|
||||
|
||||
// Is there a message beginning with the substring "Do not clean."?
|
||||
// This isn't a very reliable system, because if the lists have been evaluated in some language
|
||||
// other than English, the strings will be in different languages (and the API can't tell what they'd be)
|
||||
// and the strings may be non-standard and begin with something other than "Do not clean." anyway.
|
||||
std::list<Message> messages(game_.GetMasterlist().FindPlugin(PluginMetadata(plugin)).Messages());
|
||||
|
||||
for (const auto& message : messages) {
|
||||
if (boost::starts_with(message.GetText(), "Do not clean")) {
|
||||
return PluginCleanliness::do_not_clean;
|
||||
}
|
||||
}
|
||||
|
||||
messages = game_.GetUserlist().FindPlugin(PluginMetadata(plugin)).Messages();
|
||||
|
||||
for (const auto& message : messages) {
|
||||
if (boost::starts_with(message.GetText(), "Do not clean")) {
|
||||
return PluginCleanliness::do_not_clean;
|
||||
}
|
||||
}
|
||||
|
||||
return PluginCleanliness::unknown;
|
||||
}
|
||||
|
||||
// Writes a minimal masterlist that only contains mods that have Bash Tag suggestions,
|
||||
// and/or dirty messages, plus the Tag suggestions and/or messages themselves and their
|
||||
// conditions, in order to create the Wrye Bash taglist. outputFile is the path to use
|
||||
// for output. If outputFile already exists, it will only be overwritten if overwrite is true.
|
||||
void ApiDatabase::WriteMinimalList(const std::string& outputFile, const bool overwrite) {
|
||||
if (!boost::filesystem::exists(boost::filesystem::path(outputFile).parent_path()))
|
||||
throw Error(Error::Code::invalid_args, "Output directory does not exist.");
|
||||
|
||||
if (boost::filesystem::exists(outputFile) && !overwrite)
|
||||
throw Error(Error::Code::path_write_fail, "Output file exists but overwrite is not set to true.");
|
||||
|
||||
Masterlist temp = game_.GetMasterlist();
|
||||
std::unordered_set<PluginMetadata> minimalPlugins;
|
||||
for (const auto &plugin : temp.Plugins()) {
|
||||
PluginMetadata p(plugin.Name());
|
||||
p.Tags(plugin.Tags());
|
||||
p.DirtyInfo(plugin.DirtyInfo());
|
||||
minimalPlugins.insert(p);
|
||||
}
|
||||
|
||||
YAML::Emitter yout;
|
||||
yout.SetIndent(2);
|
||||
yout << YAML::BeginMap
|
||||
<< YAML::Key << "plugins" << YAML::Value << minimalPlugins
|
||||
<< YAML::EndMap;
|
||||
|
||||
boost::filesystem::path p(outputFile);
|
||||
boost::filesystem::ofstream out(p);
|
||||
if (out.fail())
|
||||
throw Error(Error::Code::path_write_fail, "Couldn't open output file.");
|
||||
out << yout.c_str();
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/* 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_LOOT_DB
|
||||
#define LOOT_API_LOOT_DB
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "backend/game/game.h"
|
||||
#include "loot/database_interface.h"
|
||||
|
||||
namespace loot {
|
||||
struct ApiDatabase : public DatabaseInterface {
|
||||
ApiDatabase(const GameType clientGame,
|
||||
const std::string& gamePath,
|
||||
const std::string& gameLocalDataPath);
|
||||
|
||||
void LoadLists(const std::string& masterlist_path,
|
||||
const std::string& userlist_path);
|
||||
|
||||
void EvalLists(const LanguageCode language);
|
||||
|
||||
std::vector<std::string> SortPlugins();
|
||||
|
||||
void ApplyLoadOrder(const std::vector<std::string>& loadOrder);
|
||||
|
||||
bool UpdateMasterlist(const std::string& masterlist_path,
|
||||
const std::string& remote_url,
|
||||
const std::string& remote_branch);
|
||||
|
||||
MasterlistInfo GetMasterlistRevision(const std::string& masterlist_path,
|
||||
const bool get_short_id);
|
||||
|
||||
PluginTags GetPluginTags(const std::string& plugin);
|
||||
|
||||
std::vector<PluginMessage> GetPluginMessages(const std::string& plugin);
|
||||
|
||||
PluginCleanliness GetPluginCleanliness(const std::string& plugin);
|
||||
|
||||
void WriteMinimalList(const std::string& outputFile,
|
||||
const bool overwrite);
|
||||
private:
|
||||
Game game_;
|
||||
|
||||
Masterlist unevaluatedMasterlist_;
|
||||
MetadataList unevaluatedUserlist_;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,144 +0,0 @@
|
||||
/* 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/loot_db.h"
|
||||
|
||||
#include "backend/error.h"
|
||||
|
||||
loot_db::loot_db(const unsigned int clientGame, const std::string& gamePath, const boost::filesystem::path& gameLocalDataPath)
|
||||
: Game(loot::GameType(clientGame)) {
|
||||
this->SetGamePath(gamePath);
|
||||
this->Init(false, gameLocalDataPath);
|
||||
}
|
||||
|
||||
loot::Masterlist& loot_db::getUnevaluatedMasterlist() {
|
||||
return unevaluatedMasterlist_;
|
||||
}
|
||||
|
||||
loot::MetadataList& loot_db::getUnevaluatedUserlist() {
|
||||
return unevaluatedUserlist_;
|
||||
}
|
||||
|
||||
const char * loot_db::getRevisionIdString() const {
|
||||
return revisionId.c_str();
|
||||
}
|
||||
|
||||
const char * loot_db::getRevisionDateString() const {
|
||||
return revisionDate.c_str();
|
||||
}
|
||||
|
||||
const std::vector<const char *>& loot_db::getPluginNames() const {
|
||||
return cPluginNames;
|
||||
}
|
||||
|
||||
const std::vector<const char *>& loot_db::getBashTagMap() const {
|
||||
return cBashTagMap;
|
||||
}
|
||||
|
||||
unsigned int loot_db::getBashTagUid(const std::string& name) const {
|
||||
auto it = bashTagMap.find(name);
|
||||
if (it != end(bashTagMap))
|
||||
return it->second;
|
||||
|
||||
throw loot::Error(loot::Error::Code::no_tag_map, "The Bash Tag \"" + name + "\" does not exist in the Bash Tag map.");
|
||||
}
|
||||
|
||||
const std::vector<unsigned int>& loot_db::getAddedTagIds() const {
|
||||
return addedTagIds;
|
||||
}
|
||||
|
||||
const std::vector<unsigned int>& loot_db::getRemovedTagIds() const {
|
||||
return removedTagIds;
|
||||
}
|
||||
|
||||
const std::vector<loot_message>& loot_db::getPluginMessages() const {
|
||||
return cPluginMessages;
|
||||
}
|
||||
|
||||
void loot_db::setRevisionIdString(const std::string& str) {
|
||||
revisionId = str;
|
||||
}
|
||||
|
||||
void loot_db::setRevisionDateString(const std::string& str) {
|
||||
revisionDate = str;
|
||||
}
|
||||
|
||||
void loot_db::setAddedTags(const std::set<std::string>& names) {
|
||||
addedTagIds.clear();
|
||||
for (const auto& name : names)
|
||||
addedTagIds.push_back(getBashTagUid(name));
|
||||
}
|
||||
|
||||
void loot_db::setRemovedTags(const std::set<std::string>& names) {
|
||||
removedTagIds.clear();
|
||||
for (const auto& name : names)
|
||||
removedTagIds.push_back(getBashTagUid(name));
|
||||
}
|
||||
|
||||
void loot_db::setPluginMessages(const std::list<loot::Message>& pluginMessages) {
|
||||
cPluginMessages.resize(pluginMessages.size());
|
||||
pluginMessageStrings.resize(pluginMessages.size());
|
||||
|
||||
size_t i = 0;
|
||||
for (const auto& message : pluginMessages) {
|
||||
pluginMessageStrings[i] = message.GetText();
|
||||
|
||||
cPluginMessages[i].type = static_cast<unsigned int>(message.GetType());
|
||||
cPluginMessages[i].message = pluginMessageStrings[i].c_str();
|
||||
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
void loot_db::addBashTagsToMap(std::set<std::string> names) {
|
||||
for (const auto& name : names) {
|
||||
// Try adding the Bash Tag to the map assuming it's not already in
|
||||
// there, then use the UID in the returned value, as that will be
|
||||
// equal to the value in the map, even if the Bash Tag was already
|
||||
// present.
|
||||
unsigned int uid = bashTagMap.size();
|
||||
// If the tag already exists in the map, do
|
||||
auto it = bashTagMap.emplace(name, uid).first;
|
||||
if (it->second == cBashTagMap.size())
|
||||
cBashTagMap.push_back(it->first.c_str());
|
||||
else
|
||||
cBashTagMap.at(it->second) = it->first.c_str();
|
||||
}
|
||||
}
|
||||
|
||||
void loot_db::clearBashTagMap() {
|
||||
bashTagMap.clear();
|
||||
cBashTagMap.clear();
|
||||
}
|
||||
|
||||
void loot_db::clearArrays() {
|
||||
pluginNames.clear();
|
||||
cPluginNames.clear();
|
||||
|
||||
addedTagIds.clear();
|
||||
removedTagIds.clear();
|
||||
|
||||
cPluginMessages.clear();
|
||||
pluginMessageStrings.clear();
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
/* 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_LOOT_DB
|
||||
#define LOOT_API_LOOT_DB
|
||||
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "backend/game/game.h"
|
||||
#include "loot/api.h"
|
||||
|
||||
struct loot_db : public loot::Game {
|
||||
loot_db(const unsigned int clientGame,
|
||||
const std::string& gamePath,
|
||||
const boost::filesystem::path& gameLocalDataPath);
|
||||
|
||||
loot::Masterlist& getUnevaluatedMasterlist();
|
||||
loot::MetadataList& getUnevaluatedUserlist();
|
||||
|
||||
const char * getRevisionIdString() const;
|
||||
const char * getRevisionDateString() const;
|
||||
|
||||
const std::vector<const char *>& getPluginNames() const;
|
||||
|
||||
const std::vector<const char *>& getBashTagMap() const;
|
||||
unsigned int getBashTagUid(const std::string& name) const;
|
||||
|
||||
const std::vector<unsigned int>& getAddedTagIds() const;
|
||||
const std::vector<unsigned int>& getRemovedTagIds() const;
|
||||
|
||||
const std::vector<loot_message>& getPluginMessages() const;
|
||||
|
||||
void setRevisionIdString(const std::string& str);
|
||||
void setRevisionDateString(const std::string& str);
|
||||
|
||||
template<class T>
|
||||
void setPluginNames(const T& plugins) {
|
||||
// First take copies of the C++ strings to store.
|
||||
pluginNames.resize(plugins.size());
|
||||
std::transform(begin(plugins),
|
||||
end(plugins),
|
||||
begin(pluginNames),
|
||||
[](const loot::PluginMetadata& plugin) {
|
||||
return plugin.Name();
|
||||
});
|
||||
|
||||
// Now store their C strings.
|
||||
cPluginNames.resize(pluginNames.size());
|
||||
std::transform(begin(pluginNames),
|
||||
end(pluginNames),
|
||||
begin(cPluginNames),
|
||||
[](const std::string& pluginName) {
|
||||
return pluginName.c_str();
|
||||
});
|
||||
}
|
||||
|
||||
void setAddedTags(const std::set<std::string>& names);
|
||||
void setRemovedTags(const std::set<std::string>& names);
|
||||
|
||||
void setPluginMessages(const std::list<loot::Message>& pluginMessages);
|
||||
|
||||
void addBashTagsToMap(std::set<std::string> names);
|
||||
|
||||
void clearBashTagMap();
|
||||
void clearArrays();
|
||||
private:
|
||||
loot::Masterlist unevaluatedMasterlist_;
|
||||
loot::MetadataList unevaluatedUserlist_;
|
||||
|
||||
std::string revisionId;
|
||||
std::string revisionDate;
|
||||
|
||||
std::vector<std::string> pluginNames;
|
||||
std::vector<const char *> cPluginNames;
|
||||
|
||||
// For the Bash Tag map, a string is mapped to a UID that is also the
|
||||
// index of the vector where the C string can be found.
|
||||
std::unordered_map<std::string, unsigned int> bashTagMap;
|
||||
std::vector<const char *> cBashTagMap;
|
||||
|
||||
std::vector<unsigned int> addedTagIds;
|
||||
std::vector<unsigned int> removedTagIds;
|
||||
|
||||
std::vector<loot_message> cPluginMessages;
|
||||
std::vector<std::string> pluginMessageStrings;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -32,11 +32,11 @@ along with LOOT. If not, see
|
||||
namespace loot {
|
||||
namespace test {
|
||||
class ApiGameOperationsTest :
|
||||
public ::testing::TestWithParam<unsigned int>,
|
||||
public ::testing::TestWithParam<GameType>,
|
||||
public CommonGameTestFixture {
|
||||
protected:
|
||||
ApiGameOperationsTest() :
|
||||
CommonGameTestFixture(GetParam()),
|
||||
CommonGameTestFixture(static_cast<unsigned int>(GetParam())),
|
||||
db_(nullptr),
|
||||
masterlistPath(localPath / "masterlist.yaml"),
|
||||
noteMessage("Do not clean ITM records, they are intentional and required for the mod to function."),
|
||||
@@ -48,14 +48,12 @@ protected:
|
||||
|
||||
ASSERT_FALSE(boost::filesystem::exists(masterlistPath));
|
||||
|
||||
ASSERT_EQ(loot_ok, loot_create_db(&db_, GetParam(), dataPath.parent_path().string().c_str(), localPath.string().c_str()));
|
||||
db_ = CreateDatabase(GetParam(), dataPath.parent_path().string(), localPath.string());
|
||||
}
|
||||
|
||||
virtual void TearDown() {
|
||||
tearDown();
|
||||
|
||||
ASSERT_NO_THROW(loot_destroy_db(db_));
|
||||
|
||||
// The masterlist may have been created during the test, so delete it.
|
||||
ASSERT_NO_THROW(boost::filesystem::remove(masterlistPath));
|
||||
}
|
||||
@@ -109,7 +107,7 @@ protected:
|
||||
masterlist.close();
|
||||
}
|
||||
|
||||
loot_db * db_;
|
||||
std::shared_ptr<DatabaseInterface> db_;
|
||||
|
||||
const boost::filesystem::path masterlistPath;
|
||||
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
/* 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_CREATE_DATABASE_TEST
|
||||
#define LOOT_TESTS_API_CREATE_DATABASE_TEST
|
||||
|
||||
#include "loot/api.h"
|
||||
|
||||
#include <climits>
|
||||
|
||||
#include "tests/common_game_test_fixture.h"
|
||||
|
||||
namespace loot {
|
||||
namespace test {
|
||||
class CreateDatabaseTest :
|
||||
public ::testing::TestWithParam<GameType>,
|
||||
public CommonGameTestFixture {
|
||||
protected:
|
||||
CreateDatabaseTest() :
|
||||
CommonGameTestFixture(static_cast<unsigned int>(GetParam())),
|
||||
db_(nullptr) {}
|
||||
|
||||
void SetUp() {
|
||||
setUp();
|
||||
}
|
||||
|
||||
void TearDown() {
|
||||
tearDown();
|
||||
}
|
||||
|
||||
std::shared_ptr<DatabaseInterface> db_;
|
||||
};
|
||||
|
||||
// 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,
|
||||
::testing::Values(
|
||||
GameType::tes4,
|
||||
GameType::tes5,
|
||||
GameType::fo3,
|
||||
GameType::fonv,
|
||||
GameType::fo4));
|
||||
|
||||
TEST_P(CreateDatabaseTest, shouldSucceedIfPassedValidParametersWithRelativePaths) {
|
||||
EXPECT_NO_THROW(db_ = CreateDatabase(GetParam(), dataPath.parent_path().string(), localPath.string()));
|
||||
EXPECT_NE(nullptr, db_);
|
||||
}
|
||||
|
||||
TEST_P(CreateDatabaseTest, 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_);
|
||||
}
|
||||
|
||||
TEST_P(CreateDatabaseTest, shouldThrowIfPassedAGamePathThatDoesNotExist) {
|
||||
EXPECT_ANY_THROW(CreateDatabase(GetParam(), missingPath.string(), localPath.string()));
|
||||
}
|
||||
|
||||
TEST_P(CreateDatabaseTest, shouldThrowIfPassedALocalPathThatDoesNotExist) {
|
||||
EXPECT_ANY_THROW(CreateDatabase(GetParam(), dataPath.parent_path().string(), missingPath.string()));
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
TEST_P(CreateDatabaseTest, shouldReturnOkIfPassedAnEmptyLocalPathString) {
|
||||
EXPECT_NO_THROW(db_ = CreateDatabase(GetParam(), dataPath.parent_path().string(), ""));
|
||||
EXPECT_NE(nullptr, db_);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,485 @@
|
||||
/* 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_DATABASE_INTERFACE_TEST
|
||||
#define LOOT_TESTS_API_DATABASE_INTERFACE_TEST
|
||||
|
||||
#include "loot/api.h"
|
||||
|
||||
#include "tests/api/api_game_operations_test.h"
|
||||
|
||||
namespace loot {
|
||||
namespace test {
|
||||
class DatabaseInterfaceTest : public ApiGameOperationsTest {
|
||||
protected:
|
||||
DatabaseInterfaceTest() :
|
||||
userlistPath_(localPath / "userlist.yaml"),
|
||||
url_("https://github.com/loot/testing-metadata.git"),
|
||||
branch_("2.x"),
|
||||
minimalOutputPath_(localPath / "minimal.yml") {}
|
||||
|
||||
void SetUp() {
|
||||
ApiGameOperationsTest::SetUp();
|
||||
|
||||
ASSERT_FALSE(boost::filesystem::exists(minimalOutputPath_));
|
||||
}
|
||||
|
||||
void TearDown() {
|
||||
if (boost::filesystem::exists(minimalOutputPath_)) {
|
||||
boost::filesystem::permissions(minimalOutputPath_,
|
||||
boost::filesystem::perms::add_perms
|
||||
| boost::filesystem::perms::owner_write);
|
||||
}
|
||||
|
||||
ApiGameOperationsTest::TearDown();
|
||||
|
||||
// The userlist may have been created during the test, so delete it.
|
||||
ASSERT_NO_THROW(boost::filesystem::remove(userlistPath_));
|
||||
|
||||
// Also remove the ".git" folder if it has been created.
|
||||
ASSERT_NO_THROW(boost::filesystem::remove_all(masterlistPath.parent_path() / ".git"));
|
||||
|
||||
ASSERT_NO_THROW(boost::filesystem::remove(minimalOutputPath_));
|
||||
}
|
||||
|
||||
std::string GetExpectedMinimalContent() const {
|
||||
using std::endl;
|
||||
|
||||
std::stringstream expectedContent;
|
||||
expectedContent
|
||||
<< "plugins:" << endl
|
||||
<< " - name: '" << blankEsm << "'" << endl
|
||||
<< " tag:" << endl
|
||||
<< " - Actors.ACBS" << endl
|
||||
<< " - Actors.AIData" << endl
|
||||
<< " - -C.Water" << endl
|
||||
<< " - name: '" << blankDifferentEsm << "'" << endl
|
||||
<< " dirty:" << endl
|
||||
<< " - crc: 0x7d22f9df" << endl
|
||||
<< " utility: 'TES4Edit'" << endl
|
||||
<< " udr: 4";
|
||||
|
||||
return expectedContent.str();
|
||||
}
|
||||
|
||||
const boost::filesystem::path userlistPath_;
|
||||
const boost::filesystem::path minimalOutputPath_;
|
||||
const std::string url_;
|
||||
const std::string branch_;
|
||||
};
|
||||
|
||||
// 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(,
|
||||
DatabaseInterfaceTest,
|
||||
::testing::Values(
|
||||
GameType::tes4,
|
||||
GameType::tes5,
|
||||
GameType::fo3,
|
||||
GameType::fonv,
|
||||
GameType::fo4));
|
||||
|
||||
TEST_P(DatabaseInterfaceTest, loadListsShouldThrowIfNoMasterlistIsPresent) {
|
||||
EXPECT_ANY_THROW(db_->LoadLists(masterlistPath.string(), ""));
|
||||
}
|
||||
|
||||
TEST_P(DatabaseInterfaceTest, loadListsShouldThrowIfAMasterlistIsPresentButAUserlistDoesNotExistAtTheGivenPath) {
|
||||
ASSERT_NO_THROW(GenerateMasterlist());
|
||||
EXPECT_ANY_THROW(db_->LoadLists(masterlistPath.string(), userlistPath_.string()));
|
||||
}
|
||||
|
||||
TEST_P(DatabaseInterfaceTest, loadListsShouldSucceedIfTheMasterlistIsPresentAndTheUserlistPathIsAnEmptyString) {
|
||||
ASSERT_NO_THROW(GenerateMasterlist());
|
||||
|
||||
EXPECT_NO_THROW(db_->LoadLists(masterlistPath.string(), ""));
|
||||
}
|
||||
|
||||
TEST_P(DatabaseInterfaceTest, loadListsShouldSucceedIfTheMasterlistAndUserlistAreBothPresent) {
|
||||
ASSERT_NO_THROW(GenerateMasterlist());
|
||||
ASSERT_NO_THROW(boost::filesystem::copy(masterlistPath, userlistPath_));
|
||||
|
||||
EXPECT_NO_THROW(db_->LoadLists(masterlistPath.string(), userlistPath_.string()));
|
||||
}
|
||||
|
||||
TEST_P(DatabaseInterfaceTest, evalListsShouldReturnOkForAllLanguagesWithNoListsLoaded) {
|
||||
EXPECT_NO_THROW(db_->EvalLists(LanguageCode::english));
|
||||
EXPECT_NO_THROW(db_->EvalLists(LanguageCode::english));
|
||||
EXPECT_NO_THROW(db_->EvalLists(LanguageCode::spanish));
|
||||
EXPECT_NO_THROW(db_->EvalLists(LanguageCode::russian));
|
||||
EXPECT_NO_THROW(db_->EvalLists(LanguageCode::french));
|
||||
EXPECT_NO_THROW(db_->EvalLists(LanguageCode::chinese));
|
||||
EXPECT_NO_THROW(db_->EvalLists(LanguageCode::polish));
|
||||
EXPECT_NO_THROW(db_->EvalLists(LanguageCode::brazilian_portuguese));
|
||||
EXPECT_NO_THROW(db_->EvalLists(LanguageCode::finnish));
|
||||
EXPECT_NO_THROW(db_->EvalLists(LanguageCode::german));
|
||||
EXPECT_NO_THROW(db_->EvalLists(LanguageCode::danish));
|
||||
}
|
||||
|
||||
TEST_P(DatabaseInterfaceTest, evalListsShouldReturnOKForAllLanguagesWithAMasterlistLoaded) {
|
||||
ASSERT_NO_THROW(GenerateMasterlist());
|
||||
ASSERT_NO_THROW(db_->LoadLists(masterlistPath.string(), ""));
|
||||
|
||||
EXPECT_NO_THROW(db_->EvalLists(LanguageCode::english));
|
||||
EXPECT_NO_THROW(db_->EvalLists(LanguageCode::english));
|
||||
EXPECT_NO_THROW(db_->EvalLists(LanguageCode::spanish));
|
||||
EXPECT_NO_THROW(db_->EvalLists(LanguageCode::russian));
|
||||
EXPECT_NO_THROW(db_->EvalLists(LanguageCode::french));
|
||||
EXPECT_NO_THROW(db_->EvalLists(LanguageCode::chinese));
|
||||
EXPECT_NO_THROW(db_->EvalLists(LanguageCode::polish));
|
||||
EXPECT_NO_THROW(db_->EvalLists(LanguageCode::brazilian_portuguese));
|
||||
EXPECT_NO_THROW(db_->EvalLists(LanguageCode::finnish));
|
||||
EXPECT_NO_THROW(db_->EvalLists(LanguageCode::german));
|
||||
EXPECT_NO_THROW(db_->EvalLists(LanguageCode::danish));
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
ASSERT_EQ(expectedOrder, actualOrder);
|
||||
}
|
||||
|
||||
TEST_P(DatabaseInterfaceTest, applyLoadOrderShouldReturnOkIfLoadOrderGivenIsNotEmpty) {
|
||||
std::vector<std::string> loadOrder = {
|
||||
masterFile,
|
||||
blankEsm,
|
||||
blankMasterDependentEsm,
|
||||
blankDifferentEsm,
|
||||
blankDifferentMasterDependentEsm,
|
||||
blankMasterDependentEsp,
|
||||
blankDifferentMasterDependentEsp,
|
||||
blankEsp,
|
||||
blankPluginDependentEsp,
|
||||
blankDifferentEsp,
|
||||
blankDifferentPluginDependentEsp,
|
||||
};
|
||||
|
||||
EXPECT_NO_THROW(db_->ApplyLoadOrder(loadOrder));
|
||||
}
|
||||
|
||||
TEST_P(DatabaseInterfaceTest, updateMasterlistShouldReturnAnInvalidArgsErrorIfTheMasterlistPathGivenIsInvalid) {
|
||||
EXPECT_ANY_THROW(db_->UpdateMasterlist(";//\?", url_, branch_));
|
||||
}
|
||||
|
||||
TEST_P(DatabaseInterfaceTest, updateMasterlistShouldReturnAnInvalidArgsErrorIfTheMasterlistPathGivenIsEmpty) {
|
||||
EXPECT_ANY_THROW(db_->UpdateMasterlist("", url_, branch_));
|
||||
}
|
||||
|
||||
TEST_P(DatabaseInterfaceTest, updateMasterlistShouldReturnAGitErrorIfTheRepositoryUrlGivenCannotBeFound) {
|
||||
EXPECT_ANY_THROW(db_->UpdateMasterlist(masterlistPath.string(), "https://github.com/loot/oblivion-does-not-exist.git", branch_));
|
||||
}
|
||||
|
||||
TEST_P(DatabaseInterfaceTest, updateMasterlistShouldReturnAnInvalidArgsErrorIfTheRepositoryUrlGivenIsEmpty) {
|
||||
EXPECT_ANY_THROW(db_->UpdateMasterlist(masterlistPath.string(), "", branch_));
|
||||
}
|
||||
|
||||
TEST_P(DatabaseInterfaceTest, updateMasterlistShouldReturnAGitErrorIfTheRepositoryBranchGivenCannotBeFound) {
|
||||
EXPECT_ANY_THROW(db_->UpdateMasterlist(masterlistPath.string(), url_, "missing-branch"));
|
||||
}
|
||||
|
||||
TEST_P(DatabaseInterfaceTest, updateMasterlistShouldReturnAnInvalidArgsErrorIfTheRepositoryBranchGivenIsEmpty) {
|
||||
EXPECT_ANY_THROW(db_->UpdateMasterlist(masterlistPath.string(), url_, ""));
|
||||
}
|
||||
|
||||
TEST_P(DatabaseInterfaceTest, updateMasterlistShouldSucceedIfPassedValidParametersAndOutputTrueIfTheMasterlistWasUpdated) {
|
||||
bool updated = false;
|
||||
EXPECT_NO_THROW(updated = db_->UpdateMasterlist(masterlistPath.string(), url_, branch_));
|
||||
EXPECT_TRUE(updated);
|
||||
EXPECT_TRUE(boost::filesystem::exists(masterlistPath));
|
||||
}
|
||||
|
||||
TEST_P(DatabaseInterfaceTest, updateMasterlistShouldSucceedIfCalledRepeatedlyButOnlyOutputTrueForTheFirstCall) {
|
||||
bool updated = false;
|
||||
EXPECT_NO_THROW(updated = db_->UpdateMasterlist(masterlistPath.string(), url_, branch_));
|
||||
EXPECT_TRUE(updated);
|
||||
|
||||
EXPECT_NO_THROW(updated = db_->UpdateMasterlist(masterlistPath.string(), url_, branch_));
|
||||
EXPECT_FALSE(updated);
|
||||
EXPECT_TRUE(boost::filesystem::exists(masterlistPath));
|
||||
}
|
||||
|
||||
TEST_P(DatabaseInterfaceTest, getMasterlistRevisionShouldSucceedIfNoMasterlistIsPresent) {
|
||||
MasterlistInfo info;
|
||||
EXPECT_NO_THROW(info = db_->GetMasterlistRevision(masterlistPath.string(), false));
|
||||
EXPECT_TRUE(info.revision_id.empty());
|
||||
EXPECT_TRUE(info.revision_date.empty());
|
||||
EXPECT_FALSE(info.is_modified);
|
||||
}
|
||||
|
||||
TEST_P(DatabaseInterfaceTest, getMasterlistRevisionShouldSucceedIfANonVersionControlledMasterlistIsPresent) {
|
||||
ASSERT_NO_THROW(GenerateMasterlist());
|
||||
|
||||
MasterlistInfo info;
|
||||
EXPECT_NO_THROW(info = db_->GetMasterlistRevision(masterlistPath.string(), false));
|
||||
EXPECT_TRUE(info.revision_id.empty());
|
||||
EXPECT_TRUE(info.revision_date.empty());
|
||||
EXPECT_FALSE(info.is_modified);
|
||||
}
|
||||
|
||||
TEST_P(DatabaseInterfaceTest, getMasterlistRevisionShouldOutputLongStringsAndBooleanFalseIfAVersionControlledMasterlistIsPresentAndGetShortIdParameterIsFalse) {
|
||||
ASSERT_NO_THROW(db_->UpdateMasterlist(masterlistPath.string(), url_, branch_));
|
||||
|
||||
MasterlistInfo info;
|
||||
EXPECT_NO_THROW(info = db_->GetMasterlistRevision(masterlistPath.string(), false));
|
||||
EXPECT_EQ(40, info.revision_id.length());
|
||||
EXPECT_EQ(10, info.revision_date.length());
|
||||
EXPECT_FALSE(info.is_modified);
|
||||
}
|
||||
|
||||
TEST_P(DatabaseInterfaceTest, getMasterlistRevisionShouldOutputShortStringsAndBooleanFalseIfAVersionControlledMasterlistIsPresentAndGetShortIdParameterIsTrue) {
|
||||
ASSERT_NO_THROW(db_->UpdateMasterlist(masterlistPath.string(), url_, branch_));
|
||||
|
||||
MasterlistInfo info;
|
||||
EXPECT_NO_THROW(info = db_->GetMasterlistRevision(masterlistPath.string(), false));
|
||||
EXPECT_GE(size_t(40), info.revision_id.length());
|
||||
EXPECT_LE(size_t(7), info.revision_id.length());
|
||||
EXPECT_EQ(10, info.revision_date.length());
|
||||
EXPECT_FALSE(info.is_modified);
|
||||
}
|
||||
|
||||
TEST_P(DatabaseInterfaceTest, getMasterlistRevisionShouldSucceedIfAnEditedVersionControlledMasterlistIsPresent) {
|
||||
ASSERT_NO_THROW(db_->UpdateMasterlist(masterlistPath.string(), url_, branch_));
|
||||
ASSERT_NO_THROW(GenerateMasterlist());
|
||||
|
||||
MasterlistInfo info;
|
||||
EXPECT_NO_THROW(info = db_->GetMasterlistRevision(masterlistPath.string(), false));
|
||||
EXPECT_EQ(40, info.revision_id.length());
|
||||
EXPECT_EQ(10, info.revision_date.length());
|
||||
EXPECT_TRUE(info.is_modified);
|
||||
}
|
||||
|
||||
TEST_P(DatabaseInterfaceTest, getPluginTagsShouldReturnOkAndOutputEmptyNonModifiedArraysIfAPluginWithoutTagsIsQueried) {
|
||||
ASSERT_NO_THROW(GenerateMasterlist());
|
||||
ASSERT_NO_THROW(db_->LoadLists(masterlistPath.string(), ""));
|
||||
|
||||
PluginTags tags;
|
||||
EXPECT_NO_THROW(tags = db_->GetPluginTags(blankEsp));
|
||||
|
||||
EXPECT_TRUE(tags.added.empty());
|
||||
EXPECT_TRUE(tags.removed.empty());
|
||||
EXPECT_FALSE(tags.userlist_modified);
|
||||
}
|
||||
|
||||
TEST_P(DatabaseInterfaceTest, getPluginTagsShouldReturnOkAndNonEmptyNonModifiedArraysIfAPluginWithTagsIsQueried) {
|
||||
ASSERT_NO_THROW(GenerateMasterlist());
|
||||
ASSERT_NO_THROW(db_->LoadLists(masterlistPath.string(), ""));
|
||||
|
||||
PluginTags tags;
|
||||
EXPECT_NO_THROW(tags = db_->GetPluginTags(blankEsm));
|
||||
|
||||
EXPECT_EQ(std::set<std::string>({
|
||||
"Actors.ACBS",
|
||||
"Actors.AIData",
|
||||
}), tags.added);
|
||||
EXPECT_EQ(std::set<std::string>({
|
||||
"C.Water",
|
||||
}), tags.removed);
|
||||
EXPECT_FALSE(tags.userlist_modified);
|
||||
}
|
||||
|
||||
TEST_P(DatabaseInterfaceTest, getPluginTagsShouldReturnOkAndNonEmptyModifiedArraysIfAPluginWithTagsIsQueriedAndMetadataWasAlsoLoadedFromAUserlist) {
|
||||
ASSERT_NO_THROW(GenerateMasterlist());
|
||||
ASSERT_NO_THROW(db_->LoadLists(masterlistPath.string(), masterlistPath.string()));
|
||||
|
||||
PluginTags tags;
|
||||
EXPECT_NO_THROW(tags = db_->GetPluginTags(blankEsm));
|
||||
|
||||
EXPECT_EQ(std::set<std::string>({
|
||||
"Actors.ACBS",
|
||||
"Actors.AIData",
|
||||
}), tags.added);
|
||||
EXPECT_EQ(std::set<std::string>({
|
||||
"C.Water",
|
||||
}), tags.removed);
|
||||
EXPECT_TRUE(tags.userlist_modified);
|
||||
}
|
||||
|
||||
TEST_P(DatabaseInterfaceTest, getPluginTagsShouldOutputTheCorrectBashTagsForPluginsWhenMakingConsecutiveCalls) {
|
||||
ASSERT_NO_THROW(GenerateMasterlist());
|
||||
ASSERT_NO_THROW(db_->LoadLists(masterlistPath.string(), ""));
|
||||
|
||||
PluginTags tags;
|
||||
EXPECT_NO_THROW(tags = db_->GetPluginTags(blankEsm));
|
||||
|
||||
EXPECT_EQ(std::set<std::string>({
|
||||
"Actors.ACBS",
|
||||
"Actors.AIData",
|
||||
}), tags.added);
|
||||
EXPECT_EQ(std::set<std::string>({
|
||||
"C.Water",
|
||||
}), tags.removed);
|
||||
EXPECT_FALSE(tags.userlist_modified);
|
||||
|
||||
EXPECT_NO_THROW(tags = db_->GetPluginTags(blankEsp));
|
||||
|
||||
EXPECT_TRUE(tags.added.empty());
|
||||
EXPECT_TRUE(tags.removed.empty());
|
||||
EXPECT_FALSE(tags.userlist_modified);
|
||||
}
|
||||
|
||||
TEST_P(DatabaseInterfaceTest, getPluginMessagesShouldReturnOkAndOutputANullArrayIfAPluginWithNoMessagesIsQueried) {
|
||||
std::vector<PluginMessage> messages;
|
||||
EXPECT_NO_THROW(messages = db_->GetPluginMessages(blankEsp));
|
||||
EXPECT_TRUE(messages.empty());
|
||||
}
|
||||
|
||||
TEST_P(DatabaseInterfaceTest, getPluginMessagesShouldReturnOkAndOutputANoteIfAPluginWithANoteMessageIsQueried) {
|
||||
ASSERT_NO_THROW(GenerateMasterlist());
|
||||
ASSERT_NO_THROW(db_->LoadLists(masterlistPath.string(), ""));
|
||||
|
||||
std::vector<PluginMessage> messages;
|
||||
EXPECT_NO_THROW(messages = db_->GetPluginMessages(blankEsm));
|
||||
ASSERT_EQ(1, messages.size());
|
||||
EXPECT_EQ(MessageType::say, messages[0].type);
|
||||
EXPECT_EQ(noteMessage, messages[0].text);
|
||||
}
|
||||
|
||||
TEST_P(DatabaseInterfaceTest, getPluginMessagesShouldReturnOkAndOutputAWarningIfAPluginWithAWarningMessageIsQueried) {
|
||||
ASSERT_NO_THROW(GenerateMasterlist());
|
||||
ASSERT_NO_THROW(db_->LoadLists(masterlistPath.string(), ""));
|
||||
|
||||
std::vector<PluginMessage> messages;
|
||||
EXPECT_NO_THROW(messages = db_->GetPluginMessages(blankDifferentEsm));
|
||||
ASSERT_EQ(1, messages.size());
|
||||
EXPECT_EQ(MessageType::warn, messages[0].type);
|
||||
EXPECT_EQ(warningMessage, messages[0].text);
|
||||
}
|
||||
|
||||
TEST_P(DatabaseInterfaceTest, getPluginMessagesShouldReturnOkAndOutputAnErrorIfAPluginWithAnErrorMessageIsQueried) {
|
||||
ASSERT_NO_THROW(GenerateMasterlist());
|
||||
ASSERT_NO_THROW(db_->LoadLists(masterlistPath.string(), ""));
|
||||
|
||||
std::vector<PluginMessage> messages;
|
||||
EXPECT_NO_THROW(messages = db_->GetPluginMessages(blankDifferentEsp));
|
||||
ASSERT_EQ(1, messages.size());
|
||||
EXPECT_EQ(MessageType::error, messages[0].type);
|
||||
EXPECT_EQ(errorMessage, messages[0].text);
|
||||
}
|
||||
|
||||
TEST_P(DatabaseInterfaceTest, getPluginMessagesShouldReturnOkAndOutputMultipleMessagesIfAPluginWithMultipleMessagesIsQueried) {
|
||||
ASSERT_NO_THROW(GenerateMasterlist());
|
||||
ASSERT_NO_THROW(db_->LoadLists(masterlistPath.string(), ""));
|
||||
|
||||
std::vector<PluginMessage> messages;
|
||||
EXPECT_NO_THROW(messages = db_->GetPluginMessages(blankDifferentMasterDependentEsp));
|
||||
ASSERT_EQ(3, messages.size());
|
||||
EXPECT_EQ(MessageType::say, messages[0].type);
|
||||
EXPECT_EQ(noteMessage, messages[0].text);
|
||||
EXPECT_EQ(MessageType::warn, messages[1].type);
|
||||
EXPECT_EQ(warningMessage, messages[1].text);
|
||||
EXPECT_EQ(MessageType::error, messages[2].type);
|
||||
EXPECT_EQ(errorMessage, messages[2].text);
|
||||
}
|
||||
|
||||
TEST_P(DatabaseInterfaceTest, getPluginCleanlinessShouldReturnOkAndOutputUnknownForAPluginWithNoDirtyInfo) {
|
||||
PluginCleanliness cleanliness;
|
||||
EXPECT_NO_THROW(cleanliness = db_->GetPluginCleanliness(blankEsp));
|
||||
EXPECT_EQ(PluginCleanliness::unknown, cleanliness);
|
||||
}
|
||||
|
||||
TEST_P(DatabaseInterfaceTest, getPluginCleanlinessShouldReturnOkAndOutputYesForAPluginWithDirtyInfo) {
|
||||
ASSERT_NO_THROW(GenerateMasterlist());
|
||||
ASSERT_NO_THROW(db_->LoadLists(masterlistPath.string(), ""));
|
||||
|
||||
PluginCleanliness cleanliness;
|
||||
EXPECT_NO_THROW(cleanliness = db_->GetPluginCleanliness(blankDifferentEsm));
|
||||
EXPECT_EQ(PluginCleanliness::dirty, cleanliness);
|
||||
}
|
||||
|
||||
TEST_P(DatabaseInterfaceTest, getPluginCleanlinessShouldReturnOkAndOutputNoForAPluginWithADoNotCleanMessage) {
|
||||
ASSERT_NO_THROW(GenerateMasterlist());
|
||||
ASSERT_NO_THROW(db_->LoadLists(masterlistPath.string(), ""));
|
||||
|
||||
PluginCleanliness cleanliness;
|
||||
EXPECT_NO_THROW(cleanliness = db_->GetPluginCleanliness(blankEsm));
|
||||
EXPECT_EQ(PluginCleanliness::do_not_clean, cleanliness);
|
||||
}
|
||||
|
||||
TEST_P(DatabaseInterfaceTest, writeMinimalListShouldReturnOkAndWriteToFileIfArgumentsGivenAreValid) {
|
||||
EXPECT_NO_THROW(db_->WriteMinimalList(minimalOutputPath_.string(), false));
|
||||
EXPECT_TRUE(boost::filesystem::exists(minimalOutputPath_));
|
||||
}
|
||||
|
||||
TEST_P(DatabaseInterfaceTest, writeMinimalListShouldReturnAFileWriteErrorIfTheFileAlreadyExistsAndTheOverwriteArgumentIsFalse) {
|
||||
ASSERT_NO_THROW(db_->WriteMinimalList(minimalOutputPath_.string(), false));
|
||||
ASSERT_TRUE(boost::filesystem::exists(minimalOutputPath_));
|
||||
|
||||
EXPECT_ANY_THROW(db_->WriteMinimalList(minimalOutputPath_.string(), false));
|
||||
}
|
||||
|
||||
TEST_P(DatabaseInterfaceTest, writeMinimalListShouldReturnOkAndWriteToFileIfTheArgumentsAreValidAndTheOverwriteArgumentIsTrue) {
|
||||
EXPECT_NO_THROW(db_->WriteMinimalList(minimalOutputPath_.string(), true));
|
||||
EXPECT_TRUE(boost::filesystem::exists(minimalOutputPath_));
|
||||
}
|
||||
|
||||
TEST_P(DatabaseInterfaceTest, writeMinimalListShouldReturnOkIfTheFileAlreadyExistsAndTheOverwriteArgumentIsTrue) {
|
||||
ASSERT_NO_THROW(db_->WriteMinimalList(minimalOutputPath_.string(), false));
|
||||
ASSERT_TRUE(boost::filesystem::exists(minimalOutputPath_));
|
||||
|
||||
EXPECT_NO_THROW(db_->WriteMinimalList(minimalOutputPath_.string(), true));
|
||||
}
|
||||
|
||||
TEST_P(DatabaseInterfaceTest, writeMinimalListShouldReturnAFileWriteErrorIfPathGivenExistsAndIsReadOnly) {
|
||||
ASSERT_NO_THROW(db_->WriteMinimalList(minimalOutputPath_.string(), false));
|
||||
ASSERT_TRUE(boost::filesystem::exists(minimalOutputPath_));
|
||||
|
||||
boost::filesystem::permissions(minimalOutputPath_,
|
||||
boost::filesystem::perms::remove_perms
|
||||
| boost::filesystem::perms::owner_write);
|
||||
|
||||
EXPECT_ANY_THROW(db_->WriteMinimalList(minimalOutputPath_.string(), true));
|
||||
}
|
||||
|
||||
TEST_P(DatabaseInterfaceTest, writeMinimalListShouldWriteOnlyBashTagsAndDirtyInfo) {
|
||||
ASSERT_NO_THROW(GenerateMasterlist());
|
||||
ASSERT_NO_THROW(db_->LoadLists(masterlistPath.string(), ""));
|
||||
|
||||
EXPECT_NO_THROW(db_->WriteMinimalList(minimalOutputPath_.string(), true));
|
||||
|
||||
boost::filesystem::ifstream in(minimalOutputPath_);
|
||||
std::stringstream content;
|
||||
content << in.rdbuf();
|
||||
|
||||
EXPECT_EQ(GetExpectedMinimalContent(), content.str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,44 @@
|
||||
/* 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_IS_COMPATIBLE_TEST
|
||||
#define LOOT_TESTS_API_IS_COMPATIBLE_TEST
|
||||
|
||||
#include "loot/api.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace loot {
|
||||
namespace test {
|
||||
TEST(IsCompatible, shouldReturnTrueWithEqualMajorAndMinorVersionsAndUnequalPatchVersion) {
|
||||
EXPECT_TRUE(IsCompatible(LootVersion::major, LootVersion::minor, LootVersion::patch + 1));
|
||||
}
|
||||
|
||||
TEST(IsCompatible, shouldReturnFalseWithEqualMajorVersionAndUnequalMinorAndPatchVersions) {
|
||||
EXPECT_FALSE(IsCompatible(LootVersion::major, LootVersion::minor + 1, LootVersion::patch + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,78 +0,0 @@
|
||||
/* 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_LOOT_APPLY_LOAD_ORDER_TEST
|
||||
#define LOOT_TESTS_API_LOOT_APPLY_LOAD_ORDER_TEST
|
||||
|
||||
#include "loot/api.h"
|
||||
|
||||
#include "tests/api/api_game_operations_test.h"
|
||||
|
||||
namespace loot {
|
||||
namespace test {
|
||||
class loot_apply_load_order_test : 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(,
|
||||
loot_apply_load_order_test,
|
||||
::testing::Values(
|
||||
loot_game_tes4,
|
||||
loot_game_tes5,
|
||||
loot_game_fo3,
|
||||
loot_game_fonv,
|
||||
loot_game_fo4));
|
||||
|
||||
TEST_P(loot_apply_load_order_test, shouldReturnAnInvalidArgsIfTheDbOrLoadOrderPointersAreNull) {
|
||||
const char * loadOrder[1] = {
|
||||
masterFile.c_str(),
|
||||
};
|
||||
size_t numPlugins = 0;
|
||||
|
||||
EXPECT_EQ(loot_error_invalid_args, loot_apply_load_order(NULL, loadOrder, numPlugins));
|
||||
EXPECT_EQ(loot_error_invalid_args, loot_apply_load_order(db_, NULL, numPlugins));
|
||||
}
|
||||
|
||||
TEST_P(loot_apply_load_order_test, shouldReturnOkIfLoadOrderGivenIsNotEmpty) {
|
||||
const char * loadOrder[11] = {
|
||||
masterFile.c_str(),
|
||||
blankEsm.c_str(),
|
||||
blankMasterDependentEsm.c_str(),
|
||||
blankDifferentEsm.c_str(),
|
||||
blankDifferentMasterDependentEsm.c_str(),
|
||||
blankMasterDependentEsp.c_str(),
|
||||
blankDifferentMasterDependentEsp.c_str(),
|
||||
blankEsp.c_str(),
|
||||
blankPluginDependentEsp.c_str(),
|
||||
blankDifferentEsp.c_str(),
|
||||
blankDifferentPluginDependentEsp.c_str(),
|
||||
};
|
||||
size_t numPlugins = 11;
|
||||
|
||||
EXPECT_EQ(loot_ok, loot_apply_load_order(db_, loadOrder, numPlugins));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,105 +0,0 @@
|
||||
/* 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_LOOT_CREATE_DB_TEST
|
||||
#define LOOT_TESTS_API_LOOT_CREATE_DB_TEST
|
||||
|
||||
#include "loot/api.h"
|
||||
|
||||
#include <climits>
|
||||
|
||||
#include "tests/common_game_test_fixture.h"
|
||||
|
||||
namespace loot {
|
||||
namespace test {
|
||||
class loot_create_db_test :
|
||||
public ::testing::TestWithParam<unsigned int>,
|
||||
public CommonGameTestFixture {
|
||||
protected:
|
||||
loot_create_db_test() :
|
||||
CommonGameTestFixture(GetParam()),
|
||||
db_(nullptr) {}
|
||||
|
||||
void SetUp() {
|
||||
setUp();
|
||||
}
|
||||
|
||||
void TearDown() {
|
||||
tearDown();
|
||||
|
||||
ASSERT_NO_THROW(loot_destroy_db(db_));
|
||||
}
|
||||
|
||||
loot_db * db_;
|
||||
};
|
||||
|
||||
// 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(,
|
||||
loot_create_db_test,
|
||||
::testing::Values(
|
||||
loot_game_tes4,
|
||||
loot_game_tes5,
|
||||
loot_game_fo3,
|
||||
loot_game_fonv,
|
||||
loot_game_fo4));
|
||||
|
||||
TEST_P(loot_create_db_test, shouldSucceedIfPassedValidParametersWithRelativePaths) {
|
||||
EXPECT_EQ(loot_ok, loot_create_db(&db_, GetParam(), dataPath.parent_path().string().c_str(), localPath.string().c_str()));
|
||||
EXPECT_NE(nullptr, db_);
|
||||
}
|
||||
|
||||
TEST_P(loot_create_db_test, shouldSucceedIfPassedValidParametersWithAbsolutePaths) {
|
||||
boost::filesystem::path game = boost::filesystem::current_path() / dataPath.parent_path();
|
||||
boost::filesystem::path local = boost::filesystem::current_path() / localPath;
|
||||
|
||||
EXPECT_EQ(loot_ok, loot_create_db(&db_, GetParam(), game.string().c_str(), local.string().c_str()));
|
||||
EXPECT_NE(nullptr, db_);
|
||||
}
|
||||
|
||||
TEST_P(loot_create_db_test, shouldReturnAnInvalidArgsErrorIfPassedANullPointer) {
|
||||
EXPECT_EQ(loot_error_invalid_args, loot_create_db(NULL, GetParam(), dataPath.parent_path().string().c_str(), localPath.string().c_str()));
|
||||
}
|
||||
|
||||
TEST_P(loot_create_db_test, shouldReturnAnInvalidArgsErrorIfPassedAnInvalidGameType) {
|
||||
EXPECT_EQ(loot_error_invalid_args, loot_create_db(&db_, UINT_MAX, dataPath.parent_path().string().c_str(), localPath.string().c_str()));
|
||||
}
|
||||
|
||||
TEST_P(loot_create_db_test, shouldReturnAnInvalidArgsErrorIfPassedAGamePathThatDoesNotExist) {
|
||||
EXPECT_EQ(loot_error_invalid_args, loot_create_db(&db_, GetParam(), missingPath.string().c_str(), localPath.string().c_str()));
|
||||
}
|
||||
|
||||
TEST_P(loot_create_db_test, shouldReturnAnInvalidArgsErrorIfPassedALocalPathThatDoesNotExist) {
|
||||
EXPECT_EQ(loot_error_invalid_args, loot_create_db(&db_, GetParam(), dataPath.parent_path().string().c_str(), missingPath.string().c_str()));
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
TEST_P(loot_create_db_test, shouldReturnOkIfPassedANullLocalPathPointer) {
|
||||
EXPECT_EQ(loot_ok, loot_create_db(&db_, GetParam(), dataPath.parent_path().string().c_str(), NULL));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,327 +0,0 @@
|
||||
/* 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_LOOT_DB_TEST
|
||||
#define LOOT_TESTS_API_LOOT_DB_TEST
|
||||
|
||||
#include "api/loot_db.h"
|
||||
|
||||
#include "tests/common_game_test_fixture.h"
|
||||
|
||||
namespace loot {
|
||||
namespace test {
|
||||
class loot_db_test :
|
||||
public ::testing::TestWithParam<unsigned int>,
|
||||
public CommonGameTestFixture {
|
||||
protected:
|
||||
loot_db_test() :
|
||||
CommonGameTestFixture(GetParam()),
|
||||
db_(nullptr) {}
|
||||
|
||||
virtual void SetUp() {
|
||||
setUp();
|
||||
|
||||
db_ = new loot_db(static_cast<unsigned int>(GetParam()), dataPath.parent_path().string().c_str(), localPath.string().c_str());
|
||||
}
|
||||
|
||||
inline virtual void TearDown() {
|
||||
tearDown();
|
||||
|
||||
delete db_;
|
||||
}
|
||||
|
||||
loot_db * db_;
|
||||
};
|
||||
|
||||
// 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(,
|
||||
loot_db_test,
|
||||
::testing::Values(
|
||||
static_cast<unsigned int>(GameType::tes4),
|
||||
static_cast<unsigned int>(GameType::tes5),
|
||||
static_cast<unsigned int>(GameType::fo3),
|
||||
static_cast<unsigned int>(GameType::fonv),
|
||||
static_cast<unsigned int>(GameType::fo4)));
|
||||
|
||||
TEST_P(loot_db_test, settingRevisionIdStringShouldCopyIt) {
|
||||
db_->setRevisionIdString("id");
|
||||
EXPECT_STREQ("id", db_->getRevisionIdString());
|
||||
}
|
||||
|
||||
TEST_P(loot_db_test, settingRevisionDateStringShouldCopyIt) {
|
||||
db_->setRevisionDateString("date");
|
||||
EXPECT_STREQ("date", db_->getRevisionDateString());
|
||||
}
|
||||
|
||||
TEST_P(loot_db_test, settingPluginNamesShouldCopyThem) {
|
||||
db_->setPluginNames(std::vector<PluginMetadata>({
|
||||
PluginMetadata("Blank.esm"),
|
||||
PluginMetadata("Blank.esp"),
|
||||
}));
|
||||
|
||||
EXPECT_EQ(2, db_->getPluginNames().size());
|
||||
EXPECT_STREQ("Blank.esm", db_->getPluginNames()[0]);
|
||||
EXPECT_STREQ("Blank.esp", db_->getPluginNames()[1]);
|
||||
}
|
||||
|
||||
TEST_P(loot_db_test, settingPluginNamesTwiceShouldOverwriteTheFirstDataSet) {
|
||||
db_->setPluginNames(std::vector<PluginMetadata>({
|
||||
PluginMetadata("Blank.esm"),
|
||||
PluginMetadata("Blank.esp"),
|
||||
}));
|
||||
db_->setPluginNames(std::vector<PluginMetadata>({
|
||||
PluginMetadata("Blank - Different.esm"),
|
||||
PluginMetadata("Blank - Different.esp"),
|
||||
}));
|
||||
|
||||
EXPECT_EQ(2, db_->getPluginNames().size());
|
||||
EXPECT_STREQ("Blank - Different.esm", db_->getPluginNames()[0]);
|
||||
EXPECT_STREQ("Blank - Different.esp", db_->getPluginNames()[1]);
|
||||
}
|
||||
|
||||
TEST_P(loot_db_test, addingNewBashTagsToTheMapShouldAppendThem) {
|
||||
db_->addBashTagsToMap({
|
||||
"C.Climate",
|
||||
"Relev",
|
||||
});
|
||||
|
||||
EXPECT_EQ(2, db_->getBashTagMap().size());
|
||||
EXPECT_STREQ("C.Climate", db_->getBashTagMap()[0]);
|
||||
EXPECT_STREQ("Relev", db_->getBashTagMap()[1]);
|
||||
}
|
||||
|
||||
TEST_P(loot_db_test, addingAnExistingBashTagToTheMapShouldNotDuplicateIt) {
|
||||
db_->addBashTagsToMap({
|
||||
"C.Climate",
|
||||
"Relev",
|
||||
"C.Climate",
|
||||
});
|
||||
|
||||
EXPECT_EQ(2, db_->getBashTagMap().size());
|
||||
EXPECT_STREQ("C.Climate", db_->getBashTagMap()[0]);
|
||||
EXPECT_STREQ("Relev", db_->getBashTagMap()[1]);
|
||||
}
|
||||
|
||||
TEST_P(loot_db_test, gettingABashTagsUidForATagThatIsNotInTheMapShouldThrow) {
|
||||
EXPECT_ANY_THROW(db_->getBashTagUid("Relev"));
|
||||
}
|
||||
|
||||
TEST_P(loot_db_test, gettingABashTagsUidShouldReturnItsTagMapIndex) {
|
||||
db_->addBashTagsToMap({
|
||||
"C.Climate",
|
||||
"Relev",
|
||||
});
|
||||
|
||||
EXPECT_EQ(1, db_->getBashTagUid("Relev"));
|
||||
}
|
||||
|
||||
TEST_P(loot_db_test, clearingAnEmptyBashTagMapShouldDoNothing) {
|
||||
EXPECT_NO_THROW(db_->clearBashTagMap());
|
||||
}
|
||||
|
||||
TEST_P(loot_db_test, clearingABashTagMapShouldEmptyIt) {
|
||||
db_->addBashTagsToMap({
|
||||
"C.Climate",
|
||||
"Relev",
|
||||
});
|
||||
|
||||
db_->clearBashTagMap();
|
||||
EXPECT_TRUE(db_->getBashTagMap().empty());
|
||||
}
|
||||
|
||||
TEST_P(loot_db_test, clearingABashTagMapShouldAffectExistingReferences) {
|
||||
db_->addBashTagsToMap({
|
||||
"C.Climate",
|
||||
"Relev",
|
||||
});
|
||||
|
||||
auto& bashTagMap = db_->getBashTagMap();
|
||||
db_->clearBashTagMap();
|
||||
EXPECT_TRUE(bashTagMap.empty());
|
||||
}
|
||||
|
||||
TEST_P(loot_db_test, settingAddedTagsWithNoTagMapShouldThrow) {
|
||||
EXPECT_ANY_THROW(db_->setAddedTags({
|
||||
"Relev",
|
||||
}));
|
||||
}
|
||||
|
||||
TEST_P(loot_db_test, gettingSetAddedTagsShouldReturnTheirUids) {
|
||||
db_->addBashTagsToMap({
|
||||
"C.Climate",
|
||||
"Relev",
|
||||
});
|
||||
|
||||
db_->setAddedTags({
|
||||
"Relev",
|
||||
});
|
||||
|
||||
EXPECT_EQ(std::vector<unsigned int>({
|
||||
1,
|
||||
}), db_->getAddedTagIds());
|
||||
}
|
||||
|
||||
TEST_P(loot_db_test, settingAddedTagsShouldReplaceExistingTags) {
|
||||
db_->addBashTagsToMap({
|
||||
"C.Climate",
|
||||
"Relev",
|
||||
});
|
||||
|
||||
db_->setAddedTags({
|
||||
"Relev",
|
||||
});
|
||||
|
||||
db_->setAddedTags({
|
||||
"C.Climate",
|
||||
});
|
||||
|
||||
EXPECT_EQ(std::vector<unsigned int>({
|
||||
0,
|
||||
}), db_->getAddedTagIds());
|
||||
}
|
||||
|
||||
TEST_P(loot_db_test, settingRemovedTagsWithNoTagMapShouldThrow) {
|
||||
EXPECT_ANY_THROW(db_->setRemovedTags({
|
||||
"Relev",
|
||||
}));
|
||||
}
|
||||
|
||||
TEST_P(loot_db_test, gettingSetRemovedTagsShouldReturnTheirUids) {
|
||||
db_->addBashTagsToMap({
|
||||
"C.Climate",
|
||||
"Relev",
|
||||
});
|
||||
|
||||
db_->setRemovedTags({
|
||||
"Relev",
|
||||
});
|
||||
|
||||
EXPECT_EQ(std::vector<unsigned int>({
|
||||
1,
|
||||
}), db_->getRemovedTagIds());
|
||||
}
|
||||
|
||||
TEST_P(loot_db_test, settingRemovedTagsShouldReplaceExistingTags) {
|
||||
db_->addBashTagsToMap({
|
||||
"C.Climate",
|
||||
"Relev",
|
||||
});
|
||||
|
||||
db_->setRemovedTags({
|
||||
"Relev",
|
||||
});
|
||||
|
||||
db_->setRemovedTags({
|
||||
"C.Climate",
|
||||
});
|
||||
|
||||
EXPECT_EQ(std::vector<unsigned int>({
|
||||
0,
|
||||
}), db_->getRemovedTagIds());
|
||||
}
|
||||
|
||||
TEST_P(loot_db_test, settingPluginMessagesShouldCopyThem) {
|
||||
db_->setPluginMessages(std::list<Message>({
|
||||
Message(MessageType::warn, "Test 1"),
|
||||
Message(MessageType::error, "Test 2"),
|
||||
}));
|
||||
|
||||
EXPECT_EQ(2, db_->getPluginMessages().size());
|
||||
EXPECT_EQ(static_cast<unsigned int>(MessageType::warn), db_->getPluginMessages()[0].type);
|
||||
EXPECT_STREQ("Test 1", db_->getPluginMessages()[0].message);
|
||||
EXPECT_EQ(static_cast<unsigned int>(MessageType::error), db_->getPluginMessages()[1].type);
|
||||
EXPECT_STREQ("Test 2", db_->getPluginMessages()[1].message);
|
||||
}
|
||||
|
||||
TEST_P(loot_db_test, settingPluginMessagesTwiceShouldOverwriteTheFirstDataSet) {
|
||||
db_->setPluginMessages(std::list<Message>({
|
||||
Message(MessageType::warn, "Test 1"),
|
||||
Message(MessageType::error, "Test 2"),
|
||||
}));
|
||||
db_->setPluginMessages(std::list<Message>({
|
||||
Message(MessageType::error, "Test 3"),
|
||||
Message(MessageType::warn, "Test 4"),
|
||||
Message(MessageType::say, "Test 5"),
|
||||
}));
|
||||
|
||||
EXPECT_EQ(3, db_->getPluginMessages().size());
|
||||
EXPECT_EQ(static_cast<unsigned int>(MessageType::error), db_->getPluginMessages()[0].type);
|
||||
EXPECT_STREQ("Test 3", db_->getPluginMessages()[0].message);
|
||||
EXPECT_EQ(static_cast<unsigned int>(MessageType::warn), db_->getPluginMessages()[1].type);
|
||||
EXPECT_STREQ("Test 4", db_->getPluginMessages()[1].message);
|
||||
EXPECT_EQ(static_cast<unsigned int>(MessageType::say), db_->getPluginMessages()[2].type);
|
||||
EXPECT_STREQ("Test 5", db_->getPluginMessages()[2].message);
|
||||
}
|
||||
|
||||
TEST_P(loot_db_test, clearingArraysShouldEmptyPluginNamesTagIdsAndMessages) {
|
||||
db_->setPluginMessages(std::list<Message>({
|
||||
Message(MessageType::warn, "Test 1"),
|
||||
Message(MessageType::error, "Test 2"),
|
||||
}));
|
||||
db_->setPluginNames(std::vector<PluginMetadata>({
|
||||
PluginMetadata("Blank.esm"),
|
||||
PluginMetadata("Blank.esp"),
|
||||
}));
|
||||
|
||||
db_->addBashTagsToMap({
|
||||
"C.Climate",
|
||||
"Relev",
|
||||
});
|
||||
db_->setAddedTags({
|
||||
"Relev",
|
||||
});
|
||||
db_->setRemovedTags({
|
||||
"Relev",
|
||||
});
|
||||
|
||||
ASSERT_FALSE(db_->getPluginMessages().empty());
|
||||
ASSERT_FALSE(db_->getPluginNames().empty());
|
||||
ASSERT_FALSE(db_->getAddedTagIds().empty());
|
||||
ASSERT_FALSE(db_->getRemovedTagIds().empty());
|
||||
ASSERT_FALSE(db_->getBashTagMap().empty());
|
||||
|
||||
EXPECT_NO_THROW(db_->clearArrays());
|
||||
|
||||
EXPECT_TRUE(db_->getPluginMessages().empty());
|
||||
EXPECT_TRUE(db_->getPluginNames().empty());
|
||||
EXPECT_TRUE(db_->getAddedTagIds().empty());
|
||||
EXPECT_TRUE(db_->getRemovedTagIds().empty());
|
||||
}
|
||||
|
||||
TEST_P(loot_db_test, clearingArraysShouldNotEmptyBashTagMap) {
|
||||
db_->addBashTagsToMap({
|
||||
"C.Climate",
|
||||
"Relev",
|
||||
});
|
||||
ASSERT_FALSE(db_->getBashTagMap().empty());
|
||||
|
||||
EXPECT_NO_THROW(db_->clearArrays());
|
||||
|
||||
EXPECT_FALSE(db_->getBashTagMap().empty());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,88 +0,0 @@
|
||||
/* 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_LOOT_EVAL_LISTS_TEST
|
||||
#define LOOT_TESTS_API_LOOT_EVAL_LISTS_TEST
|
||||
|
||||
#include "loot/api.h"
|
||||
|
||||
#include "tests/api/api_game_operations_test.h"
|
||||
|
||||
namespace loot {
|
||||
namespace test {
|
||||
class loot_eval_lists_test : 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(,
|
||||
loot_eval_lists_test,
|
||||
::testing::Values(
|
||||
loot_game_tes4,
|
||||
loot_game_tes5,
|
||||
loot_game_fo3,
|
||||
loot_game_fonv,
|
||||
loot_game_fo4));
|
||||
|
||||
TEST_P(loot_eval_lists_test, shouldReturnAnInvalidArgsErrorIfPassedANullPointer) {
|
||||
EXPECT_EQ(loot_error_invalid_args, loot_eval_lists(NULL, loot_lang_english));
|
||||
}
|
||||
|
||||
TEST_P(loot_eval_lists_test, shouldReturnAnInvalidArgsErrorIfPassedAnInvalidLanguageCode) {
|
||||
EXPECT_EQ(loot_error_invalid_args, loot_eval_lists(db_, UINT_MAX));
|
||||
}
|
||||
|
||||
TEST_P(loot_eval_lists_test, shouldReturnOkForAllLanguagesWithNoListsLoaded) {
|
||||
EXPECT_EQ(loot_ok, loot_eval_lists(db_, loot_lang_english));
|
||||
EXPECT_EQ(loot_ok, loot_eval_lists(db_, loot_lang_english));
|
||||
EXPECT_EQ(loot_ok, loot_eval_lists(db_, loot_lang_spanish));
|
||||
EXPECT_EQ(loot_ok, loot_eval_lists(db_, loot_lang_russian));
|
||||
EXPECT_EQ(loot_ok, loot_eval_lists(db_, loot_lang_french));
|
||||
EXPECT_EQ(loot_ok, loot_eval_lists(db_, loot_lang_chinese));
|
||||
EXPECT_EQ(loot_ok, loot_eval_lists(db_, loot_lang_polish));
|
||||
EXPECT_EQ(loot_ok, loot_eval_lists(db_, loot_lang_brazilian_portuguese));
|
||||
EXPECT_EQ(loot_ok, loot_eval_lists(db_, loot_lang_finnish));
|
||||
EXPECT_EQ(loot_ok, loot_eval_lists(db_, loot_lang_german));
|
||||
EXPECT_EQ(loot_ok, loot_eval_lists(db_, loot_lang_danish));
|
||||
}
|
||||
|
||||
TEST_P(loot_eval_lists_test, shouldReturnOKForAllLanguagesWithAMasterlistLoaded) {
|
||||
ASSERT_NO_THROW(GenerateMasterlist());
|
||||
ASSERT_EQ(loot_ok, loot_load_lists(db_, masterlistPath.string().c_str(), NULL));
|
||||
|
||||
EXPECT_EQ(loot_ok, loot_eval_lists(db_, loot_lang_english));
|
||||
EXPECT_EQ(loot_ok, loot_eval_lists(db_, loot_lang_english));
|
||||
EXPECT_EQ(loot_ok, loot_eval_lists(db_, loot_lang_spanish));
|
||||
EXPECT_EQ(loot_ok, loot_eval_lists(db_, loot_lang_russian));
|
||||
EXPECT_EQ(loot_ok, loot_eval_lists(db_, loot_lang_french));
|
||||
EXPECT_EQ(loot_ok, loot_eval_lists(db_, loot_lang_chinese));
|
||||
EXPECT_EQ(loot_ok, loot_eval_lists(db_, loot_lang_polish));
|
||||
EXPECT_EQ(loot_ok, loot_eval_lists(db_, loot_lang_brazilian_portuguese));
|
||||
EXPECT_EQ(loot_ok, loot_eval_lists(db_, loot_lang_finnish));
|
||||
EXPECT_EQ(loot_ok, loot_eval_lists(db_, loot_lang_german));
|
||||
EXPECT_EQ(loot_ok, loot_eval_lists(db_, loot_lang_danish));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user