From 8d410599939b7ca5b0abe003907b12dbefc04e9f Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Thu, 23 Aug 2018 07:16:20 +0100 Subject: [PATCH] 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. --- src/api/game/game.cpp | 8 +- src/api/metadata/condition_evaluator.cpp | 7 +- src/api/plugin.cpp | 76 ++++----- src/api/plugin.h | 16 +- src/tests/api/interface/game_interface_test.h | 30 +++- .../api/internals/game/game_cache_test.h | 21 +-- src/tests/api/internals/plugin_test.h | 151 +++++++----------- 7 files changed, 149 insertions(+), 160 deletions(-) diff --git a/src/api/game/game.cpp b/src/api/game/game.cpp index dc206d3f..5691e5b0 100644 --- a/src/api/game/game.cpp +++ b/src/api/game/game.cpp @@ -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 Game::GetLoadOrderHandler() { std::shared_ptr 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& plugins, bool loadHeadersOnly) { + auto logger = getLogger(); uintmax_t meanFileSize = 0; std::multimap sizeMap; @@ -101,7 +103,7 @@ void Game::LoadPlugins(const std::vector& 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& 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( diff --git a/src/api/metadata/condition_evaluator.cpp b/src/api/metadata/condition_evaluator.cpp index d610d564..8354e091 100644 --- a/src/api/metadata/condition_evaluator.cpp +++ b/src/api/metadata/condition_evaluator.cpp @@ -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 { diff --git a/src/api/plugin.cpp b/src/api/plugin.cpp index 8cc5b0f0..d280ef81 100644 --- a/src/api/plugin.cpp +++ b/src/api/plugin.cpp @@ -41,12 +41,11 @@ using std::string; namespace loot { Plugin::Plugin(const GameType gameType, - const std::filesystem::path& dataPath, std::shared_ptr gameCache, std::shared_ptr 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, - 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 diff --git a/src/api/plugin.h b/src/api/plugin.h index cd9d118f..b6ef1967 100644 --- a/src/api/plugin.h +++ b/src/api/plugin.h @@ -44,10 +44,9 @@ class GameCache; class Plugin : public PluginInterface { public: Plugin(const GameType gameType, - const std::filesystem::path& dataPath, std::shared_ptr gameCache, std::shared_ptr 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, - 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 diff --git a/src/tests/api/interface/game_interface_test.h b/src/tests/api/interface/game_interface_test.h index c633de4c..4a157313 100644 --- a/src/tests/api/interface/game_interface_test.h +++ b/src/tests/api/interface/game_interface_test.h @@ -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 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 loadOrder({ masterFile, diff --git a/src/tests/api/internals/game/game_cache_test.h b/src/tests/api/internals/game/game_cache_test.h index 02da6108..01493ecb 100644 --- a/src/tests/api/internals/game/game_cache_test.h +++ b/src/tests/api/internals/game/game_cache_test.h @@ -81,10 +81,9 @@ TEST_P(GameCacheTest, gettingAnUncachedCrcShouldReturnZero) { TEST_P(GameCacheTest, addingAPluginThatDoesNotExistShouldSucceed) { cache_.AddPlugin(Plugin(game_.Type(), - game_.DataPath(), std::make_shared(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()), 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()), 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()), 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()), game_.GetLoadOrderHandler(), - blankEsm, + game_.DataPath() / blankEsm, true)); cache_.AddPlugin(Plugin(game_.Type(), - game_.DataPath(), std::make_shared(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()), game_.GetLoadOrderHandler(), - blankEsm, + game_.DataPath() / blankEsm, true)); cache_.ClearCachedPlugins(); diff --git a/src/tests/api/internals/plugin_test.h b/src/tests/api/internals/plugin_test.h index e9304d3a..315dd2aa 100644 --- a/src/tests/api/internals/plugin_test.h +++ b/src/tests/api/internals/plugin_test.h @@ -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({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));