Add group methods to DatabaseInterface

This commit is contained in:
Oliver Hamlet
2018-03-17 18:26:37 +00:00
parent 343b1133ef
commit fab92f4f55
9 changed files with 246 additions and 2 deletions
+1 -1
View File
@@ -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 "")
+28
View File
@@ -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
+36
View File
@@ -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 {
+4
View File
@@ -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;
+16
View File
@@ -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());
+5
View File
@@ -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());
+42 -1
View File
@@ -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());
}
}
}