nav | integer | ✗ | The number of deleted navmeshes reported for the dirty plugin. If the number is unknown or zero, this field should not be supplied.
diff --git a/resources/l10n/template.pot b/resources/l10n/template.pot
index 499d2b74..ee0f57b0 100644
--- a/resources/l10n/template.pot
+++ b/resources/l10n/template.pot
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: LOOT 0.9.2\n"
"Report-Msgid-Bugs-To: https://github.com/loot/loot/issues\n"
-"POT-Creation-Date: 2016-08-06 16:32+0100\n"
+"POT-Creation-Date: 2016-08-06 16:58+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
@@ -131,132 +131,127 @@ msgstr ""
#: src/gui/html/js/translateStaticText.js:33
#: src/gui/html/js/translateStaticText.js:88
-msgid "Global Priority"
+msgid "Priority"
msgstr ""
#: src/gui/html/js/translateStaticText.js:34
-msgid ""
-"Global priorities are compared against all other plugins. Normal priorities "
-"are compared against only conflicting plugins."
+#: src/gui/html/js/translateStaticText.js:87
+msgid "Global Priority"
msgstr ""
-#: src/gui/html/js/translateStaticText.js:35
-msgid "Priority Value"
-msgstr ""
-
-#: src/gui/html/js/translateStaticText.js:37
+#: src/gui/html/js/translateStaticText.js:36
msgid "Main"
msgstr ""
-#: src/gui/html/js/translateStaticText.js:38
+#: src/gui/html/js/translateStaticText.js:37
msgid "Load After"
msgstr ""
-#: src/gui/html/js/translateStaticText.js:39
+#: src/gui/html/js/translateStaticText.js:38
msgid "Requirements"
msgstr ""
-#: src/gui/html/js/translateStaticText.js:40
+#: src/gui/html/js/translateStaticText.js:39
msgid "Incompatibilities"
msgstr ""
-#: src/gui/html/js/translateStaticText.js:41
+#: src/gui/html/js/translateStaticText.js:40
msgid "Messages"
msgstr ""
-#: src/gui/html/js/translateStaticText.js:42
+#: src/gui/html/js/translateStaticText.js:41
msgid "Bash Tags"
msgstr ""
-#: src/gui/html/js/translateStaticText.js:43
+#: src/gui/html/js/translateStaticText.js:42
msgid "Dirty Plugin Info"
msgstr ""
-#: src/gui/html/js/translateStaticText.js:44
+#: src/gui/html/js/translateStaticText.js:43
msgid "Clean Plugin Info"
msgstr ""
-#: src/gui/html/js/translateStaticText.js:45
+#: src/gui/html/js/translateStaticText.js:44
msgid "Locations"
msgstr ""
+#: src/gui/html/js/translateStaticText.js:46
+#: src/gui/html/js/translateStaticText.js:50
+#: src/gui/html/js/translateStaticText.js:54
+msgid "Filename"
+msgstr ""
+
#: src/gui/html/js/translateStaticText.js:47
#: src/gui/html/js/translateStaticText.js:51
#: src/gui/html/js/translateStaticText.js:55
-msgid "Filename"
+msgid "Display Name"
msgstr ""
#: src/gui/html/js/translateStaticText.js:48
#: src/gui/html/js/translateStaticText.js:52
#: src/gui/html/js/translateStaticText.js:56
-msgid "Display Name"
-msgstr ""
-
-#: src/gui/html/js/translateStaticText.js:49
-#: src/gui/html/js/translateStaticText.js:53
-#: src/gui/html/js/translateStaticText.js:57
-#: src/gui/html/js/translateStaticText.js:61
-#: src/gui/html/js/translateStaticText.js:66
+#: src/gui/html/js/translateStaticText.js:60
+#: src/gui/html/js/translateStaticText.js:65
msgid "Condition"
msgstr ""
-#: src/gui/html/js/translateStaticText.js:59
+#: src/gui/html/js/translateStaticText.js:58
msgid "Type"
msgstr ""
-#: src/gui/html/js/translateStaticText.js:60
+#: src/gui/html/js/translateStaticText.js:59
msgid "Content"
msgstr ""
-#: src/gui/html/js/translateStaticText.js:62
+#: src/gui/html/js/translateStaticText.js:61
#: src/gui/html/js/translateStaticText.js:252
msgid "Language"
msgstr ""
-#: src/gui/html/js/translateStaticText.js:64
+#: src/gui/html/js/translateStaticText.js:63
msgid "Add/Remove"
msgstr ""
-#: src/gui/html/js/translateStaticText.js:65
+#: src/gui/html/js/translateStaticText.js:64
msgid "Bash Tag"
msgstr ""
-#: src/gui/html/js/translateStaticText.js:68
-#: src/gui/html/js/translateStaticText.js:74
+#: src/gui/html/js/translateStaticText.js:67
+#: src/gui/html/js/translateStaticText.js:73
msgid "CRC"
msgstr ""
-#: src/gui/html/js/translateStaticText.js:69
+#: src/gui/html/js/translateStaticText.js:68
msgid "ITM Count"
msgstr ""
-#: src/gui/html/js/translateStaticText.js:70
+#: src/gui/html/js/translateStaticText.js:69
msgid "Deleted References"
msgstr ""
-#: src/gui/html/js/translateStaticText.js:71
+#: src/gui/html/js/translateStaticText.js:70
msgid "Deleted Navmeshes"
msgstr ""
-#: src/gui/html/js/translateStaticText.js:72
-#: src/gui/html/js/translateStaticText.js:75
+#: src/gui/html/js/translateStaticText.js:71
+#: src/gui/html/js/translateStaticText.js:74
msgid "Cleaning Utility"
msgstr ""
-#: src/gui/html/js/translateStaticText.js:77
+#: src/gui/html/js/translateStaticText.js:76
msgid "URL"
msgstr ""
-#: src/gui/html/js/translateStaticText.js:78
+#: src/gui/html/js/translateStaticText.js:77
#: src/gui/html/js/translateStaticText.js:261
msgid "Name"
msgstr ""
-#: src/gui/html/js/translateStaticText.js:80
+#: src/gui/html/js/translateStaticText.js:79
msgid "Save Metadata"
msgstr ""
-#: src/gui/html/js/translateStaticText.js:81
+#: src/gui/html/js/translateStaticText.js:80
#: src/gui/html/js/translateStaticText.js:98
#: src/gui/html/js/translateStaticText.js:182
#: src/gui/html/js/translateStaticText.js:275
@@ -607,14 +602,14 @@ msgstr ""
msgid "Failed to apply plugin metadata. Details: %1%"
msgstr ""
-#: src/gui/query_handler.cpp:598
+#: src/gui/query_handler.cpp:601
msgid ""
"An error occurred while parsing the masterlist: %1%. This probably happened "
"because an update to LOOT changed its metadata syntax support. Try updating "
"your masterlist to resolve the error."
msgstr ""
-#: src/gui/query_handler.cpp:613
+#: src/gui/query_handler.cpp:616
msgid ""
"An error occurred while parsing the userlist: %1%. This probably happened "
"because an update to LOOT changed its metadata syntax support. Your user "
@@ -630,33 +625,33 @@ msgid ""
"[LOOT's website](https://loot.github.io/)."
msgstr ""
-#: src/gui/query_handler.cpp:723 src/gui/query_handler.cpp:726
+#: src/gui/query_handler.cpp:721 src/gui/query_handler.cpp:724
msgid "Failed to get game data. Details: %1%"
msgstr ""
-#: src/gui/query_handler.cpp:808 src/gui/query_handler.cpp:811
+#: src/gui/query_handler.cpp:806 src/gui/query_handler.cpp:809
msgid "Failed to update the masterlist. Details: %1%"
msgstr ""
-#: src/gui/query_handler.cpp:850
+#: src/gui/query_handler.cpp:848
msgid "Loading plugin contents..."
msgstr ""
-#: src/gui/query_handler.cpp:854
+#: src/gui/query_handler.cpp:852
msgid "Sorting load order..."
msgstr ""
-#: src/gui/query_handler.cpp:911
+#: src/gui/query_handler.cpp:909
msgid "Failed to sort plugins. Details: %1%"
msgstr ""
-#: src/gui/query_handler.cpp:941
+#: src/gui/query_handler.cpp:939
msgid ""
"A global message contains a condition that could not be evaluated. Details: "
"%1%"
msgstr ""
-#: src/gui/query_handler.cpp:963 src/backend/plugin/plugin_sorter.cpp:216
+#: src/gui/query_handler.cpp:961 src/backend/plugin/plugin_sorter.cpp:216
msgid "\"%1%\" contains a condition that could not be evaluated. Details: %2%"
msgstr ""
@@ -764,22 +759,16 @@ msgstr ""
msgid "Failed to open file in its default application."
msgstr ""
-#: src/backend/metadata/condition_grammar.h:146
-#: src/backend/metadata/condition_grammar.h:281
-#: src/backend/metadata/condition_grammar.h:365
+#: src/backend/metadata/condition_evaluator.cpp:173
msgid "Invalid file path:"
msgstr ""
-#: src/backend/metadata/condition_grammar.h:187
-#: src/backend/metadata/condition_grammar.h:213
+#: src/backend/metadata/condition_evaluator.cpp:183
+#: src/backend/metadata/condition_evaluator.cpp:223
msgid "Invalid regex string \"%1%\": %2%"
msgstr ""
-#: src/backend/metadata/condition_grammar.h:205
-msgid "Invalid folder path:"
-msgstr ""
-
-#: src/backend/metadata/condition_grammar.h:385
+#: src/backend/metadata/condition_grammar.h:202
msgid "Expected \"%1%\" at \"%2%\"."
msgstr ""
@@ -793,39 +782,37 @@ msgstr ""
msgid "Failed to parse condition \"%1%\"."
msgstr ""
-#: src/backend/metadata/plugin_cleaning_data.cpp:71
-msgid ""
-"Contains %1% ITM records, %2% deleted references and %3% deleted navmeshes. "
-"Clean with %4%."
-msgstr ""
-
-#: src/backend/metadata/plugin_cleaning_data.cpp:73
-msgid "Clean with %1%."
-msgstr ""
-
-#: src/backend/metadata/plugin_cleaning_data.cpp:76
-msgid ""
-"Contains %1% deleted references and %2% deleted navmeshes. Clean with %3%."
-msgstr ""
-
-#: src/backend/metadata/plugin_cleaning_data.cpp:78
-msgid "Contains %1% deleted navmeshes. Clean with %2%."
-msgstr ""
-
-#: src/backend/metadata/plugin_cleaning_data.cpp:80
-msgid "Contains %1% deleted references. Clean with %2%."
-msgstr ""
-
-#: src/backend/metadata/plugin_cleaning_data.cpp:83
-msgid "Contains %1% ITM records and %2% deleted navmeshes. Clean with %3%."
-msgstr ""
-
-#: src/backend/metadata/plugin_cleaning_data.cpp:85
-msgid "Contains %1% ITM records. Clean with %2%."
-msgstr ""
-
#: src/backend/metadata/plugin_cleaning_data.cpp:88
-msgid "Contains %1% ITM records and %2% deleted references. Clean with %3%."
+msgid ""
+"%1% found %2% ITM records, %3% deleted references and %4% deleted navmeshes."
+msgstr ""
+
+#: src/backend/metadata/plugin_cleaning_data.cpp:90
+msgid "%1% found dirty edits."
+msgstr ""
+
+#: src/backend/metadata/plugin_cleaning_data.cpp:93
+msgid "%1% found %2% deleted references and %3% deleted navmeshes."
+msgstr ""
+
+#: src/backend/metadata/plugin_cleaning_data.cpp:95
+msgid "%1% found %2% deleted navmeshes."
+msgstr ""
+
+#: src/backend/metadata/plugin_cleaning_data.cpp:97
+msgid "%1% found %2% deleted references."
+msgstr ""
+
+#: src/backend/metadata/plugin_cleaning_data.cpp:100
+msgid "%1% found %2% ITM records and %3% deleted navmeshes."
+msgstr ""
+
+#: src/backend/metadata/plugin_cleaning_data.cpp:102
+msgid "%1% found %2% ITM records."
+msgstr ""
+
+#: src/backend/metadata/plugin_cleaning_data.cpp:105
+msgid "%1% found %2% ITM records and %3% deleted references."
msgstr ""
#: src/backend/plugin/plugin.cpp:115
diff --git a/src/backend/metadata/message.cpp b/src/backend/metadata/message.cpp
index 293d0d19..9694fbb5 100644
--- a/src/backend/metadata/message.cpp
+++ b/src/backend/metadata/message.cpp
@@ -73,20 +73,7 @@ bool Message::EvalCondition(loot::Game& game, const Language::Code language) {
MessageContent Message::ChooseContent(const Language::Code language) const {
BOOST_LOG_TRIVIAL(trace) << "Choosing message content.";
- if (content_.empty())
- return MessageContent();
- else if (content_.size() == 1)
- return content_[0];
- else {
- MessageContent english;
- for (const auto &mc : content_) {
- if (mc.GetLanguage() == language) {
- return mc;
- } else if (mc.GetLanguage() == Language::Code::english)
- english = mc;
- }
- return english;
- }
+ return MessageContent::Choose(content_, language);
}
Message::Type Message::GetType() const {
diff --git a/src/backend/metadata/message_content.cpp b/src/backend/metadata/message_content.cpp
index 986d3381..de6c521d 100644
--- a/src/backend/metadata/message_content.cpp
+++ b/src/backend/metadata/message_content.cpp
@@ -48,6 +48,23 @@ bool MessageContent::operator < (const MessageContent& rhs) const {
bool MessageContent::operator == (const MessageContent& rhs) const {
return (boost::iequals(text_, rhs.GetText()));
}
+MessageContent MessageContent::Choose(const std::vector content,
+ const Language::Code language) {
+ if (content.empty())
+ return MessageContent();
+ else if (content.size() == 1)
+ return content[0];
+ else {
+ MessageContent english;
+ for (const auto &mc : content) {
+ if (mc.GetLanguage() == language) {
+ return mc;
+ } else if (mc.GetLanguage() == Language::Code::english)
+ english = mc;
+ }
+ return english;
+ }
+}
}
namespace YAML {
diff --git a/src/backend/metadata/message_content.h b/src/backend/metadata/message_content.h
index ce55ad5b..28f2d858 100644
--- a/src/backend/metadata/message_content.h
+++ b/src/backend/metadata/message_content.h
@@ -41,6 +41,9 @@ public:
bool operator < (const MessageContent& rhs) const;
bool operator == (const MessageContent& rhs) const;
+
+ static MessageContent Choose(const std::vector content,
+ const Language::Code language);
private:
std::string text_;
Language::Code language_;
diff --git a/src/backend/metadata/plugin_cleaning_data.cpp b/src/backend/metadata/plugin_cleaning_data.cpp
index f4fdc6dc..308399f2 100644
--- a/src/backend/metadata/plugin_cleaning_data.cpp
+++ b/src/backend/metadata/plugin_cleaning_data.cpp
@@ -26,6 +26,7 @@
#include
#include
+#include
#include "backend/game/game.h"
#include "backend/helpers/helpers.h"
@@ -33,9 +34,16 @@
namespace loot {
PluginCleaningData::PluginCleaningData() : crc_(0), itm_(0), ref_(0), nav_(0) {}
-PluginCleaningData::PluginCleaningData(uint32_t crc, const std::string& utility) : crc_(crc), utility_(utility), itm_(0), ref_(0), nav_(0) {}
+PluginCleaningData::PluginCleaningData(uint32_t crc, const std::string& utility)
+ : crc_(crc), utility_(utility), itm_(0), ref_(0), nav_(0) {}
-PluginCleaningData::PluginCleaningData(uint32_t crc, unsigned int itm, unsigned int ref, unsigned int nav, const std::string& utility) : crc_(crc), itm_(itm), ref_(ref), nav_(nav), utility_(utility) {}
+PluginCleaningData::PluginCleaningData(uint32_t crc,
+ const std::string& utility,
+ const std::vector& info,
+ unsigned int itm,
+ unsigned int ref,
+ unsigned int nav)
+ : crc_(crc), itm_(itm), ref_(ref), nav_(nav), utility_(utility), info_(info) {}
bool PluginCleaningData::operator < (const PluginCleaningData& rhs) const {
return crc_ < rhs.CRC();
@@ -65,29 +73,44 @@ std::string PluginCleaningData::CleaningUtility() const {
return utility_;
}
+std::vector PluginCleaningData::Info() const {
+ return info_;
+}
+
+MessageContent PluginCleaningData::ChooseInfo(const Language::Code language) const {
+ BOOST_LOG_TRIVIAL(trace) << "Choosing dirty info content.";
+ return MessageContent::Choose(info_, language);
+}
+
Message PluginCleaningData::AsMessage() const {
boost::format f;
- if (this->itm_ > 0 && this->ref_ > 0 && this->nav_ > 0)
- f = boost::format(boost::locale::translate("Contains %1% ITM records, %2% deleted references and %3% deleted navmeshes. Clean with %4%.")) % this->itm_ % this->ref_ % this->nav_ % this->utility_;
- else if (this->itm_ == 0 && this->ref_ == 0 && this->nav_ == 0)
- f = boost::format(boost::locale::translate("Clean with %1%.")) % this->utility_;
+ if (itm_ > 0 && ref_ > 0 && nav_ > 0)
+ f = boost::format(boost::locale::translate("%1% found %2% ITM records, %3% deleted references and %4% deleted navmeshes.")) % utility_ % itm_ % ref_ % nav_;
+ else if (itm_ == 0 && ref_ == 0 && nav_ == 0)
+ f = boost::format(boost::locale::translate("%1% found dirty edits.")) % utility_;
- else if (this->itm_ == 0 && this->ref_ > 0 && this->nav_ > 0)
- f = boost::format(boost::locale::translate("Contains %1% deleted references and %2% deleted navmeshes. Clean with %3%.")) % this->ref_ % this->nav_ % this->utility_;
- else if (this->itm_ == 0 && this->ref_ == 0 && this->nav_ > 0)
- f = boost::format(boost::locale::translate("Contains %1% deleted navmeshes. Clean with %2%.")) % this->nav_ % this->utility_;
- else if (this->itm_ == 0 && this->ref_ > 0 && this->nav_ == 0)
- f = boost::format(boost::locale::translate("Contains %1% deleted references. Clean with %2%.")) % this->ref_ % this->utility_;
+ else if (itm_ == 0 && ref_ > 0 && nav_ > 0)
+ f = boost::format(boost::locale::translate("%1% found %2% deleted references and %3% deleted navmeshes.")) % utility_ % ref_ % nav_;
+ else if (itm_ == 0 && ref_ == 0 && nav_ > 0)
+ f = boost::format(boost::locale::translate("%1% found %2% deleted navmeshes.")) % utility_ % nav_;
+ else if (itm_ == 0 && ref_ > 0 && nav_ == 0)
+ f = boost::format(boost::locale::translate("%1% found %2% deleted references.")) % utility_ % ref_;
- else if (this->itm_ > 0 && this->ref_ == 0 && this->nav_ > 0)
- f = boost::format(boost::locale::translate("Contains %1% ITM records and %2% deleted navmeshes. Clean with %3%.")) % this->itm_ % this->nav_ % this->utility_;
- else if (this->itm_ > 0 && this->ref_ == 0 && this->nav_ == 0)
- f = boost::format(boost::locale::translate("Contains %1% ITM records. Clean with %2%.")) % this->itm_ % this->utility_;
+ else if (itm_ > 0 && ref_ == 0 && nav_ > 0)
+ f = boost::format(boost::locale::translate("%1% found %2% ITM records and %3% deleted navmeshes.")) % utility_ % itm_ % nav_;
+ else if (itm_ > 0 && ref_ == 0 && nav_ == 0)
+ f = boost::format(boost::locale::translate("%1% found %2% ITM records.")) % utility_ % itm_;
- else if (this->itm_ > 0 && this->ref_ > 0 && this->nav_ == 0)
- f = boost::format(boost::locale::translate("Contains %1% ITM records and %2% deleted references. Clean with %3%.")) % this->itm_ % this->ref_ % this->utility_;
+ else if (itm_ > 0 && ref_ > 0 && nav_ == 0)
+ f = boost::format(boost::locale::translate("%1% found %2% ITM records and %3% deleted references.")) % utility_ % itm_ % ref_;
- return Message(Message::Type::warn, f.str());
+ std::string message = f.str();
+ auto info = info_;
+ for (auto& content : info) {
+ content = MessageContent(message + " " + content.GetText(), content.GetLanguage());
+ }
+
+ return Message(Message::Type::warn, info);
}
bool PluginCleaningData::EvalCondition(Game& game, const std::string& pluginName) const {
@@ -119,7 +142,14 @@ namespace YAML {
Emitter& operator << (Emitter& out, const loot::PluginCleaningData& rhs) {
out << BeginMap
<< Key << "crc" << Value << Hex << rhs.CRC() << Dec
- << Key << "util" << Value << YAML::SingleQuoted << rhs.CleaningUtility();
+ << Key << "utility" << Value << YAML::SingleQuoted << rhs.CleaningUtility();
+
+ if (!rhs.Info().empty()) {
+ if (rhs.Info().size() == 1)
+ out << Key << "info" << Value << YAML::SingleQuoted << rhs.Info().front().GetText();
+ else
+ out << Key << "info" << Value << rhs.Info();
+ }
if (rhs.ITMs() > 0)
out << Key << "itm" << Value << rhs.ITMs();
diff --git a/src/backend/metadata/plugin_cleaning_data.h b/src/backend/metadata/plugin_cleaning_data.h
index b5d979a1..65e84a0c 100644
--- a/src/backend/metadata/plugin_cleaning_data.h
+++ b/src/backend/metadata/plugin_cleaning_data.h
@@ -39,7 +39,12 @@ class PluginCleaningData {
public:
PluginCleaningData();
PluginCleaningData(uint32_t crc, const std::string& utility);
- PluginCleaningData(uint32_t crc, unsigned int itm, unsigned int ref, unsigned int nav, const std::string& utility);
+ PluginCleaningData(uint32_t crc,
+ const std::string& utility,
+ const std::vector& info,
+ unsigned int itm,
+ unsigned int ref,
+ unsigned int nav);
bool operator < (const PluginCleaningData& rhs) const;
bool operator == (const PluginCleaningData& rhs) const;
@@ -49,7 +54,9 @@ public:
unsigned int DeletedRefs() const;
unsigned int DeletedNavmeshes() const;
std::string CleaningUtility() const;
+ std::vector Info() const;
+ MessageContent ChooseInfo(const Language::Code language) const;
Message AsMessage() const;
bool EvalCondition(Game& game, const std::string& pluginName) const;
@@ -59,6 +66,7 @@ private:
unsigned int ref_;
unsigned int nav_;
std::string utility_;
+ std::vector info_;
};
}
@@ -68,7 +76,8 @@ struct convert {
static Node encode(const loot::PluginCleaningData& rhs) {
Node node;
node["crc"] = rhs.CRC();
- node["util"] = rhs.CleaningUtility();
+ node["utility"] = rhs.CleaningUtility();
+ node["info"] = rhs.Info();
if (rhs.ITMs() > 0)
node["itm"] = rhs.ITMs();
@@ -85,7 +94,7 @@ struct convert {
throw RepresentationException(node.Mark(), "bad conversion: 'cleaning data' object must be a map");
if (!node["crc"])
throw RepresentationException(node.Mark(), "bad conversion: 'crc' key missing from 'cleaning data' object");
- if (!node["util"])
+ if (!node["utility"])
throw RepresentationException(node.Mark(), "bad conversion: 'util' key missing from 'cleaning data' object");
uint32_t crc = node["crc"].as();
@@ -98,9 +107,29 @@ struct convert {
if (node["nav"])
nav = node["nav"].as();
- std::string utility = node["util"].as();
+ std::string utility = node["utility"].as();
- rhs = loot::PluginCleaningData(crc, itm, ref, nav, utility);
+ std::vector info;
+ if (node["info"]) {
+ if (node["info"].IsSequence())
+ info = node["info"].as>();
+ else {
+ info.push_back(loot::MessageContent(node["info"].as(), loot::Language::Code::english));
+ }
+ }
+
+ //Check now that at least one item in info is English if there are multiple items.
+ if (info.size() > 1) {
+ bool found = false;
+ for (const auto &mc : info) {
+ if (mc.GetLanguage() == loot::Language::Code::english)
+ found = true;
+ }
+ if (!found)
+ throw RepresentationException(node.Mark(), "bad conversion: multilingual messages must contain an English info string");
+ }
+
+ rhs = loot::PluginCleaningData(crc, utility, info, itm, ref, nav);
return true;
}
diff --git a/src/backend/plugin/plugin.cpp b/src/backend/plugin/plugin.cpp
index 7e414499..1530e745 100644
--- a/src/backend/plugin/plugin.cpp
+++ b/src/backend/plugin/plugin.cpp
@@ -171,11 +171,11 @@ bool Plugin::IsValid(const std::string& filename, const Game& game) {
else
name = filename;
-// Check that the file has a valid extension.
+ // Check that the file has a valid extension.
if (!boost::iends_with(name, ".esm") && !boost::iends_with(name, ".esp"))
return false;
-// Add the ".ghost" file extension if the plugin is ghosted.
+ // Add the ".ghost" file extension if the plugin is ghosted.
boost::filesystem::path filepath = game.DataPath() / name;
if (!boost::filesystem::exists(filepath) && boost::filesystem::exists(filepath.string() + ".ghost"))
filepath += ".ghost";
@@ -199,7 +199,7 @@ uint32_t Plugin::Crc() const {
return crc_;
}
-bool Plugin::CheckInstallValidity(const Game& game) {
+void Plugin::CheckInstallValidity(const Game& game) {
BOOST_LOG_TRIVIAL(trace) << "Checking that the current install is valid according to " << Name() << "'s data.";
if (IsActive()) {
auto pluginExists = [](const Game& game, const std::string& file) {
@@ -236,8 +236,6 @@ bool Plugin::CheckInstallValidity(const Game& game) {
for (const auto &element : DirtyInfo()) {
messages_.push_back(element.AsMessage());
}
-
- return !DirtyInfo().empty();
}
bool Plugin::LoadsArchive() const {
diff --git a/src/backend/plugin/plugin.h b/src/backend/plugin/plugin.h
index fb30d93b..c6400fd0 100644
--- a/src/backend/plugin/plugin.h
+++ b/src/backend/plugin/plugin.h
@@ -58,8 +58,9 @@ public:
bool DoFormIDsOverlap(const Plugin& plugin) const;
std::set OverlapFormIDs(const Plugin& plugin) const;
- //Validity checks.
- bool CheckInstallValidity(const Game& game); //Checks that reqs and masters are all present, and that no incs are present. Returns true if the plugin is dirty.
+ // Validity checks.
+ // Checks that reqs and masters are all present, and that no incs are present.
+ void CheckInstallValidity(const Game& game);
static bool IsValid(const std::string& filename, const Game& game);
bool operator < (const Plugin& rhs) const;
diff --git a/src/gui/query_handler.cpp b/src/gui/query_handler.cpp
index 29e56475..fed99b38 100644
--- a/src/gui/query_handler.cpp
+++ b/src/gui/query_handler.cpp
@@ -963,7 +963,7 @@ YAML::Node QueryHandler::GenerateDerivedMetadata(const Plugin& file, const Plugi
}
//Also check install validity.
- bool isDirty = tempPlugin.CheckInstallValidity(lootState_.getCurrentGame());
+ tempPlugin.CheckInstallValidity(lootState_.getCurrentGame());
// Now add to pluginNode.
YAML::Node pluginNode;
@@ -972,7 +972,7 @@ YAML::Node QueryHandler::GenerateDerivedMetadata(const Plugin& file, const Plugi
pluginNode["globalPriority"] = tempPlugin.GlobalPriority().getValue();
pluginNode["messages"] = tempPlugin.Messages();
pluginNode["tags"] = tempPlugin.Tags();
- pluginNode["isDirty"] = isDirty;
+ pluginNode["isDirty"] = !tempPlugin.DirtyInfo().empty();
pluginNode["loadOrderIndex"] = lootState_.getCurrentGame().GetActiveLoadOrderIndex(tempPlugin.Name());
if (!tempPlugin.CleanInfo().empty()) {
diff --git a/src/tests/api/api_game_operations_test.h b/src/tests/api/api_game_operations_test.h
index d8857472..25c31bbb 100644
--- a/src/tests/api/api_game_operations_test.h
+++ b/src/tests/api/api_game_operations_test.h
@@ -84,7 +84,7 @@ protected:
<< " content: '" << warningMessage << "'" << endl
<< " dirty:" << endl
<< " - crc: 0x7d22f9df" << endl
- << " util: TES4Edit" << endl
+ << " utility: TES4Edit" << endl
<< " udr: 4" << endl
<< " - name: " << blankDifferentEsp << endl
<< " after:" << endl
diff --git a/src/tests/api/loot_get_masterlist_revision_test.h b/src/tests/api/loot_get_masterlist_revision_test.h
index b411ab6b..d98c7a11 100644
--- a/src/tests/api/loot_get_masterlist_revision_test.h
+++ b/src/tests/api/loot_get_masterlist_revision_test.h
@@ -34,11 +34,13 @@ namespace test {
class loot_get_masterlist_revision_test : public ApiGameOperationsTest {
protected:
loot_get_masterlist_revision_test() :
+ branch_("2.x"),
revisionId_("foo"),
revisionDate_("bar"),
isModified_(true),
updated_(false) {}
+ const std::string branch_;
const char * revisionId_;
const char * revisionDate_;
bool isModified_;
@@ -80,7 +82,7 @@ TEST_P(loot_get_masterlist_revision_test, shouldSucceedIfANonVersionControlledMa
}
TEST_P(loot_get_masterlist_revision_test, shouldOutputLongStringsAndBooleanFalseIfAVersionControlledMasterlistIsPresentAndGetShortIdParameterIsFalse) {
- ASSERT_EQ(loot_ok, loot_update_masterlist(db_, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "master", &updated_));
+ ASSERT_EQ(loot_ok, loot_update_masterlist(db_, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", branch_.c_str(), &updated_));
EXPECT_EQ(loot_ok, loot_get_masterlist_revision(db_, masterlistPath.string().c_str(), false, &revisionId_, &revisionDate_, &isModified_));
EXPECT_STRNE(NULL, revisionId_);
@@ -91,7 +93,7 @@ TEST_P(loot_get_masterlist_revision_test, shouldOutputLongStringsAndBooleanFalse
}
TEST_P(loot_get_masterlist_revision_test, shouldOutputShortStringsAndBooleanFalseIfAVersionControlledMasterlistIsPresentAndGetShortIdParameterIsTrue) {
- ASSERT_EQ(loot_ok, loot_update_masterlist(db_, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "master", &updated_));
+ ASSERT_EQ(loot_ok, loot_update_masterlist(db_, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", branch_.c_str(), &updated_));
EXPECT_EQ(loot_ok, loot_get_masterlist_revision(db_, masterlistPath.string().c_str(), false, &revisionId_, &revisionDate_, &isModified_));
EXPECT_STRNE(NULL, revisionId_);
@@ -103,7 +105,7 @@ TEST_P(loot_get_masterlist_revision_test, shouldOutputShortStringsAndBooleanFals
}
TEST_P(loot_get_masterlist_revision_test, shouldSucceedIfAnEditedVersionControlledMasterlistIsPresent) {
- ASSERT_EQ(loot_ok, loot_update_masterlist(db_, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "master", &updated_));
+ ASSERT_EQ(loot_ok, loot_update_masterlist(db_, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", branch_.c_str(), &updated_));
ASSERT_NO_THROW(GenerateMasterlist());
EXPECT_EQ(loot_ok, loot_get_masterlist_revision(db_, masterlistPath.string().c_str(), false, &revisionId_, &revisionDate_, &isModified_));
diff --git a/src/tests/api/loot_update_masterlist_test.h b/src/tests/api/loot_update_masterlist_test.h
index 15660ae3..0f1b4824 100644
--- a/src/tests/api/loot_update_masterlist_test.h
+++ b/src/tests/api/loot_update_masterlist_test.h
@@ -34,6 +34,7 @@ namespace test {
class loot_update_masterlist_test : public ApiGameOperationsTest {
protected:
loot_update_masterlist_test() :
+ branch_("2.x"),
updated_(false) {}
inline void TearDown() {
@@ -43,6 +44,7 @@ protected:
ASSERT_NO_THROW(boost::filesystem::remove_all(masterlistPath.parent_path() / ".git"));
}
+ const std::string branch_;
bool updated_;
};
@@ -58,27 +60,27 @@ INSTANTIATE_TEST_CASE_P(,
loot_game_fo4));
TEST_P(loot_update_masterlist_test, shouldReturnAnInvalidArgsErrorIfAnyOfTheArgumentsAreNull) {
- EXPECT_EQ(loot_error_invalid_args, loot_update_masterlist(NULL, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "master", &updated_));
- EXPECT_EQ(loot_error_invalid_args, loot_update_masterlist(db_, NULL, "https://github.com/loot/testing-metadata.git", "master", &updated_));
- EXPECT_EQ(loot_error_invalid_args, loot_update_masterlist(db_, masterlistPath.string().c_str(), NULL, "master", &updated_));
+ EXPECT_EQ(loot_error_invalid_args, loot_update_masterlist(NULL, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", branch_.c_str(), &updated_));
+ EXPECT_EQ(loot_error_invalid_args, loot_update_masterlist(db_, NULL, "https://github.com/loot/testing-metadata.git", branch_.c_str(), &updated_));
+ EXPECT_EQ(loot_error_invalid_args, loot_update_masterlist(db_, masterlistPath.string().c_str(), NULL, branch_.c_str(), &updated_));
EXPECT_EQ(loot_error_invalid_args, loot_update_masterlist(db_, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", NULL, &updated_));
- EXPECT_EQ(loot_error_invalid_args, loot_update_masterlist(db_, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "master", NULL));
+ EXPECT_EQ(loot_error_invalid_args, loot_update_masterlist(db_, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", branch_.c_str(), NULL));
}
TEST_P(loot_update_masterlist_test, shouldReturnAnInvalidArgsErrorIfTheMasterlistPathGivenIsInvalid) {
- EXPECT_EQ(loot_error_invalid_args, loot_update_masterlist(db_, ";//\?", "https://github.com/loot/testing-metadata.git", "master", &updated_));
+ EXPECT_EQ(loot_error_invalid_args, loot_update_masterlist(db_, ";//\?", "https://github.com/loot/testing-metadata.git", branch_.c_str(), &updated_));
}
TEST_P(loot_update_masterlist_test, shouldReturnAnInvalidArgsErrorIfTheMasterlistPathGivenIsEmpty) {
- EXPECT_EQ(loot_error_invalid_args, loot_update_masterlist(db_, "", "https://github.com/loot/testing-metadata.git", "master", &updated_));
+ EXPECT_EQ(loot_error_invalid_args, loot_update_masterlist(db_, "", "https://github.com/loot/testing-metadata.git", branch_.c_str(), &updated_));
}
TEST_P(loot_update_masterlist_test, shouldReturnAGitErrorIfTheRepositoryUrlGivenCannotBeFound) {
- EXPECT_EQ(loot_error_git_error, loot_update_masterlist(db_, masterlistPath.string().c_str(), "https://github.com/loot/oblivion-does-not-exist.git", "master", &updated_));
+ EXPECT_EQ(loot_error_git_error, loot_update_masterlist(db_, masterlistPath.string().c_str(), "https://github.com/loot/oblivion-does-not-exist.git", branch_.c_str(), &updated_));
}
TEST_P(loot_update_masterlist_test, shouldReturnAnInvalidArgsErrorIfTheRepositoryUrlGivenIsEmpty) {
- EXPECT_EQ(loot_error_invalid_args, loot_update_masterlist(db_, masterlistPath.string().c_str(), "", "master", &updated_));
+ EXPECT_EQ(loot_error_invalid_args, loot_update_masterlist(db_, masterlistPath.string().c_str(), "", branch_.c_str(), &updated_));
}
TEST_P(loot_update_masterlist_test, shouldReturnAGitErrorIfTheRepositoryBranchGivenCannotBeFound) {
@@ -90,16 +92,16 @@ TEST_P(loot_update_masterlist_test, shouldReturnAnInvalidArgsErrorIfTheRepositor
}
TEST_P(loot_update_masterlist_test, shouldSucceedIfPassedValidParametersAndOutputTrueIfTheMasterlistWasUpdated) {
- EXPECT_EQ(loot_ok, loot_update_masterlist(db_, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "master", &updated_));
+ EXPECT_EQ(loot_ok, loot_update_masterlist(db_, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", branch_.c_str(), &updated_));
EXPECT_TRUE(updated_);
EXPECT_TRUE(boost::filesystem::exists(masterlistPath));
}
TEST_P(loot_update_masterlist_test, shouldSucceedIfCalledRepeatedlyButOnlyOutputTrueForTheFirstCall) {
- EXPECT_EQ(loot_ok, loot_update_masterlist(db_, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "master", &updated_));
+ EXPECT_EQ(loot_ok, loot_update_masterlist(db_, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", branch_.c_str(), &updated_));
EXPECT_TRUE(updated_);
- EXPECT_EQ(loot_ok, loot_update_masterlist(db_, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "master", &updated_));
+ EXPECT_EQ(loot_ok, loot_update_masterlist(db_, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", branch_.c_str(), &updated_));
EXPECT_FALSE(updated_);
EXPECT_TRUE(boost::filesystem::exists(masterlistPath));
}
diff --git a/src/tests/api/loot_write_minimal_list_test.h b/src/tests/api/loot_write_minimal_list_test.h
index 54ecd7d5..0ba4ca32 100644
--- a/src/tests/api/loot_write_minimal_list_test.h
+++ b/src/tests/api/loot_write_minimal_list_test.h
@@ -68,7 +68,7 @@ protected:
<< " - name: '" << blankDifferentEsm << "'" << endl
<< " dirty:" << endl
<< " - crc: 0x7d22f9df" << endl
- << " util: 'TES4Edit'" << endl
+ << " utility: 'TES4Edit'" << endl
<< " udr: 4";
return expectedContent.str();
diff --git a/src/tests/backend/masterlist_test.h b/src/tests/backend/masterlist_test.h
index 0cb6af8c..0e5021ff 100644
--- a/src/tests/backend/masterlist_test.h
+++ b/src/tests/backend/masterlist_test.h
@@ -35,7 +35,7 @@ namespace test {
class MasterlistTest : public BaseGameTest {
protected:
MasterlistTest() :
- repoBranch("master"),
+ repoBranch("2.x"),
repoUrl("https://github.com/loot/testing-metadata.git"),
masterlistPath(localPath / "masterlist.yaml") {}
diff --git a/src/tests/backend/metadata/plugin_cleaning_data_test.h b/src/tests/backend/metadata/plugin_cleaning_data_test.h
index c11010ab..33b3c480 100644
--- a/src/tests/backend/metadata/plugin_cleaning_data_test.h
+++ b/src/tests/backend/metadata/plugin_cleaning_data_test.h
@@ -32,7 +32,14 @@ along with LOOT. If not, see
namespace loot {
namespace test {
-class PluginCleaningDataTest : public BaseGameTest {};
+class PluginCleaningDataTest : public BaseGameTest {
+protected:
+ PluginCleaningDataTest() : info_(std::vector({
+ MessageContent("info", Language::Code::english),
+ })) {}
+
+ const std::vector info_;
+};
// Pass an empty first argument, as it's a prefix for the test instantation,
// but we only have the one so no prefix is necessary.
@@ -48,69 +55,71 @@ TEST_P(PluginCleaningDataTest, defaultConstructorShouldLeaveAllCountsAtZeroAndTh
EXPECT_EQ(0, info.DeletedRefs());
EXPECT_EQ(0, info.DeletedNavmeshes());
EXPECT_TRUE(info.CleaningUtility().empty());
+ EXPECT_TRUE(info.Info().empty());
}
TEST_P(PluginCleaningDataTest, contentConstructorShouldStoreAllGivenData) {
- PluginCleaningData info(0x12345678, 2, 10, 30, "cleaner");
+ PluginCleaningData info(0x12345678, "cleaner", info_, 2, 10, 30);
EXPECT_EQ(0x12345678, info.CRC());
EXPECT_EQ(2, info.ITMs());
EXPECT_EQ(10, info.DeletedRefs());
EXPECT_EQ(30, info.DeletedNavmeshes());
EXPECT_EQ("cleaner", info.CleaningUtility());
+ EXPECT_EQ(info_, info.Info());
}
TEST_P(PluginCleaningDataTest, asMessageShouldOutputAllNonZeroCounts) {
- Message message = PluginCleaningData(0x12345678, 2, 10, 30, "cleaner").AsMessage();
+ Message message = PluginCleaningData(0x12345678, "cleaner", info_, 2, 10, 30).AsMessage();
EXPECT_EQ(Message::Type::warn, message.GetType());
- EXPECT_EQ("Contains 2 ITM records, 10 deleted references and 30 deleted navmeshes. Clean with cleaner.", message.ChooseContent(Language::Code::english).GetText());
+ EXPECT_EQ("cleaner found 2 ITM records, 10 deleted references and 30 deleted navmeshes. info", message.ChooseContent(Language::Code::english).GetText());
- message = PluginCleaningData(0x12345678, 0, 0, 0, "cleaner").AsMessage();
+ message = PluginCleaningData(0x12345678, "cleaner", info_, 0, 0, 0).AsMessage();
EXPECT_EQ(Message::Type::warn, message.GetType());
- EXPECT_EQ("Clean with cleaner.", message.ChooseContent(Language::Code::english).GetText());
+ EXPECT_EQ("cleaner found dirty edits. info", message.ChooseContent(Language::Code::english).GetText());
- message = PluginCleaningData(0x12345678, 0, 10, 30, "cleaner").AsMessage();
+ message = PluginCleaningData(0x12345678, "cleaner", info_, 0, 10, 30).AsMessage();
EXPECT_EQ(Message::Type::warn, message.GetType());
- EXPECT_EQ("Contains 10 deleted references and 30 deleted navmeshes. Clean with cleaner.", message.ChooseContent(Language::Code::english).GetText());
+ EXPECT_EQ("cleaner found 10 deleted references and 30 deleted navmeshes. info", message.ChooseContent(Language::Code::english).GetText());
- message = PluginCleaningData(0x12345678, 0, 0, 30, "cleaner").AsMessage();
+ message = PluginCleaningData(0x12345678, "cleaner", info_, 0, 0, 30).AsMessage();
EXPECT_EQ(Message::Type::warn, message.GetType());
- EXPECT_EQ("Contains 30 deleted navmeshes. Clean with cleaner.", message.ChooseContent(Language::Code::english).GetText());
+ EXPECT_EQ("cleaner found 30 deleted navmeshes. info", message.ChooseContent(Language::Code::english).GetText());
- message = PluginCleaningData(0x12345678, 0, 10, 0, "cleaner").AsMessage();
+ message = PluginCleaningData(0x12345678, "cleaner", info_, 0, 10, 0).AsMessage();
EXPECT_EQ(Message::Type::warn, message.GetType());
- EXPECT_EQ("Contains 10 deleted references. Clean with cleaner.", message.ChooseContent(Language::Code::english).GetText());
+ EXPECT_EQ("cleaner found 10 deleted references. info", message.ChooseContent(Language::Code::english).GetText());
- message = PluginCleaningData(0x12345678, 2, 0, 30, "cleaner").AsMessage();
+ message = PluginCleaningData(0x12345678, "cleaner", info_, 2, 0, 30).AsMessage();
EXPECT_EQ(Message::Type::warn, message.GetType());
- EXPECT_EQ("Contains 2 ITM records and 30 deleted navmeshes. Clean with cleaner.", message.ChooseContent(Language::Code::english).GetText());
+ EXPECT_EQ("cleaner found 2 ITM records and 30 deleted navmeshes. info", message.ChooseContent(Language::Code::english).GetText());
- message = PluginCleaningData(0x12345678, 2, 0, 0, "cleaner").AsMessage();
+ message = PluginCleaningData(0x12345678, "cleaner", info_, 2, 0, 0).AsMessage();
EXPECT_EQ(Message::Type::warn, message.GetType());
- EXPECT_EQ("Contains 2 ITM records. Clean with cleaner.", message.ChooseContent(Language::Code::english).GetText());
+ EXPECT_EQ("cleaner found 2 ITM records. info", message.ChooseContent(Language::Code::english).GetText());
- message = PluginCleaningData(0x12345678, 2, 10, 0, "cleaner").AsMessage();
+ message = PluginCleaningData(0x12345678, "cleaner", info_, 2, 10, 0).AsMessage();
EXPECT_EQ(Message::Type::warn, message.GetType());
- EXPECT_EQ("Contains 2 ITM records and 10 deleted references. Clean with cleaner.", message.ChooseContent(Language::Code::english).GetText());
+ EXPECT_EQ("cleaner found 2 ITM records and 10 deleted references. info", message.ChooseContent(Language::Code::english).GetText());
}
TEST_P(PluginCleaningDataTest, dirtyInfoShouldBeEqualIfCrcValuesAreEqual) {
- PluginCleaningData info1(0x12345678, 2, 10, 30, "cleaner1");
- PluginCleaningData info2(0x12345678, 4, 20, 60, "cleaner2");
+ PluginCleaningData info1(0x12345678, "cleaner1", info_, 2, 10, 30);
+ PluginCleaningData info2(0x12345678, "cleaner2", info_, 4, 20, 60);
EXPECT_TRUE(info1 == info2);
- info1 = PluginCleaningData(0x12345678, 2, 10, 30, "cleaner");
- info2 = PluginCleaningData(0x87654321, 2, 10, 30, "cleaner");
+ info1 = PluginCleaningData(0x12345678, "cleaner", info_, 2, 10, 30);
+ info2 = PluginCleaningData(0x87654321, "cleaner", info_, 2, 10, 30);
EXPECT_FALSE(info1 == info2);
}
TEST_P(PluginCleaningDataTest, LessThanOperatorShouldCompareCrcValues) {
- PluginCleaningData info1(0x12345678, 2, 10, 30, "cleaner1");
- PluginCleaningData info2(0x12345678, 4, 20, 60, "cleaner2");
+ PluginCleaningData info1(0x12345678, "cleaner1", info_, 2, 10, 30);
+ PluginCleaningData info2(0x12345678, "cleaner2", info_, 4, 20, 60);
EXPECT_FALSE(info1 < info2);
EXPECT_FALSE(info2 < info1);
- info1 = PluginCleaningData(0x12345678, 2, 10, 30, "cleaner");
- info2 = PluginCleaningData(0x87654321, 2, 10, 30, "cleaner");
+ info1 = PluginCleaningData(0x12345678, "cleaner", info_, 2, 10, 30);
+ info2 = PluginCleaningData(0x87654321, "cleaner", info_, 2, 10, 30);
EXPECT_TRUE(info1 < info2);
EXPECT_FALSE(info2 < info1);
}
@@ -119,7 +128,7 @@ TEST_P(PluginCleaningDataTest, evalConditionShouldBeTrueIfTheCrcGivenMatchesTheR
Game game(GetParam());
game.SetGamePath(dataPath.parent_path());
- PluginCleaningData dirtyInfo(blankEsmCrc, 2, 10, 30, "cleaner");
+ PluginCleaningData dirtyInfo(blankEsmCrc, "cleaner", info_, 2, 10, 30);
EXPECT_TRUE(dirtyInfo.EvalCondition(game, blankEsm));
}
@@ -127,7 +136,7 @@ TEST_P(PluginCleaningDataTest, evalConditionShouldBeFalseIfTheCrcGivenDoesNotMat
Game game(GetParam());
game.SetGamePath(dataPath.parent_path());
- PluginCleaningData dirtyInfo(0xDEADBEEF, 2, 10, 30, "cleaner");
+ PluginCleaningData dirtyInfo(0xDEADBEEF, "cleaner", info_, 2, 10, 30);
EXPECT_FALSE(dirtyInfo.EvalCondition(game, blankEsm));
}
@@ -139,51 +148,89 @@ TEST_P(PluginCleaningDataTest, evalConditionShouldBeFalseIfAnEmptyPluginFilename
EXPECT_FALSE(dirtyInfo.EvalCondition(game, ""));
}
+TEST_P(PluginCleaningDataTest, chooseInfoShouldCreateADefaultContentObjectIfNoneExists) {
+ PluginCleaningData dirtyInfo(0xDEADBEEF, "cleaner", std::vector(), 2, 10, 30);
+ EXPECT_EQ(MessageContent(), dirtyInfo.ChooseInfo(Language::Code::english));
+}
+
+TEST_P(PluginCleaningDataTest, chooseInfoShouldLeaveTheContentUnchangedIfOnlyOneStringExists) {
+ PluginCleaningData dirtyInfo(0xDEADBEEF, "cleaner", info_, 2, 10, 30);
+
+ EXPECT_EQ(info_[0], dirtyInfo.ChooseInfo(Language::Code::french));
+ EXPECT_EQ(info_[0], dirtyInfo.ChooseInfo(Language::Code::english));
+}
+
+TEST_P(PluginCleaningDataTest, chooseInfoShouldSelectTheEnglishStringIfNoStringExistsForTheGivenLanguage) {
+ MessageContent content("content1", Language::Code::english);
+ std::vector info({
+ content,
+ MessageContent("content1", Language::Code::german),
+ });
+ PluginCleaningData dirtyInfo(0xDEADBEEF, "cleaner", info, 2, 10, 30);
+
+ EXPECT_EQ(content, dirtyInfo.ChooseInfo(Language::Code::french));
+}
+
+TEST_P(PluginCleaningDataTest, chooseInfoShouldSelectTheStringForTheGivenLanguageIfOneExists) {
+ MessageContent french("content3", Language::Code::french);
+ std::vector info({
+ MessageContent("content1", Language::Code::german),
+ MessageContent("content2", Language::Code::english),
+ french,
+ });
+ PluginCleaningData dirtyInfo(0xDEADBEEF, "cleaner", info, 2, 10, 30);
+
+ EXPECT_EQ(french, dirtyInfo.ChooseInfo(Language::Code::french));
+}
+
TEST_P(PluginCleaningDataTest, emittingAsYamlShouldOutputAllNonZeroCounts) {
- PluginCleaningData info(0x12345678, 2, 10, 30, "cleaner");
+ PluginCleaningData info(0x12345678, "cleaner", info_, 2, 10, 30);
YAML::Emitter emitter;
emitter << info;
- EXPECT_STREQ("crc: 0x12345678\nutil: 'cleaner'\nitm: 2\nudr: 10\nnav: 30", emitter.c_str());
+ EXPECT_STREQ("crc: 0x12345678\nutility: 'cleaner'\ninfo: 'info'\nitm: 2\nudr: 10\nnav: 30", emitter.c_str());
}
TEST_P(PluginCleaningDataTest, emittingAsYamlShouldOmitAllZeroCounts) {
- PluginCleaningData info(0x12345678, 0, 0, 0, "cleaner");
+ PluginCleaningData info(0x12345678, "cleaner", info_, 0, 0, 0);
YAML::Emitter emitter;
emitter << info;
- EXPECT_STREQ("crc: 0x12345678\nutil: 'cleaner'", emitter.c_str());
+ EXPECT_STREQ("crc: 0x12345678\nutility: 'cleaner'\ninfo: 'info'", emitter.c_str());
}
TEST_P(PluginCleaningDataTest, encodingAsYamlShouldOmitAllZeroCountFields) {
- PluginCleaningData info(0x12345678, 0, 0, 0, "cleaner");
+ PluginCleaningData info(0x12345678, "cleaner", info_, 0, 0, 0);
YAML::Node node;
node = info;
EXPECT_EQ(0x12345678, node["crc"].as());
- EXPECT_EQ("cleaner", node["util"].as());
+ EXPECT_EQ("cleaner", node["utility"].as());
+ EXPECT_EQ(info_, node["info"].as>());
EXPECT_FALSE(node["itm"]);
EXPECT_FALSE(node["udr"]);
EXPECT_FALSE(node["nav"]);
}
TEST_P(PluginCleaningDataTest, encodingAsYamlShouldOutputAllNonZeroCountFields) {
- PluginCleaningData info(0x12345678, 2, 10, 30, "cleaner");
+ PluginCleaningData info(0x12345678, "cleaner", info_, 2, 10, 30);
YAML::Node node;
node = info;
EXPECT_EQ(0x12345678, node["crc"].as());
- EXPECT_EQ("cleaner", node["util"].as());
+ EXPECT_EQ("cleaner", node["utility"].as());
+ EXPECT_EQ(info_, node["info"].as>());
EXPECT_EQ(2, node["itm"].as());
EXPECT_EQ(10, node["udr"].as());
EXPECT_EQ(30, node["nav"].as());
}
TEST_P(PluginCleaningDataTest, decodingFromYamlShouldLeaveMissingFieldsWithZeroValues) {
- YAML::Node node = YAML::Load("{crc: 0x12345678, util: cleaner}");
+ YAML::Node node = YAML::Load("{crc: 0x12345678, utility: cleaner}");
PluginCleaningData info = node.as();
EXPECT_EQ(0x12345678, info.CRC());
+ EXPECT_TRUE(info.Info().empty());
EXPECT_EQ(0, info.ITMs());
EXPECT_EQ(0, info.DeletedRefs());
EXPECT_EQ(0, info.DeletedNavmeshes());
@@ -191,10 +238,11 @@ TEST_P(PluginCleaningDataTest, decodingFromYamlShouldLeaveMissingFieldsWithZeroV
}
TEST_P(PluginCleaningDataTest, decodingFromYamlShouldStoreAllNonZeroCounts) {
- YAML::Node node = YAML::Load("{crc: 0x12345678, util: cleaner, itm: 2, udr: 10, nav: 30}");
+ YAML::Node node = YAML::Load("{crc: 0x12345678, utility: cleaner, info: info, itm: 2, udr: 10, nav: 30}");
PluginCleaningData info = node.as();
EXPECT_EQ(0x12345678, info.CRC());
+ EXPECT_EQ(info_, info.Info());
EXPECT_EQ(2, info.ITMs());
EXPECT_EQ(10, info.DeletedRefs());
EXPECT_EQ(30, info.DeletedNavmeshes());
diff --git a/src/tests/backend/metadata/plugin_metadata_test.h b/src/tests/backend/metadata/plugin_metadata_test.h
index d32b0929..7717bf46 100644
--- a/src/tests/backend/metadata/plugin_metadata_test.h
+++ b/src/tests/backend/metadata/plugin_metadata_test.h
@@ -31,7 +31,14 @@ along with LOOT. If not, see
namespace loot {
namespace test {
-class PluginMetadataTest : public BaseGameTest {};
+class PluginMetadataTest : public BaseGameTest {
+protected:
+ PluginMetadataTest() : info_(std::vector({
+ MessageContent("info", Language::Code::english),
+ })) {}
+
+ const std::vector info_;
+};
// Pass an empty first argument, as it's a prefix for the test instantation,
// but we only have the one so no prefix is necessary.
@@ -254,8 +261,8 @@ TEST_P(PluginMetadataTest, mergeMetadataShouldMergeTags) {
TEST_P(PluginMetadataTest, mergeMetadataShouldMergeDirtyInfoData) {
PluginMetadata plugin1;
PluginMetadata plugin2;
- PluginCleaningData info1(0x5, 1, 2, 3, "utility");
- PluginCleaningData info2(0xA, 1, 2, 3, "utility");
+ PluginCleaningData info1(0x5, "utility", info_, 1, 2, 3);
+ PluginCleaningData info2(0xA, "utility", info_, 1, 2, 3);
plugin1.DirtyInfo({info1});
plugin2.DirtyInfo({info1, info2});
@@ -432,9 +439,9 @@ TEST_P(PluginMetadataTest, diffMetadataShouldOutputTagsThatAreNotCommonToBothInp
TEST_P(PluginMetadataTest, diffMetadataShouldOutputDirtyInfoObjectsThatAreNotCommonToBothInputPlugins) {
PluginMetadata plugin1;
PluginMetadata plugin2;
- PluginCleaningData info1(0x5, 1, 2, 3, "utility");
- PluginCleaningData info2(0xA, 1, 2, 3, "utility");
- PluginCleaningData info3(0x1, 1, 2, 3, "utility");
+ PluginCleaningData info1(0x5, "utility", info_, 1, 2, 3);
+ PluginCleaningData info2(0xA, "utility", info_, 1, 2, 3);
+ PluginCleaningData info3(0x1, "utility", info_, 1, 2, 3);
plugin1.DirtyInfo({info1, info2});
plugin2.DirtyInfo({info1, info3});
@@ -588,9 +595,9 @@ TEST_P(PluginMetadataTest, newMetadataShouldOutputTagsThatAreNotCommonToBothInpu
TEST_P(PluginMetadataTest, newMetadataShouldOutputDirtyInfoObjectsThatAreNotCommonToBothInputPlugins) {
PluginMetadata plugin1;
PluginMetadata plugin2;
- PluginCleaningData info1(0x5, 1, 2, 3, "utility");
- PluginCleaningData info2(0xA, 1, 2, 3, "utility");
- PluginCleaningData info3(0x1, 1, 2, 3, "utility");
+ PluginCleaningData info1(0x5, "utility", info_, 1, 2, 3);
+ PluginCleaningData info2(0xA, "utility", info_, 1, 2, 3);
+ PluginCleaningData info3(0x1, "utility", info_, 1, 2, 3);
plugin1.DirtyInfo({info1, info2});
plugin2.DirtyInfo({info1, info3});
@@ -647,8 +654,8 @@ TEST_P(PluginMetadataTest, evalAllConditionsShouldEvaluateAllMetadataConditions)
Tag tag2("Relev", true, "file(\"" + missingEsp + "\")");
plugin.Tags({tag1, tag2});
- PluginCleaningData info1(blankEsmCrc, 1, 2, 3, "utility");
- PluginCleaningData info2(0xDEADBEEF, 1, 2, 3, "utility");
+ PluginCleaningData info1(blankEsmCrc, "utility", info_, 1, 2, 3);
+ PluginCleaningData info2(0xDEADBEEF, "utility", info_, 1, 2, 3);
plugin.DirtyInfo({info1, info2});
plugin.CleanInfo({info1, info2});
@@ -734,7 +741,7 @@ TEST_P(PluginMetadataTest, hasNameOnlyShouldBeFalseIfTagsExist) {
TEST_P(PluginMetadataTest, hasNameOnlyShouldBeFalseIfDirtyInfoExists) {
PluginMetadata plugin(blankEsp);
- plugin.DirtyInfo({PluginCleaningData(5, 0, 1, 2, "utility")});
+ plugin.DirtyInfo({PluginCleaningData(5, "utility", info_, 0, 1, 2)});
EXPECT_FALSE(plugin.HasNameOnly());
}
@@ -911,7 +918,7 @@ TEST_P(PluginMetadataTest, emittingAsYamlShouldOutputAPluginWithTagsCorrectly) {
TEST_P(PluginMetadataTest, emittingAsYamlShouldOutputAPluginWithDirtyInfoCorrectly) {
PluginMetadata plugin(blankEsp);
- plugin.DirtyInfo({PluginCleaningData(5, 0, 1, 2, "utility")});
+ plugin.DirtyInfo({PluginCleaningData(5, "utility", info_, 0, 1, 2)});
YAML::Emitter emitter;
emitter << plugin;
@@ -919,7 +926,8 @@ TEST_P(PluginMetadataTest, emittingAsYamlShouldOutputAPluginWithDirtyInfoCorrect
EXPECT_STREQ("name: 'Blank.esp'\n"
"dirty:\n"
" - crc: 0x5\n"
- " util: 'utility'\n"
+ " utility: 'utility'\n"
+ " info: 'info'\n"
" udr: 1\n"
" nav: 2", emitter.c_str());
}
@@ -934,7 +942,7 @@ TEST_P(PluginMetadataTest, emittingAsYamlShouldOutputAPluginWithCleanInfoCorrect
EXPECT_STREQ("name: 'Blank.esp'\n"
"clean:\n"
" - crc: 0x5\n"
- " util: 'utility'", emitter.c_str());
+ " utility: 'utility'", emitter.c_str());
}
TEST_P(PluginMetadataTest, emittingAsYamlShouldOutputAPluginWithLocationsCorrectly) {
@@ -1057,7 +1065,7 @@ TEST_P(PluginMetadataTest, encodingAsYamlShouldSetTagFieldIfTagsExist) {
TEST_P(PluginMetadataTest, encodingAsYamlShouldSetDirtyFieldIfDirtyInfoExists) {
PluginMetadata plugin(blankEsp);
- plugin.DirtyInfo({PluginCleaningData(5, 0, 1, 2, "utility")});
+ plugin.DirtyInfo({PluginCleaningData(5, "utility", info_, 0, 1, 2)});
YAML::Node node;
node = plugin;
@@ -1111,12 +1119,12 @@ TEST_P(PluginMetadataTest, decodingFromYamlShouldStoreAllGivenData) {
" - Relev\n"
"dirty:\n"
" - crc: 0x5\n"
- " util: 'utility'\n"
+ " utility: 'utility'\n"
" udr: 1\n"
" nav: 2\n"
"clean:\n"
" - crc: 0x6\n"
- " util: 'utility'\n"
+ " utility: 'utility'\n"
"url:\n"
" - 'http://www.example.com'");
PluginMetadata plugin = node.as();
@@ -1140,7 +1148,7 @@ TEST_P(PluginMetadataTest, decodingFromYamlShouldStoreAllGivenData) {
Tag("Relev")
}), plugin.Tags());
EXPECT_EQ(std::set({
- PluginCleaningData(5, 0, 1, 2, "utility")
+ PluginCleaningData(5, "utility", info_, 0, 1, 2)
}), plugin.DirtyInfo());
EXPECT_EQ(std::set({
PluginCleaningData(6, "utility")
@@ -1154,7 +1162,7 @@ TEST_P(PluginMetadataTest, decodingFromYamlWithDirtyInfoInARegexPluginMetadataOb
YAML::Node node = YAML::Load("name: 'Blank\\.esp'\n"
"dirty:\n"
" - crc: 0x5\n"
- " util: 'utility'\n"
+ " utility: 'utility'\n"
" udr: 1\n"
" nav: 2");
@@ -1165,7 +1173,7 @@ TEST_P(PluginMetadataTest, decodingFromYamlWithCleanInfoInARegexPluginMetadataOb
YAML::Node node = YAML::Load("name: 'Blank\\.esp'\n"
"clean:\n"
" - crc: 0x5\n"
- " util: 'utility'");
+ " utility: 'utility'");
EXPECT_THROW(node.as(), YAML::RepresentationException);
}
@@ -1174,7 +1182,7 @@ TEST_P(PluginMetadataTest, decodingFromYamlWithAnInvalidRegexNameShouldThrow) {
YAML::Node node = YAML::Load("name: 'RagnvaldBook(Farengar(+Ragnvald)?)?\\.esp'\n"
"dirty:\n"
" - crc: 0x5\n"
- " util: 'utility'\n"
+ " utility: 'utility'\n"
" udr: 1\n"
" nav: 2");
diff --git a/src/tests/backend/plugin/plugin_test.h b/src/tests/backend/plugin/plugin_test.h
index cf841793..9bc42107 100644
--- a/src/tests/backend/plugin/plugin_test.h
+++ b/src/tests/backend/plugin/plugin_test.h
@@ -280,7 +280,7 @@ TEST_P(PluginTest, checkInstallValidityShouldCheckThatRequirementsArePresent) {
File(blankEsp),
});
- EXPECT_FALSE(plugin.CheckInstallValidity(game_));
+ plugin.CheckInstallValidity(game_);
EXPECT_EQ(std::list({
Message(Message::Type::error, "This plugin requires \"" + missingEsp + "\" to be installed, but it is missing."),
}), plugin.Messages());
@@ -293,30 +293,34 @@ TEST_P(PluginTest, checkInstallValidityShouldCheckThatIncompatibilitiesAreAbsent
File(masterFile),
});
- EXPECT_FALSE(plugin.CheckInstallValidity(game_));
+ plugin.CheckInstallValidity(game_);
EXPECT_EQ(std::list({
Message(Message::Type::error, "This plugin is incompatible with \"" + masterFile + "\", but both are present."),
}), plugin.Messages());
}
TEST_P(PluginTest, checkInstallValidityShouldGenerateMessagesFromDirtyInfo) {
- Plugin plugin(game_, blankEsm, false);
- plugin.DirtyInfo({
- PluginCleaningData(blankEsmCrc, 0, 1, 2, "utility1"),
- PluginCleaningData(0xDEADBEEF, 0, 5, 10, "utility2"),
+ const std::vector info = std::vector({
+ MessageContent("info", Language::Code::english),
});
- EXPECT_TRUE(plugin.CheckInstallValidity(game_));
+ Plugin plugin(game_, blankEsm, false);
+ plugin.DirtyInfo({
+ PluginCleaningData(blankEsmCrc, "utility1", info, 0, 1, 2),
+ PluginCleaningData(0xDEADBEEF, "utility2", info, 0, 5, 10),
+ });
+
+ plugin.CheckInstallValidity(game_);
EXPECT_EQ(std::list({
- PluginCleaningData(blankEsmCrc, 0, 1, 2, "utility1").AsMessage(),
- PluginCleaningData(0xDEADBEEF, 0, 5, 10, "utility2").AsMessage(),
+ PluginCleaningData(blankEsmCrc, "utility1", info, 0, 1, 2).AsMessage(),
+ PluginCleaningData(0xDEADBEEF, "utility2", info, 0, 5, 10).AsMessage(),
}), plugin.Messages());
}
TEST_P(PluginTest, checkInstallValidityShouldCheckIfAPluginsMastersAreAllPresentAndActiveIfNoFilterTagIsPresent) {
Plugin plugin(game_, blankDifferentMasterDependentEsp, false);
- EXPECT_FALSE(plugin.CheckInstallValidity(game_));
+ plugin.CheckInstallValidity(game_);
EXPECT_EQ(std::list({
Message(Message::Type::error, "This plugin requires \"" + blankDifferentEsm + "\" to be active, but it is inactive."),
}), plugin.Messages());
@@ -326,7 +330,7 @@ TEST_P(PluginTest, checkInstallValidityShouldNotCheckIfAPluginsMastersAreAllActi
Plugin plugin(game_, blankDifferentMasterDependentEsp, false);
plugin.Tags({Tag("Filter")});
- EXPECT_FALSE(plugin.CheckInstallValidity(game_));
+ plugin.CheckInstallValidity(game_);
EXPECT_TRUE(plugin.Messages().empty());
}
}
|