mirror of
https://github.com/loot/libloot.git
synced 2026-07-27 14:16:01 -07:00
Add group methods to DatabaseInterface
This commit is contained in:
+1
-1
@@ -125,7 +125,7 @@ set(PSEUDOSEM_INCLUDE_DIRS "${SOURCE_DIR}/include")
|
||||
|
||||
ExternalProject_Add(testing-metadata
|
||||
PREFIX "external"
|
||||
URL "https://github.com/loot/testing-metadata/archive/1.2.0.tar.gz"
|
||||
URL "https://github.com/loot/testing-metadata/archive/1.3.0.tar.gz"
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND ""
|
||||
INSTALL_COMMAND "")
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "loot/metadata/group.h"
|
||||
#include "loot/metadata/message.h"
|
||||
#include "loot/metadata/plugin_metadata.h"
|
||||
#include "loot/struct/masterlist_info.h"
|
||||
@@ -180,6 +181,33 @@ public:
|
||||
virtual std::vector<Message> GetGeneralMessages(
|
||||
bool evaluateConditions = false) const = 0;
|
||||
|
||||
/**
|
||||
* @brief Gets the groups that are defined in the loaded metadata lists.
|
||||
* @returns An unordered set of Group objects.
|
||||
*/
|
||||
virtual std::unordered_set<Group> GetGroups(bool includeUserMetadata = true) const = 0;
|
||||
|
||||
/**
|
||||
* @brief Gets the groups that are defined or extended in the loaded userlist.
|
||||
* @param includeUserMetadata
|
||||
* If true, any group metadata present in the userlist is included in
|
||||
* the returned metadata, otherwise the metadata returned only includes
|
||||
* metadata from the masterlist.
|
||||
* @returns An unordered set of Group objects.
|
||||
*/
|
||||
virtual std::unordered_set<Group> GetUserGroups() const = 0;
|
||||
|
||||
/**
|
||||
* @brief Sets the group definitions to store in the userlist, overwriting any
|
||||
* existing definitions there.
|
||||
* @param groups
|
||||
* The unordered set of Group objects to set.
|
||||
*/
|
||||
virtual void SetUserGroups(const std::unordered_set<Group>& groups) = 0;
|
||||
|
||||
/**
|
||||
* @brief Set the groups
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @name Plugin Data Access
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "api/metadata/condition_evaluator.h"
|
||||
#include "api/metadata/yaml/plugin_metadata.h"
|
||||
#include "api/plugin/plugin_sorter.h"
|
||||
#include "loot/metadata/group.h"
|
||||
#include "loot/exception/file_access_error.h"
|
||||
|
||||
namespace loot {
|
||||
@@ -160,6 +161,41 @@ std::vector<Message> ApiDatabase::GetGeneralMessages(
|
||||
return masterlistMessages;
|
||||
}
|
||||
|
||||
std::unordered_set<Group> ApiDatabase::GetGroups(bool includeUserMetadata) const {
|
||||
if (!includeUserMetadata) {
|
||||
return masterlist_.Groups();
|
||||
}
|
||||
|
||||
std::unordered_set<Group> mergedGroups;
|
||||
|
||||
auto userlistGroups = userlist_.Groups();
|
||||
for (const auto& group : masterlist_.Groups()) {
|
||||
auto userlistGroup = userlistGroups.find(group.GetName());
|
||||
if (userlistGroup != userlistGroups.end()) {
|
||||
auto afterGroups = group.GetAfterGroups();
|
||||
auto userlistAfterGroups = userlistGroup->GetAfterGroups();
|
||||
|
||||
afterGroups.insert(userlistAfterGroups.begin(), userlistAfterGroups.end());
|
||||
mergedGroups.insert(Group(group.GetName(), afterGroups));
|
||||
} else {
|
||||
mergedGroups.insert(group);
|
||||
}
|
||||
}
|
||||
mergedGroups.insert(userlistGroups.begin(), userlistGroups.end());
|
||||
|
||||
// Insert the default group if it's not already present.
|
||||
mergedGroups.insert(Group());
|
||||
|
||||
return mergedGroups;
|
||||
}
|
||||
|
||||
std::unordered_set<Group> ApiDatabase::GetUserGroups() const {
|
||||
return userlist_.Groups();
|
||||
}
|
||||
void ApiDatabase::SetUserGroups(const std::unordered_set<Group>& groups) {
|
||||
userlist_.SetGroups(groups);
|
||||
}
|
||||
|
||||
PluginMetadata ApiDatabase::GetPluginMetadata(const std::string& plugin,
|
||||
bool includeUserMetadata,
|
||||
bool evaluateConditions) const {
|
||||
|
||||
@@ -68,6 +68,10 @@ struct ApiDatabase : public DatabaseInterface {
|
||||
std::vector<Message> GetGeneralMessages(
|
||||
bool evaluateConditions = false) const;
|
||||
|
||||
std::unordered_set<Group> GetGroups(bool includeUserMetadata = true) const;
|
||||
std::unordered_set<Group> GetUserGroups() const;
|
||||
void SetUserGroups(const std::unordered_set<Group>& groups);
|
||||
|
||||
PluginMetadata GetPluginMetadata(const std::string& plugin,
|
||||
bool includeUserMetadata = true,
|
||||
bool evaluateConditions = false) const;
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "api/game/game.h"
|
||||
#include "api/helpers/logging.h"
|
||||
#include "api/metadata/condition_evaluator.h"
|
||||
#include "api/metadata/yaml/group.h"
|
||||
#include "api/metadata/yaml/plugin_metadata.h"
|
||||
#include "loot/exception/file_access_error.h"
|
||||
|
||||
@@ -69,6 +70,11 @@ void MetadataList::Load(const boost::filesystem::path& filepath) {
|
||||
if (metadataList["bash_tags"])
|
||||
bashTags_ = metadataList["bash_tags"].as<std::set<std::string>>();
|
||||
|
||||
if (metadataList["groups"])
|
||||
groups_ = metadataList["groups"].as<std::unordered_set<Group>>();
|
||||
|
||||
groups_.insert(Group());
|
||||
|
||||
if (logger) {
|
||||
logger->debug("File loaded successfully.");
|
||||
}
|
||||
@@ -86,6 +92,9 @@ void MetadataList::Save(const boost::filesystem::path& filepath) const {
|
||||
if (!bashTags_.empty())
|
||||
emitter << YAML::Key << "bash_tags" << YAML::Value << bashTags_;
|
||||
|
||||
if (!groups_.empty())
|
||||
emitter << YAML::Key << "groups" << YAML::Value << groups_;
|
||||
|
||||
if (!messages_.empty())
|
||||
emitter << YAML::Key << "globals" << YAML::Value << messages_;
|
||||
|
||||
@@ -127,6 +136,13 @@ std::vector<Message> MetadataList::Messages() const { return messages_; }
|
||||
|
||||
std::set<std::string> MetadataList::BashTags() const { return bashTags_; }
|
||||
|
||||
std::unordered_set<Group> MetadataList::Groups() const { return groups_; }
|
||||
|
||||
void MetadataList::SetGroups(const std::unordered_set<Group>& groups) {
|
||||
groups_ = groups;
|
||||
groups_.insert(Group());
|
||||
}
|
||||
|
||||
// Merges multiple matching regex entries if any are found.
|
||||
PluginMetadata MetadataList::FindPlugin(const PluginMetadata& plugin) const {
|
||||
PluginMetadata match(plugin.GetName());
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
|
||||
#include "api/metadata/condition_evaluator.h"
|
||||
#include "loot/metadata/plugin_metadata.h"
|
||||
#include "loot/metadata/group.h"
|
||||
|
||||
namespace loot {
|
||||
class MetadataList {
|
||||
@@ -44,6 +45,9 @@ public:
|
||||
std::list<PluginMetadata> Plugins() const;
|
||||
std::vector<Message> Messages() const;
|
||||
std::set<std::string> BashTags() const;
|
||||
std::unordered_set<Group> Groups() const;
|
||||
|
||||
void SetGroups(const std::unordered_set<Group>& groups);
|
||||
|
||||
// Merges multiple matching regex entries if any are found.
|
||||
PluginMetadata FindPlugin(const PluginMetadata& plugin) const;
|
||||
@@ -59,6 +63,7 @@ public:
|
||||
void EvalAllConditions(const ConditionEvaluator& conditionEvaluator);
|
||||
|
||||
protected:
|
||||
std::unordered_set<Group> groups_;
|
||||
std::set<std::string> bashTags_;
|
||||
std::unordered_set<PluginMetadata> plugins_;
|
||||
std::list<PluginMetadata> regexPlugins_;
|
||||
|
||||
@@ -72,6 +72,11 @@ protected:
|
||||
<< " - type: say" << endl
|
||||
<< " content: '" << generalMasterlistMessage << "'" << endl
|
||||
<< " condition: 'file(\"" << missingEsp << "\")'" << endl
|
||||
<< "groups:" << endl
|
||||
<< " - name: group1" << endl
|
||||
<< " - name: group2" << endl
|
||||
<< " after:" << endl
|
||||
<< " - group1" << endl
|
||||
<< "plugins:" << endl
|
||||
<< " - name: " << blankEsm << endl
|
||||
<< " after:" << endl
|
||||
|
||||
@@ -103,6 +103,13 @@ protected:
|
||||
userlist << "bash_tags:" << endl
|
||||
<< " - RaceRelations" << endl
|
||||
<< " - C.Lighting" << endl
|
||||
<< "groups:" << endl
|
||||
<< " - name: group2" << endl
|
||||
<< " after:" << endl
|
||||
<< " - default" << endl
|
||||
<< " - name: group3" << endl
|
||||
<< " after:" << endl
|
||||
<< " - group1" << endl
|
||||
<< "globals:" << endl
|
||||
<< " - type: say" << endl
|
||||
<< " content: '" << generalUserlistMessage << "'" << endl
|
||||
@@ -396,6 +403,108 @@ TEST_P(
|
||||
EXPECT_TRUE(db_->IsLatestMasterlist(masterlistPath.string(), branch_));
|
||||
}
|
||||
|
||||
TEST_P(DatabaseInterfaceTest,
|
||||
getGroupsShouldReturnAllGroupsListedInTheLoadedMetadata) {
|
||||
ASSERT_NO_THROW(GenerateMasterlist());
|
||||
ASSERT_NO_THROW(GenerateUserlist());
|
||||
|
||||
ASSERT_NO_THROW(
|
||||
db_->LoadLists(masterlistPath.string(), userlistPath_.string()));
|
||||
|
||||
auto groups = db_->GetGroups();
|
||||
|
||||
EXPECT_EQ(4, groups.size());
|
||||
|
||||
EXPECT_EQ(1, groups.count(Group("default")));
|
||||
EXPECT_TRUE(groups.find(Group("default"))->GetAfterGroups().empty());
|
||||
|
||||
EXPECT_EQ(1, groups.count(Group("group1")));
|
||||
EXPECT_TRUE(groups.find(Group("group1"))->GetAfterGroups().empty());
|
||||
|
||||
EXPECT_EQ(1, groups.count(Group("group2")));
|
||||
EXPECT_EQ(std::unordered_set<std::string>({ "group1", "default" }), groups.find(Group("group2"))->GetAfterGroups());
|
||||
|
||||
EXPECT_EQ(1, groups.count(Group("group3")));
|
||||
EXPECT_EQ(std::unordered_set<std::string>({ "group1" }), groups.find(Group("group3"))->GetAfterGroups());
|
||||
}
|
||||
|
||||
TEST_P(DatabaseInterfaceTest,
|
||||
getGroupsShouldReturnDefaultGroupEvenIfNoMetadataIsLoaded) {
|
||||
auto groups = db_->GetGroups();
|
||||
|
||||
EXPECT_EQ(1, groups.size());
|
||||
|
||||
EXPECT_EQ("default", groups.begin()->GetName());
|
||||
EXPECT_TRUE(groups.begin()->GetAfterGroups().empty());
|
||||
}
|
||||
|
||||
TEST_P(DatabaseInterfaceTest,
|
||||
getGroupsShouldNotIncludeUserlistMetadataIfParameterIsFalse) {
|
||||
ASSERT_NO_THROW(GenerateMasterlist());
|
||||
ASSERT_NO_THROW(GenerateUserlist());
|
||||
|
||||
ASSERT_NO_THROW(
|
||||
db_->LoadLists(masterlistPath.string(), userlistPath_.string()));
|
||||
|
||||
auto groups = db_->GetGroups(false);
|
||||
|
||||
EXPECT_EQ(3, groups.size());
|
||||
|
||||
EXPECT_EQ(1, groups.count(Group("default")));
|
||||
EXPECT_TRUE(groups.find(Group("default"))->GetAfterGroups().empty());
|
||||
|
||||
EXPECT_EQ(1, groups.count(Group("group1")));
|
||||
EXPECT_TRUE(groups.find(Group("group1"))->GetAfterGroups().empty());
|
||||
|
||||
EXPECT_EQ(1, groups.count(Group("group2")));
|
||||
EXPECT_EQ(std::unordered_set<std::string>({ "group1" }), groups.find(Group("group2"))->GetAfterGroups());
|
||||
}
|
||||
|
||||
TEST_P(DatabaseInterfaceTest,
|
||||
getUserGroupsShouldReturnOnlyGroupMetadataFromTheUserlist) {
|
||||
ASSERT_NO_THROW(GenerateMasterlist());
|
||||
ASSERT_NO_THROW(GenerateUserlist());
|
||||
|
||||
ASSERT_NO_THROW(
|
||||
db_->LoadLists(masterlistPath.string(), userlistPath_.string()));
|
||||
|
||||
auto groups = db_->GetUserGroups();
|
||||
|
||||
EXPECT_EQ(3, groups.size());
|
||||
|
||||
EXPECT_EQ(1, groups.count(Group("default")));
|
||||
EXPECT_TRUE(groups.find(Group("default"))->GetAfterGroups().empty());
|
||||
|
||||
EXPECT_EQ(1, groups.count(Group("group2")));
|
||||
EXPECT_EQ(std::unordered_set<std::string>({ "default" }), groups.find(Group("group2"))->GetAfterGroups());
|
||||
|
||||
EXPECT_EQ(1, groups.count(Group("group3")));
|
||||
EXPECT_EQ(std::unordered_set<std::string>({ "group1" }), groups.find(Group("group3"))->GetAfterGroups());
|
||||
}
|
||||
|
||||
TEST_P(DatabaseInterfaceTest,
|
||||
setUserGroupsShouldReplaceExistingUserGroupMetadataWithTheGivenMetadata) {
|
||||
ASSERT_NO_THROW(GenerateMasterlist());
|
||||
ASSERT_NO_THROW(GenerateUserlist());
|
||||
|
||||
ASSERT_NO_THROW(
|
||||
db_->LoadLists(masterlistPath.string(), userlistPath_.string()));
|
||||
|
||||
db_->SetUserGroups(std::unordered_set<Group>({
|
||||
Group("group4"),
|
||||
}));
|
||||
|
||||
auto groups = db_->GetUserGroups();
|
||||
|
||||
EXPECT_EQ(2, groups.size());
|
||||
|
||||
EXPECT_EQ(1, groups.count(Group("default")));
|
||||
EXPECT_TRUE(groups.find(Group("default"))->GetAfterGroups().empty());
|
||||
|
||||
EXPECT_EQ(1, groups.count(Group("group4")));
|
||||
EXPECT_TRUE(groups.find(Group("group4"))->GetAfterGroups().empty());
|
||||
}
|
||||
|
||||
TEST_P(DatabaseInterfaceTest,
|
||||
getKnownBashTagsShouldReturnAllBashTagsListedInLoadedMetadata) {
|
||||
ASSERT_NO_THROW(GenerateMasterlist());
|
||||
|
||||
@@ -68,6 +68,7 @@ protected:
|
||||
|
||||
const boost::filesystem::path metadataPath;
|
||||
const boost::filesystem::path savedMetadataPath;
|
||||
const boost::filesystem::path groupMetadataPath;
|
||||
const boost::filesystem::path missingMetadataPath;
|
||||
const std::vector<boost::filesystem::path> invalidMetadataPaths;
|
||||
};
|
||||
@@ -118,6 +119,24 @@ TEST_P(MetadataListTest, loadShouldLoadBashTags) {
|
||||
metadataList.BashTags());
|
||||
}
|
||||
|
||||
TEST_P(MetadataListTest, loadShouldLoadGroups) {
|
||||
MetadataList metadataList;
|
||||
ASSERT_NO_THROW(metadataList.Load(metadataPath));
|
||||
|
||||
auto groups = metadataList.Groups();
|
||||
|
||||
EXPECT_EQ(3, groups.size());
|
||||
|
||||
EXPECT_EQ(1, groups.count(Group("default")));
|
||||
EXPECT_TRUE(groups.find(Group("default"))->GetAfterGroups().empty());
|
||||
|
||||
EXPECT_EQ(1, groups.count(Group("group1")));
|
||||
EXPECT_EQ(std::unordered_set<std::string>({ "group2" }), groups.find(Group("group1"))->GetAfterGroups());
|
||||
|
||||
EXPECT_EQ(1, groups.count(Group("group2")));
|
||||
EXPECT_EQ(std::unordered_set<std::string>({ "default" }), groups.find(Group("group2"))->GetAfterGroups());
|
||||
}
|
||||
|
||||
TEST_P(MetadataListTest, loadShouldThrowIfAnInvalidMetadataFileIsGiven) {
|
||||
MetadataList ml;
|
||||
for (const auto& path : invalidMetadataPaths) {
|
||||
@@ -169,6 +188,9 @@ TEST_P(MetadataListTest, saveShouldWriteTheLoadedMetadataToTheGivenFilePath) {
|
||||
EXPECT_EQ(std::set<std::string>({"C.Climate", "Relev"}),
|
||||
metadataList.BashTags());
|
||||
|
||||
EXPECT_EQ(std::unordered_set<Group>({ Group("default"), Group("group1"), Group("group2") }),
|
||||
metadataList.Groups());
|
||||
|
||||
EXPECT_EQ(std::vector<Message>({
|
||||
Message(MessageType::say, "A global message."),
|
||||
}),
|
||||
@@ -206,6 +228,25 @@ TEST_P(MetadataListTest, clearShouldClearLoadedData) {
|
||||
EXPECT_TRUE(metadataList.BashTags().empty());
|
||||
}
|
||||
|
||||
TEST_P(MetadataListTest, setGroupsShouldReplaceExistingGroups) {
|
||||
MetadataList metadataList;
|
||||
ASSERT_NO_THROW(metadataList.Load(metadataPath));
|
||||
|
||||
metadataList.SetGroups({
|
||||
Group("group4")
|
||||
});
|
||||
|
||||
auto groups = metadataList.Groups();
|
||||
|
||||
EXPECT_EQ(2, groups.size());
|
||||
|
||||
EXPECT_EQ(1, groups.count(Group("default")));
|
||||
EXPECT_TRUE(groups.find(Group("default"))->GetAfterGroups().empty());
|
||||
|
||||
EXPECT_EQ(1, groups.count(Group("group4")));
|
||||
EXPECT_TRUE(groups.find(Group("group4"))->GetAfterGroups().empty());
|
||||
}
|
||||
|
||||
TEST_P(
|
||||
MetadataListTest,
|
||||
findPluginShouldReturnAnEmptyPluginObjectIfTheGivenPluginIsNotInTheMetadataList) {
|
||||
@@ -329,7 +370,7 @@ TEST_P(
|
||||
|
||||
plugin = metadataList.FindPlugin(PluginMetadata(blankEsp));
|
||||
EXPECT_EQ(blankEsp, plugin.GetName());
|
||||
EXPECT_TRUE(plugin.HasNameOnly());
|
||||
EXPECT_TRUE(plugin.GetDirtyInfo().empty());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user