Split metadata class test files in two

So that the classes that are part of the public API get treated as interface tests, and the YAML serialisation and deserialisation are tested as internal tests.
This commit is contained in:
Oliver Hamlet
2025-04-29 17:26:39 +01:00
parent ea741d08f1
commit e61171bdbe
20 changed files with 1633 additions and 1344 deletions
+18 -10
View File
@@ -44,15 +44,14 @@ set(LIBLOOT_SRC_TESTS_INTERNALS_H_FILES
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/helpers/crc_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/helpers/text_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/metadata/condition_evaluator_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/metadata/conditional_metadata_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/metadata/file_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/metadata/group_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/metadata/location_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/metadata/message_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/metadata/message_content_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/metadata/plugin_cleaning_data_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/metadata/plugin_metadata_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/metadata/tag_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/metadata/yaml/file_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/metadata/yaml/group_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/metadata/yaml/location_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/metadata/yaml/message_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/metadata/yaml/message_content_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/metadata/yaml/plugin_cleaning_data_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/metadata/yaml/plugin_metadata_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/metadata/yaml/tag_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/plugin_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/sorting/group_sort_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/internals/sorting/plugin_sort_test.h"
@@ -68,7 +67,16 @@ set(LIBLOOT_SRC_TESTS_INTERFACE_H_FILES
"${CMAKE_SOURCE_DIR}/src/tests/api/interface/create_game_handle_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/interface/database_interface_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/interface/game_interface_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/interface/is_compatible_test.h")
"${CMAKE_SOURCE_DIR}/src/tests/api/interface/is_compatible_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/interface/metadata/conditional_metadata_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/interface/metadata/file_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/interface/metadata/group_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/interface/metadata/location_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/interface/metadata/message_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/interface/metadata/message_content_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/interface/metadata/plugin_cleaning_data_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/interface/metadata/plugin_metadata_test.h"
"${CMAKE_SOURCE_DIR}/src/tests/api/interface/metadata/tag_test.h")
source_group(TREE "${CMAKE_SOURCE_DIR}/src/tests/api/internals"
PREFIX "Source Files"
+9
View File
@@ -25,6 +25,15 @@
#include <gtest/gtest.h>
#include "loot/api.h"
#include "tests/api/interface/metadata/conditional_metadata_test.h"
#include "tests/api/interface/metadata/file_test.h"
#include "tests/api/interface/metadata/group_test.h"
#include "tests/api/interface/metadata/location_test.h"
#include "tests/api/interface/metadata/message_content_test.h"
#include "tests/api/interface/metadata/message_test.h"
#include "tests/api/interface/metadata/plugin_cleaning_data_test.h"
#include "tests/api/interface/metadata/plugin_metadata_test.h"
#include "tests/api/interface/metadata/tag_test.h"
#include "tests/api/interface/create_game_handle_test.h"
#include "tests/api/interface/database_interface_test.h"
#include "tests/api/interface/game_interface_test.h"
@@ -22,8 +22,8 @@ along with LOOT. If not, see
<https://www.gnu.org/licenses/>.
*/
#ifndef LOOT_TESTS_API_INTERNALS_METADATA_CONDITIONAL_METADATA_TEST
#define LOOT_TESTS_API_INTERNALS_METADATA_CONDITIONAL_METADATA_TEST
#ifndef LOOT_TESTS_API_INTERFACE_METADATA_CONDITIONAL_METADATA_TEST
#define LOOT_TESTS_API_INTERFACE_METADATA_CONDITIONAL_METADATA_TEST
#include "loot/metadata/conditional_metadata.h"
#include "tests/common_game_test_fixture.h"
@@ -22,16 +22,14 @@ along with LOOT. If not, see
<https://www.gnu.org/licenses/>.
*/
#ifndef LOOT_TESTS_API_INTERNALS_METADATA_FILE_TEST
#define LOOT_TESTS_API_INTERNALS_METADATA_FILE_TEST
#ifndef LOOT_TESTS_API_INTERFACE_METADATA_FILE_TEST
#define LOOT_TESTS_API_INTERFACE_METADATA_FILE_TEST
#include <gtest/gtest.h>
#include "api/metadata/yaml/file.h"
#include "loot/metadata/file.h"
namespace loot {
namespace test {
namespace loot::test {
TEST(File, defaultConstructorShouldInitialiseEmptyStrings) {
File file;
@@ -381,174 +379,6 @@ TEST(File, getDisplayNameShouldReturnDisplayString) {
EXPECT_EQ("display", file.GetDisplayName());
}
TEST(File, emittingAsYamlShouldSingleQuoteValues) {
File file("name1",
"display1",
"condition1",
{MessageContent("english", "en")},
"constraint1");
YAML::Emitter emitter;
emitter << file;
std::string expected = "name: '" + std::string(file.GetName()) +
"'\ncondition: '" + file.GetCondition() +
"'\ndisplay: '" + file.GetDisplayName() +
"'\nconstraint: '" + file.GetConstraint() +
"'\ndetail: '" + file.GetDetail()[0].GetText() + "'";
EXPECT_EQ(expected, emitter.c_str());
}
TEST(File, emittingAsYamlShouldOutputAsAScalarIfOnlyTheNameStringIsNotEmpty) {
File file("file.esp");
YAML::Emitter emitter;
emitter << file;
EXPECT_EQ("'" + std::string(file.GetName()) + "'", emitter.c_str());
}
TEST(File, emittingAsYamlShouldOmitEmptyConditionAndConstraintStrings) {
File file("name1", "display1");
YAML::Emitter emitter;
emitter << file;
std::string expected = "name: '" + std::string(file.GetName()) +
"'\ndisplay: '" + file.GetDisplayName() + "'";
EXPECT_EQ(expected, emitter.c_str());
}
TEST(
File,
emittingAsYamlShouldWriteDetailAsAListIfTheVectorContainsMoreThanOneElement) {
File file("",
"",
"",
{MessageContent("english", "en"), MessageContent("french", "fr")});
YAML::Emitter emitter;
emitter << file;
std::string expected =
"name: ''\n"
"detail:\n"
" - lang: en\n"
" text: 'english'\n"
" - lang: fr\n"
" text: 'french'";
EXPECT_EQ(expected, emitter.c_str());
}
TEST(File, encodingAsYamlShouldStoreDataCorrectly) {
auto detail = {MessageContent("english", "en"),
MessageContent("french", "fr")};
File file("name1", "display1", "condition1", detail, "constraint1");
YAML::Node node;
node = file;
EXPECT_EQ(std::string(file.GetName()), node["name"].as<std::string>());
EXPECT_EQ(file.GetDisplayName(), node["display"].as<std::string>());
EXPECT_EQ(file.GetCondition(), node["condition"].as<std::string>());
EXPECT_EQ(file.GetDetail(), node["detail"].as<std::vector<MessageContent>>());
EXPECT_EQ(file.GetConstraint(), node["constraint"].as<std::string>());
}
TEST(File, encodingAsYamlShouldOmitEmptyFields) {
File file("file.esp");
YAML::Node node;
node = file;
EXPECT_EQ(std::string(file.GetName()), node["name"].as<std::string>());
EXPECT_FALSE(node["display"]);
EXPECT_FALSE(node["condition"]);
EXPECT_FALSE(node["detail"]);
}
TEST(File, decodingFromYamlShouldSetDataCorrectly) {
YAML::Node node = YAML::Load(
"{name: name1, display: display1, condition: 'file(\"Foo.esp\")', "
"detail: 'details', constraint: 'file(\"Bar.esp\")'}");
File file = node.as<File>();
std::vector<MessageContent> expectedDetail = {
MessageContent("details", "en")};
EXPECT_EQ(node["name"].as<std::string>(), std::string(file.GetName()));
EXPECT_EQ(node["display"].as<std::string>(), file.GetDisplayName());
EXPECT_EQ(node["condition"].as<std::string>(), file.GetCondition());
EXPECT_EQ(expectedDetail, file.GetDetail());
EXPECT_EQ(node["constraint"].as<std::string>(), file.GetConstraint());
}
TEST(File,
decodingFromYamlWithMissingConditionFieldShouldLeaveConditionStringEmpty) {
YAML::Node node = YAML::Load("{name: name1, display: display1}");
File file = node.as<File>();
EXPECT_EQ(node["name"].as<std::string>(), std::string(file.GetName()));
EXPECT_EQ(node["display"].as<std::string>(), file.GetDisplayName());
EXPECT_TRUE(file.GetCondition().empty());
EXPECT_TRUE(file.GetDetail().empty());
EXPECT_TRUE(file.GetConstraint().empty());
}
TEST(File, decodingFromYamlWithAListOfMessageContentDetailsShouldReadThemAll) {
YAML::Node node = YAML::Load(
"{name: name1, display: display1, condition: 'file(\"Foo.esp\")', "
"detail: [{text: english, lang: en}, {text: french, lang: fr}]}");
File file = node.as<File>();
std::vector<MessageContent> expectedDetail = {MessageContent("english", "en"),
MessageContent("french", "fr")};
EXPECT_EQ(expectedDetail, file.GetDetail());
}
TEST(File, decodingFromYamlShouldNotThrowIfTheOnlyDetailStringIsNotEnglish) {
YAML::Node node = YAML::Load(
"name: name1\n"
"detail:\n"
" - lang: fr\n"
" text: content1");
EXPECT_NO_THROW(node.as<File>());
}
TEST(
File,
decodingFromYamlShouldThrowIfMultipleContentStringsAreGivenAndNoneAreEnglish) {
YAML::Node node = YAML::Load(
"name: name1\n"
"detail:\n"
" - lang: de\n"
" text: content1\n"
" - lang: fr\n"
" text: content2");
EXPECT_THROW(node.as<File>(), YAML::RepresentationException);
}
TEST(File, decodingFromYamlScalarShouldLeaveDisplayNameAndConditionEmpty) {
YAML::Node node = YAML::Load("name1");
File file = node.as<File>();
EXPECT_EQ(node.as<std::string>(), std::string(file.GetName()));
EXPECT_TRUE(file.GetDisplayName().empty());
EXPECT_TRUE(file.GetCondition().empty());
EXPECT_TRUE(file.GetDetail().empty());
EXPECT_TRUE(file.GetConstraint().empty());
}
TEST(File, decodingFromYamlShouldThrowIfAnInvalidMapIsGiven) {
YAML::Node node = YAML::Load("{name: name1, condition: invalid}");
EXPECT_THROW(node.as<File>(), YAML::RepresentationException);
}
TEST(File, decodingFromYamlShouldThrowIfAListIsGiven) {
YAML::Node node = YAML::Load("[0, 1, 2]");
EXPECT_THROW(node.as<File>(), YAML::RepresentationException);
}
}
}
#endif
@@ -22,16 +22,14 @@ along with LOOT. If not, see
<https://www.gnu.org/licenses/>.
*/
#ifndef LOOT_TESTS_API_INTERNALS_METADATA_GROUP_TEST
#define LOOT_TESTS_API_INTERNALS_METADATA_GROUP_TEST
#ifndef LOOT_TESTS_API_INTERFACE_METADATA_GROUP_TEST
#define LOOT_TESTS_API_INTERFACE_METADATA_GROUP_TEST
#include <gtest/gtest.h>
#include "api/metadata/yaml/group.h"
#include "loot/metadata/group.h"
namespace loot {
namespace test {
namespace loot::test {
TEST(Group, defaultConstructorShouldCreateDefaultGroup) {
Group group;
@@ -350,115 +348,6 @@ TEST(
EXPECT_FALSE(group1 >= group2);
EXPECT_TRUE(group2 >= group1);
}
TEST(Group, emittingAsYamlShouldOmitAfterKeyIfAfterGroupsIsEmpty) {
Group group;
YAML::Emitter emitter;
emitter << group;
EXPECT_STREQ("name: 'default'", emitter.c_str());
}
TEST(Group, emittingAsYamlShouldIncludeDescriptionKeyIfDescriptionIsNotEmpty) {
Group group("group1", {}, "test");
YAML::Emitter emitter;
emitter << group;
EXPECT_STREQ(
"name: 'group1'\n"
"description: 'test'",
emitter.c_str());
}
TEST(Group, emittingAsYamlShouldIncludeAfterKeyIfAfterGroupsIsNotEmpty) {
Group group("group1", {"other_group"});
YAML::Emitter emitter;
emitter << group;
EXPECT_STREQ(
"name: 'group1'\n"
"after:\n"
" - other_group",
emitter.c_str());
}
TEST(Group, encodingAsYamlShouldOmitDescriptionKeyIfDescriptionIsEmpty) {
Group group;
YAML::Node node;
node = group;
EXPECT_EQ("default", node["name"].as<std::string>());
EXPECT_FALSE(node["description"]);
}
TEST(Group, encodingAsYamlShouldIncludeDescriptionKeyIfDescriptionIsNotEmpty) {
Group group("group1", {}, "test");
YAML::Node node;
node = group;
EXPECT_EQ("group1", node["name"].as<std::string>());
EXPECT_EQ("test", node["description"].as<std::string>());
}
TEST(Group, encodingAsYamlShouldOmitAfterKeyIfAfterGroupsIsEmpty) {
Group group;
YAML::Node node;
node = group;
EXPECT_EQ("default", node["name"].as<std::string>());
EXPECT_FALSE(node["after"]);
}
TEST(Group, encodingAsYamlShouldIncludeAfterKeyIfAfterGroupsIsNotEmpty) {
Group group("group1", {"other_group"});
YAML::Node node;
node = group;
std::vector<std::string> expectedAfterGroups = {"other_group"};
EXPECT_EQ("group1", node["name"].as<std::string>());
EXPECT_EQ(expectedAfterGroups, node["after"].as<std::vector<std::string>>());
}
TEST(Group, decodingFromYamlShouldSetGivenName) {
YAML::Node node = YAML::Load("{name: group1}");
Group group = node.as<Group>();
EXPECT_EQ("group1", group.GetName());
EXPECT_TRUE(group.GetAfterGroups().empty());
}
TEST(Group, decodingFromYamlShouldSetDescriptionIfOneIsGiven) {
YAML::Node node = YAML::Load("{name: group1, description: test}");
Group group = node.as<Group>();
EXPECT_EQ("group1", group.GetName());
EXPECT_EQ("test", group.GetDescription());
}
TEST(Group, decodingFromYamlShouldSetAfterGroupsIfAnyAreGiven) {
YAML::Node node = YAML::Load("{name: group1, after: [ other_group ]}");
Group group = node.as<Group>();
std::vector<std::string> expectedAfterGroups = {"other_group"};
EXPECT_EQ("group1", group.GetName());
EXPECT_EQ(expectedAfterGroups, group.GetAfterGroups());
}
TEST(Group, decodingFromYamlShouldThrowIfTheNameKeyIsMissing) {
YAML::Node node = YAML::Load("{after: []}");
EXPECT_THROW(node.as<Group>(), YAML::RepresentationException);
}
TEST(Group, decodingFromYamlShouldThrowIfAListIsGiven) {
YAML::Node node = YAML::Load("[0, 1, 2]");
EXPECT_THROW(node.as<Group>(), YAML::RepresentationException);
}
}
}
#endif
@@ -22,16 +22,14 @@ along with LOOT. If not, see
<https://www.gnu.org/licenses/>.
*/
#ifndef LOOT_TESTS_API_INTERNALS_METADATA_LOCATION_TEST
#define LOOT_TESTS_API_INTERNALS_METADATA_LOCATION_TEST
#ifndef LOOT_TESTS_API_INTERFACE_METADATA_LOCATION_TEST
#define LOOT_TESTS_API_INTERFACE_METADATA_LOCATION_TEST
#include <gtest/gtest.h>
#include "api/metadata/yaml/location.h"
#include "loot/metadata/location.h"
namespace loot {
namespace test {
namespace loot::test {
TEST(Location, defaultConstructorShouldInitialiseEmptyStrings) {
Location location;
@@ -234,66 +232,6 @@ TEST(
EXPECT_TRUE(location2 >= location1);
EXPECT_FALSE(location1 >= location2);
}
TEST(Location, emittingAsYamlShouldOutputAScalarIfTheNameStringIsEmpty) {
Location location("http://www.example.com");
YAML::Emitter emitter;
emitter << location;
EXPECT_EQ("'" + location.GetURL() + "'", emitter.c_str());
}
TEST(Location, emittingAsYamlShouldOutputAMapIfTheNameStringIsNotEmpty) {
Location location("http://www.example.com", "example");
YAML::Emitter emitter;
emitter << location;
EXPECT_EQ(
"link: '" + location.GetURL() + "'\nname: '" + location.GetName() + "'",
emitter.c_str());
}
TEST(Location, encodingAsYamlShouldStoreDataCorrectly) {
Location location("http://www.example.com", "example");
YAML::Node node;
node = location;
EXPECT_EQ(location.GetURL(), node["link"].as<std::string>());
EXPECT_EQ(location.GetName(), node["name"].as<std::string>());
}
TEST(Location, encodingAsYamlShouldOmitEmptyFields) {
Location location("http://www.example.com");
YAML::Node node;
node = location;
EXPECT_EQ(location.GetURL(), node["link"].as<std::string>());
EXPECT_FALSE(node["name"]);
}
TEST(Location, decodingFromYamlShouldSetDataCorrectly) {
YAML::Node node = YAML::Load("{link: http://www.example.com, name: example}");
Location location = node.as<Location>();
EXPECT_EQ(node["link"].as<std::string>(), location.GetURL());
EXPECT_EQ(node["name"].as<std::string>(), location.GetName());
}
TEST(Location,
decodingFromYamlScalarShouldSetUrlToScalarValueAndLeaveNameEmpty) {
YAML::Node node = YAML::Load("http://www.example.com");
Location location = node.as<Location>();
EXPECT_EQ(node.as<std::string>(), location.GetURL());
EXPECT_TRUE(location.GetName().empty());
}
TEST(Location, decodingFromYamlShouldThrowIfAListIsGiven) {
YAML::Node node = YAML::Load("[0, 1, 2]");
EXPECT_THROW(node.as<Location>(), YAML::RepresentationException);
}
}
}
#endif
@@ -22,16 +22,14 @@ along with LOOT. If not, see
<https://www.gnu.org/licenses/>.
*/
#ifndef LOOT_TESTS_API_INTERNALS_METADATA_MESSAGE_CONTENT_TEST
#define LOOT_TESTS_API_INTERNALS_METADATA_MESSAGE_CONTENT_TEST
#ifndef LOOT_TESTS_API_INTERFACE_METADATA_MESSAGE_CONTENT_TEST
#define LOOT_TESTS_API_INTERFACE_METADATA_MESSAGE_CONTENT_TEST
#include <gtest/gtest.h>
#include "api/metadata/yaml/message_content.h"
#include "loot/metadata/message_content.h"
namespace loot {
namespace test {
namespace loot::test {
const std::string french = "fr";
TEST(MessageContent, defaultConstructorShouldSetEmptyEnglishLanguageString) {
@@ -330,45 +328,6 @@ TEST(
EXPECT_EQ("pt_PT", content.value().GetLanguage());
EXPECT_EQ("test3", content.value().GetText());
}
TEST(MessageContent, emittingAsYamlShouldOutputDataCorrectly) {
MessageContent content("content", french);
YAML::Emitter emitter;
emitter << content;
EXPECT_EQ("lang: " + french + "\ntext: '" + content.GetText() + "'",
emitter.c_str());
}
TEST(MessageContent, encodingAsYamlShouldOutputDataCorrectly) {
MessageContent content("content", french);
YAML::Node node;
node = content;
EXPECT_EQ(content.GetText(), node["text"].as<std::string>());
EXPECT_EQ(french, node["lang"].as<std::string>());
}
TEST(MessageContent, decodingFromYamlShouldSetDataCorrectly) {
YAML::Node node = YAML::Load("{text: content, lang: fr}");
MessageContent content = node.as<MessageContent>();
EXPECT_EQ("content", content.GetText());
EXPECT_EQ(french, content.GetLanguage());
}
TEST(MessageContent, decodingFromYamlScalarShouldThrow) {
YAML::Node node = YAML::Load("scalar");
EXPECT_THROW(node.as<MessageContent>(), YAML::RepresentationException);
}
TEST(MessageContent, decodingFromYamlListShouldThrow) {
YAML::Node node = YAML::Load("[0, 1, 2]");
EXPECT_THROW(node.as<MessageContent>(), YAML::RepresentationException);
}
}
}
#endif
@@ -22,16 +22,13 @@ along with LOOT. If not, see
<https://www.gnu.org/licenses/>.
*/
#ifndef LOOT_TESTS_API_INTERNALS_METADATA_MESSAGE_TEST
#define LOOT_TESTS_API_INTERNALS_METADATA_MESSAGE_TEST
#ifndef LOOT_TESTS_API_INTERFACE_METADATA_MESSAGE_TEST
#define LOOT_TESTS_API_INTERFACE_METADATA_MESSAGE_TEST
#include "api/game/game.h"
#include "api/metadata/yaml/message.h"
#include "loot/metadata/message.h"
#include "tests/common_game_test_fixture.h"
namespace loot {
namespace test {
namespace loot::test {
class MessageTest : public CommonGameTestFixture {
protected:
MessageTest() : CommonGameTestFixture(GameType::tes4) {}
@@ -343,339 +340,6 @@ TEST_F(
EXPECT_FALSE(message1 >= message2);
EXPECT_TRUE(message2 >= message1);
}
TEST_F(MessageTest, emittingAsYamlShouldOutputNoteMessageTypeCorrectly) {
Message message(MessageType::say, "content1");
YAML::Emitter emitter;
emitter << message;
EXPECT_STREQ(
"type: say\n"
"content: 'content1'",
emitter.c_str());
}
TEST_F(MessageTest, emittingAsYamlShouldOutputWarnMessageTypeCorrectly) {
Message message(MessageType::warn, "content1");
YAML::Emitter emitter;
emitter << message;
EXPECT_STREQ(
"type: warn\n"
"content: 'content1'",
emitter.c_str());
}
TEST_F(MessageTest, emittingAsYamlShouldOutputErrorMessageTypeCorrectly) {
Message message(MessageType::error, "content1");
YAML::Emitter emitter;
emitter << message;
EXPECT_STREQ(
"type: error\n"
"content: 'content1'",
emitter.c_str());
}
TEST_F(MessageTest, emittingAsYamlShouldOutputConditionIfItIsNotEmpty) {
Message message(MessageType::say, "content1", "condition1");
YAML::Emitter emitter;
emitter << message;
EXPECT_STREQ(
"type: say\n"
"content: 'content1'\n"
"condition: 'condition1'",
emitter.c_str());
}
TEST_F(MessageTest, emittingAsYamlShouldOutputMultipleContentStringsAsAList) {
Message message(MessageType::say,
MessageContents({MessageContent("content1"),
MessageContent("content2", french)}));
YAML::Emitter emitter;
emitter << message;
EXPECT_STREQ(
"type: say\n"
"content:\n"
" - lang: en\n"
" text: 'content1'\n"
" - lang: fr\n"
" text: 'content2'",
emitter.c_str());
}
TEST_F(MessageTest, encodingAsYamlShouldStoreNoteMessageTypeCorrectly) {
Message message(MessageType::say, "content1");
YAML::Node node;
node = message;
EXPECT_EQ("say", node["type"].as<std::string>());
}
TEST_F(MessageTest, encodingAsYamlShouldStoreWarningMessageTypeCorrectly) {
Message message(MessageType::warn, "content1");
YAML::Node node;
node = message;
EXPECT_EQ("warn", node["type"].as<std::string>());
}
TEST_F(MessageTest, encodingAsYamlShouldStoreErrorMessageTypeCorrectly) {
Message message(MessageType::error, "content1");
YAML::Node node;
node = message;
EXPECT_EQ("error", node["type"].as<std::string>());
}
TEST_F(MessageTest, encodingAsYamlShouldOmitConditionFieldIfItIsEmpty) {
Message message(MessageType::say, "content1");
YAML::Node node;
node = message;
EXPECT_FALSE(node["condition"]);
}
TEST_F(MessageTest, encodingAsYamlShouldStoreConditionFieldIfItIsNotEmpty) {
Message message(MessageType::say, "content1", "condition1");
YAML::Node node;
node = message;
EXPECT_EQ("condition1", node["condition"].as<std::string>());
}
TEST_F(MessageTest, encodingAsYamlShouldStoreASingleContentStringInAVector) {
Message message(MessageType::say, "content1");
YAML::Node node;
node = message;
EXPECT_EQ(message.GetContent(), node["content"].as<MessageContents>());
}
TEST_F(MessageTest, encodingAsYamlShouldMultipleContentStringsInAVector) {
MessageContents contents({
MessageContent("content1"),
MessageContent("content2", french),
});
Message message(MessageType::say, contents);
YAML::Node node;
node = message;
EXPECT_EQ(contents, node["content"].as<MessageContents>());
}
TEST_F(MessageTest, decodingFromYamlShouldSetNoteTypeCorrectly) {
YAML::Node node = YAML::Load(
"type: say\n"
"content: content1");
Message message = node.as<Message>();
EXPECT_EQ(MessageType::say, message.GetType());
}
TEST_F(MessageTest, decodingFromYamlShouldSetWarningTypeCorrectly) {
YAML::Node node = YAML::Load(
"type: warn\n"
"content: content1");
Message message = node.as<Message>();
EXPECT_EQ(MessageType::warn, message.GetType());
}
TEST_F(MessageTest, decodingFromYamlShouldSetErrorTypeCorrectly) {
YAML::Node node = YAML::Load(
"type: error\n"
"content: content1");
Message message = node.as<Message>();
EXPECT_EQ(MessageType::error, message.GetType());
}
TEST_F(MessageTest, decodingFromYamlShouldHandleAnUnrecognisedTypeAsANote) {
YAML::Node node = YAML::Load(
"type: invalid\n"
"content: content1");
Message message = node.as<Message>();
EXPECT_EQ(MessageType::say, message.GetType());
}
TEST_F(MessageTest,
decodingFromYamlShouldLeaveTheConditionEmptyIfNoneIsPresent) {
YAML::Node node = YAML::Load(
"type: say\n"
"content: content1");
Message message = node.as<Message>();
EXPECT_TRUE(message.GetCondition().empty());
}
TEST_F(MessageTest, decodingFromYamlShouldStoreANonEmptyConditionField) {
YAML::Node node = YAML::Load(
"type: say\n"
"content: content1\n"
"condition: 'file(\"Foo.esp\")'");
Message message = node.as<Message>();
EXPECT_EQ("file(\"Foo.esp\")", message.GetCondition());
}
TEST_F(MessageTest, decodingFromYamlShouldStoreAScalarContentValueCorrectly) {
YAML::Node node = YAML::Load(
"type: say\n"
"content: content1\n");
Message message = node.as<Message>();
MessageContents expectedContent({MessageContent("content1")});
EXPECT_EQ(expectedContent, message.GetContent());
}
TEST_F(MessageTest, decodingFromYamlShouldStoreAListOfContentStringsCorrectly) {
YAML::Node node = YAML::Load(
"type: say\n"
"content:\n"
" - lang: en\n"
" text: content1\n"
" - lang: fr\n"
" text: content2");
Message message = node.as<Message>();
EXPECT_EQ(MessageContents({
MessageContent("content1"),
MessageContent("content2", french),
}),
message.GetContent());
}
TEST_F(MessageTest,
decodingFromYamlShouldNotThrowIfTheOnlyContentStringIsNotEnglish) {
YAML::Node node = YAML::Load(
"type: say\n"
"content:\n"
" - lang: fr\n"
" text: content1");
EXPECT_NO_THROW(Message message = node.as<Message>());
}
TEST_F(
MessageTest,
decodingFromYamlShouldThrowIfMultipleContentStringsAreGivenAndNoneAreEnglish) {
YAML::Node node = YAML::Load(
"type: say\n"
"content:\n"
" - lang: de\n"
" text: content1\n"
" - lang: fr\n"
" text: content2");
EXPECT_THROW(node.as<Message>(), YAML::RepresentationException);
}
TEST_F(
MessageTest,
decodingFromYamlShouldApplySubstitutionsWhenThereIsOnlyOneContentString) {
YAML::Node node = YAML::Load(
"type: say\n"
"content: con{0}tent1\n"
"subs:\n"
" - sub1");
Message message = node.as<Message>();
EXPECT_EQ(MessageContents({MessageContent("consub1tent1")}),
message.GetContent());
}
TEST_F(MessageTest,
decodingFromYamlShouldApplySubstitutionsToAllContentStrings) {
YAML::Node node = YAML::Load(
"type: say\n"
"content:\n"
" - lang: en\n"
" text: content1 {0}\n"
" - lang: fr\n"
" text: content2 {0}\n"
"subs:\n"
" - sub");
Message message = node.as<Message>();
EXPECT_EQ(MessageContents({
MessageContent("content1 sub"),
MessageContent("content2 sub", french),
}),
message.GetContent());
}
TEST_F(
MessageTest,
decodingFromYamlShouldThrowIfTheContentStringExpectsMoreSubstitutionsThanExist) {
YAML::Node node = YAML::Load(
"type: say\n"
"content: '{0} {1}'\n"
"subs:\n"
" - sub1");
EXPECT_THROW(node.as<Message>(), YAML::RepresentationException);
}
// Don't throw because no subs are given, so none are expected in the content
// string.
TEST_F(MessageTest,
decodingFromYamlShouldIgnoreSubstitutionSyntaxIfNoSubstitutionsExist) {
YAML::Node node = YAML::Load(
"type: say\n"
"content: con{0}tent1\n");
Message message = node.as<Message>();
EXPECT_EQ(MessageContents({MessageContent("con{0}tent1")}),
message.GetContent());
}
TEST_F(MessageTest, decodingFromYamlShouldAcceptPercentagePlaceholderSyntax) {
YAML::Node node = YAML::Load(
"type: say\n"
"content: content %1% %2% %3% %4% %5% %6% %7% %8% %9% %10% %11%\n"
"subs:\n"
" - a\n"
" - b\n"
" - c\n"
" - d\n"
" - e\n"
" - f\n"
" - g\n"
" - h\n"
" - i\n"
" - j\n"
" - k");
Message message = node.as<Message>();
ASSERT_EQ(1, message.GetContent().size());
EXPECT_EQ("content a b c d e f g h i j k", message.GetContent()[0].GetText());
}
TEST_F(MessageTest, decodingFromYamlShouldThrowIfAnInvalidConditionIsGiven) {
YAML::Node node = YAML::Load(
"type: say\n"
"content: content1\n"
"condition: invalid");
EXPECT_THROW(node.as<Message>(), YAML::RepresentationException);
}
TEST_F(MessageTest, decodingFromYamlShouldThrowIfAScalarIsGiven) {
YAML::Node node = YAML::Load("scalar");
EXPECT_THROW(node.as<Message>(), YAML::RepresentationException);
}
TEST_F(MessageTest, decodingFromYamlShouldThrowIfAListIsGiven) {
YAML::Node node = YAML::Load("[0, 1, 2]");
EXPECT_THROW(node.as<Message>(), YAML::RepresentationException);
}
}
}
#endif
@@ -22,16 +22,13 @@ along with LOOT. If not, see
<https://www.gnu.org/licenses/>.
*/
#ifndef LOOT_TESTS_API_INTERNALS_METADATA_PLUGIN_CLEANING_DATA
#define LOOT_TESTS_API_INTERNALS_METADATA_PLUGIN_CLEANING_DATA
#ifndef LOOT_TESTS_API_INTERFACE_METADATA_PLUGIN_CLEANING_DATA_TEST
#define LOOT_TESTS_API_INTERFACE_METADATA_PLUGIN_CLEANING_DATA_TEST
#include "api/game/game.h"
#include "api/metadata/yaml/plugin_cleaning_data.h"
#include "loot/metadata/plugin_cleaning_data.h"
#include "tests/common_game_test_fixture.h"
namespace loot {
namespace test {
namespace loot::test {
class PluginCleaningDataTest : public CommonGameTestFixture {
protected:
PluginCleaningDataTest() :
@@ -311,120 +308,6 @@ TEST_F(
EXPECT_FALSE(info1 > info2);
EXPECT_TRUE(info2 > info1);
}
TEST_F(PluginCleaningDataTest, emittingAsYamlShouldOutputAllNonZeroCounts) {
PluginCleaningData info(0x12345678, "cleaner", info_, 2, 10, 30);
YAML::Emitter emitter;
emitter << info;
EXPECT_STREQ(
"crc: 0x12345678\nutil: 'cleaner'\ndetail: 'info'\nitm: 2\nudr: 10\nnav: "
"30",
emitter.c_str());
}
TEST_F(PluginCleaningDataTest, emittingAsYamlShouldOmitAllZeroCounts) {
PluginCleaningData info(0x12345678, "cleaner", info_, 0, 0, 0);
YAML::Emitter emitter;
emitter << info;
EXPECT_STREQ("crc: 0x12345678\nutil: 'cleaner'\ndetail: 'info'",
emitter.c_str());
}
TEST_F(PluginCleaningDataTest, encodingAsYamlShouldOmitAllZeroCountFields) {
PluginCleaningData info(0x12345678, "cleaner", info_, 0, 0, 0);
YAML::Node node;
node = info;
EXPECT_EQ(0x12345678u, node["crc"].as<uint32_t>());
EXPECT_EQ("cleaner", node["util"].as<std::string>());
EXPECT_EQ(info_, node["detail"].as<std::vector<MessageContent>>());
EXPECT_FALSE(node["itm"]);
EXPECT_FALSE(node["udr"]);
EXPECT_FALSE(node["nav"]);
}
TEST_F(PluginCleaningDataTest,
encodingAsYamlShouldOutputAllNonZeroCountFields) {
PluginCleaningData info(0x12345678, "cleaner", info_, 2, 10, 30);
YAML::Node node;
node = info;
EXPECT_EQ(0x12345678u, node["crc"].as<uint32_t>());
EXPECT_EQ("cleaner", node["util"].as<std::string>());
EXPECT_EQ(info_, node["detail"].as<std::vector<MessageContent>>());
EXPECT_EQ(2u, node["itm"].as<unsigned int>());
EXPECT_EQ(10u, node["udr"].as<unsigned int>());
EXPECT_EQ(30u, node["nav"].as<unsigned int>());
}
TEST_F(PluginCleaningDataTest,
decodingFromYamlShouldLeaveMissingFieldsWithZeroValues) {
YAML::Node node = YAML::Load("{crc: 0x12345678, util: cleaner}");
PluginCleaningData info = node.as<PluginCleaningData>();
EXPECT_EQ(0x12345678u, info.GetCRC());
EXPECT_TRUE(info.GetDetail().empty());
EXPECT_EQ(0u, info.GetITMCount());
EXPECT_EQ(0u, info.GetDeletedReferenceCount());
EXPECT_EQ(0u, info.GetDeletedNavmeshCount());
EXPECT_EQ("cleaner", info.GetCleaningUtility());
}
TEST_F(PluginCleaningDataTest, decodingFromYamlShouldStoreAllNonZeroCounts) {
YAML::Node node = YAML::Load(
"{crc: 0x12345678, util: cleaner, detail: info, itm: 2, udr: 10, nav: "
"30}");
PluginCleaningData info = node.as<PluginCleaningData>();
EXPECT_EQ(0x12345678u, info.GetCRC());
EXPECT_EQ(info_, info.GetDetail());
EXPECT_EQ(2u, info.GetITMCount());
EXPECT_EQ(10u, info.GetDeletedReferenceCount());
EXPECT_EQ(30u, info.GetDeletedNavmeshCount());
EXPECT_EQ("cleaner", info.GetCleaningUtility());
}
TEST_F(PluginCleaningDataTest,
decodingFromYamlShouldNotThrowIfTheOnlyDetailStringIsNotEnglish) {
YAML::Node node = YAML::Load(
"crc: 0x12345678\n"
"util: cleaner\n"
"detail:\n"
" - lang: fr\n"
" text: content1");
EXPECT_NO_THROW(node.as<PluginCleaningData>());
}
TEST_F(
PluginCleaningDataTest,
decodingFromYamlShouldThrowIfMultipleDetailStringsAreGivenAndNoneAreEnglish) {
YAML::Node node = YAML::Load(
"crc: 0x12345678\n"
"util: cleaner\n"
"detail:\n"
" - lang: de\n"
" text: content1\n"
" - lang: fr\n"
" text: content2");
EXPECT_THROW(node.as<PluginCleaningData>(), YAML::RepresentationException);
}
TEST_F(PluginCleaningDataTest, decodingFromYamlScalarShouldThrow) {
YAML::Node node = YAML::Load("scalar");
EXPECT_THROW(node.as<PluginCleaningData>(), YAML::RepresentationException);
}
TEST_F(PluginCleaningDataTest, decodingFromYamlListShouldThrow) {
YAML::Node node = YAML::Load("[0, 1, 2]");
EXPECT_THROW(node.as<PluginCleaningData>(), YAML::RepresentationException);
}
}
}
#endif
@@ -0,0 +1,395 @@
/* LOOT
A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and
Fallout: New Vegas.
Copyright (C) 2014-2016 WrinklyNinja
This file is part of LOOT.
LOOT is free software: you can redistribute
it and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
LOOT is distributed in the hope that it will
be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with LOOT. If not, see
<https://www.gnu.org/licenses/>.
*/
#ifndef LOOT_TESTS_API_INTERFACE_METADATA_PLUGIN_METADATA_TEST
#define LOOT_TESTS_API_INTERFACE_METADATA_PLUGIN_METADATA_TEST
#include "loot/metadata/plugin_metadata.h"
#include "tests/common_game_test_fixture.h"
namespace loot::test {
class PluginMetadataTest : public CommonGameTestFixture {
protected:
PluginMetadataTest() :
CommonGameTestFixture(GameType::tes5),
info_(std::vector<MessageContent>({
MessageContent("info"),
})) {}
const std::vector<MessageContent> info_;
};
TEST_F(
PluginMetadataTest,
defaultConstructorShouldLeaveNameEmptyAndEnableMetadataAndLeaveGroupUnset) {
PluginMetadata plugin;
EXPECT_TRUE(plugin.GetName().empty());
EXPECT_FALSE(plugin.GetGroup());
}
TEST_F(
PluginMetadataTest,
stringConstructorShouldSetNameToGivenStringAndEnableMetadataAndLeaveGroupUnset) {
PluginMetadata plugin(blankEsm);
EXPECT_EQ(blankEsm, plugin.GetName());
EXPECT_FALSE(plugin.GetGroup());
}
TEST_F(PluginMetadataTest,
nameMatchesShouldUseCaseInsensitiveNameComparisonForNonRegexNames) {
PluginMetadata plugin(blankEsm);
EXPECT_TRUE(plugin.NameMatches(boost::to_lower_copy(blankEsm)));
EXPECT_FALSE(plugin.NameMatches(blankDifferentEsm));
}
TEST_F(PluginMetadataTest,
nameMatchesShouldTreatGivenPluginNameStringsAsLiterals) {
PluginMetadata plugin(blankEsm);
std::string regex = "blan.\\.esm";
EXPECT_FALSE(plugin.NameMatches(regex));
}
TEST_F(PluginMetadataTest,
nameMatchesShouldUseCaseInsensitiveRegexMatchingForARegexName) {
PluginMetadata plugin("Blan.\\.esm");
EXPECT_TRUE(plugin.NameMatches(boost::to_lower_copy(blankEsm)));
EXPECT_FALSE(plugin.NameMatches(blankDifferentEsm));
}
TEST_F(PluginMetadataTest, mergeMetadataShouldNotChangeName) {
PluginMetadata plugin1(blankEsm);
PluginMetadata plugin2(blankDifferentEsm);
plugin1.MergeMetadata(plugin2);
EXPECT_EQ(blankEsm, plugin1.GetName());
}
TEST_F(PluginMetadataTest,
mergeMetadataShouldNotUseMergedGroupIfItAndCurrentGroupAreBothExplicit) {
PluginMetadata plugin1;
PluginMetadata plugin2;
plugin1.SetGroup("group1");
plugin2.SetGroup("group2");
plugin1.MergeMetadata(plugin2);
EXPECT_EQ("group1", plugin1.GetGroup());
}
TEST_F(PluginMetadataTest,
mergeMetadataShouldNotUseMergedGroupIfItAndCurrentGroupAreBothImplicit) {
PluginMetadata plugin1;
PluginMetadata plugin2;
plugin1.MergeMetadata(plugin2);
EXPECT_FALSE(plugin1.GetGroup().has_value());
}
TEST_F(
PluginMetadataTest,
mergeMetadataShouldNotUseMergedGroupIfItIsImplicitAndCurrentGroupIsExplicit) {
PluginMetadata plugin1;
PluginMetadata plugin2;
plugin1.SetGroup("group1");
plugin1.MergeMetadata(plugin2);
EXPECT_EQ("group1", plugin1.GetGroup());
}
TEST_F(
PluginMetadataTest,
mergeMetadataShouldUseMergedGroupIfItIsExplicitAndCurrentGroupIsImplicit) {
PluginMetadata plugin1;
PluginMetadata plugin2;
plugin2.SetGroup("group2");
plugin1.MergeMetadata(plugin2);
EXPECT_EQ("group2", plugin1.GetGroup());
}
TEST_F(PluginMetadataTest, mergeMetadataShouldMergeLoadAfterData) {
PluginMetadata plugin1;
PluginMetadata plugin2;
File file1(blankEsm);
File file2(blankDifferentEsm);
plugin1.SetLoadAfterFiles({file1});
plugin2.SetLoadAfterFiles({file1, file2});
plugin1.MergeMetadata(plugin2);
EXPECT_EQ(std::vector<File>({file1, file2}), plugin1.GetLoadAfterFiles());
}
TEST_F(PluginMetadataTest, mergeMetadataShouldMergeRequirementData) {
PluginMetadata plugin1;
PluginMetadata plugin2;
File file1(blankEsm);
File file2(blankDifferentEsm);
plugin1.SetRequirements({file1});
plugin2.SetRequirements({file1, file2});
plugin1.MergeMetadata(plugin2);
EXPECT_EQ(std::vector<File>({file1, file2}), plugin1.GetRequirements());
}
TEST_F(PluginMetadataTest, mergeMetadataShouldMergeIncompatibilityData) {
PluginMetadata plugin1;
PluginMetadata plugin2;
File file1(blankEsm);
File file2(blankDifferentEsm);
plugin1.SetIncompatibilities({file1});
plugin2.SetIncompatibilities({file1, file2});
plugin1.MergeMetadata(plugin2);
EXPECT_EQ(std::vector<File>({file1, file2}), plugin1.GetIncompatibilities());
}
TEST_F(PluginMetadataTest, mergeMetadataShouldMergeMessages) {
PluginMetadata plugin1;
PluginMetadata plugin2;
Message message(MessageType::say, "content");
plugin1.SetMessages({message});
plugin2.SetMessages({message});
plugin1.MergeMetadata(plugin2);
EXPECT_EQ(std::vector<Message>({message, message}), plugin1.GetMessages());
}
TEST_F(PluginMetadataTest, mergeMetadataShouldMergeTags) {
PluginMetadata plugin1;
PluginMetadata plugin2;
Tag tag1("Relev");
Tag tag2("Relev", false);
Tag tag3("Delev");
plugin1.SetTags({tag1});
plugin2.SetTags({tag1, tag2, tag3});
plugin1.MergeMetadata(plugin2);
EXPECT_EQ(std::vector<Tag>({tag1, tag2, tag3}), plugin1.GetTags());
}
TEST_F(PluginMetadataTest, mergeMetadataShouldMergeDirtyInfoData) {
PluginMetadata plugin1;
PluginMetadata plugin2;
PluginCleaningData info1(0x5, "utility", info_, 1, 2, 3);
PluginCleaningData info2(0xA, "utility", info_, 1, 2, 3);
plugin1.SetDirtyInfo({info1});
plugin2.SetDirtyInfo({info1, info2});
plugin1.MergeMetadata(plugin2);
EXPECT_EQ(std::vector<PluginCleaningData>({info1, info2}),
plugin1.GetDirtyInfo());
}
TEST_F(PluginMetadataTest, mergeMetadataShouldMergeCleanInfoData) {
PluginMetadata plugin1;
PluginMetadata plugin2;
PluginCleaningData info1(0x5, "utility");
PluginCleaningData info2(0xA, "utility");
plugin1.SetCleanInfo({info1});
plugin2.SetCleanInfo({info1, info2});
plugin1.MergeMetadata(plugin2);
EXPECT_EQ(std::vector<PluginCleaningData>({info1, info2}),
plugin1.GetCleanInfo());
}
TEST_F(PluginMetadataTest, mergeMetadataShouldMergeLocationData) {
PluginMetadata plugin1;
PluginMetadata plugin2;
Location location1("http://www.example.com/1");
Location location2("http://www.example.com/2");
plugin1.SetLocations({location1});
plugin2.SetLocations({location1, location2});
plugin1.MergeMetadata(plugin2);
EXPECT_EQ(std::vector<Location>({location1, location2}),
plugin1.GetLocations());
}
TEST_F(PluginMetadataTest, unsetGroupShouldLeaveNoGroupValueSet) {
PluginMetadata plugin;
EXPECT_FALSE(plugin.GetGroup().has_value());
plugin.SetGroup("test");
EXPECT_EQ("test", plugin.GetGroup().value());
plugin.UnsetGroup();
EXPECT_FALSE(plugin.GetGroup().has_value());
}
TEST_F(PluginMetadataTest,
hasNameOnlyShouldBeTrueForADefaultConstructedPluginMetadataObject) {
PluginMetadata plugin;
EXPECT_TRUE(plugin.HasNameOnly());
}
TEST_F(PluginMetadataTest,
hasNameOnlyShouldBeTrueForAPluginMetadataObjectConstructedWithAName) {
PluginMetadata plugin(blankEsp);
EXPECT_TRUE(plugin.HasNameOnly());
}
TEST_F(PluginMetadataTest, hasNameOnlyShouldBeFalseIfTheGroupIsExplicit) {
PluginMetadata plugin;
plugin.SetGroup("group");
EXPECT_FALSE(plugin.HasNameOnly());
}
TEST_F(PluginMetadataTest, hasNameOnlyShouldBeFalseIfLoadAfterMetadataExists) {
PluginMetadata plugin(blankEsp);
plugin.SetLoadAfterFiles({File(blankEsm)});
EXPECT_FALSE(plugin.HasNameOnly());
}
TEST_F(PluginMetadataTest,
hasNameOnlyShouldBeFalseIfRequirementMetadataExists) {
PluginMetadata plugin(blankEsp);
plugin.SetRequirements({File(blankEsm)});
EXPECT_FALSE(plugin.HasNameOnly());
}
TEST_F(PluginMetadataTest,
hasNameOnlyShouldBeFalseIfIncompatibilityMetadataExists) {
PluginMetadata plugin(blankEsp);
plugin.SetIncompatibilities({File(blankEsm)});
EXPECT_FALSE(plugin.HasNameOnly());
}
TEST_F(PluginMetadataTest, hasNameOnlyShouldBeFalseIfMessagesExist) {
PluginMetadata plugin(blankEsp);
plugin.SetMessages({Message(MessageType::say, "content")});
EXPECT_FALSE(plugin.HasNameOnly());
}
TEST_F(PluginMetadataTest, hasNameOnlyShouldBeFalseIfTagsExist) {
PluginMetadata plugin(blankEsp);
plugin.SetTags({Tag("Relev")});
EXPECT_FALSE(plugin.HasNameOnly());
}
TEST_F(PluginMetadataTest, hasNameOnlyShouldBeFalseIfDirtyInfoExists) {
PluginMetadata plugin(blankEsp);
plugin.SetDirtyInfo({PluginCleaningData(5, "utility", info_, 0, 1, 2)});
EXPECT_FALSE(plugin.HasNameOnly());
}
TEST_F(PluginMetadataTest, hasNameOnlyShouldBeFalseIfCleanInfoExists) {
PluginMetadata plugin(blankEsp);
plugin.SetCleanInfo({PluginCleaningData(5, "utility")});
EXPECT_FALSE(plugin.HasNameOnly());
}
TEST_F(PluginMetadataTest, hasNameOnlyShouldBeFalseIfLocationsExist) {
PluginMetadata plugin(blankEsp);
plugin.SetLocations({Location("http://www.example.com")});
EXPECT_FALSE(plugin.HasNameOnly());
}
TEST_F(PluginMetadataTest, isRegexPluginShouldBeFalseForAnEmptyPluginName) {
PluginMetadata plugin;
EXPECT_FALSE(plugin.IsRegexPlugin());
}
TEST_F(PluginMetadataTest, isRegexPluginShouldBeFalseForAnExactPluginFilename) {
PluginMetadata plugin(blankEsm);
EXPECT_FALSE(plugin.IsRegexPlugin());
}
TEST_F(PluginMetadataTest,
isRegexPluginShouldBeTrueIfThePluginNameContainsAColon) {
PluginMetadata plugin("Blank:.esm");
EXPECT_TRUE(plugin.IsRegexPlugin());
}
TEST_F(PluginMetadataTest,
isRegexPluginShouldBeTrueIfThePluginNameContainsABackslash) {
PluginMetadata plugin("Blank\\.esm");
EXPECT_TRUE(plugin.IsRegexPlugin());
}
TEST_F(PluginMetadataTest,
isRegexPluginShouldBeTrueIfThePluginNameContainsAnAsterisk) {
PluginMetadata plugin("Blank*.esm");
EXPECT_TRUE(plugin.IsRegexPlugin());
}
TEST_F(PluginMetadataTest,
isRegexPluginShouldBeTrueIfThePluginNameContainsAQuestionMark) {
PluginMetadata plugin("Blank?.esm");
EXPECT_TRUE(plugin.IsRegexPlugin());
}
TEST_F(PluginMetadataTest,
isRegexPluginShouldBeTrueIfThePluginNameContainsAVerticalBar) {
PluginMetadata plugin("Blank|.esm");
EXPECT_TRUE(plugin.IsRegexPlugin());
}
TEST_F(PluginMetadataTest,
asYamlShouldReturnAStringContainingTheMetadataEmittedAsYaml) {
PluginMetadata plugin(blankEsm);
plugin.SetLoadAfterFiles({File(blankEsm)});
EXPECT_EQ(
"name: 'Blank.esm'\n"
"after: ['Blank.esm']",
plugin.AsYaml());
}
}
#endif
@@ -22,16 +22,14 @@ along with LOOT. If not, see
<https://www.gnu.org/licenses/>.
*/
#ifndef LOOT_TESTS_API_INTERNALS_METADATA_TAG_TEST
#define LOOT_TESTS_API_INTERNALS_METADATA_TAG_TEST
#ifndef LOOT_TESTS_API_INTERFACE_METADATA_TAG_TEST
#define LOOT_TESTS_API_INTERFACE_METADATA_TAG_TEST
#include <gtest/gtest.h>
#include "api/metadata/yaml/tag.h"
#include "loot/metadata/tag.h"
namespace loot {
namespace test {
namespace loot::test {
TEST(Tag,
defaultConstructorShouldSetEmptyNameAndConditionStringsForATagAddition) {
Tag tag;
@@ -284,112 +282,6 @@ TEST(
EXPECT_FALSE(tag1 >= tag2);
EXPECT_TRUE(tag2 >= tag1);
}
TEST(
Tag,
emittingAsYamlShouldOutputOnlyTheNameStringIfTheTagIsAnAdditionWithNoCondition) {
Tag tag("name1");
YAML::Emitter emitter;
emitter << tag;
EXPECT_EQ(tag.GetName(), emitter.c_str());
}
TEST(
Tag,
emittingAsYamlShouldOutputOnlyTheNameStringPrefixedWithAHyphenIfTheTagIsARemovalWithNoCondition) {
Tag tag("name1", false);
YAML::Emitter emitter;
emitter << tag;
EXPECT_EQ("-" + tag.GetName(), emitter.c_str());
}
TEST(Tag, emittingAsYamlShouldOutputAMapIfTheTagHasACondition) {
Tag tag("name1", false, "condition1");
YAML::Emitter emitter;
emitter << tag;
EXPECT_STREQ("name: -name1\ncondition: 'condition1'", emitter.c_str());
}
TEST(Tag,
encodingAsYamlShouldOmitTheConditionFieldIfTheConditionStringIsEmpty) {
Tag tag;
YAML::Node node;
node = tag;
EXPECT_FALSE(node["condition"]);
}
TEST(Tag, encodingAsYamlShouldOutputTheNameFieldCorrectly) {
Tag tag("name1");
YAML::Node node;
node = tag;
EXPECT_EQ(tag.GetName(), node["name"].as<std::string>());
}
TEST(
Tag,
encodingAsYamlShouldOutputTheNameFieldWithAHyphenPrefixIfTheTagIsARemoval) {
Tag tag("name1", false);
YAML::Node node;
node = tag;
EXPECT_EQ("-" + tag.GetName(), node["name"].as<std::string>());
}
TEST(
Tag,
encodingAsYamlShouldOutputTheConditionFieldIfTheConditionStringIsNotEmpty) {
Tag tag("name1", true, "condition1");
YAML::Node node;
node = tag;
EXPECT_EQ(tag.GetName(), node["name"].as<std::string>());
EXPECT_EQ(tag.GetCondition(), node["condition"].as<std::string>());
}
TEST(Tag, decodingFromYamlScalarShouldSetNameCorrectly) {
YAML::Node node = YAML::Load("name1");
Tag tag = node.as<Tag>();
EXPECT_EQ("name1", tag.GetName());
EXPECT_TRUE(tag.IsAddition());
EXPECT_EQ("", tag.GetCondition());
}
TEST(Tag, decodingFromYamlScalarShouldSetAdditionStateCorrectly) {
YAML::Node node = YAML::Load("-name1");
Tag tag = node.as<Tag>();
EXPECT_EQ("name1", tag.GetName());
EXPECT_FALSE(tag.IsAddition());
EXPECT_EQ("", tag.GetCondition());
}
TEST(Tag, decodingFromYamlMapShouldSetDataCorrectly) {
YAML::Node node = YAML::Load("{name: name1, condition: 'file(\"Foo.esp\")'}");
Tag tag = node.as<Tag>();
EXPECT_EQ("name1", tag.GetName());
EXPECT_TRUE(tag.IsAddition());
EXPECT_EQ("file(\"Foo.esp\")", tag.GetCondition());
}
TEST(Tag, decodingFromYamlShouldThrowIfAnInvalidConditionIsGiven) {
YAML::Node node = YAML::Load("{name: name1, condition: invalid}");
EXPECT_THROW(node.as<Tag>(), YAML::RepresentationException);
}
TEST(Tag, decodingFromYamlListShouldThrow) {
YAML::Node node = YAML::Load("[0, 1, 2]");
EXPECT_THROW(node.as<Tag>(), YAML::RepresentationException);
}
}
}
#endif
+8 -9
View File
@@ -29,15 +29,14 @@
#include "tests/api/internals/helpers/crc_test.h"
#include "tests/api/internals/helpers/text_test.h"
#include "tests/api/internals/metadata/condition_evaluator_test.h"
#include "tests/api/internals/metadata/conditional_metadata_test.h"
#include "tests/api/internals/metadata/file_test.h"
#include "tests/api/internals/metadata/group_test.h"
#include "tests/api/internals/metadata/location_test.h"
#include "tests/api/internals/metadata/message_content_test.h"
#include "tests/api/internals/metadata/message_test.h"
#include "tests/api/internals/metadata/plugin_cleaning_data_test.h"
#include "tests/api/internals/metadata/plugin_metadata_test.h"
#include "tests/api/internals/metadata/tag_test.h"
#include "tests/api/internals/metadata/yaml/file_test.h"
#include "tests/api/internals/metadata/yaml/group_test.h"
#include "tests/api/internals/metadata/yaml/location_test.h"
#include "tests/api/internals/metadata/yaml/message_content_test.h"
#include "tests/api/internals/metadata/yaml/message_test.h"
#include "tests/api/internals/metadata/yaml/plugin_cleaning_data_test.h"
#include "tests/api/internals/metadata/yaml/plugin_metadata_test.h"
#include "tests/api/internals/metadata/yaml/tag_test.h"
#include "tests/api/internals/metadata_list_test.h"
#include "tests/api/internals/plugin_test.h"
#include "tests/api/internals/sorting/group_sort_test.h"
@@ -0,0 +1,201 @@
/* LOOT
A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and
Fallout: New Vegas.
Copyright (C) 2014-2016 WrinklyNinja
This file is part of LOOT.
LOOT is free software: you can redistribute
it and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
LOOT is distributed in the hope that it will
be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with LOOT. If not, see
<https://www.gnu.org/licenses/>.
*/
#ifndef LOOT_TESTS_API_INTERNALS_METADATA_YAML_FILE_TEST
#define LOOT_TESTS_API_INTERNALS_METADATA_YAML_FILE_TEST
#include <gtest/gtest.h>
#include "api/metadata/yaml/file.h"
namespace loot::test {
TEST(File, emittingAsYamlShouldSingleQuoteValues) {
File file("name1",
"display1",
"condition1",
{MessageContent("english", "en")},
"constraint1");
YAML::Emitter emitter;
emitter << file;
std::string expected = "name: '" + std::string(file.GetName()) +
"'\ncondition: '" + file.GetCondition() +
"'\ndisplay: '" + file.GetDisplayName() +
"'\nconstraint: '" + file.GetConstraint() +
"'\ndetail: '" + file.GetDetail()[0].GetText() + "'";
EXPECT_EQ(expected, emitter.c_str());
}
TEST(File, emittingAsYamlShouldOutputAsAScalarIfOnlyTheNameStringIsNotEmpty) {
File file("file.esp");
YAML::Emitter emitter;
emitter << file;
EXPECT_EQ("'" + std::string(file.GetName()) + "'", emitter.c_str());
}
TEST(File, emittingAsYamlShouldOmitEmptyConditionAndConstraintStrings) {
File file("name1", "display1");
YAML::Emitter emitter;
emitter << file;
std::string expected = "name: '" + std::string(file.GetName()) +
"'\ndisplay: '" + file.GetDisplayName() + "'";
EXPECT_EQ(expected, emitter.c_str());
}
TEST(
File,
emittingAsYamlShouldWriteDetailAsAListIfTheVectorContainsMoreThanOneElement) {
File file("",
"",
"",
{MessageContent("english", "en"), MessageContent("french", "fr")});
YAML::Emitter emitter;
emitter << file;
std::string expected =
"name: ''\n"
"detail:\n"
" - lang: en\n"
" text: 'english'\n"
" - lang: fr\n"
" text: 'french'";
EXPECT_EQ(expected, emitter.c_str());
}
TEST(File, encodingAsYamlShouldStoreDataCorrectly) {
auto detail = {MessageContent("english", "en"),
MessageContent("french", "fr")};
File file("name1", "display1", "condition1", detail, "constraint1");
YAML::Node node;
node = file;
EXPECT_EQ(std::string(file.GetName()), node["name"].as<std::string>());
EXPECT_EQ(file.GetDisplayName(), node["display"].as<std::string>());
EXPECT_EQ(file.GetCondition(), node["condition"].as<std::string>());
EXPECT_EQ(file.GetDetail(), node["detail"].as<std::vector<MessageContent>>());
EXPECT_EQ(file.GetConstraint(), node["constraint"].as<std::string>());
}
TEST(File, encodingAsYamlShouldOmitEmptyFields) {
File file("file.esp");
YAML::Node node;
node = file;
EXPECT_EQ(std::string(file.GetName()), node["name"].as<std::string>());
EXPECT_FALSE(node["display"]);
EXPECT_FALSE(node["condition"]);
EXPECT_FALSE(node["detail"]);
}
TEST(File, decodingFromYamlShouldSetDataCorrectly) {
YAML::Node node = YAML::Load(
"{name: name1, display: display1, condition: 'file(\"Foo.esp\")', "
"detail: 'details', constraint: 'file(\"Bar.esp\")'}");
File file = node.as<File>();
std::vector<MessageContent> expectedDetail = {
MessageContent("details", "en")};
EXPECT_EQ(node["name"].as<std::string>(), std::string(file.GetName()));
EXPECT_EQ(node["display"].as<std::string>(), file.GetDisplayName());
EXPECT_EQ(node["condition"].as<std::string>(), file.GetCondition());
EXPECT_EQ(expectedDetail, file.GetDetail());
EXPECT_EQ(node["constraint"].as<std::string>(), file.GetConstraint());
}
TEST(File,
decodingFromYamlWithMissingConditionFieldShouldLeaveConditionStringEmpty) {
YAML::Node node = YAML::Load("{name: name1, display: display1}");
File file = node.as<File>();
EXPECT_EQ(node["name"].as<std::string>(), std::string(file.GetName()));
EXPECT_EQ(node["display"].as<std::string>(), file.GetDisplayName());
EXPECT_TRUE(file.GetCondition().empty());
EXPECT_TRUE(file.GetDetail().empty());
EXPECT_TRUE(file.GetConstraint().empty());
}
TEST(File, decodingFromYamlWithAListOfMessageContentDetailsShouldReadThemAll) {
YAML::Node node = YAML::Load(
"{name: name1, display: display1, condition: 'file(\"Foo.esp\")', "
"detail: [{text: english, lang: en}, {text: french, lang: fr}]}");
File file = node.as<File>();
std::vector<MessageContent> expectedDetail = {MessageContent("english", "en"),
MessageContent("french", "fr")};
EXPECT_EQ(expectedDetail, file.GetDetail());
}
TEST(File, decodingFromYamlShouldNotThrowIfTheOnlyDetailStringIsNotEnglish) {
YAML::Node node = YAML::Load(
"name: name1\n"
"detail:\n"
" - lang: fr\n"
" text: content1");
EXPECT_NO_THROW(node.as<File>());
}
TEST(
File,
decodingFromYamlShouldThrowIfMultipleContentStringsAreGivenAndNoneAreEnglish) {
YAML::Node node = YAML::Load(
"name: name1\n"
"detail:\n"
" - lang: de\n"
" text: content1\n"
" - lang: fr\n"
" text: content2");
EXPECT_THROW(node.as<File>(), YAML::RepresentationException);
}
TEST(File, decodingFromYamlScalarShouldLeaveDisplayNameAndConditionEmpty) {
YAML::Node node = YAML::Load("name1");
File file = node.as<File>();
EXPECT_EQ(node.as<std::string>(), std::string(file.GetName()));
EXPECT_TRUE(file.GetDisplayName().empty());
EXPECT_TRUE(file.GetCondition().empty());
EXPECT_TRUE(file.GetDetail().empty());
EXPECT_TRUE(file.GetConstraint().empty());
}
TEST(File, decodingFromYamlShouldThrowIfAnInvalidMapIsGiven) {
YAML::Node node = YAML::Load("{name: name1, condition: invalid}");
EXPECT_THROW(node.as<File>(), YAML::RepresentationException);
}
TEST(File, decodingFromYamlShouldThrowIfAListIsGiven) {
YAML::Node node = YAML::Load("[0, 1, 2]");
EXPECT_THROW(node.as<File>(), YAML::RepresentationException);
}
}
#endif
@@ -0,0 +1,142 @@
/* LOOT
A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and
Fallout: New Vegas.
Copyright (C) 2014-2016 WrinklyNinja
This file is part of LOOT.
LOOT is free software: you can redistribute
it and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
LOOT is distributed in the hope that it will
be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with LOOT. If not, see
<https://www.gnu.org/licenses/>.
*/
#ifndef LOOT_TESTS_API_INTERNALS_METADATA_YAML_GROUP_TEST
#define LOOT_TESTS_API_INTERNALS_METADATA_YAML_GROUP_TEST
#include <gtest/gtest.h>
#include "api/metadata/yaml/group.h"
namespace loot::test {
TEST(Group, emittingAsYamlShouldOmitAfterKeyIfAfterGroupsIsEmpty) {
Group group;
YAML::Emitter emitter;
emitter << group;
EXPECT_STREQ("name: 'default'", emitter.c_str());
}
TEST(Group, emittingAsYamlShouldIncludeDescriptionKeyIfDescriptionIsNotEmpty) {
Group group("group1", {}, "test");
YAML::Emitter emitter;
emitter << group;
EXPECT_STREQ(
"name: 'group1'\n"
"description: 'test'",
emitter.c_str());
}
TEST(Group, emittingAsYamlShouldIncludeAfterKeyIfAfterGroupsIsNotEmpty) {
Group group("group1", {"other_group"});
YAML::Emitter emitter;
emitter << group;
EXPECT_STREQ(
"name: 'group1'\n"
"after:\n"
" - other_group",
emitter.c_str());
}
TEST(Group, encodingAsYamlShouldOmitDescriptionKeyIfDescriptionIsEmpty) {
Group group;
YAML::Node node;
node = group;
EXPECT_EQ("default", node["name"].as<std::string>());
EXPECT_FALSE(node["description"]);
}
TEST(Group, encodingAsYamlShouldIncludeDescriptionKeyIfDescriptionIsNotEmpty) {
Group group("group1", {}, "test");
YAML::Node node;
node = group;
EXPECT_EQ("group1", node["name"].as<std::string>());
EXPECT_EQ("test", node["description"].as<std::string>());
}
TEST(Group, encodingAsYamlShouldOmitAfterKeyIfAfterGroupsIsEmpty) {
Group group;
YAML::Node node;
node = group;
EXPECT_EQ("default", node["name"].as<std::string>());
EXPECT_FALSE(node["after"]);
}
TEST(Group, encodingAsYamlShouldIncludeAfterKeyIfAfterGroupsIsNotEmpty) {
Group group("group1", {"other_group"});
YAML::Node node;
node = group;
std::vector<std::string> expectedAfterGroups = {"other_group"};
EXPECT_EQ("group1", node["name"].as<std::string>());
EXPECT_EQ(expectedAfterGroups, node["after"].as<std::vector<std::string>>());
}
TEST(Group, decodingFromYamlShouldSetGivenName) {
YAML::Node node = YAML::Load("{name: group1}");
Group group = node.as<Group>();
EXPECT_EQ("group1", group.GetName());
EXPECT_TRUE(group.GetAfterGroups().empty());
}
TEST(Group, decodingFromYamlShouldSetDescriptionIfOneIsGiven) {
YAML::Node node = YAML::Load("{name: group1, description: test}");
Group group = node.as<Group>();
EXPECT_EQ("group1", group.GetName());
EXPECT_EQ("test", group.GetDescription());
}
TEST(Group, decodingFromYamlShouldSetAfterGroupsIfAnyAreGiven) {
YAML::Node node = YAML::Load("{name: group1, after: [ other_group ]}");
Group group = node.as<Group>();
std::vector<std::string> expectedAfterGroups = {"other_group"};
EXPECT_EQ("group1", group.GetName());
EXPECT_EQ(expectedAfterGroups, group.GetAfterGroups());
}
TEST(Group, decodingFromYamlShouldThrowIfTheNameKeyIsMissing) {
YAML::Node node = YAML::Load("{after: []}");
EXPECT_THROW(node.as<Group>(), YAML::RepresentationException);
}
TEST(Group, decodingFromYamlShouldThrowIfAListIsGiven) {
YAML::Node node = YAML::Load("[0, 1, 2]");
EXPECT_THROW(node.as<Group>(), YAML::RepresentationException);
}
}
#endif
@@ -0,0 +1,93 @@
/* LOOT
A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and
Fallout: New Vegas.
Copyright (C) 2014-2016 WrinklyNinja
This file is part of LOOT.
LOOT is free software: you can redistribute
it and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
LOOT is distributed in the hope that it will
be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with LOOT. If not, see
<https://www.gnu.org/licenses/>.
*/
#ifndef LOOT_TESTS_API_INTERNALS_METADATA_YAML_LOCATION_TEST
#define LOOT_TESTS_API_INTERNALS_METADATA_YAML_LOCATION_TEST
#include <gtest/gtest.h>
#include "api/metadata/yaml/location.h"
namespace loot::test {
TEST(Location, emittingAsYamlShouldOutputAScalarIfTheNameStringIsEmpty) {
Location location("http://www.example.com");
YAML::Emitter emitter;
emitter << location;
EXPECT_EQ("'" + location.GetURL() + "'", emitter.c_str());
}
TEST(Location, emittingAsYamlShouldOutputAMapIfTheNameStringIsNotEmpty) {
Location location("http://www.example.com", "example");
YAML::Emitter emitter;
emitter << location;
EXPECT_EQ(
"link: '" + location.GetURL() + "'\nname: '" + location.GetName() + "'",
emitter.c_str());
}
TEST(Location, encodingAsYamlShouldStoreDataCorrectly) {
Location location("http://www.example.com", "example");
YAML::Node node;
node = location;
EXPECT_EQ(location.GetURL(), node["link"].as<std::string>());
EXPECT_EQ(location.GetName(), node["name"].as<std::string>());
}
TEST(Location, encodingAsYamlShouldOmitEmptyFields) {
Location location("http://www.example.com");
YAML::Node node;
node = location;
EXPECT_EQ(location.GetURL(), node["link"].as<std::string>());
EXPECT_FALSE(node["name"]);
}
TEST(Location, decodingFromYamlShouldSetDataCorrectly) {
YAML::Node node = YAML::Load("{link: http://www.example.com, name: example}");
Location location = node.as<Location>();
EXPECT_EQ(node["link"].as<std::string>(), location.GetURL());
EXPECT_EQ(node["name"].as<std::string>(), location.GetName());
}
TEST(Location,
decodingFromYamlScalarShouldSetUrlToScalarValueAndLeaveNameEmpty) {
YAML::Node node = YAML::Load("http://www.example.com");
Location location = node.as<Location>();
EXPECT_EQ(node.as<std::string>(), location.GetURL());
EXPECT_TRUE(location.GetName().empty());
}
TEST(Location, decodingFromYamlShouldThrowIfAListIsGiven) {
YAML::Node node = YAML::Load("[0, 1, 2]");
EXPECT_THROW(node.as<Location>(), YAML::RepresentationException);
}
}
#endif
@@ -0,0 +1,74 @@
/* LOOT
A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and
Fallout: New Vegas.
Copyright (C) 2014-2016 WrinklyNinja
This file is part of LOOT.
LOOT is free software: you can redistribute
it and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
LOOT is distributed in the hope that it will
be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with LOOT. If not, see
<https://www.gnu.org/licenses/>.
*/
#ifndef LOOT_TESTS_API_INTERNALS_METADATA_YAML_MESSAGE_CONTENT_TEST
#define LOOT_TESTS_API_INTERNALS_METADATA_YAML_MESSAGE_CONTENT_TEST
#include <gtest/gtest.h>
#include "api/metadata/yaml/message_content.h"
namespace loot::test {
const std::string french = "fr";
TEST(MessageContent, emittingAsYamlShouldOutputDataCorrectly) {
MessageContent content("content", french);
YAML::Emitter emitter;
emitter << content;
EXPECT_EQ("lang: " + french + "\ntext: '" + content.GetText() + "'",
emitter.c_str());
}
TEST(MessageContent, encodingAsYamlShouldOutputDataCorrectly) {
MessageContent content("content", french);
YAML::Node node;
node = content;
EXPECT_EQ(content.GetText(), node["text"].as<std::string>());
EXPECT_EQ(french, node["lang"].as<std::string>());
}
TEST(MessageContent, decodingFromYamlShouldSetDataCorrectly) {
YAML::Node node = YAML::Load("{text: content, lang: fr}");
MessageContent content = node.as<MessageContent>();
EXPECT_EQ("content", content.GetText());
EXPECT_EQ(french, content.GetLanguage());
}
TEST(MessageContent, decodingFromYamlScalarShouldThrow) {
YAML::Node node = YAML::Load("scalar");
EXPECT_THROW(node.as<MessageContent>(), YAML::RepresentationException);
}
TEST(MessageContent, decodingFromYamlListShouldThrow) {
YAML::Node node = YAML::Load("[0, 1, 2]");
EXPECT_THROW(node.as<MessageContent>(), YAML::RepresentationException);
}
}
#endif
@@ -0,0 +1,371 @@
/* LOOT
A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and
Fallout: New Vegas.
Copyright (C) 2014-2016 WrinklyNinja
This file is part of LOOT.
LOOT is free software: you can redistribute
it and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
LOOT is distributed in the hope that it will
be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with LOOT. If not, see
<https://www.gnu.org/licenses/>.
*/
#ifndef LOOT_TESTS_API_INTERNALS_METADATA_YAML_MESSAGE_TEST
#define LOOT_TESTS_API_INTERNALS_METADATA_YAML_MESSAGE_TEST
#include "api/metadata/yaml/message.h"
#include "tests/common_game_test_fixture.h"
namespace loot::test {
class MessageTest : public CommonGameTestFixture {
protected:
MessageTest() : CommonGameTestFixture(GameType::tes4) {}
typedef std::vector<MessageContent> MessageContents;
};
TEST_F(MessageTest, emittingAsYamlShouldOutputNoteMessageTypeCorrectly) {
Message message(MessageType::say, "content1");
YAML::Emitter emitter;
emitter << message;
EXPECT_STREQ(
"type: say\n"
"content: 'content1'",
emitter.c_str());
}
TEST_F(MessageTest, emittingAsYamlShouldOutputWarnMessageTypeCorrectly) {
Message message(MessageType::warn, "content1");
YAML::Emitter emitter;
emitter << message;
EXPECT_STREQ(
"type: warn\n"
"content: 'content1'",
emitter.c_str());
}
TEST_F(MessageTest, emittingAsYamlShouldOutputErrorMessageTypeCorrectly) {
Message message(MessageType::error, "content1");
YAML::Emitter emitter;
emitter << message;
EXPECT_STREQ(
"type: error\n"
"content: 'content1'",
emitter.c_str());
}
TEST_F(MessageTest, emittingAsYamlShouldOutputConditionIfItIsNotEmpty) {
Message message(MessageType::say, "content1", "condition1");
YAML::Emitter emitter;
emitter << message;
EXPECT_STREQ(
"type: say\n"
"content: 'content1'\n"
"condition: 'condition1'",
emitter.c_str());
}
TEST_F(MessageTest, emittingAsYamlShouldOutputMultipleContentStringsAsAList) {
Message message(MessageType::say,
MessageContents({MessageContent("content1"),
MessageContent("content2", french)}));
YAML::Emitter emitter;
emitter << message;
EXPECT_STREQ(
"type: say\n"
"content:\n"
" - lang: en\n"
" text: 'content1'\n"
" - lang: fr\n"
" text: 'content2'",
emitter.c_str());
}
TEST_F(MessageTest, encodingAsYamlShouldStoreNoteMessageTypeCorrectly) {
Message message(MessageType::say, "content1");
YAML::Node node;
node = message;
EXPECT_EQ("say", node["type"].as<std::string>());
}
TEST_F(MessageTest, encodingAsYamlShouldStoreWarningMessageTypeCorrectly) {
Message message(MessageType::warn, "content1");
YAML::Node node;
node = message;
EXPECT_EQ("warn", node["type"].as<std::string>());
}
TEST_F(MessageTest, encodingAsYamlShouldStoreErrorMessageTypeCorrectly) {
Message message(MessageType::error, "content1");
YAML::Node node;
node = message;
EXPECT_EQ("error", node["type"].as<std::string>());
}
TEST_F(MessageTest, encodingAsYamlShouldOmitConditionFieldIfItIsEmpty) {
Message message(MessageType::say, "content1");
YAML::Node node;
node = message;
EXPECT_FALSE(node["condition"]);
}
TEST_F(MessageTest, encodingAsYamlShouldStoreConditionFieldIfItIsNotEmpty) {
Message message(MessageType::say, "content1", "condition1");
YAML::Node node;
node = message;
EXPECT_EQ("condition1", node["condition"].as<std::string>());
}
TEST_F(MessageTest, encodingAsYamlShouldStoreASingleContentStringInAVector) {
Message message(MessageType::say, "content1");
YAML::Node node;
node = message;
EXPECT_EQ(message.GetContent(), node["content"].as<MessageContents>());
}
TEST_F(MessageTest, encodingAsYamlShouldMultipleContentStringsInAVector) {
MessageContents contents({
MessageContent("content1"),
MessageContent("content2", french),
});
Message message(MessageType::say, contents);
YAML::Node node;
node = message;
EXPECT_EQ(contents, node["content"].as<MessageContents>());
}
TEST_F(MessageTest, decodingFromYamlShouldSetNoteTypeCorrectly) {
YAML::Node node = YAML::Load(
"type: say\n"
"content: content1");
Message message = node.as<Message>();
EXPECT_EQ(MessageType::say, message.GetType());
}
TEST_F(MessageTest, decodingFromYamlShouldSetWarningTypeCorrectly) {
YAML::Node node = YAML::Load(
"type: warn\n"
"content: content1");
Message message = node.as<Message>();
EXPECT_EQ(MessageType::warn, message.GetType());
}
TEST_F(MessageTest, decodingFromYamlShouldSetErrorTypeCorrectly) {
YAML::Node node = YAML::Load(
"type: error\n"
"content: content1");
Message message = node.as<Message>();
EXPECT_EQ(MessageType::error, message.GetType());
}
TEST_F(MessageTest, decodingFromYamlShouldHandleAnUnrecognisedTypeAsANote) {
YAML::Node node = YAML::Load(
"type: invalid\n"
"content: content1");
Message message = node.as<Message>();
EXPECT_EQ(MessageType::say, message.GetType());
}
TEST_F(MessageTest,
decodingFromYamlShouldLeaveTheConditionEmptyIfNoneIsPresent) {
YAML::Node node = YAML::Load(
"type: say\n"
"content: content1");
Message message = node.as<Message>();
EXPECT_TRUE(message.GetCondition().empty());
}
TEST_F(MessageTest, decodingFromYamlShouldStoreANonEmptyConditionField) {
YAML::Node node = YAML::Load(
"type: say\n"
"content: content1\n"
"condition: 'file(\"Foo.esp\")'");
Message message = node.as<Message>();
EXPECT_EQ("file(\"Foo.esp\")", message.GetCondition());
}
TEST_F(MessageTest, decodingFromYamlShouldStoreAScalarContentValueCorrectly) {
YAML::Node node = YAML::Load(
"type: say\n"
"content: content1\n");
Message message = node.as<Message>();
MessageContents expectedContent({MessageContent("content1")});
EXPECT_EQ(expectedContent, message.GetContent());
}
TEST_F(MessageTest, decodingFromYamlShouldStoreAListOfContentStringsCorrectly) {
YAML::Node node = YAML::Load(
"type: say\n"
"content:\n"
" - lang: en\n"
" text: content1\n"
" - lang: fr\n"
" text: content2");
Message message = node.as<Message>();
EXPECT_EQ(MessageContents({
MessageContent("content1"),
MessageContent("content2", french),
}),
message.GetContent());
}
TEST_F(MessageTest,
decodingFromYamlShouldNotThrowIfTheOnlyContentStringIsNotEnglish) {
YAML::Node node = YAML::Load(
"type: say\n"
"content:\n"
" - lang: fr\n"
" text: content1");
EXPECT_NO_THROW(Message message = node.as<Message>());
}
TEST_F(
MessageTest,
decodingFromYamlShouldThrowIfMultipleContentStringsAreGivenAndNoneAreEnglish) {
YAML::Node node = YAML::Load(
"type: say\n"
"content:\n"
" - lang: de\n"
" text: content1\n"
" - lang: fr\n"
" text: content2");
EXPECT_THROW(node.as<Message>(), YAML::RepresentationException);
}
TEST_F(
MessageTest,
decodingFromYamlShouldApplySubstitutionsWhenThereIsOnlyOneContentString) {
YAML::Node node = YAML::Load(
"type: say\n"
"content: con{0}tent1\n"
"subs:\n"
" - sub1");
Message message = node.as<Message>();
EXPECT_EQ(MessageContents({MessageContent("consub1tent1")}),
message.GetContent());
}
TEST_F(MessageTest,
decodingFromYamlShouldApplySubstitutionsToAllContentStrings) {
YAML::Node node = YAML::Load(
"type: say\n"
"content:\n"
" - lang: en\n"
" text: content1 {0}\n"
" - lang: fr\n"
" text: content2 {0}\n"
"subs:\n"
" - sub");
Message message = node.as<Message>();
EXPECT_EQ(MessageContents({
MessageContent("content1 sub"),
MessageContent("content2 sub", french),
}),
message.GetContent());
}
TEST_F(
MessageTest,
decodingFromYamlShouldThrowIfTheContentStringExpectsMoreSubstitutionsThanExist) {
YAML::Node node = YAML::Load(
"type: say\n"
"content: '{0} {1}'\n"
"subs:\n"
" - sub1");
EXPECT_THROW(node.as<Message>(), YAML::RepresentationException);
}
// Don't throw because no subs are given, so none are expected in the content
// string.
TEST_F(MessageTest,
decodingFromYamlShouldIgnoreSubstitutionSyntaxIfNoSubstitutionsExist) {
YAML::Node node = YAML::Load(
"type: say\n"
"content: con{0}tent1\n");
Message message = node.as<Message>();
EXPECT_EQ(MessageContents({MessageContent("con{0}tent1")}),
message.GetContent());
}
TEST_F(MessageTest, decodingFromYamlShouldAcceptPercentagePlaceholderSyntax) {
YAML::Node node = YAML::Load(
"type: say\n"
"content: content %1% %2% %3% %4% %5% %6% %7% %8% %9% %10% %11%\n"
"subs:\n"
" - a\n"
" - b\n"
" - c\n"
" - d\n"
" - e\n"
" - f\n"
" - g\n"
" - h\n"
" - i\n"
" - j\n"
" - k");
Message message = node.as<Message>();
ASSERT_EQ(1, message.GetContent().size());
EXPECT_EQ("content a b c d e f g h i j k", message.GetContent()[0].GetText());
}
TEST_F(MessageTest, decodingFromYamlShouldThrowIfAnInvalidConditionIsGiven) {
YAML::Node node = YAML::Load(
"type: say\n"
"content: content1\n"
"condition: invalid");
EXPECT_THROW(node.as<Message>(), YAML::RepresentationException);
}
TEST_F(MessageTest, decodingFromYamlShouldThrowIfAScalarIsGiven) {
YAML::Node node = YAML::Load("scalar");
EXPECT_THROW(node.as<Message>(), YAML::RepresentationException);
}
TEST_F(MessageTest, decodingFromYamlShouldThrowIfAListIsGiven) {
YAML::Node node = YAML::Load("[0, 1, 2]");
EXPECT_THROW(node.as<Message>(), YAML::RepresentationException);
}
}
#endif
@@ -0,0 +1,157 @@
/* LOOT
A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and
Fallout: New Vegas.
Copyright (C) 2014-2016 WrinklyNinja
This file is part of LOOT.
LOOT is free software: you can redistribute
it and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
LOOT is distributed in the hope that it will
be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with LOOT. If not, see
<https://www.gnu.org/licenses/>.
*/
#ifndef LOOT_TESTS_API_INTERNALS_METADATA_YAML_PLUGIN_CLEANING_DATA_TEST
#define LOOT_TESTS_API_INTERNALS_METADATA_YAML_PLUGIN_CLEANING_DATA_TEST
#include "api/metadata/yaml/plugin_cleaning_data.h"
#include "tests/common_game_test_fixture.h"
namespace loot::test {
class PluginCleaningDataTest : public CommonGameTestFixture {
protected:
PluginCleaningDataTest() :
CommonGameTestFixture(GameType::tes4),
info_(std::vector<MessageContent>({
MessageContent("info"),
})) {}
const std::vector<MessageContent> info_;
};
TEST_F(PluginCleaningDataTest, emittingAsYamlShouldOutputAllNonZeroCounts) {
PluginCleaningData info(0x12345678, "cleaner", info_, 2, 10, 30);
YAML::Emitter emitter;
emitter << info;
EXPECT_STREQ(
"crc: 0x12345678\nutil: 'cleaner'\ndetail: 'info'\nitm: 2\nudr: 10\nnav: "
"30",
emitter.c_str());
}
TEST_F(PluginCleaningDataTest, emittingAsYamlShouldOmitAllZeroCounts) {
PluginCleaningData info(0x12345678, "cleaner", info_, 0, 0, 0);
YAML::Emitter emitter;
emitter << info;
EXPECT_STREQ("crc: 0x12345678\nutil: 'cleaner'\ndetail: 'info'",
emitter.c_str());
}
TEST_F(PluginCleaningDataTest, encodingAsYamlShouldOmitAllZeroCountFields) {
PluginCleaningData info(0x12345678, "cleaner", info_, 0, 0, 0);
YAML::Node node;
node = info;
EXPECT_EQ(0x12345678u, node["crc"].as<uint32_t>());
EXPECT_EQ("cleaner", node["util"].as<std::string>());
EXPECT_EQ(info_, node["detail"].as<std::vector<MessageContent>>());
EXPECT_FALSE(node["itm"]);
EXPECT_FALSE(node["udr"]);
EXPECT_FALSE(node["nav"]);
}
TEST_F(PluginCleaningDataTest,
encodingAsYamlShouldOutputAllNonZeroCountFields) {
PluginCleaningData info(0x12345678, "cleaner", info_, 2, 10, 30);
YAML::Node node;
node = info;
EXPECT_EQ(0x12345678u, node["crc"].as<uint32_t>());
EXPECT_EQ("cleaner", node["util"].as<std::string>());
EXPECT_EQ(info_, node["detail"].as<std::vector<MessageContent>>());
EXPECT_EQ(2u, node["itm"].as<unsigned int>());
EXPECT_EQ(10u, node["udr"].as<unsigned int>());
EXPECT_EQ(30u, node["nav"].as<unsigned int>());
}
TEST_F(PluginCleaningDataTest,
decodingFromYamlShouldLeaveMissingFieldsWithZeroValues) {
YAML::Node node = YAML::Load("{crc: 0x12345678, util: cleaner}");
PluginCleaningData info = node.as<PluginCleaningData>();
EXPECT_EQ(0x12345678u, info.GetCRC());
EXPECT_TRUE(info.GetDetail().empty());
EXPECT_EQ(0u, info.GetITMCount());
EXPECT_EQ(0u, info.GetDeletedReferenceCount());
EXPECT_EQ(0u, info.GetDeletedNavmeshCount());
EXPECT_EQ("cleaner", info.GetCleaningUtility());
}
TEST_F(PluginCleaningDataTest, decodingFromYamlShouldStoreAllNonZeroCounts) {
YAML::Node node = YAML::Load(
"{crc: 0x12345678, util: cleaner, detail: info, itm: 2, udr: 10, nav: "
"30}");
PluginCleaningData info = node.as<PluginCleaningData>();
EXPECT_EQ(0x12345678u, info.GetCRC());
EXPECT_EQ(info_, info.GetDetail());
EXPECT_EQ(2u, info.GetITMCount());
EXPECT_EQ(10u, info.GetDeletedReferenceCount());
EXPECT_EQ(30u, info.GetDeletedNavmeshCount());
EXPECT_EQ("cleaner", info.GetCleaningUtility());
}
TEST_F(PluginCleaningDataTest,
decodingFromYamlShouldNotThrowIfTheOnlyDetailStringIsNotEnglish) {
YAML::Node node = YAML::Load(
"crc: 0x12345678\n"
"util: cleaner\n"
"detail:\n"
" - lang: fr\n"
" text: content1");
EXPECT_NO_THROW(node.as<PluginCleaningData>());
}
TEST_F(
PluginCleaningDataTest,
decodingFromYamlShouldThrowIfMultipleDetailStringsAreGivenAndNoneAreEnglish) {
YAML::Node node = YAML::Load(
"crc: 0x12345678\n"
"util: cleaner\n"
"detail:\n"
" - lang: de\n"
" text: content1\n"
" - lang: fr\n"
" text: content2");
EXPECT_THROW(node.as<PluginCleaningData>(), YAML::RepresentationException);
}
TEST_F(PluginCleaningDataTest, decodingFromYamlScalarShouldThrow) {
YAML::Node node = YAML::Load("scalar");
EXPECT_THROW(node.as<PluginCleaningData>(), YAML::RepresentationException);
}
TEST_F(PluginCleaningDataTest, decodingFromYamlListShouldThrow) {
YAML::Node node = YAML::Load("[0, 1, 2]");
EXPECT_THROW(node.as<PluginCleaningData>(), YAML::RepresentationException);
}
}
#endif
@@ -22,15 +22,13 @@ along with LOOT. If not, see
<https://www.gnu.org/licenses/>.
*/
#ifndef LOOT_TESTS_API_INTERNALS_METADATA_PLUGIN_METADATA_TEST
#define LOOT_TESTS_API_INTERNALS_METADATA_PLUGIN_METADATA_TEST
#ifndef LOOT_TESTS_API_INTERNALS_METADATA_YAML_PLUGIN_METADATA_TEST
#define LOOT_TESTS_API_INTERNALS_METADATA_YAML_PLUGIN_METADATA_TEST
#include "api/metadata/yaml/plugin_metadata.h"
#include "loot/metadata/plugin_metadata.h"
#include "tests/common_game_test_fixture.h"
namespace loot {
namespace test {
namespace loot::test {
class PluginMetadataTest : public CommonGameTestFixture {
protected:
PluginMetadataTest() :
@@ -42,357 +40,6 @@ protected:
const std::vector<MessageContent> info_;
};
TEST_F(
PluginMetadataTest,
defaultConstructorShouldLeaveNameEmptyAndEnableMetadataAndLeaveGroupUnset) {
PluginMetadata plugin;
EXPECT_TRUE(plugin.GetName().empty());
EXPECT_FALSE(plugin.GetGroup());
}
TEST_F(
PluginMetadataTest,
stringConstructorShouldSetNameToGivenStringAndEnableMetadataAndLeaveGroupUnset) {
PluginMetadata plugin(blankEsm);
EXPECT_EQ(blankEsm, plugin.GetName());
EXPECT_FALSE(plugin.GetGroup());
}
TEST_F(PluginMetadataTest,
nameMatchesShouldUseCaseInsensitiveNameComparisonForNonRegexNames) {
PluginMetadata plugin(blankEsm);
EXPECT_TRUE(plugin.NameMatches(boost::to_lower_copy(blankEsm)));
EXPECT_FALSE(plugin.NameMatches(blankDifferentEsm));
}
TEST_F(PluginMetadataTest,
nameMatchesShouldTreatGivenPluginNameStringsAsLiterals) {
PluginMetadata plugin(blankEsm);
std::string regex = "blan.\\.esm";
EXPECT_FALSE(plugin.NameMatches(regex));
}
TEST_F(PluginMetadataTest,
nameMatchesShouldUseCaseInsensitiveRegexMatchingForARegexName) {
PluginMetadata plugin("Blan.\\.esm");
EXPECT_TRUE(plugin.NameMatches(boost::to_lower_copy(blankEsm)));
EXPECT_FALSE(plugin.NameMatches(blankDifferentEsm));
}
TEST_F(PluginMetadataTest, mergeMetadataShouldNotChangeName) {
PluginMetadata plugin1(blankEsm);
PluginMetadata plugin2(blankDifferentEsm);
plugin1.MergeMetadata(plugin2);
EXPECT_EQ(blankEsm, plugin1.GetName());
}
TEST_F(PluginMetadataTest,
mergeMetadataShouldNotUseMergedGroupIfItAndCurrentGroupAreBothExplicit) {
PluginMetadata plugin1;
PluginMetadata plugin2;
plugin1.SetGroup("group1");
plugin2.SetGroup("group2");
plugin1.MergeMetadata(plugin2);
EXPECT_EQ("group1", plugin1.GetGroup());
}
TEST_F(PluginMetadataTest,
mergeMetadataShouldNotUseMergedGroupIfItAndCurrentGroupAreBothImplicit) {
PluginMetadata plugin1;
PluginMetadata plugin2;
plugin1.MergeMetadata(plugin2);
EXPECT_FALSE(plugin1.GetGroup().has_value());
}
TEST_F(
PluginMetadataTest,
mergeMetadataShouldNotUseMergedGroupIfItIsImplicitAndCurrentGroupIsExplicit) {
PluginMetadata plugin1;
PluginMetadata plugin2;
plugin1.SetGroup("group1");
plugin1.MergeMetadata(plugin2);
EXPECT_EQ("group1", plugin1.GetGroup());
}
TEST_F(
PluginMetadataTest,
mergeMetadataShouldUseMergedGroupIfItIsExplicitAndCurrentGroupIsImplicit) {
PluginMetadata plugin1;
PluginMetadata plugin2;
plugin2.SetGroup("group2");
plugin1.MergeMetadata(plugin2);
EXPECT_EQ("group2", plugin1.GetGroup());
}
TEST_F(PluginMetadataTest, mergeMetadataShouldMergeLoadAfterData) {
PluginMetadata plugin1;
PluginMetadata plugin2;
File file1(blankEsm);
File file2(blankDifferentEsm);
plugin1.SetLoadAfterFiles({file1});
plugin2.SetLoadAfterFiles({file1, file2});
plugin1.MergeMetadata(plugin2);
EXPECT_EQ(std::vector<File>({file1, file2}), plugin1.GetLoadAfterFiles());
}
TEST_F(PluginMetadataTest, mergeMetadataShouldMergeRequirementData) {
PluginMetadata plugin1;
PluginMetadata plugin2;
File file1(blankEsm);
File file2(blankDifferentEsm);
plugin1.SetRequirements({file1});
plugin2.SetRequirements({file1, file2});
plugin1.MergeMetadata(plugin2);
EXPECT_EQ(std::vector<File>({file1, file2}), plugin1.GetRequirements());
}
TEST_F(PluginMetadataTest, mergeMetadataShouldMergeIncompatibilityData) {
PluginMetadata plugin1;
PluginMetadata plugin2;
File file1(blankEsm);
File file2(blankDifferentEsm);
plugin1.SetIncompatibilities({file1});
plugin2.SetIncompatibilities({file1, file2});
plugin1.MergeMetadata(plugin2);
EXPECT_EQ(std::vector<File>({file1, file2}), plugin1.GetIncompatibilities());
}
TEST_F(PluginMetadataTest, mergeMetadataShouldMergeMessages) {
PluginMetadata plugin1;
PluginMetadata plugin2;
Message message(MessageType::say, "content");
plugin1.SetMessages({message});
plugin2.SetMessages({message});
plugin1.MergeMetadata(plugin2);
EXPECT_EQ(std::vector<Message>({message, message}), plugin1.GetMessages());
}
TEST_F(PluginMetadataTest, mergeMetadataShouldMergeTags) {
PluginMetadata plugin1;
PluginMetadata plugin2;
Tag tag1("Relev");
Tag tag2("Relev", false);
Tag tag3("Delev");
plugin1.SetTags({tag1});
plugin2.SetTags({tag1, tag2, tag3});
plugin1.MergeMetadata(plugin2);
EXPECT_EQ(std::vector<Tag>({tag1, tag2, tag3}), plugin1.GetTags());
}
TEST_F(PluginMetadataTest, mergeMetadataShouldMergeDirtyInfoData) {
PluginMetadata plugin1;
PluginMetadata plugin2;
PluginCleaningData info1(0x5, "utility", info_, 1, 2, 3);
PluginCleaningData info2(0xA, "utility", info_, 1, 2, 3);
plugin1.SetDirtyInfo({info1});
plugin2.SetDirtyInfo({info1, info2});
plugin1.MergeMetadata(plugin2);
EXPECT_EQ(std::vector<PluginCleaningData>({info1, info2}),
plugin1.GetDirtyInfo());
}
TEST_F(PluginMetadataTest, mergeMetadataShouldMergeCleanInfoData) {
PluginMetadata plugin1;
PluginMetadata plugin2;
PluginCleaningData info1(0x5, "utility");
PluginCleaningData info2(0xA, "utility");
plugin1.SetCleanInfo({info1});
plugin2.SetCleanInfo({info1, info2});
plugin1.MergeMetadata(plugin2);
EXPECT_EQ(std::vector<PluginCleaningData>({info1, info2}),
plugin1.GetCleanInfo());
}
TEST_F(PluginMetadataTest, mergeMetadataShouldMergeLocationData) {
PluginMetadata plugin1;
PluginMetadata plugin2;
Location location1("http://www.example.com/1");
Location location2("http://www.example.com/2");
plugin1.SetLocations({location1});
plugin2.SetLocations({location1, location2});
plugin1.MergeMetadata(plugin2);
EXPECT_EQ(std::vector<Location>({location1, location2}),
plugin1.GetLocations());
}
TEST_F(PluginMetadataTest, unsetGroupShouldLeaveNoGroupValueSet) {
PluginMetadata plugin;
EXPECT_FALSE(plugin.GetGroup().has_value());
plugin.SetGroup("test");
EXPECT_EQ("test", plugin.GetGroup().value());
plugin.UnsetGroup();
EXPECT_FALSE(plugin.GetGroup().has_value());
}
TEST_F(PluginMetadataTest,
hasNameOnlyShouldBeTrueForADefaultConstructedPluginMetadataObject) {
PluginMetadata plugin;
EXPECT_TRUE(plugin.HasNameOnly());
}
TEST_F(PluginMetadataTest,
hasNameOnlyShouldBeTrueForAPluginMetadataObjectConstructedWithAName) {
PluginMetadata plugin(blankEsp);
EXPECT_TRUE(plugin.HasNameOnly());
}
TEST_F(PluginMetadataTest, hasNameOnlyShouldBeFalseIfTheGroupIsExplicit) {
PluginMetadata plugin;
plugin.SetGroup("group");
EXPECT_FALSE(plugin.HasNameOnly());
}
TEST_F(PluginMetadataTest, hasNameOnlyShouldBeFalseIfLoadAfterMetadataExists) {
PluginMetadata plugin(blankEsp);
plugin.SetLoadAfterFiles({File(blankEsm)});
EXPECT_FALSE(plugin.HasNameOnly());
}
TEST_F(PluginMetadataTest,
hasNameOnlyShouldBeFalseIfRequirementMetadataExists) {
PluginMetadata plugin(blankEsp);
plugin.SetRequirements({File(blankEsm)});
EXPECT_FALSE(plugin.HasNameOnly());
}
TEST_F(PluginMetadataTest,
hasNameOnlyShouldBeFalseIfIncompatibilityMetadataExists) {
PluginMetadata plugin(blankEsp);
plugin.SetIncompatibilities({File(blankEsm)});
EXPECT_FALSE(plugin.HasNameOnly());
}
TEST_F(PluginMetadataTest, hasNameOnlyShouldBeFalseIfMessagesExist) {
PluginMetadata plugin(blankEsp);
plugin.SetMessages({Message(MessageType::say, "content")});
EXPECT_FALSE(plugin.HasNameOnly());
}
TEST_F(PluginMetadataTest, hasNameOnlyShouldBeFalseIfTagsExist) {
PluginMetadata plugin(blankEsp);
plugin.SetTags({Tag("Relev")});
EXPECT_FALSE(plugin.HasNameOnly());
}
TEST_F(PluginMetadataTest, hasNameOnlyShouldBeFalseIfDirtyInfoExists) {
PluginMetadata plugin(blankEsp);
plugin.SetDirtyInfo({PluginCleaningData(5, "utility", info_, 0, 1, 2)});
EXPECT_FALSE(plugin.HasNameOnly());
}
TEST_F(PluginMetadataTest, hasNameOnlyShouldBeFalseIfCleanInfoExists) {
PluginMetadata plugin(blankEsp);
plugin.SetCleanInfo({PluginCleaningData(5, "utility")});
EXPECT_FALSE(plugin.HasNameOnly());
}
TEST_F(PluginMetadataTest, hasNameOnlyShouldBeFalseIfLocationsExist) {
PluginMetadata plugin(blankEsp);
plugin.SetLocations({Location("http://www.example.com")});
EXPECT_FALSE(plugin.HasNameOnly());
}
TEST_F(PluginMetadataTest, isRegexPluginShouldBeFalseForAnEmptyPluginName) {
PluginMetadata plugin;
EXPECT_FALSE(plugin.IsRegexPlugin());
}
TEST_F(PluginMetadataTest, isRegexPluginShouldBeFalseForAnExactPluginFilename) {
PluginMetadata plugin(blankEsm);
EXPECT_FALSE(plugin.IsRegexPlugin());
}
TEST_F(PluginMetadataTest,
isRegexPluginShouldBeTrueIfThePluginNameContainsAColon) {
PluginMetadata plugin("Blank:.esm");
EXPECT_TRUE(plugin.IsRegexPlugin());
}
TEST_F(PluginMetadataTest,
isRegexPluginShouldBeTrueIfThePluginNameContainsABackslash) {
PluginMetadata plugin("Blank\\.esm");
EXPECT_TRUE(plugin.IsRegexPlugin());
}
TEST_F(PluginMetadataTest,
isRegexPluginShouldBeTrueIfThePluginNameContainsAnAsterisk) {
PluginMetadata plugin("Blank*.esm");
EXPECT_TRUE(plugin.IsRegexPlugin());
}
TEST_F(PluginMetadataTest,
isRegexPluginShouldBeTrueIfThePluginNameContainsAQuestionMark) {
PluginMetadata plugin("Blank?.esm");
EXPECT_TRUE(plugin.IsRegexPlugin());
}
TEST_F(PluginMetadataTest,
isRegexPluginShouldBeTrueIfThePluginNameContainsAVerticalBar) {
PluginMetadata plugin("Blank|.esm");
EXPECT_TRUE(plugin.IsRegexPlugin());
}
TEST_F(PluginMetadataTest,
asYamlShouldReturnAStringContainingTheMetadataEmittedAsYaml) {
PluginMetadata plugin(blankEsm);
plugin.SetLoadAfterFiles({File(blankEsm)});
EXPECT_EQ(
"name: 'Blank.esm'\n"
"after: ['Blank.esm']",
plugin.AsYaml());
}
TEST_F(PluginMetadataTest,
emittingAsYamlShouldOutputAPluginWithNoMetadataAsABlankString) {
PluginMetadata plugin(blankEsm);
@@ -740,6 +387,5 @@ TEST_F(PluginMetadataTest, decodingFromAYamlListShouldThrow) {
EXPECT_THROW(node.as<PluginMetadata>(), YAML::RepresentationException);
}
}
}
#endif
@@ -0,0 +1,139 @@
/* LOOT
A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and
Fallout: New Vegas.
Copyright (C) 2014-2016 WrinklyNinja
This file is part of LOOT.
LOOT is free software: you can redistribute
it and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
LOOT is distributed in the hope that it will
be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with LOOT. If not, see
<https://www.gnu.org/licenses/>.
*/
#ifndef LOOT_TESTS_API_INTERNALS_METADATA_YAML_TAG_TEST
#define LOOT_TESTS_API_INTERNALS_METADATA_YAML_TAG_TEST
#include <gtest/gtest.h>
#include "api/metadata/yaml/tag.h"
namespace loot::test {
TEST(
Tag,
emittingAsYamlShouldOutputOnlyTheNameStringIfTheTagIsAnAdditionWithNoCondition) {
Tag tag("name1");
YAML::Emitter emitter;
emitter << tag;
EXPECT_EQ(tag.GetName(), emitter.c_str());
}
TEST(
Tag,
emittingAsYamlShouldOutputOnlyTheNameStringPrefixedWithAHyphenIfTheTagIsARemovalWithNoCondition) {
Tag tag("name1", false);
YAML::Emitter emitter;
emitter << tag;
EXPECT_EQ("-" + tag.GetName(), emitter.c_str());
}
TEST(Tag, emittingAsYamlShouldOutputAMapIfTheTagHasACondition) {
Tag tag("name1", false, "condition1");
YAML::Emitter emitter;
emitter << tag;
EXPECT_STREQ("name: -name1\ncondition: 'condition1'", emitter.c_str());
}
TEST(Tag,
encodingAsYamlShouldOmitTheConditionFieldIfTheConditionStringIsEmpty) {
Tag tag;
YAML::Node node;
node = tag;
EXPECT_FALSE(node["condition"]);
}
TEST(Tag, encodingAsYamlShouldOutputTheNameFieldCorrectly) {
Tag tag("name1");
YAML::Node node;
node = tag;
EXPECT_EQ(tag.GetName(), node["name"].as<std::string>());
}
TEST(
Tag,
encodingAsYamlShouldOutputTheNameFieldWithAHyphenPrefixIfTheTagIsARemoval) {
Tag tag("name1", false);
YAML::Node node;
node = tag;
EXPECT_EQ("-" + tag.GetName(), node["name"].as<std::string>());
}
TEST(
Tag,
encodingAsYamlShouldOutputTheConditionFieldIfTheConditionStringIsNotEmpty) {
Tag tag("name1", true, "condition1");
YAML::Node node;
node = tag;
EXPECT_EQ(tag.GetName(), node["name"].as<std::string>());
EXPECT_EQ(tag.GetCondition(), node["condition"].as<std::string>());
}
TEST(Tag, decodingFromYamlScalarShouldSetNameCorrectly) {
YAML::Node node = YAML::Load("name1");
Tag tag = node.as<Tag>();
EXPECT_EQ("name1", tag.GetName());
EXPECT_TRUE(tag.IsAddition());
EXPECT_EQ("", tag.GetCondition());
}
TEST(Tag, decodingFromYamlScalarShouldSetAdditionStateCorrectly) {
YAML::Node node = YAML::Load("-name1");
Tag tag = node.as<Tag>();
EXPECT_EQ("name1", tag.GetName());
EXPECT_FALSE(tag.IsAddition());
EXPECT_EQ("", tag.GetCondition());
}
TEST(Tag, decodingFromYamlMapShouldSetDataCorrectly) {
YAML::Node node = YAML::Load("{name: name1, condition: 'file(\"Foo.esp\")'}");
Tag tag = node.as<Tag>();
EXPECT_EQ("name1", tag.GetName());
EXPECT_TRUE(tag.IsAddition());
EXPECT_EQ("file(\"Foo.esp\")", tag.GetCondition());
}
TEST(Tag, decodingFromYamlShouldThrowIfAnInvalidConditionIsGiven) {
YAML::Node node = YAML::Load("{name: name1, condition: invalid}");
EXPECT_THROW(node.as<Tag>(), YAML::RepresentationException);
}
TEST(Tag, decodingFromYamlListShouldThrow) {
YAML::Node node = YAML::Load("[0, 1, 2]");
EXPECT_THROW(node.as<Tag>(), YAML::RepresentationException);
}
}
#endif