mirror of
https://github.com/loot/libloot.git
synced 2026-07-27 14:16:01 -07:00
Don't pass parent path and filename separately to Plugin functions
Given that we're passing a full path to the plugin, just pass it as a single path argument.
This commit is contained in:
@@ -48,6 +48,7 @@
|
||||
#include "windows.h"
|
||||
#endif
|
||||
|
||||
using std::filesystem::u8path;
|
||||
using std::list;
|
||||
using std::string;
|
||||
using std::thread;
|
||||
@@ -87,11 +88,12 @@ std::shared_ptr<LoadOrderHandler> Game::GetLoadOrderHandler() {
|
||||
std::shared_ptr<DatabaseInterface> Game::GetDatabase() { return database_; }
|
||||
|
||||
bool Game::IsValidPlugin(const std::string& plugin) const {
|
||||
return Plugin::IsValid(plugin, Type(), DataPath());
|
||||
return Plugin::IsValid(Type(), DataPath() / u8path(plugin));
|
||||
}
|
||||
|
||||
void Game::LoadPlugins(const std::vector<std::string>& plugins,
|
||||
bool loadHeadersOnly) {
|
||||
|
||||
auto logger = getLogger();
|
||||
uintmax_t meanFileSize = 0;
|
||||
std::multimap<uintmax_t, string> sizeMap;
|
||||
@@ -101,7 +103,7 @@ void Game::LoadPlugins(const std::vector<std::string>& plugins,
|
||||
if (!IsValidPlugin(plugin))
|
||||
throw std::invalid_argument("\"" + plugin + "\" is not a valid plugin");
|
||||
|
||||
uintmax_t fileSize = Plugin::GetFileSize(plugin, DataPath());
|
||||
uintmax_t fileSize = Plugin::GetFileSize(DataPath() / u8path(plugin));
|
||||
meanFileSize += fileSize;
|
||||
|
||||
// Trim .ghost extension if present.
|
||||
@@ -170,7 +172,7 @@ void Game::LoadPlugins(const std::vector<std::string>& plugins,
|
||||
boost::iequals(pluginName, masterFile_) || loadHeadersOnly;
|
||||
try {
|
||||
cache_->AddPlugin(Plugin(
|
||||
Type(), DataPath(), cache_, loadOrderHandler_, pluginName, loadHeader));
|
||||
Type(), cache_, loadOrderHandler_, DataPath() / u8path(pluginName), loadHeader));
|
||||
} catch (std::exception& e) {
|
||||
if (logger) {
|
||||
logger->error(
|
||||
|
||||
@@ -421,13 +421,14 @@ Version ConditionEvaluator::getVersion(const std::string& filePath) const {
|
||||
// The file wasn't in the plugin cache, load it as a plugin
|
||||
// if it appears to be valid, otherwise treat it as a non
|
||||
// plugin file.
|
||||
if (Plugin::IsValid(filePath, gameType_, dataPath_))
|
||||
auto pluginPath = dataPath_ / u8path(filePath);
|
||||
if (Plugin::IsValid(gameType_, pluginPath))
|
||||
return Version(
|
||||
Plugin(gameType_, dataPath_, gameCache_, loadOrderHandler_, filePath, true)
|
||||
Plugin(gameType_, gameCache_, loadOrderHandler_, pluginPath, true)
|
||||
.GetVersion()
|
||||
.value_or(""));
|
||||
|
||||
return Version(dataPath_ / u8path(filePath));
|
||||
return Version(pluginPath);
|
||||
}
|
||||
}
|
||||
bool ConditionEvaluator::shouldParseOnly() const {
|
||||
|
||||
+38
-38
@@ -41,12 +41,11 @@ using std::string;
|
||||
|
||||
namespace loot {
|
||||
Plugin::Plugin(const GameType gameType,
|
||||
const std::filesystem::path& dataPath,
|
||||
std::shared_ptr<GameCache> gameCache,
|
||||
std::shared_ptr<LoadOrderHandler> loadOrderHandler,
|
||||
const std::string& name,
|
||||
std::filesystem::path pluginPath,
|
||||
const bool headerOnly) :
|
||||
name_(name),
|
||||
name_(pluginPath.filename().u8string()),
|
||||
esPlugin(nullptr),
|
||||
isEmpty_(true),
|
||||
isActive_(false),
|
||||
@@ -55,18 +54,16 @@ Plugin::Plugin(const GameType gameType,
|
||||
auto logger = getLogger();
|
||||
|
||||
try {
|
||||
std::filesystem::path filepath = dataPath / std::filesystem::u8path(name_);
|
||||
|
||||
// In case the plugin is ghosted.
|
||||
if (!std::filesystem::exists(filepath)) {
|
||||
filepath += ".ghost";
|
||||
if (!std::filesystem::exists(pluginPath)) {
|
||||
pluginPath += ".ghost";
|
||||
}
|
||||
|
||||
Load(filepath, gameType, headerOnly);
|
||||
Load(pluginPath, gameType, headerOnly);
|
||||
|
||||
auto ret = esp_plugin_is_empty(esPlugin.get(), &isEmpty_);
|
||||
if (ret != ESP_OK) {
|
||||
throw FileAccessError(name +
|
||||
throw FileAccessError(name_ +
|
||||
" : esplugin error code: " + std::to_string(ret));
|
||||
}
|
||||
|
||||
@@ -74,7 +71,7 @@ Plugin::Plugin(const GameType gameType,
|
||||
if (logger) {
|
||||
logger->trace("{}: Caching CRC value.", name_);
|
||||
}
|
||||
crc_ = GetCrc32(filepath);
|
||||
crc_ = GetCrc32(pluginPath);
|
||||
|
||||
if (logger) {
|
||||
logger->trace("{}: Counting override FormIDs.", name_);
|
||||
@@ -82,7 +79,7 @@ Plugin::Plugin(const GameType gameType,
|
||||
ret = esp_plugin_count_override_records(esPlugin.get(),
|
||||
&numOverrideRecords_);
|
||||
if (ret != ESP_OK) {
|
||||
throw FileAccessError(name +
|
||||
throw FileAccessError(name_ +
|
||||
" : esplugin error code: " + std::to_string(ret));
|
||||
}
|
||||
}
|
||||
@@ -118,13 +115,13 @@ Plugin::Plugin(const GameType gameType,
|
||||
// Get whether the plugin is active or not.
|
||||
isActive_ = loadOrderHandler->IsPluginActive(name_);
|
||||
|
||||
loadsArchive_ = LoadsArchive(name_, gameType, gameCache, dataPath);
|
||||
loadsArchive_ = LoadsArchive(gameType, gameCache, pluginPath);
|
||||
} catch (std::exception& e) {
|
||||
if (logger) {
|
||||
logger->error(
|
||||
"Cannot read plugin file \"{}\". Details: {}", name_, e.what());
|
||||
}
|
||||
throw FileAccessError("Cannot read \"" + name + "\". Details: " + e.what());
|
||||
throw FileAccessError("Cannot read \"" + name_ + "\". Details: " + e.what());
|
||||
}
|
||||
|
||||
if (logger) {
|
||||
@@ -219,47 +216,50 @@ bool Plugin::DoFormIDsOverlap(const PluginInterface& plugin) const {
|
||||
|
||||
size_t Plugin::NumOverrideFormIDs() const { return numOverrideRecords_; }
|
||||
|
||||
bool Plugin::IsValid(const std::string& filename,
|
||||
const GameType gameType,
|
||||
const std::filesystem::path& dataPath) {
|
||||
bool Plugin::IsValid(const GameType gameType,
|
||||
const std::filesystem::path& pluginPath) {
|
||||
auto logger = getLogger();
|
||||
if (logger) {
|
||||
logger->trace("Checking to see if \"{}\" is a valid plugin.", filename);
|
||||
logger->trace("Checking to see if \"{}\" is a valid plugin.", pluginPath.filename().u8string());
|
||||
}
|
||||
|
||||
// If the filename passed ends in '.ghost', that should be trimmed.
|
||||
std::string name;
|
||||
if (boost::iends_with(filename, ".ghost"))
|
||||
name = filename.substr(0, filename.length() - 6);
|
||||
else
|
||||
name = filename;
|
||||
std::string trimmedFilename = pluginPath.filename().u8string();
|
||||
if (boost::iends_with(trimmedFilename, ".ghost")) {
|
||||
trimmedFilename = trimmedFilename.substr(0, trimmedFilename.length() - 6);
|
||||
}
|
||||
|
||||
// Check that the file has a valid extension.
|
||||
if (!hasPluginFileExtension(name, gameType))
|
||||
if (!hasPluginFileExtension(trimmedFilename, gameType))
|
||||
return false;
|
||||
|
||||
bool isValid;
|
||||
auto path = dataPath / std::filesystem::u8path(filename);
|
||||
int ret = esp_plugin_is_valid(
|
||||
GetEspluginGameId(gameType), path.u8string().c_str(), true, &isValid);
|
||||
GetEspluginGameId(gameType), pluginPath.u8string().c_str(), true, &isValid);
|
||||
|
||||
if (ret != ESP_OK || !isValid) {
|
||||
// Try adding .ghost extension.
|
||||
auto ghostedPath = pluginPath;
|
||||
ghostedPath += ".ghost";
|
||||
|
||||
ret = esp_plugin_is_valid(
|
||||
GetEspluginGameId(gameType), ghostedPath.u8string().c_str(), true, &isValid);
|
||||
}
|
||||
|
||||
if (ret != ESP_OK || !isValid) {
|
||||
if (logger) {
|
||||
logger->warn("The file \"{}\" is not a valid plugin.", filename);
|
||||
logger->warn("The file \"{}\" is not a valid plugin.", pluginPath.filename().u8string());
|
||||
}
|
||||
}
|
||||
|
||||
return (ret == ESP_OK && isValid) ||
|
||||
Plugin::IsValid(filename + ".ghost", gameType, dataPath);
|
||||
return ret == ESP_OK && isValid;
|
||||
}
|
||||
|
||||
uintmax_t Plugin::GetFileSize(const std::string& filename,
|
||||
const std::filesystem::path& dataPath) {
|
||||
std::filesystem::path realPath = dataPath / std::filesystem::u8path(filename);
|
||||
if (!std::filesystem::exists(realPath))
|
||||
realPath += ".ghost";
|
||||
uintmax_t Plugin::GetFileSize(std::filesystem::path pluginPath) {
|
||||
if (!std::filesystem::exists(pluginPath))
|
||||
pluginPath += ".ghost";
|
||||
|
||||
return std::filesystem::file_size(realPath);
|
||||
return std::filesystem::file_size(pluginPath);
|
||||
}
|
||||
|
||||
bool Plugin::operator<(const Plugin& rhs) const {
|
||||
@@ -314,17 +314,17 @@ std::string GetArchiveFileExtension(const GameType gameType) {
|
||||
return ".bsa";
|
||||
}
|
||||
|
||||
bool Plugin::LoadsArchive(const std::string& pluginName,
|
||||
const GameType gameType,
|
||||
bool Plugin::LoadsArchive(const GameType gameType,
|
||||
const std::shared_ptr<GameCache> gameCache,
|
||||
const std::filesystem::path& dataPath) {
|
||||
const std::filesystem::path& pluginPath) {
|
||||
// Get whether the plugin loads an archive (BSA/BA2) or not.
|
||||
const string archiveExtension = GetArchiveFileExtension(gameType);
|
||||
auto pluginName = pluginPath.filename().u8string();
|
||||
|
||||
if (gameType == GameType::tes5) {
|
||||
// Skyrim plugins only load BSAs that exactly match their basename.
|
||||
auto filename = pluginName.substr(0, pluginName.length() - 4) + archiveExtension;
|
||||
return std::filesystem::exists(dataPath / std::filesystem::u8path(filename));
|
||||
return std::filesystem::exists(pluginPath.parent_path() / std::filesystem::u8path(filename));
|
||||
} else if (gameType != GameType::tes4 ||
|
||||
boost::iends_with(pluginName, ".esp")) {
|
||||
// Oblivion .esp files and FO3, FNV, FO4 plugins can load archives which
|
||||
|
||||
+6
-10
@@ -44,10 +44,9 @@ class GameCache;
|
||||
class Plugin : public PluginInterface {
|
||||
public:
|
||||
Plugin(const GameType gameType,
|
||||
const std::filesystem::path& dataPath,
|
||||
std::shared_ptr<GameCache> gameCache,
|
||||
std::shared_ptr<LoadOrderHandler> loadOrderHandler,
|
||||
const std::string& name,
|
||||
std::filesystem::path pluginPath,
|
||||
const bool headerOnly);
|
||||
|
||||
std::string GetName() const;
|
||||
@@ -69,11 +68,9 @@ public:
|
||||
size_t NumOverrideFormIDs() const;
|
||||
|
||||
// Validity checks.
|
||||
static bool IsValid(const std::string& filename,
|
||||
const GameType gameType,
|
||||
const std::filesystem::path& dataPath);
|
||||
static uintmax_t GetFileSize(const std::string& filename,
|
||||
const std::filesystem::path& dataPath);
|
||||
static bool IsValid(const GameType gameType,
|
||||
const std::filesystem::path& pluginPath);
|
||||
static uintmax_t GetFileSize(std::filesystem::path pluginPath);
|
||||
|
||||
bool operator<(const Plugin& rhs) const;
|
||||
|
||||
@@ -83,10 +80,9 @@ private:
|
||||
bool headerOnly);
|
||||
std::string GetDescription() const;
|
||||
|
||||
static bool LoadsArchive(const std::string& pluginName,
|
||||
const GameType gameType,
|
||||
static bool LoadsArchive(const GameType gameType,
|
||||
const std::shared_ptr<GameCache> gameCache,
|
||||
const std::filesystem::path& dataPath);
|
||||
const std::filesystem::path& pluginPath);
|
||||
static unsigned int GetEspluginGameId(GameType gameType);
|
||||
|
||||
bool isEmpty_; // Does the plugin contain any records other than the TES4
|
||||
|
||||
@@ -35,6 +35,7 @@ class GameInterfaceTest : public ApiGameOperationsTest {
|
||||
protected:
|
||||
GameInterfaceTest() :
|
||||
emptyFile("EmptyFile.esm"),
|
||||
nonAsciiEsm(u8"non\u00C1scii.esm"),
|
||||
pluginsToLoad({
|
||||
masterFile,
|
||||
blankEsm,
|
||||
@@ -47,9 +48,14 @@ protected:
|
||||
blankDifferentMasterDependentEsp,
|
||||
blankPluginDependentEsp,
|
||||
blankDifferentPluginDependentEsp,
|
||||
}) {}
|
||||
}) {
|
||||
// Make sure the plugin with a non-ASCII filename exists.
|
||||
std::filesystem::copy_file(dataPath / blankEsm,
|
||||
dataPath / std::filesystem::u8path(nonAsciiEsm));
|
||||
}
|
||||
|
||||
const std::string emptyFile;
|
||||
const std::string nonAsciiEsm;
|
||||
const std::vector<std::string> pluginsToLoad;
|
||||
};
|
||||
|
||||
@@ -68,6 +74,10 @@ TEST_P(GameInterfaceTest, isValidPluginShouldReturnTrueForAValidPlugin) {
|
||||
EXPECT_TRUE(handle_->IsValidPlugin(blankEsm));
|
||||
}
|
||||
|
||||
TEST_P(GameInterfaceTest, isValidPluginShouldReturnTrueForAValidNonAsciiPlugin) {
|
||||
EXPECT_TRUE(handle_->IsValidPlugin(nonAsciiEsm));
|
||||
}
|
||||
|
||||
TEST_P(GameInterfaceTest, isValidPluginShouldReturnFalseForANonPluginFile) {
|
||||
EXPECT_FALSE(handle_->IsValidPlugin(nonPluginFile));
|
||||
}
|
||||
@@ -110,6 +120,18 @@ TEST_P(GameInterfaceTest,
|
||||
EXPECT_EQ(blankEsmCrc, plugin->GetCRC().value());
|
||||
}
|
||||
|
||||
TEST_P(GameInterfaceTest, loadPluginsWithANonAsciiPluginShouldLoadIt) {
|
||||
handle_->LoadPlugins({ nonAsciiEsm }, false);
|
||||
EXPECT_EQ(1, handle_->GetLoadedPlugins().size());
|
||||
|
||||
// Check that one plugin's header has been read.
|
||||
auto plugin = handle_->GetPlugin(nonAsciiEsm).value();
|
||||
EXPECT_EQ("5.0", plugin->GetVersion().value());
|
||||
|
||||
// Check that not only the header has been read.
|
||||
EXPECT_EQ(blankEsmCrc, plugin->GetCRC().value());
|
||||
}
|
||||
|
||||
TEST_P(GameInterfaceTest, getPluginThatIsNotCachedShouldReturnAnEmptyOptional) {
|
||||
EXPECT_FALSE(handle_->GetPlugin(blankEsm));
|
||||
}
|
||||
@@ -179,11 +201,17 @@ TEST_P(GameInterfaceTest,
|
||||
}
|
||||
|
||||
TEST_P(GameInterfaceTest, getLoadOrderShouldReturnTheCurrentLoadOrder) {
|
||||
// Remove the non-ASCII duplicate plugin.
|
||||
std::filesystem::remove(dataPath / std::filesystem::u8path(nonAsciiEsm));
|
||||
|
||||
handle_->LoadCurrentLoadOrderState();
|
||||
ASSERT_EQ(getLoadOrder(), handle_->GetLoadOrder());
|
||||
}
|
||||
|
||||
TEST_P(GameInterfaceTest, setLoadOrderShouldSetTheLoadOrder) {
|
||||
// Remove the non-ASCII duplicate plugin.
|
||||
std::filesystem::remove(dataPath / std::filesystem::u8path(nonAsciiEsm));
|
||||
|
||||
handle_->LoadCurrentLoadOrderState();
|
||||
std::vector<std::string> loadOrder({
|
||||
masterFile,
|
||||
|
||||
@@ -81,10 +81,9 @@ TEST_P(GameCacheTest, gettingAnUncachedCrcShouldReturnZero) {
|
||||
|
||||
TEST_P(GameCacheTest, addingAPluginThatDoesNotExistShouldSucceed) {
|
||||
cache_.AddPlugin(Plugin(game_.Type(),
|
||||
game_.DataPath(),
|
||||
std::make_shared<GameCache>(GameCache()),
|
||||
game_.GetLoadOrderHandler(),
|
||||
blankEsm,
|
||||
game_.DataPath() / blankEsm,
|
||||
true));
|
||||
EXPECT_EQ(blankEsm, cache_.GetPlugin(blankEsm).value()->GetName());
|
||||
}
|
||||
@@ -92,18 +91,16 @@ TEST_P(GameCacheTest, addingAPluginThatDoesNotExistShouldSucceed) {
|
||||
TEST_P(GameCacheTest,
|
||||
addingAPluginThatIsAlreadyCachedShouldOverwriteExistingEntry) {
|
||||
cache_.AddPlugin(Plugin(game_.Type(),
|
||||
game_.DataPath(),
|
||||
std::make_shared<GameCache>(GameCache()),
|
||||
game_.GetLoadOrderHandler(),
|
||||
blankEsm,
|
||||
game_.DataPath() / blankEsm,
|
||||
true));
|
||||
EXPECT_FALSE(cache_.GetPlugin(blankEsm).value()->GetCRC());
|
||||
|
||||
cache_.AddPlugin(Plugin(game_.Type(),
|
||||
game_.DataPath(),
|
||||
std::make_shared<GameCache>(GameCache()),
|
||||
game_.GetLoadOrderHandler(),
|
||||
blankEsm,
|
||||
game_.DataPath() / blankEsm,
|
||||
false));
|
||||
EXPECT_EQ(blankEsmCrc, cache_.GetPlugin(blankEsm).value()->GetCRC().value());
|
||||
}
|
||||
@@ -114,10 +111,9 @@ TEST_P(GameCacheTest, gettingAPluginThatIsNotCachedShouldReturnAnEmptyOptional)
|
||||
|
||||
TEST_P(GameCacheTest, gettingAPluginShouldBeCaseInsensitive) {
|
||||
cache_.AddPlugin(Plugin(game_.Type(),
|
||||
game_.DataPath(),
|
||||
std::make_shared<GameCache>(GameCache()),
|
||||
game_.GetLoadOrderHandler(),
|
||||
blankEsm,
|
||||
game_.DataPath() / blankEsm,
|
||||
true));
|
||||
EXPECT_EQ(blankEsm, cache_.GetPlugin(blankEsm).value()->GetName());
|
||||
}
|
||||
@@ -130,16 +126,14 @@ TEST_P(GameCacheTest,
|
||||
TEST_P(GameCacheTest,
|
||||
gettingPluginsShouldReturnASetOfCachedPluginsIfPluginsHaveBeenCached) {
|
||||
cache_.AddPlugin(Plugin(game_.Type(),
|
||||
game_.DataPath(),
|
||||
std::make_shared<GameCache>(GameCache()),
|
||||
game_.GetLoadOrderHandler(),
|
||||
blankEsm,
|
||||
game_.DataPath() / blankEsm,
|
||||
true));
|
||||
cache_.AddPlugin(Plugin(game_.Type(),
|
||||
game_.DataPath(),
|
||||
std::make_shared<GameCache>(GameCache()),
|
||||
game_.GetLoadOrderHandler(),
|
||||
blankMasterDependentEsm,
|
||||
game_.DataPath() / blankMasterDependentEsm,
|
||||
true));
|
||||
|
||||
EXPECT_FALSE(cache_.GetPlugins().empty());
|
||||
@@ -185,10 +179,9 @@ TEST_P(GameCacheTest, clearingCachedPluginsShouldNotThrowIfNoPluginsAreCached) {
|
||||
|
||||
TEST_P(GameCacheTest, clearingCachedPluginsShouldClearAnyCachedPlugins) {
|
||||
cache_.AddPlugin(Plugin(game_.Type(),
|
||||
game_.DataPath(),
|
||||
std::make_shared<GameCache>(GameCache()),
|
||||
game_.GetLoadOrderHandler(),
|
||||
blankEsm,
|
||||
game_.DataPath() / blankEsm,
|
||||
true));
|
||||
cache_.ClearCachedPlugins();
|
||||
|
||||
|
||||
@@ -144,10 +144,9 @@ INSTANTIATE_TEST_CASE_P(,
|
||||
|
||||
TEST_P(PluginTest, loadingShouldHandleNonAsciiFilenamesCorrectly) {
|
||||
Plugin plugin(game_.Type(),
|
||||
game_.DataPath(),
|
||||
game_.GetCache(),
|
||||
game_.GetLoadOrderHandler(),
|
||||
nonAsciiEsp,
|
||||
game_.DataPath() / std::filesystem::u8path(nonAsciiEsp),
|
||||
true);
|
||||
|
||||
EXPECT_EQ(nonAsciiEsp, plugin.GetName());
|
||||
@@ -156,10 +155,9 @@ TEST_P(PluginTest, loadingShouldHandleNonAsciiFilenamesCorrectly) {
|
||||
|
||||
TEST_P(PluginTest, loadingHeaderOnlyShouldReadHeaderData) {
|
||||
Plugin plugin(game_.Type(),
|
||||
game_.DataPath(),
|
||||
game_.GetCache(),
|
||||
game_.GetLoadOrderHandler(),
|
||||
blankEsm,
|
||||
game_.DataPath() / blankEsm,
|
||||
true);
|
||||
|
||||
EXPECT_EQ(blankEsm, plugin.GetName());
|
||||
@@ -171,10 +169,9 @@ TEST_P(PluginTest, loadingHeaderOnlyShouldReadHeaderData) {
|
||||
|
||||
TEST_P(PluginTest, loadingHeaderOnlyShouldNotReadFieldsOrCalculateCrc) {
|
||||
Plugin plugin(game_.Type(),
|
||||
game_.DataPath(),
|
||||
game_.GetCache(),
|
||||
game_.GetLoadOrderHandler(),
|
||||
blankEsm,
|
||||
game_.DataPath() / blankEsm,
|
||||
true);
|
||||
|
||||
EXPECT_FALSE(plugin.GetCRC());
|
||||
@@ -182,10 +179,9 @@ TEST_P(PluginTest, loadingHeaderOnlyShouldNotReadFieldsOrCalculateCrc) {
|
||||
|
||||
TEST_P(PluginTest, loadingWholePluginShouldReadHeaderData) {
|
||||
Plugin plugin(game_.Type(),
|
||||
game_.DataPath(),
|
||||
game_.GetCache(),
|
||||
game_.GetLoadOrderHandler(),
|
||||
blankEsm,
|
||||
game_.DataPath() / blankEsm,
|
||||
true);
|
||||
|
||||
EXPECT_EQ(blankEsm, plugin.GetName());
|
||||
@@ -197,10 +193,9 @@ TEST_P(PluginTest, loadingWholePluginShouldReadHeaderData) {
|
||||
|
||||
TEST_P(PluginTest, loadingWholePluginShouldReadFields) {
|
||||
Plugin plugin(game_.Type(),
|
||||
game_.DataPath(),
|
||||
game_.GetCache(),
|
||||
game_.GetLoadOrderHandler(),
|
||||
blankMasterDependentEsm,
|
||||
game_.DataPath() / blankMasterDependentEsm,
|
||||
false);
|
||||
|
||||
EXPECT_EQ(4, plugin.NumOverrideFormIDs());
|
||||
@@ -208,10 +203,9 @@ TEST_P(PluginTest, loadingWholePluginShouldReadFields) {
|
||||
|
||||
TEST_P(PluginTest, loadingWholePluginShouldCalculateCrc) {
|
||||
Plugin plugin(game_.Type(),
|
||||
game_.DataPath(),
|
||||
game_.GetCache(),
|
||||
game_.GetLoadOrderHandler(),
|
||||
blankEsm,
|
||||
game_.DataPath() / blankEsm,
|
||||
false);
|
||||
|
||||
EXPECT_EQ(blankEsmCrc, plugin.GetCRC());
|
||||
@@ -219,10 +213,9 @@ TEST_P(PluginTest, loadingWholePluginShouldCalculateCrc) {
|
||||
|
||||
TEST_P(PluginTest, loadingANonMasterPluginShouldReadTheMasterFlagAsFalse) {
|
||||
Plugin plugin(game_.Type(),
|
||||
game_.DataPath(),
|
||||
game_.GetCache(),
|
||||
game_.GetLoadOrderHandler(),
|
||||
blankMasterDependentEsp,
|
||||
game_.DataPath() / blankMasterDependentEsp,
|
||||
true);
|
||||
|
||||
EXPECT_FALSE(plugin.IsMaster());
|
||||
@@ -232,22 +225,19 @@ TEST_P(
|
||||
PluginTest,
|
||||
isLightMasterShouldBeTrueForAPluginWithEslFileExtensionForFallout4AndSkyrimSeAndFalseOtherwise) {
|
||||
Plugin plugin1(game_.Type(),
|
||||
game_.DataPath(),
|
||||
game_.GetCache(),
|
||||
game_.GetCache(),
|
||||
game_.GetLoadOrderHandler(),
|
||||
blankEsm,
|
||||
game_.DataPath() / blankEsm,
|
||||
true);
|
||||
Plugin plugin2(game_.Type(),
|
||||
game_.DataPath(),
|
||||
game_.GetCache(),
|
||||
game_.GetCache(),
|
||||
game_.GetLoadOrderHandler(),
|
||||
blankMasterDependentEsp,
|
||||
game_.DataPath() / blankMasterDependentEsp,
|
||||
true);
|
||||
Plugin plugin3(game_.Type(),
|
||||
game_.DataPath(),
|
||||
game_.GetCache(),
|
||||
game_.GetCache(),
|
||||
game_.GetLoadOrderHandler(),
|
||||
blankEsl,
|
||||
game_.DataPath() / blankEsl,
|
||||
true);
|
||||
|
||||
EXPECT_FALSE(plugin1.IsLightMaster());
|
||||
@@ -258,10 +248,9 @@ TEST_P(
|
||||
|
||||
TEST_P(PluginTest, loadingAPluginWithMastersShouldReadThemCorrectly) {
|
||||
Plugin plugin(game_.Type(),
|
||||
game_.DataPath(),
|
||||
game_.GetCache(),
|
||||
game_.GetLoadOrderHandler(),
|
||||
blankMasterDependentEsp,
|
||||
game_.DataPath() / blankMasterDependentEsp,
|
||||
true);
|
||||
|
||||
EXPECT_EQ(std::vector<std::string>({blankEsm}), plugin.GetMasters());
|
||||
@@ -269,10 +258,9 @@ TEST_P(PluginTest, loadingAPluginWithMastersShouldReadThemCorrectly) {
|
||||
|
||||
TEST_P(PluginTest, loadingAPluginThatDoesNotExistShouldThrow) {
|
||||
EXPECT_THROW(Plugin(game_.Type(),
|
||||
game_.DataPath(),
|
||||
game_.GetCache(),
|
||||
game_.GetCache(),
|
||||
game_.GetLoadOrderHandler(),
|
||||
"Blank\\.esp",
|
||||
game_.DataPath() / "Blank\\.esp",
|
||||
true),
|
||||
FileAccessError);
|
||||
}
|
||||
@@ -281,10 +269,9 @@ TEST_P(
|
||||
PluginTest,
|
||||
loadsArchiveForAnArchiveThatExactlyMatchesAnEsmFileBasenameShouldReturnTrueForAllGamesExceptOblivion) {
|
||||
bool loadsArchive = Plugin(game_.Type(),
|
||||
game_.DataPath(),
|
||||
game_.GetCache(),
|
||||
game_.GetCache(),
|
||||
game_.GetLoadOrderHandler(),
|
||||
blankEsm,
|
||||
game_.DataPath() / blankEsm,
|
||||
true)
|
||||
.LoadsArchive();
|
||||
|
||||
@@ -298,10 +285,9 @@ TEST_P(
|
||||
PluginTest,
|
||||
loadsArchiveForAnArchiveThatExactlyMatchesANonAsciiEspFileBasenameShouldReturnTrue) {
|
||||
EXPECT_TRUE(Plugin(game_.Type(),
|
||||
game_.DataPath(),
|
||||
game_.GetCache(),
|
||||
game_.GetCache(),
|
||||
game_.GetLoadOrderHandler(),
|
||||
nonAsciiEsp,
|
||||
game_.DataPath() / std::filesystem::u8path(nonAsciiEsp),
|
||||
true)
|
||||
.LoadsArchive());
|
||||
}
|
||||
@@ -310,10 +296,9 @@ TEST_P(
|
||||
PluginTest,
|
||||
loadsArchiveForAnArchiveThatExactlyMatchesAnEspFileBasenameShouldReturnTrue) {
|
||||
EXPECT_TRUE(Plugin(game_.Type(),
|
||||
game_.DataPath(),
|
||||
game_.GetCache(),
|
||||
game_.GetLoadOrderHandler(),
|
||||
blankEsp,
|
||||
game_.DataPath() / blankEsp,
|
||||
true)
|
||||
.LoadsArchive());
|
||||
}
|
||||
@@ -322,10 +307,9 @@ TEST_P(
|
||||
PluginTest,
|
||||
loadsArchiveForAnArchiveWithAFilenameWhichStartsWithTheEsmFileBasenameShouldReturnTrueForAllGamesExceptOblivionAndSkyrim) {
|
||||
bool loadsArchive = Plugin(game_.Type(),
|
||||
game_.DataPath(),
|
||||
game_.GetCache(),
|
||||
game_.GetCache(),
|
||||
game_.GetLoadOrderHandler(),
|
||||
blankDifferentEsm,
|
||||
game_.DataPath() / blankDifferentEsm,
|
||||
true)
|
||||
.LoadsArchive();
|
||||
|
||||
@@ -339,10 +323,9 @@ TEST_P(
|
||||
PluginTest,
|
||||
loadsArchiveForAnArchiveWithAFilenameWhichStartsWithTheEspFileBasenameShouldReturnTrueForAllGamesExceptSkyrim) {
|
||||
bool loadsArchive = Plugin(game_.Type(),
|
||||
game_.DataPath(),
|
||||
game_.GetCache(),
|
||||
game_.GetCache(),
|
||||
game_.GetLoadOrderHandler(),
|
||||
blankDifferentEsp,
|
||||
game_.DataPath() / blankDifferentEsp,
|
||||
true)
|
||||
.LoadsArchive();
|
||||
|
||||
@@ -355,58 +338,55 @@ TEST_P(
|
||||
TEST_P(PluginTest,
|
||||
loadsArchiveShouldReturnFalseForAPluginThatDoesNotLoadAnArchive) {
|
||||
EXPECT_FALSE(Plugin(game_.Type(),
|
||||
game_.DataPath(),
|
||||
game_.GetCache(),
|
||||
game_.GetCache(),
|
||||
game_.GetLoadOrderHandler(),
|
||||
blankMasterDependentEsp,
|
||||
game_.DataPath() / blankMasterDependentEsp,
|
||||
true)
|
||||
.LoadsArchive());
|
||||
}
|
||||
|
||||
TEST_P(PluginTest, isValidShouldReturnTrueForAValidPlugin) {
|
||||
EXPECT_TRUE(Plugin::IsValid(blankEsm, game_.Type(), game_.DataPath()));
|
||||
EXPECT_TRUE(Plugin::IsValid(game_.Type(), game_.DataPath() / blankEsm));
|
||||
}
|
||||
|
||||
TEST_P(PluginTest, isValidShouldReturnTrueForAValidNonAsciiPlugin) {
|
||||
EXPECT_TRUE(Plugin::IsValid(nonAsciiEsp, game_.Type(), game_.DataPath()));
|
||||
EXPECT_TRUE(Plugin::IsValid(game_.Type(), game_.DataPath() / std::filesystem::u8path(nonAsciiEsp)));
|
||||
}
|
||||
|
||||
TEST_P(PluginTest, isValidShouldReturnFalseForANonPluginFile) {
|
||||
EXPECT_FALSE(Plugin::IsValid(nonPluginFile, game_.Type(), game_.DataPath()));
|
||||
EXPECT_FALSE(Plugin::IsValid(game_.Type(), game_.DataPath() / nonPluginFile));
|
||||
}
|
||||
|
||||
TEST_P(PluginTest, isValidShouldReturnFalseForAnEmptyFile) {
|
||||
EXPECT_FALSE(Plugin::IsValid(emptyFile, game_.Type(), game_.DataPath()));
|
||||
EXPECT_FALSE(Plugin::IsValid(game_.Type(), game_.DataPath() / emptyFile));
|
||||
}
|
||||
|
||||
TEST_P(PluginTest, getFileSizeShouldThrowForAMissingPlugin) {
|
||||
EXPECT_THROW(Plugin::GetFileSize(missingEsp, game_.DataPath()), std::filesystem::filesystem_error);
|
||||
EXPECT_THROW(Plugin::GetFileSize(game_.DataPath() / missingEsp), std::filesystem::filesystem_error);
|
||||
}
|
||||
|
||||
TEST_P(PluginTest, getFileSizeShouldReturnCorrectValueForAPlugin) {
|
||||
EXPECT_EQ(getNonAsciiEspFileSize(), Plugin::GetFileSize(nonAsciiEsp, game_.DataPath()));
|
||||
EXPECT_EQ(getNonAsciiEspFileSize(), Plugin::GetFileSize(game_.DataPath() / std::filesystem::u8path(nonAsciiEsp)));
|
||||
}
|
||||
|
||||
TEST_P(PluginTest, getFileSizeShouldReturnCorrectValueForAGhostedPlugin) {
|
||||
EXPECT_EQ(getGhostedPluginFileSize(), Plugin::GetFileSize(blankMasterDependentEsm, game_.DataPath()));
|
||||
EXPECT_EQ(getGhostedPluginFileSize(), Plugin::GetFileSize(game_.DataPath() / blankMasterDependentEsm));
|
||||
}
|
||||
|
||||
TEST_P(PluginTest, isActiveShouldReturnTrueForAPluginThatIsActive) {
|
||||
EXPECT_TRUE(Plugin(game_.Type(),
|
||||
game_.DataPath(),
|
||||
game_.GetCache(),
|
||||
game_.GetCache(),
|
||||
game_.GetLoadOrderHandler(),
|
||||
blankEsm,
|
||||
game_.DataPath() / blankEsm,
|
||||
true)
|
||||
.IsActive());
|
||||
}
|
||||
|
||||
TEST_P(PluginTest, isActiveShouldReturnFalseForAPluginThatIsNotActive) {
|
||||
EXPECT_FALSE(Plugin(game_.Type(),
|
||||
game_.DataPath(),
|
||||
game_.GetCache(),
|
||||
game_.GetCache(),
|
||||
game_.GetLoadOrderHandler(),
|
||||
blankEsp,
|
||||
game_.DataPath() / blankEsp,
|
||||
true)
|
||||
.IsActive());
|
||||
}
|
||||
@@ -414,32 +394,28 @@ TEST_P(PluginTest, isActiveShouldReturnFalseForAPluginThatIsNotActive) {
|
||||
TEST_P(PluginTest,
|
||||
lessThanOperatorShouldUseCaseInsensitiveLexicographicalNameComparison) {
|
||||
Plugin plugin1(game_.Type(),
|
||||
game_.DataPath(),
|
||||
game_.GetCache(),
|
||||
game_.GetCache(),
|
||||
game_.GetLoadOrderHandler(),
|
||||
blankEsp,
|
||||
game_.DataPath() / blankEsp,
|
||||
true);
|
||||
Plugin plugin2(game_.Type(),
|
||||
game_.DataPath(),
|
||||
game_.GetCache(),
|
||||
game_.GetCache(),
|
||||
game_.GetLoadOrderHandler(),
|
||||
lowercaseBlankEsp,
|
||||
game_.DataPath() / lowercaseBlankEsp,
|
||||
true);
|
||||
|
||||
EXPECT_FALSE(plugin1 < plugin2);
|
||||
EXPECT_FALSE(plugin2 < plugin1);
|
||||
|
||||
Plugin plugin3 = Plugin(game_.Type(),
|
||||
game_.DataPath(),
|
||||
game_.GetCache(),
|
||||
game_.GetCache(),
|
||||
game_.GetLoadOrderHandler(),
|
||||
blankEsm,
|
||||
game_.DataPath() / blankEsm,
|
||||
true);
|
||||
Plugin plugin4 = Plugin(game_.Type(),
|
||||
game_.DataPath(),
|
||||
game_.GetCache(),
|
||||
game_.GetCache(),
|
||||
game_.GetLoadOrderHandler(),
|
||||
blankEsp,
|
||||
game_.DataPath() / blankEsp,
|
||||
true);
|
||||
|
||||
EXPECT_TRUE(plugin3 < plugin4);
|
||||
@@ -449,10 +425,9 @@ TEST_P(PluginTest,
|
||||
TEST_P(PluginTest,
|
||||
doFormIDsOverlapShouldReturnFalseIfTheArgumentIsNotAPluginObject) {
|
||||
Plugin plugin1(game_.Type(),
|
||||
game_.DataPath(),
|
||||
game_.GetCache(),
|
||||
game_.GetCache(),
|
||||
game_.GetLoadOrderHandler(),
|
||||
blankEsm,
|
||||
game_.DataPath() / blankEsm,
|
||||
false);
|
||||
OtherPluginType plugin2;
|
||||
|
||||
@@ -463,16 +438,14 @@ TEST_P(PluginTest,
|
||||
TEST_P(PluginTest,
|
||||
doFormIDsOverlapShouldReturnFalseForTwoPluginsWithOnlyHeadersLoaded) {
|
||||
Plugin plugin1(game_.Type(),
|
||||
game_.DataPath(),
|
||||
game_.GetCache(),
|
||||
game_.GetCache(),
|
||||
game_.GetLoadOrderHandler(),
|
||||
blankEsm,
|
||||
game_.DataPath() / blankEsm,
|
||||
true);
|
||||
Plugin plugin2(game_.Type(),
|
||||
game_.DataPath(),
|
||||
game_.GetCache(),
|
||||
game_.GetCache(),
|
||||
game_.GetLoadOrderHandler(),
|
||||
blankMasterDependentEsm,
|
||||
game_.DataPath() / blankMasterDependentEsm,
|
||||
true);
|
||||
|
||||
EXPECT_FALSE(plugin1.DoFormIDsOverlap(plugin2));
|
||||
@@ -482,16 +455,14 @@ TEST_P(PluginTest,
|
||||
TEST_P(PluginTest,
|
||||
doFormIDsOverlapShouldReturnFalseIfThePluginsHaveUnrelatedRecords) {
|
||||
Plugin plugin1(game_.Type(),
|
||||
game_.DataPath(),
|
||||
game_.GetCache(),
|
||||
game_.GetCache(),
|
||||
game_.GetLoadOrderHandler(),
|
||||
blankEsm,
|
||||
game_.DataPath() / blankEsm,
|
||||
false);
|
||||
Plugin plugin2(game_.Type(),
|
||||
game_.DataPath(),
|
||||
game_.GetCache(),
|
||||
game_.GetCache(),
|
||||
game_.GetLoadOrderHandler(),
|
||||
blankEsp,
|
||||
game_.DataPath() / blankEsp,
|
||||
false);
|
||||
|
||||
EXPECT_FALSE(plugin1.DoFormIDsOverlap(plugin2));
|
||||
@@ -501,16 +472,14 @@ TEST_P(PluginTest,
|
||||
TEST_P(PluginTest,
|
||||
doFormIDsOverlapShouldReturnTrueIfOnePluginOverridesTheOthersRecords) {
|
||||
Plugin plugin1(game_.Type(),
|
||||
game_.DataPath(),
|
||||
game_.GetCache(),
|
||||
game_.GetCache(),
|
||||
game_.GetLoadOrderHandler(),
|
||||
blankEsm,
|
||||
game_.DataPath() / blankEsm,
|
||||
false);
|
||||
Plugin plugin2(game_.Type(),
|
||||
game_.DataPath(),
|
||||
game_.GetCache(),
|
||||
game_.GetCache(),
|
||||
game_.GetLoadOrderHandler(),
|
||||
blankMasterDependentEsm,
|
||||
game_.DataPath() / blankMasterDependentEsm,
|
||||
false);
|
||||
|
||||
EXPECT_TRUE(plugin1.DoFormIDsOverlap(plugin2));
|
||||
|
||||
Reference in New Issue
Block a user