diff --git a/include/loot/database_interface.h b/include/loot/database_interface.h index 9d48818d..a7e70678 100644 --- a/include/loot/database_interface.h +++ b/include/loot/database_interface.h @@ -24,6 +24,7 @@ #ifndef LOOT_DATABASE_INTERFACE #define LOOT_DATABASE_INTERFACE +#include #include #include @@ -226,11 +227,10 @@ public: * If true, any metadata conditions are evaluated before the metadata * is returned, otherwise unevaluated metadata is returned. Evaluating * plugin metadata conditions does not clear the condition cache. - * @returns A PluginMetadata object containing all the plugin's metadata. - * If the plugin has no metadata, PluginMetadata.IsNameOnly() - * will return true. + * @returns If the plugin has metadata, an optional containing that metadata, + * otherwise an optional containing no value. */ - virtual PluginMetadata GetPluginMetadata( + virtual std::optional GetPluginMetadata( const std::string& plugin, bool includeUserMetadata = true, bool evaluateConditions = false) const = 0; @@ -243,11 +243,10 @@ public: * If true, any metadata conditions are evaluated before the metadata * is returned, otherwise unevaluated metadata is returned. Evaluating * plugin metadata conditions does not clear the condition cache. - * @returns A PluginMetadata object containing the plugin's user-added - * metadata. If the plugin has no metadata, - * PluginMetadata.IsNameOnly() will return true. + * @returns If the plugin has user-added metadata, an optional containing + * that metadata, otherwise an optional containing no value. */ - virtual PluginMetadata GetPluginUserMetadata( + virtual std::optional GetPluginUserMetadata( const std::string& plugin, bool evaluateConditions = false) const = 0; diff --git a/include/loot/game_interface.h b/include/loot/game_interface.h index 8c406192..4d2859e7 100644 --- a/include/loot/game_interface.h +++ b/include/loot/game_interface.h @@ -24,6 +24,8 @@ #ifndef LOOT_GAME_INTERFACE #define LOOT_GAME_INTERFACE +#include + #include "loot/database_interface.h" #include "loot/plugin_interface.h" @@ -77,14 +79,13 @@ public: /** * @brief Get data for a loaded plugin. - * @details Throws an exception if the given plugin has not been loaded. * @param pluginName * The filename of the plugin to get data for. - * @returns A const PluginInterface reference. The reference remains valid - * until the ``LoadPlugins()`` or ``SortPlugins()`` functions are - * next called or this GameInterface is destroyed. + * @returns If the plugin has been loaded, an optional containing a pointer to + * an implementation of PluginInterface for that plugin, otherwise an + * optional containing no value. */ - virtual std::shared_ptr GetPlugin( + virtual std::optional> GetPlugin( const std::string& pluginName) const = 0; /** diff --git a/include/loot/plugin_interface.h b/include/loot/plugin_interface.h index 471dbef4..9dfc7316 100644 --- a/include/loot/plugin_interface.h +++ b/include/loot/plugin_interface.h @@ -25,6 +25,7 @@ #define LOOT_PLUGIN_INTERFACE #include +#include #include #include #include @@ -53,12 +54,13 @@ public: /** * Get the plugin's version number from its description field. * - * If no version number is found in the description field, an empty string is - * returned. The description field parsing may fail to extract the version - * number correctly, though it functions correctly in all known cases. - * @return A string containing a version number, or an empty string. + * The description field may not contain a version number, or LOOT may be + * unable to detect it. The description field parsing may fail to extract the + * version number correctly, though it functions correctly in all known cases. + * @return An optional containing a version string if one is found, otherwise + * an optional containing no value. */ - virtual std::string GetVersion() const = 0; + virtual std::optional GetVersion() const = 0; /** * Get the plugin's masters. @@ -75,10 +77,10 @@ public: /** * Get the plugin's CRC-32 checksum. - * @return The plugin's CRC-32 checksum if it has been fully read. If only the - * plugin's header has been read, ``0`` will be returned. + * @return An optional containing the plugin's CRC-32 checksum if the plugin + * has been fully loaded, otherwise an optional containing no value. */ - virtual uint32_t GetCRC() const = 0; + virtual std::optional GetCRC() const = 0; /** * Check if the plugin's master flag is set. diff --git a/src/api/api_database.cpp b/src/api/api_database.cpp index dcdbb216..db7ac37f 100644 --- a/src/api/api_database.cpp +++ b/src/api/api_database.cpp @@ -199,29 +199,34 @@ void ApiDatabase::SetUserGroups(const std::unordered_set& groups) { userlist_.SetGroups(groups); } -PluginMetadata ApiDatabase::GetPluginMetadata(const std::string& plugin, +std::optional ApiDatabase::GetPluginMetadata(const std::string& plugin, bool includeUserMetadata, bool evaluateConditions) const { - PluginMetadata metadata = masterlist_.FindPlugin(plugin); + auto metadata = masterlist_.FindPlugin(plugin); if (includeUserMetadata) { - metadata.MergeMetadata(userlist_.FindPlugin(plugin)); + auto userMetadata = userlist_.FindPlugin(plugin); + if (metadata && userMetadata) { + metadata.value().MergeMetadata(userMetadata.value()); + } else if (userMetadata) { + metadata = userMetadata; + } } - if (evaluateConditions) { - return conditionEvaluator_.evaluateAll(metadata); + if (evaluateConditions && metadata) { + return conditionEvaluator_.evaluateAll(metadata.value()); } return metadata; } -PluginMetadata ApiDatabase::GetPluginUserMetadata( +std::optional ApiDatabase::GetPluginUserMetadata( const std::string& plugin, bool evaluateConditions) const { - PluginMetadata metadata = userlist_.FindPlugin(plugin); + auto metadata = userlist_.FindPlugin(plugin); - if (evaluateConditions) { - return conditionEvaluator_.evaluateAll(metadata); + if (evaluateConditions && metadata) { + return conditionEvaluator_.evaluateAll(metadata.value()); } return metadata; diff --git a/src/api/api_database.h b/src/api/api_database.h index 6a542851..aa1df596 100644 --- a/src/api/api_database.h +++ b/src/api/api_database.h @@ -72,12 +72,14 @@ struct ApiDatabase : public DatabaseInterface { std::unordered_set GetUserGroups() const; void SetUserGroups(const std::unordered_set& groups); - PluginMetadata GetPluginMetadata(const std::string& plugin, - bool includeUserMetadata = true, - bool evaluateConditions = false) const; + std::optional GetPluginMetadata( + const std::string& plugin, + bool includeUserMetadata = true, + bool evaluateConditions = false) const; - PluginMetadata GetPluginUserMetadata(const std::string& plugin, - bool evaluateConditions = false) const; + std::optional GetPluginUserMetadata( + const std::string& plugin, + bool evaluateConditions = false) const; void SetPluginUserMetadata(const PluginMetadata& pluginMetadata); diff --git a/src/api/game/game.cpp b/src/api/game/game.cpp index 0efaae75..724ab933 100644 --- a/src/api/game/game.cpp +++ b/src/api/game/game.cpp @@ -192,10 +192,9 @@ void Game::LoadPlugins(const std::vector& plugins, } } -std::shared_ptr Game::GetPlugin( +std::optional> Game::GetPlugin( const std::string& pluginName) const { - return std::static_pointer_cast( - cache_->GetPlugin(pluginName)); + return cache_->GetPlugin(pluginName); } std::set> Game::GetLoadedPlugins() @@ -226,13 +225,14 @@ void Game::LoadCurrentLoadOrderState() { loadOrderHandler_->LoadCurrentState(); } -bool Game::IsPluginActive(const std::string& plugin) const { - try { - return std::static_pointer_cast(GetPlugin(plugin)) - ->IsActive(); - } catch (...) { - return loadOrderHandler_->IsPluginActive(plugin); +bool Game::IsPluginActive(const std::string& pluginName) const { + auto plugin = cache_->GetPlugin(pluginName); + + if (plugin) { + return plugin.value()->IsActive(); } + + return loadOrderHandler_->IsPluginActive(pluginName); } std::vector Game::GetLoadOrder() const { diff --git a/src/api/game/game.h b/src/api/game/game.h index 140f89ca..3ef95a5b 100644 --- a/src/api/game/game.h +++ b/src/api/game/game.h @@ -59,7 +59,8 @@ public: void LoadPlugins(const std::vector& plugins, bool loadHeadersOnly); - std::shared_ptr GetPlugin( + std::optional> + GetPlugin( const std::string& pluginName) const; std::set> GetLoadedPlugins() const; diff --git a/src/api/game/game_cache.cpp b/src/api/game/game_cache.cpp index e4451f29..d2bb1d43 100644 --- a/src/api/game/game_cache.cpp +++ b/src/api/game/game_cache.cpp @@ -97,13 +97,13 @@ std::set> GameCache::GetPlugins() const { return output; } -std::shared_ptr GameCache::GetPlugin( +std::optional> GameCache::GetPlugin( const std::string& pluginName) const { auto it = plugins_.find(to_lower(pluginName)); if (it != end(plugins_)) return it->second; - throw std::invalid_argument("No plugin \"" + pluginName + "\" exists."); + return std::nullopt; } void GameCache::AddPlugin(const Plugin&& plugin) { diff --git a/src/api/game/game_cache.h b/src/api/game/game_cache.h index 65311ba4..d9f58316 100644 --- a/src/api/game/game_cache.h +++ b/src/api/game/game_cache.h @@ -47,7 +47,8 @@ public: void CacheCrc(const std::string& file, uint32_t crc); std::set> GetPlugins() const; - std::shared_ptr GetPlugin(const std::string& pluginName) const; + std::optional> GetPlugin( + const std::string& pluginName) const; void AddPlugin(const Plugin&& plugin); std::set GetArchivePaths() const; diff --git a/src/api/metadata/condition_evaluator.cpp b/src/api/metadata/condition_evaluator.cpp index f11a4e19..6cde51cf 100644 --- a/src/api/metadata/condition_evaluator.cpp +++ b/src/api/metadata/condition_evaluator.cpp @@ -156,19 +156,17 @@ bool ConditionEvaluator::fileExists(const std::string& filePath) const { // Try first checking the plugin cache, as most file entries are // for plugins. - try { - // GetPlugin throws if it can't find an entry. - gameCache_->GetPlugin(filePath); - + auto plugin = gameCache_->GetPlugin(filePath); + if (plugin) { return true; - } catch (...) { - // Not a loaded plugin, check the filesystem. - if (hasPluginFileExtension(filePath, gameType_)) - return boost::filesystem::exists(dataPath_ / filePath) || - boost::filesystem::exists(dataPath_ / (filePath + ".ghost")); - else - return boost::filesystem::exists(dataPath_ / filePath); } + + // Not a loaded plugin, check the filesystem. + if (hasPluginFileExtension(filePath, gameType_)) + return boost::filesystem::exists(dataPath_ / filePath) || + boost::filesystem::exists(dataPath_ / (filePath + ".ghost")); + else + return boost::filesystem::exists(dataPath_ / filePath); } bool ConditionEvaluator::regexMatchExists( @@ -412,19 +410,22 @@ Version ConditionEvaluator::getVersion(const std::string& filePath) const { // If the file is a plugin, its version needs to be extracted // from its description field. Try getting an entry from the // plugin cache. - try { - return Version(gameCache_->GetPlugin(filePath)->GetVersion()); - } catch (...) { - // 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_)) - return Version( - Plugin(gameType_, dataPath_, gameCache_, loadOrderHandler_, filePath, true) - .GetVersion()); - return Version(dataPath_ / filePath); + auto plugin = gameCache_->GetPlugin(filePath); + if (plugin) { + return Version(plugin.value()->GetVersion().value_or("")); } + + // 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_)) + return Version( + Plugin(gameType_, dataPath_, gameCache_, loadOrderHandler_, filePath, true) + .GetVersion() + .value_or("")); + + return Version(dataPath_ / filePath); } } bool ConditionEvaluator::shouldParseOnly() const { @@ -445,9 +446,9 @@ uint32_t ConditionEvaluator::getCrc(const std::string & file) const { } // Get the CRC from the game plugin cache if possible. - try { - crc = gameCache_->GetPlugin(file)->GetCRC(); - } catch (...) { + auto plugin = gameCache_->GetPlugin(file); + if (plugin) { + crc = plugin.value()->GetCRC().value_or(0); } // Otherwise calculate it from the file. diff --git a/src/api/metadata_list.cpp b/src/api/metadata_list.cpp index 231d73a2..c765f2f6 100644 --- a/src/api/metadata_list.cpp +++ b/src/api/metadata_list.cpp @@ -143,8 +143,9 @@ void MetadataList::SetGroups(const std::unordered_set& groups) { } // Merges multiple matching regex entries if any are found. -PluginMetadata MetadataList::FindPlugin(const PluginMetadata& plugin) const { - PluginMetadata match(plugin.GetName()); +std::optional MetadataList::FindPlugin( + const std::string& plugin) const { + PluginMetadata match(plugin); auto it = plugins_.find(plugin); @@ -159,6 +160,10 @@ PluginMetadata MetadataList::FindPlugin(const PluginMetadata& plugin) const { regIt = find(++regIt, regexPlugins_.end(), plugin); } + if (match.HasNameOnly()) { + return std::nullopt; + } + return match; } diff --git a/src/api/metadata_list.h b/src/api/metadata_list.h index 19da4464..f9d6709b 100644 --- a/src/api/metadata_list.h +++ b/src/api/metadata_list.h @@ -25,6 +25,7 @@ #ifndef LOOT_API_METADATA_LIST #define LOOT_API_METADATA_LIST +#include #include #include #include @@ -32,8 +33,8 @@ #include #include "api/metadata/condition_evaluator.h" -#include "loot/metadata/plugin_metadata.h" #include "loot/metadata/group.h" +#include "loot/metadata/plugin_metadata.h" namespace loot { class MetadataList { @@ -50,7 +51,7 @@ public: void SetGroups(const std::unordered_set& groups); // Merges multiple matching regex entries if any are found. - PluginMetadata FindPlugin(const PluginMetadata& plugin) const; + std::optional FindPlugin(const std::string& plugin) const; void AddPlugin(const PluginMetadata& plugin); // Doesn't erase matching regex entries, because they might also diff --git a/src/api/plugin.cpp b/src/api/plugin.cpp index dbe01722..3cfeecf3 100644 --- a/src/api/plugin.cpp +++ b/src/api/plugin.cpp @@ -51,7 +51,6 @@ Plugin::Plugin(const GameType gameType, isEmpty_(true), isActive_(false), loadsArchive_(false), - crc_(0), numOverrideRecords_(0) { auto logger = getLogger(); @@ -139,8 +138,13 @@ std::string Plugin::GetLowercasedName() const { return boost::locale::to_lower(name_); } -std::string Plugin::GetVersion() const { - return Version(GetDescription()).AsString(); +std::optional Plugin::GetVersion() const { + std::string version = Version(GetDescription()).AsString(); + if (version.empty()) { + return std::nullopt; + } + + return version; } std::vector Plugin::GetMasters() const { @@ -160,7 +164,7 @@ std::vector Plugin::GetMasters() const { std::set Plugin::GetBashTags() const { return tags_; } -uint32_t Plugin::GetCRC() const { return crc_; } +std::optional Plugin::GetCRC() const { return crc_; } bool Plugin::IsMaster() const { bool isMaster; diff --git a/src/api/plugin.h b/src/api/plugin.h index 241b97f4..1d0c44e4 100644 --- a/src/api/plugin.h +++ b/src/api/plugin.h @@ -52,10 +52,10 @@ public: std::string GetName() const; std::string GetLowercasedName() const; - std::string GetVersion() const; + std::optional GetVersion() const; std::vector GetMasters() const; std::set GetBashTags() const; - uint32_t GetCRC() const; + std::optional GetCRC() const; bool IsMaster() const; bool IsLightMaster() const; @@ -94,8 +94,8 @@ private: bool isActive_; bool loadsArchive_; const std::string name_; - std::string version_; // Obtained from description field. - uint32_t crc_; + std::optional version_; // Obtained from description field. + std::optional crc_; std::set tags_; // Useful caches. diff --git a/src/api/sorting/plugin_sorter.cpp b/src/api/sorting/plugin_sorter.cpp index c39d99a2..e122137f 100644 --- a/src/api/sorting/plugin_sorter.cpp +++ b/src/api/sorting/plugin_sorter.cpp @@ -210,7 +210,7 @@ void PluginSorter::AddPluginVertices(Game& game) { } auto metadata = - game.GetDatabase()->GetPluginMetadata(plugin->GetName(), true, true); + game.GetDatabase()->GetPluginMetadata(plugin->GetName(), true, true).value_or(PluginMetadata(plugin->GetName())); auto groupIt = groupPlugins.find(metadata.GetGroup()); if (groupIt == groupPlugins.end()) { diff --git a/src/tests/api/interface/database_interface_test.h b/src/tests/api/interface/database_interface_test.h index b76d97a6..96b82400 100644 --- a/src/tests/api/interface/database_interface_test.h +++ b/src/tests/api/interface/database_interface_test.h @@ -544,10 +544,8 @@ TEST_P( TEST_P( DatabaseInterfaceTest, - getPluginMetadataShouldReturnAnEmptyPluginMetadataObjectIfThePluginHasNoMetadata) { - auto metadata = db_->GetPluginMetadata(blankEsm); - - EXPECT_TRUE(metadata.HasNameOnly()); + getPluginMetadataShouldReturnAnEmptyOptionalIfThePluginHasNoMetadata) { + EXPECT_FALSE(db_->GetPluginMetadata(blankEsm)); } TEST_P( @@ -558,7 +556,7 @@ TEST_P( ASSERT_NO_THROW( db_->LoadLists(masterlistPath.string(), userlistPath_.string())); - auto metadata = db_->GetPluginMetadata(blankEsm, true); + auto metadata = db_->GetPluginMetadata(blankEsm, true).value(); std::set expectedLoadAfter({ File(masterFile), @@ -575,7 +573,7 @@ TEST_P( ASSERT_NO_THROW( db_->LoadLists(masterlistPath.string(), userlistPath_.string())); - auto metadata = db_->GetPluginMetadata(blankEsm, false); + auto metadata = db_->GetPluginMetadata(blankEsm, false).value(); std::set expectedLoadAfter({ File(masterFile), @@ -589,7 +587,7 @@ TEST_P( ASSERT_NO_THROW(GenerateMasterlist()); ASSERT_NO_THROW(db_->LoadLists(masterlistPath.string(), "")); - auto metadata = db_->GetPluginMetadata(blankEsm, false, true); + auto metadata = db_->GetPluginMetadata(blankEsm, false, true).value(); EXPECT_TRUE(metadata.GetMessages().empty()); } @@ -602,9 +600,7 @@ TEST_P( ASSERT_NO_THROW( db_->LoadLists(masterlistPath.string(), userlistPath_.string())); - auto metadata = db_->GetPluginUserMetadata(blankDifferentEsm); - - EXPECT_TRUE(metadata.HasNameOnly()); + EXPECT_FALSE(db_->GetPluginUserMetadata(blankDifferentEsm)); } TEST_P(DatabaseInterfaceTest, @@ -614,7 +610,7 @@ TEST_P(DatabaseInterfaceTest, ASSERT_NO_THROW( db_->LoadLists(masterlistPath.string(), userlistPath_.string())); - auto metadata = db_->GetPluginUserMetadata(blankEsm); + auto metadata = db_->GetPluginUserMetadata(blankEsm).value(); std::set expectedLoadAfter({ File(blankDifferentEsm), @@ -630,7 +626,7 @@ TEST_P( ASSERT_NO_THROW( db_->LoadLists(masterlistPath.string(), userlistPath_.string())); - auto metadata = db_->GetPluginMetadata(blankEsm, false, true); + auto metadata = db_->GetPluginMetadata(blankEsm, false, true).value(); EXPECT_TRUE(metadata.GetMessages().empty()); } @@ -648,7 +644,7 @@ TEST_P( db_->SetPluginUserMetadata(newMetadata); - auto metadata = db_->GetPluginUserMetadata(blankDifferentEsp); + auto metadata = db_->GetPluginUserMetadata(blankDifferentEsp).value(); std::set expectedLoadAfter({ File(blankDifferentEsm), @@ -669,7 +665,7 @@ TEST_P(DatabaseInterfaceTest, db_->SetPluginUserMetadata(newMetadata); - auto metadata = db_->GetPluginMetadata(blankEsm); + auto metadata = db_->GetPluginMetadata(blankEsm).value(); std::set expectedLoadAfter({ File(masterFile), @@ -686,8 +682,7 @@ TEST_P(DatabaseInterfaceTest, db_->DiscardPluginUserMetadata(blankEsm); - auto metadata = db_->GetPluginUserMetadata(blankEsm); - EXPECT_TRUE(metadata.HasNameOnly()); + EXPECT_FALSE(db_->GetPluginUserMetadata(blankEsm)); } TEST_P( @@ -700,7 +695,7 @@ TEST_P( db_->DiscardPluginUserMetadata(blankEsm); - auto metadata = db_->GetPluginMetadata(blankEsm); + auto metadata = db_->GetPluginMetadata(blankEsm).value(); std::set expectedLoadAfter({ File(masterFile), @@ -719,7 +714,7 @@ TEST_P(DatabaseInterfaceTest, auto metadata = db_->GetPluginUserMetadata(blankDifferentEsp); - EXPECT_FALSE(metadata.HasNameOnly()); + EXPECT_TRUE(metadata); } TEST_P(DatabaseInterfaceTest, @@ -770,13 +765,10 @@ TEST_P( db_->DiscardAllUserMetadata(); - auto metadata = db_->GetPluginUserMetadata(blankEsm); - EXPECT_TRUE(metadata.HasNameOnly()); + EXPECT_FALSE(db_->GetPluginUserMetadata(blankEsm)); + EXPECT_FALSE(db_->GetPluginUserMetadata(blankDifferentEsp)); - metadata = db_->GetPluginUserMetadata(blankDifferentEsp); - EXPECT_TRUE(metadata.HasNameOnly()); - - metadata = db_->GetPluginMetadata(blankEsm); + auto metadata = db_->GetPluginMetadata(blankEsm).value(); std::set expectedLoadAfter({ File(masterFile), diff --git a/src/tests/api/interface/game_interface_test.h b/src/tests/api/interface/game_interface_test.h index 7e1c62b7..5465e940 100644 --- a/src/tests/api/interface/game_interface_test.h +++ b/src/tests/api/interface/game_interface_test.h @@ -89,11 +89,11 @@ TEST_P( // Check that one plugin's header has been read. ASSERT_NO_THROW(handle_->GetPlugin(masterFile)); - auto plugin = handle_->GetPlugin(masterFile); - EXPECT_EQ("5.0", plugin->GetVersion()); + auto plugin = handle_->GetPlugin(masterFile).value(); + EXPECT_EQ("5.0", plugin->GetVersion().value()); // Check that only the header has been read. - EXPECT_EQ(0, plugin->GetCRC()); + EXPECT_FALSE(plugin->GetCRC()); } TEST_P(GameInterfaceTest, @@ -103,15 +103,15 @@ TEST_P(GameInterfaceTest, // Check that one plugin's header has been read. ASSERT_NO_THROW(handle_->GetPlugin(masterFile)); - auto plugin = handle_->GetPlugin(masterFile); - EXPECT_EQ("5.0", plugin->GetVersion()); + auto plugin = handle_->GetPlugin(masterFile).value(); + EXPECT_EQ("5.0", plugin->GetVersion().value()); // Check that not only the header has been read. - EXPECT_EQ(blankEsmCrc, plugin->GetCRC()); + EXPECT_EQ(blankEsmCrc, plugin->GetCRC().value()); } -TEST_P(GameInterfaceTest, getPluginThatIsNotCachedShouldThrow) { - EXPECT_THROW(handle_->GetPlugin(blankEsm), std::invalid_argument); +TEST_P(GameInterfaceTest, getPluginThatIsNotCachedShouldReturnAnEmptyOptional) { + EXPECT_FALSE(handle_->GetPlugin(blankEsm)); } TEST_P(GameInterfaceTest, diff --git a/src/tests/api/internals/game/game_cache_test.h b/src/tests/api/internals/game/game_cache_test.h index f2e0a587..925f268b 100644 --- a/src/tests/api/internals/game/game_cache_test.h +++ b/src/tests/api/internals/game/game_cache_test.h @@ -86,7 +86,7 @@ TEST_P(GameCacheTest, addingAPluginThatDoesNotExistShouldSucceed) { game_.GetLoadOrderHandler(), blankEsm, true)); - EXPECT_EQ(blankEsm, cache_.GetPlugin(blankEsm)->GetName()); + EXPECT_EQ(blankEsm, cache_.GetPlugin(blankEsm).value()->GetName()); } TEST_P(GameCacheTest, @@ -97,7 +97,7 @@ TEST_P(GameCacheTest, game_.GetLoadOrderHandler(), blankEsm, true)); - EXPECT_EQ(0, cache_.GetPlugin(blankEsm)->GetCRC()); + EXPECT_FALSE(cache_.GetPlugin(blankEsm).value()->GetCRC()); cache_.AddPlugin(Plugin(game_.Type(), game_.DataPath(), @@ -105,11 +105,11 @@ TEST_P(GameCacheTest, game_.GetLoadOrderHandler(), blankEsm, false)); - EXPECT_EQ(blankEsmCrc, cache_.GetPlugin(blankEsm)->GetCRC()); + EXPECT_EQ(blankEsmCrc, cache_.GetPlugin(blankEsm).value()->GetCRC().value()); } -TEST_P(GameCacheTest, gettingAPluginThatIsNotCachedShouldThrow) { - EXPECT_THROW(cache_.GetPlugin(blankEsm), std::invalid_argument); +TEST_P(GameCacheTest, gettingAPluginThatIsNotCachedShouldReturnAnEmptyOptional) { + EXPECT_FALSE(cache_.GetPlugin(blankEsm)); } TEST_P(GameCacheTest, gettingAPluginShouldBeCaseInsensitive) { @@ -119,7 +119,7 @@ TEST_P(GameCacheTest, gettingAPluginShouldBeCaseInsensitive) { game_.GetLoadOrderHandler(), blankEsm, true)); - EXPECT_EQ(blankEsm, cache_.GetPlugin(blankEsm)->GetName()); + EXPECT_EQ(blankEsm, cache_.GetPlugin(blankEsm).value()->GetName()); } TEST_P(GameCacheTest, diff --git a/src/tests/api/internals/game/game_test.h b/src/tests/api/internals/game/game_test.h index db3d8f83..585f6f62 100644 --- a/src/tests/api/internals/game/game_test.h +++ b/src/tests/api/internals/game/game_test.h @@ -108,11 +108,11 @@ TEST_P( // Check that one plugin's header has been read. ASSERT_NO_THROW(game.GetPlugin(masterFile)); - auto plugin = game.GetPlugin(masterFile); - EXPECT_EQ("5.0", plugin->GetVersion()); + auto plugin = game.GetPlugin(masterFile).value(); + EXPECT_EQ("5.0", plugin->GetVersion().value()); // Check that only the header has been read. - EXPECT_EQ(0, plugin->GetCRC()); + EXPECT_FALSE(plugin->GetCRC()); } TEST_P(GameTest, loadPluginsWithANonPluginShouldNotAddItToTheLoadedPlugins) { @@ -149,11 +149,11 @@ TEST_P(GameTest, // Check that one plugin's header has been read. ASSERT_NO_THROW(game.GetPlugin(blankEsm)); - auto plugin = game.GetPlugin(blankEsm); - EXPECT_EQ("5.0", plugin->GetVersion()); + auto plugin = game.GetPlugin(blankEsm).value(); + EXPECT_EQ("5.0", plugin->GetVersion().value()); // Check that not only the header has been read. - EXPECT_EQ(blankEsmCrc, plugin->GetCRC()); + EXPECT_EQ(blankEsmCrc, plugin->GetCRC().value()); } TEST_P(GameTest, diff --git a/src/tests/api/internals/metadata_list_test.h b/src/tests/api/internals/metadata_list_test.h index 2da0e339..9bf8bc1c 100644 --- a/src/tests/api/internals/metadata_list_test.h +++ b/src/tests/api/internals/metadata_list_test.h @@ -280,13 +280,9 @@ TEST_P(MetadataListTest, setGroupsShouldReplaceExistingGroups) { TEST_P( MetadataListTest, - findPluginShouldReturnAnEmptyPluginObjectIfTheGivenPluginIsNotInTheMetadataList) { + findPluginShouldReturnAnEmptyOptionalIfTheGivenPluginIsNotInTheMetadataList) { MetadataList metadataList; - PluginMetadata plugin = - metadataList.FindPlugin(PluginMetadata(blankDifferentEsm)); - - EXPECT_EQ(blankDifferentEsm, plugin.GetName()); - EXPECT_TRUE(plugin.HasNameOnly()); + EXPECT_FALSE(metadataList.FindPlugin(blankDifferentEsm)); } TEST_P( @@ -296,7 +292,7 @@ TEST_P( ASSERT_NO_THROW(metadataList.Load(metadataPath)); PluginMetadata plugin = - metadataList.FindPlugin(PluginMetadata(blankDifferentEsp)); + metadataList.FindPlugin(blankDifferentEsp).value(); EXPECT_EQ(blankDifferentEsp, plugin.GetName()); EXPECT_EQ(std::set({ @@ -312,14 +308,13 @@ TEST_P( TEST_P(MetadataListTest, addPluginShouldStoreGivenSpecificPluginMetadata) { MetadataList metadataList; ASSERT_NO_THROW(metadataList.Load(metadataPath)); - ASSERT_TRUE( - metadataList.FindPlugin(PluginMetadata(blankDifferentEsm)).HasNameOnly()); + ASSERT_FALSE(metadataList.FindPlugin(blankDifferentEsm)); PluginMetadata plugin(blankDifferentEsm); plugin.SetGroup("group1"); metadataList.AddPlugin(plugin); - plugin = metadataList.FindPlugin(plugin); + plugin = metadataList.FindPlugin(plugin.GetName()).value(); EXPECT_EQ(blankDifferentEsm, plugin.GetName()); EXPECT_EQ("group1", plugin.GetGroup()); @@ -333,7 +328,8 @@ TEST_P(MetadataListTest, addPluginShouldStoreGivenRegexPluginMetadata) { plugin.SetGroup("group1"); metadataList.AddPlugin(plugin); - plugin = metadataList.FindPlugin(PluginMetadata(blankPluginDependentEsp)); + plugin = + metadataList.FindPlugin(blankPluginDependentEsp).value(); EXPECT_EQ("group1", plugin.GetGroup()); } @@ -342,9 +338,8 @@ TEST_P(MetadataListTest, addPluginShouldThrowIfAMatchingPluginAlreadyExists) { MetadataList metadataList; ASSERT_NO_THROW(metadataList.Load(metadataPath)); - PluginMetadata plugin = metadataList.FindPlugin(PluginMetadata(blankEsm)); + PluginMetadata plugin = metadataList.FindPlugin(blankEsm).value(); ASSERT_EQ(blankEsm, plugin.GetName()); - ASSERT_FALSE(plugin.HasNameOnly()); EXPECT_THROW(metadataList.AddPlugin(PluginMetadata(blankEsm)), std::invalid_argument); @@ -355,15 +350,13 @@ TEST_P(MetadataListTest, MetadataList metadataList; ASSERT_NO_THROW(metadataList.Load(metadataPath)); - PluginMetadata plugin = metadataList.FindPlugin(PluginMetadata(blankEsp)); + PluginMetadata plugin = metadataList.FindPlugin(blankEsp).value(); ASSERT_EQ(blankEsp, plugin.GetName()); ASSERT_FALSE(plugin.HasNameOnly()); metadataList.ErasePlugin(plugin); - plugin = metadataList.FindPlugin(plugin); - EXPECT_EQ(blankEsp, plugin.GetName()); - EXPECT_TRUE(plugin.HasNameOnly()); + EXPECT_FALSE(metadataList.FindPlugin(plugin.GetName())); } TEST_P( @@ -378,7 +371,7 @@ TEST_P( MetadataList metadataList; ASSERT_NO_THROW(metadataList.Load(metadataPath)); - PluginMetadata plugin = metadataList.FindPlugin(PluginMetadata(blankEsm)); + PluginMetadata plugin = metadataList.FindPlugin(blankEsm).value(); ASSERT_EQ( std::vector({ Message(MessageType::warn, "This is a warning."), @@ -387,19 +380,19 @@ TEST_P( }), plugin.GetMessages()); - plugin = metadataList.FindPlugin(PluginMetadata(blankEsp)); + plugin = metadataList.FindPlugin(blankEsp).value(); ASSERT_EQ(blankEsp, plugin.GetName()); ASSERT_FALSE(plugin.HasNameOnly()); EXPECT_NO_THROW(metadataList.EvalAllConditions(evaluator)); - plugin = metadataList.FindPlugin(PluginMetadata(blankEsm)); + plugin = metadataList.FindPlugin(blankEsm).value(); EXPECT_EQ(std::vector({ Message(MessageType::warn, "This is a warning."), }), plugin.GetMessages()); - plugin = metadataList.FindPlugin(PluginMetadata(blankEsp)); + plugin = metadataList.FindPlugin(blankEsp).value(); EXPECT_EQ(blankEsp, plugin.GetName()); EXPECT_TRUE(plugin.GetDirtyInfo().empty()); } diff --git a/src/tests/api/internals/plugin_test.h b/src/tests/api/internals/plugin_test.h index 04b22820..8f379bf4 100644 --- a/src/tests/api/internals/plugin_test.h +++ b/src/tests/api/internals/plugin_test.h @@ -92,12 +92,12 @@ class OtherPluginType : public PluginInterface { public: std::string GetName() const { return ""; } std::string GetLowercasedName() const { return ""; } - std::string GetVersion() const { return ""; } + std::optional GetVersion() const { return std::nullopt; } std::vector GetMasters() const { return std::vector(); } std::set GetBashTags() const { return std::set(); } - uint32_t GetCRC() const { return 0; } + std::optional GetCRC() const { return std::nullopt; } bool IsMaster() const { return false; } bool IsLightMaster() const { return false; } @@ -140,7 +140,7 @@ TEST_P(PluginTest, loadingHeaderOnlyShouldNotReadFieldsOrCalculateCrc) { blankEsm, true); - EXPECT_EQ(0, plugin.GetCRC()); + EXPECT_FALSE(plugin.GetCRC()); } TEST_P(PluginTest, loadingWholePluginShouldReadHeaderData) { diff --git a/src/tests/api/internals/sorting/plugin_sorter_test.h b/src/tests/api/internals/sorting/plugin_sorter_test.h index c1ce6a33..49817cdf 100644 --- a/src/tests/api/internals/sorting/plugin_sorter_test.h +++ b/src/tests/api/internals/sorting/plugin_sorter_test.h @@ -146,23 +146,23 @@ TEST_P(PluginSorterTest, ASSERT_NO_THROW(loadInstalledPlugins(game_, false)); auto esp = PluginSortingData( - *dynamic_cast(game_.GetPlugin(blankEsp).get()), + *dynamic_cast(game_.GetPlugin(blankEsp).value().get()), PluginMetadata()); EXPECT_FALSE(esp.IsMaster()); auto master = PluginSortingData( - *dynamic_cast(game_.GetPlugin(blankEsm).get()), + *dynamic_cast(game_.GetPlugin(blankEsm).value().get()), PluginMetadata()); EXPECT_TRUE(master.IsMaster()); if (GetParam() == GameType::fo4 || GetParam() == GameType::tes5se) { auto lightMaster = PluginSortingData( - *dynamic_cast(game_.GetPlugin(blankEsl).get()), + *dynamic_cast(game_.GetPlugin(blankEsl).value().get()), PluginMetadata()); EXPECT_TRUE(lightMaster.IsMaster()); - auto lightMasterEsp = PluginSortingData( - *dynamic_cast(game_.GetPlugin(blankEslEsp).get()), + auto lightMasterEsp = PluginSortingData(*dynamic_cast( + game_.GetPlugin(blankEslEsp).value().get()), PluginMetadata()); EXPECT_FALSE(lightMasterEsp.IsMaster()); }