diff --git a/cmake/tests.cmake b/cmake/tests.cmake index 2584fe26..328074c0 100644 --- a/cmake/tests.cmake +++ b/cmake/tests.cmake @@ -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" diff --git a/src/tests/api/interface/main.cpp b/src/tests/api/interface/main.cpp index af00ddfd..9e42be34 100644 --- a/src/tests/api/interface/main.cpp +++ b/src/tests/api/interface/main.cpp @@ -25,6 +25,15 @@ #include #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" diff --git a/src/tests/api/internals/metadata/conditional_metadata_test.h b/src/tests/api/interface/metadata/conditional_metadata_test.h similarity index 95% rename from src/tests/api/internals/metadata/conditional_metadata_test.h rename to src/tests/api/interface/metadata/conditional_metadata_test.h index 4fdf0012..2cb4ceb9 100644 --- a/src/tests/api/internals/metadata/conditional_metadata_test.h +++ b/src/tests/api/interface/metadata/conditional_metadata_test.h @@ -22,8 +22,8 @@ along with LOOT. If not, see . */ -#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" diff --git a/src/tests/api/internals/metadata/file_test.h b/src/tests/api/interface/metadata/file_test.h similarity index 65% rename from src/tests/api/internals/metadata/file_test.h rename to src/tests/api/interface/metadata/file_test.h index b630ccdc..16aa2e1d 100644 --- a/src/tests/api/internals/metadata/file_test.h +++ b/src/tests/api/interface/metadata/file_test.h @@ -22,16 +22,14 @@ along with LOOT. If not, see . */ -#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 -#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()); - EXPECT_EQ(file.GetDisplayName(), node["display"].as()); - EXPECT_EQ(file.GetCondition(), node["condition"].as()); - EXPECT_EQ(file.GetDetail(), node["detail"].as>()); - EXPECT_EQ(file.GetConstraint(), node["constraint"].as()); -} - -TEST(File, encodingAsYamlShouldOmitEmptyFields) { - File file("file.esp"); - YAML::Node node; - node = file; - - EXPECT_EQ(std::string(file.GetName()), node["name"].as()); - 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(); - - std::vector expectedDetail = { - MessageContent("details", "en")}; - - EXPECT_EQ(node["name"].as(), std::string(file.GetName())); - EXPECT_EQ(node["display"].as(), file.GetDisplayName()); - EXPECT_EQ(node["condition"].as(), file.GetCondition()); - EXPECT_EQ(expectedDetail, file.GetDetail()); - EXPECT_EQ(node["constraint"].as(), file.GetConstraint()); -} - -TEST(File, - decodingFromYamlWithMissingConditionFieldShouldLeaveConditionStringEmpty) { - YAML::Node node = YAML::Load("{name: name1, display: display1}"); - File file = node.as(); - - EXPECT_EQ(node["name"].as(), std::string(file.GetName())); - EXPECT_EQ(node["display"].as(), 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(); - - std::vector 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()); -} - -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(), YAML::RepresentationException); -} - -TEST(File, decodingFromYamlScalarShouldLeaveDisplayNameAndConditionEmpty) { - YAML::Node node = YAML::Load("name1"); - File file = node.as(); - - EXPECT_EQ(node.as(), 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(), YAML::RepresentationException); -} - -TEST(File, decodingFromYamlShouldThrowIfAListIsGiven) { - YAML::Node node = YAML::Load("[0, 1, 2]"); - - EXPECT_THROW(node.as(), YAML::RepresentationException); -} -} } #endif diff --git a/src/tests/api/internals/metadata/group_test.h b/src/tests/api/interface/metadata/group_test.h similarity index 74% rename from src/tests/api/internals/metadata/group_test.h rename to src/tests/api/interface/metadata/group_test.h index 10e7c1e1..f3cd21fb 100644 --- a/src/tests/api/internals/metadata/group_test.h +++ b/src/tests/api/interface/metadata/group_test.h @@ -22,16 +22,14 @@ along with LOOT. If not, see . */ -#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 -#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()); - EXPECT_FALSE(node["description"]); -} - -TEST(Group, encodingAsYamlShouldIncludeDescriptionKeyIfDescriptionIsNotEmpty) { - Group group("group1", {}, "test"); - YAML::Node node; - node = group; - - EXPECT_EQ("group1", node["name"].as()); - EXPECT_EQ("test", node["description"].as()); -} - -TEST(Group, encodingAsYamlShouldOmitAfterKeyIfAfterGroupsIsEmpty) { - Group group; - YAML::Node node; - node = group; - - EXPECT_EQ("default", node["name"].as()); - EXPECT_FALSE(node["after"]); -} - -TEST(Group, encodingAsYamlShouldIncludeAfterKeyIfAfterGroupsIsNotEmpty) { - Group group("group1", {"other_group"}); - YAML::Node node; - node = group; - - std::vector expectedAfterGroups = {"other_group"}; - EXPECT_EQ("group1", node["name"].as()); - EXPECT_EQ(expectedAfterGroups, node["after"].as>()); -} - -TEST(Group, decodingFromYamlShouldSetGivenName) { - YAML::Node node = YAML::Load("{name: group1}"); - Group group = node.as(); - - 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(); - - 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(); - - std::vector 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(), YAML::RepresentationException); -} - -TEST(Group, decodingFromYamlShouldThrowIfAListIsGiven) { - YAML::Node node = YAML::Load("[0, 1, 2]"); - - EXPECT_THROW(node.as(), YAML::RepresentationException); -} -} } #endif diff --git a/src/tests/api/internals/metadata/location_test.h b/src/tests/api/interface/metadata/location_test.h similarity index 78% rename from src/tests/api/internals/metadata/location_test.h rename to src/tests/api/interface/metadata/location_test.h index edc761e6..3a00cc5f 100644 --- a/src/tests/api/internals/metadata/location_test.h +++ b/src/tests/api/interface/metadata/location_test.h @@ -22,16 +22,14 @@ along with LOOT. If not, see . */ -#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 -#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()); - EXPECT_EQ(location.GetName(), node["name"].as()); -} - -TEST(Location, encodingAsYamlShouldOmitEmptyFields) { - Location location("http://www.example.com"); - YAML::Node node; - node = location; - - EXPECT_EQ(location.GetURL(), node["link"].as()); - EXPECT_FALSE(node["name"]); -} - -TEST(Location, decodingFromYamlShouldSetDataCorrectly) { - YAML::Node node = YAML::Load("{link: http://www.example.com, name: example}"); - Location location = node.as(); - - EXPECT_EQ(node["link"].as(), location.GetURL()); - EXPECT_EQ(node["name"].as(), location.GetName()); -} - -TEST(Location, - decodingFromYamlScalarShouldSetUrlToScalarValueAndLeaveNameEmpty) { - YAML::Node node = YAML::Load("http://www.example.com"); - Location location = node.as(); - - EXPECT_EQ(node.as(), location.GetURL()); - EXPECT_TRUE(location.GetName().empty()); -} - -TEST(Location, decodingFromYamlShouldThrowIfAListIsGiven) { - YAML::Node node = YAML::Load("[0, 1, 2]"); - - EXPECT_THROW(node.as(), YAML::RepresentationException); -} -} } #endif diff --git a/src/tests/api/internals/metadata/message_content_test.h b/src/tests/api/interface/metadata/message_content_test.h similarity index 87% rename from src/tests/api/internals/metadata/message_content_test.h rename to src/tests/api/interface/metadata/message_content_test.h index d17db0de..00826bf8 100644 --- a/src/tests/api/internals/metadata/message_content_test.h +++ b/src/tests/api/interface/metadata/message_content_test.h @@ -22,16 +22,14 @@ along with LOOT. If not, see . */ -#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 -#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()); - EXPECT_EQ(french, node["lang"].as()); -} - -TEST(MessageContent, decodingFromYamlShouldSetDataCorrectly) { - YAML::Node node = YAML::Load("{text: content, lang: fr}"); - MessageContent content = node.as(); - - EXPECT_EQ("content", content.GetText()); - EXPECT_EQ(french, content.GetLanguage()); -} - -TEST(MessageContent, decodingFromYamlScalarShouldThrow) { - YAML::Node node = YAML::Load("scalar"); - - EXPECT_THROW(node.as(), YAML::RepresentationException); -} - -TEST(MessageContent, decodingFromYamlListShouldThrow) { - YAML::Node node = YAML::Load("[0, 1, 2]"); - - EXPECT_THROW(node.as(), YAML::RepresentationException); -} -} } #endif diff --git a/src/tests/api/internals/metadata/message_test.h b/src/tests/api/interface/metadata/message_test.h similarity index 53% rename from src/tests/api/internals/metadata/message_test.h rename to src/tests/api/interface/metadata/message_test.h index 8f12ca32..b55bc196 100644 --- a/src/tests/api/internals/metadata/message_test.h +++ b/src/tests/api/interface/metadata/message_test.h @@ -22,16 +22,13 @@ along with LOOT. If not, see . */ -#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()); -} - -TEST_F(MessageTest, encodingAsYamlShouldStoreWarningMessageTypeCorrectly) { - Message message(MessageType::warn, "content1"); - YAML::Node node; - node = message; - - EXPECT_EQ("warn", node["type"].as()); -} - -TEST_F(MessageTest, encodingAsYamlShouldStoreErrorMessageTypeCorrectly) { - Message message(MessageType::error, "content1"); - YAML::Node node; - node = message; - - EXPECT_EQ("error", node["type"].as()); -} - -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()); -} - -TEST_F(MessageTest, encodingAsYamlShouldStoreASingleContentStringInAVector) { - Message message(MessageType::say, "content1"); - YAML::Node node; - node = message; - - EXPECT_EQ(message.GetContent(), node["content"].as()); -} - -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()); -} - -TEST_F(MessageTest, decodingFromYamlShouldSetNoteTypeCorrectly) { - YAML::Node node = YAML::Load( - "type: say\n" - "content: content1"); - Message message = node.as(); - - EXPECT_EQ(MessageType::say, message.GetType()); -} - -TEST_F(MessageTest, decodingFromYamlShouldSetWarningTypeCorrectly) { - YAML::Node node = YAML::Load( - "type: warn\n" - "content: content1"); - Message message = node.as(); - - EXPECT_EQ(MessageType::warn, message.GetType()); -} - -TEST_F(MessageTest, decodingFromYamlShouldSetErrorTypeCorrectly) { - YAML::Node node = YAML::Load( - "type: error\n" - "content: content1"); - Message message = node.as(); - - EXPECT_EQ(MessageType::error, message.GetType()); -} - -TEST_F(MessageTest, decodingFromYamlShouldHandleAnUnrecognisedTypeAsANote) { - YAML::Node node = YAML::Load( - "type: invalid\n" - "content: content1"); - Message message = node.as(); - - EXPECT_EQ(MessageType::say, message.GetType()); -} - -TEST_F(MessageTest, - decodingFromYamlShouldLeaveTheConditionEmptyIfNoneIsPresent) { - YAML::Node node = YAML::Load( - "type: say\n" - "content: content1"); - Message message = node.as(); - - 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(); - - 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(); - 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(); - - 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()); -} - -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(), 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(); - - 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(); - - 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(), 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(); - - 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(); - - 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(), YAML::RepresentationException); -} - -TEST_F(MessageTest, decodingFromYamlShouldThrowIfAScalarIsGiven) { - YAML::Node node = YAML::Load("scalar"); - - EXPECT_THROW(node.as(), YAML::RepresentationException); -} - -TEST_F(MessageTest, decodingFromYamlShouldThrowIfAListIsGiven) { - YAML::Node node = YAML::Load("[0, 1, 2]"); - - EXPECT_THROW(node.as(), YAML::RepresentationException); -} -} } #endif diff --git a/src/tests/api/internals/metadata/plugin_cleaning_data_test.h b/src/tests/api/interface/metadata/plugin_cleaning_data_test.h similarity index 75% rename from src/tests/api/internals/metadata/plugin_cleaning_data_test.h rename to src/tests/api/interface/metadata/plugin_cleaning_data_test.h index ac017c02..0d8a6d9c 100644 --- a/src/tests/api/internals/metadata/plugin_cleaning_data_test.h +++ b/src/tests/api/interface/metadata/plugin_cleaning_data_test.h @@ -22,16 +22,13 @@ along with LOOT. If not, see . */ -#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()); - EXPECT_EQ("cleaner", node["util"].as()); - EXPECT_EQ(info_, node["detail"].as>()); - 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()); - EXPECT_EQ("cleaner", node["util"].as()); - EXPECT_EQ(info_, node["detail"].as>()); - EXPECT_EQ(2u, node["itm"].as()); - EXPECT_EQ(10u, node["udr"].as()); - EXPECT_EQ(30u, node["nav"].as()); -} - -TEST_F(PluginCleaningDataTest, - decodingFromYamlShouldLeaveMissingFieldsWithZeroValues) { - YAML::Node node = YAML::Load("{crc: 0x12345678, util: cleaner}"); - PluginCleaningData info = node.as(); - - 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(); - - 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()); -} - -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(), YAML::RepresentationException); -} - -TEST_F(PluginCleaningDataTest, decodingFromYamlScalarShouldThrow) { - YAML::Node node = YAML::Load("scalar"); - - EXPECT_THROW(node.as(), YAML::RepresentationException); -} - -TEST_F(PluginCleaningDataTest, decodingFromYamlListShouldThrow) { - YAML::Node node = YAML::Load("[0, 1, 2]"); - - EXPECT_THROW(node.as(), YAML::RepresentationException); -} -} } #endif diff --git a/src/tests/api/interface/metadata/plugin_metadata_test.h b/src/tests/api/interface/metadata/plugin_metadata_test.h new file mode 100644 index 00000000..54f7dfd7 --- /dev/null +++ b/src/tests/api/interface/metadata/plugin_metadata_test.h @@ -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 +. +*/ + +#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("info"), + })) {} + + const std::vector 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({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({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({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}), 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({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({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({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({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 diff --git a/src/tests/api/internals/metadata/tag_test.h b/src/tests/api/interface/metadata/tag_test.h similarity index 68% rename from src/tests/api/internals/metadata/tag_test.h rename to src/tests/api/interface/metadata/tag_test.h index 01a2bd01..39836935 100644 --- a/src/tests/api/internals/metadata/tag_test.h +++ b/src/tests/api/interface/metadata/tag_test.h @@ -22,16 +22,14 @@ along with LOOT. If not, see . */ -#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 -#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()); -} - -TEST( - Tag, - encodingAsYamlShouldOutputTheNameFieldWithAHyphenPrefixIfTheTagIsARemoval) { - Tag tag("name1", false); - YAML::Node node; - node = tag; - - EXPECT_EQ("-" + tag.GetName(), node["name"].as()); -} - -TEST( - Tag, - encodingAsYamlShouldOutputTheConditionFieldIfTheConditionStringIsNotEmpty) { - Tag tag("name1", true, "condition1"); - YAML::Node node; - node = tag; - - EXPECT_EQ(tag.GetName(), node["name"].as()); - EXPECT_EQ(tag.GetCondition(), node["condition"].as()); -} - -TEST(Tag, decodingFromYamlScalarShouldSetNameCorrectly) { - YAML::Node node = YAML::Load("name1"); - Tag tag = node.as(); - - 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(); - - 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(); - - 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(), YAML::RepresentationException); -} - -TEST(Tag, decodingFromYamlListShouldThrow) { - YAML::Node node = YAML::Load("[0, 1, 2]"); - - EXPECT_THROW(node.as(), YAML::RepresentationException); -} -} } #endif diff --git a/src/tests/api/internals/main.cpp b/src/tests/api/internals/main.cpp index 8e0cdc71..0850b60e 100644 --- a/src/tests/api/internals/main.cpp +++ b/src/tests/api/internals/main.cpp @@ -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" diff --git a/src/tests/api/internals/metadata/yaml/file_test.h b/src/tests/api/internals/metadata/yaml/file_test.h new file mode 100644 index 00000000..d00986f6 --- /dev/null +++ b/src/tests/api/internals/metadata/yaml/file_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 +. +*/ + +#ifndef LOOT_TESTS_API_INTERNALS_METADATA_YAML_FILE_TEST +#define LOOT_TESTS_API_INTERNALS_METADATA_YAML_FILE_TEST + +#include + +#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()); + EXPECT_EQ(file.GetDisplayName(), node["display"].as()); + EXPECT_EQ(file.GetCondition(), node["condition"].as()); + EXPECT_EQ(file.GetDetail(), node["detail"].as>()); + EXPECT_EQ(file.GetConstraint(), node["constraint"].as()); +} + +TEST(File, encodingAsYamlShouldOmitEmptyFields) { + File file("file.esp"); + YAML::Node node; + node = file; + + EXPECT_EQ(std::string(file.GetName()), node["name"].as()); + 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(); + + std::vector expectedDetail = { + MessageContent("details", "en")}; + + EXPECT_EQ(node["name"].as(), std::string(file.GetName())); + EXPECT_EQ(node["display"].as(), file.GetDisplayName()); + EXPECT_EQ(node["condition"].as(), file.GetCondition()); + EXPECT_EQ(expectedDetail, file.GetDetail()); + EXPECT_EQ(node["constraint"].as(), file.GetConstraint()); +} + +TEST(File, + decodingFromYamlWithMissingConditionFieldShouldLeaveConditionStringEmpty) { + YAML::Node node = YAML::Load("{name: name1, display: display1}"); + File file = node.as(); + + EXPECT_EQ(node["name"].as(), std::string(file.GetName())); + EXPECT_EQ(node["display"].as(), 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(); + + std::vector 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()); +} + +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(), YAML::RepresentationException); +} + +TEST(File, decodingFromYamlScalarShouldLeaveDisplayNameAndConditionEmpty) { + YAML::Node node = YAML::Load("name1"); + File file = node.as(); + + EXPECT_EQ(node.as(), 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(), YAML::RepresentationException); +} + +TEST(File, decodingFromYamlShouldThrowIfAListIsGiven) { + YAML::Node node = YAML::Load("[0, 1, 2]"); + + EXPECT_THROW(node.as(), YAML::RepresentationException); +} +} + +#endif diff --git a/src/tests/api/internals/metadata/yaml/group_test.h b/src/tests/api/internals/metadata/yaml/group_test.h new file mode 100644 index 00000000..90e44358 --- /dev/null +++ b/src/tests/api/internals/metadata/yaml/group_test.h @@ -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 +. +*/ + +#ifndef LOOT_TESTS_API_INTERNALS_METADATA_YAML_GROUP_TEST +#define LOOT_TESTS_API_INTERNALS_METADATA_YAML_GROUP_TEST + +#include + +#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()); + EXPECT_FALSE(node["description"]); +} + +TEST(Group, encodingAsYamlShouldIncludeDescriptionKeyIfDescriptionIsNotEmpty) { + Group group("group1", {}, "test"); + YAML::Node node; + node = group; + + EXPECT_EQ("group1", node["name"].as()); + EXPECT_EQ("test", node["description"].as()); +} + +TEST(Group, encodingAsYamlShouldOmitAfterKeyIfAfterGroupsIsEmpty) { + Group group; + YAML::Node node; + node = group; + + EXPECT_EQ("default", node["name"].as()); + EXPECT_FALSE(node["after"]); +} + +TEST(Group, encodingAsYamlShouldIncludeAfterKeyIfAfterGroupsIsNotEmpty) { + Group group("group1", {"other_group"}); + YAML::Node node; + node = group; + + std::vector expectedAfterGroups = {"other_group"}; + EXPECT_EQ("group1", node["name"].as()); + EXPECT_EQ(expectedAfterGroups, node["after"].as>()); +} + +TEST(Group, decodingFromYamlShouldSetGivenName) { + YAML::Node node = YAML::Load("{name: group1}"); + Group group = node.as(); + + 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(); + + 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(); + + std::vector 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(), YAML::RepresentationException); +} + +TEST(Group, decodingFromYamlShouldThrowIfAListIsGiven) { + YAML::Node node = YAML::Load("[0, 1, 2]"); + + EXPECT_THROW(node.as(), YAML::RepresentationException); +} +} + +#endif diff --git a/src/tests/api/internals/metadata/yaml/location_test.h b/src/tests/api/internals/metadata/yaml/location_test.h new file mode 100644 index 00000000..5142e99f --- /dev/null +++ b/src/tests/api/internals/metadata/yaml/location_test.h @@ -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 +. +*/ + +#ifndef LOOT_TESTS_API_INTERNALS_METADATA_YAML_LOCATION_TEST +#define LOOT_TESTS_API_INTERNALS_METADATA_YAML_LOCATION_TEST + +#include + +#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()); + EXPECT_EQ(location.GetName(), node["name"].as()); +} + +TEST(Location, encodingAsYamlShouldOmitEmptyFields) { + Location location("http://www.example.com"); + YAML::Node node; + node = location; + + EXPECT_EQ(location.GetURL(), node["link"].as()); + EXPECT_FALSE(node["name"]); +} + +TEST(Location, decodingFromYamlShouldSetDataCorrectly) { + YAML::Node node = YAML::Load("{link: http://www.example.com, name: example}"); + Location location = node.as(); + + EXPECT_EQ(node["link"].as(), location.GetURL()); + EXPECT_EQ(node["name"].as(), location.GetName()); +} + +TEST(Location, + decodingFromYamlScalarShouldSetUrlToScalarValueAndLeaveNameEmpty) { + YAML::Node node = YAML::Load("http://www.example.com"); + Location location = node.as(); + + EXPECT_EQ(node.as(), location.GetURL()); + EXPECT_TRUE(location.GetName().empty()); +} + +TEST(Location, decodingFromYamlShouldThrowIfAListIsGiven) { + YAML::Node node = YAML::Load("[0, 1, 2]"); + + EXPECT_THROW(node.as(), YAML::RepresentationException); +} +} + +#endif diff --git a/src/tests/api/internals/metadata/yaml/message_content_test.h b/src/tests/api/internals/metadata/yaml/message_content_test.h new file mode 100644 index 00000000..bf154267 --- /dev/null +++ b/src/tests/api/internals/metadata/yaml/message_content_test.h @@ -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 +. +*/ + +#ifndef LOOT_TESTS_API_INTERNALS_METADATA_YAML_MESSAGE_CONTENT_TEST +#define LOOT_TESTS_API_INTERNALS_METADATA_YAML_MESSAGE_CONTENT_TEST + +#include + +#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()); + EXPECT_EQ(french, node["lang"].as()); +} + +TEST(MessageContent, decodingFromYamlShouldSetDataCorrectly) { + YAML::Node node = YAML::Load("{text: content, lang: fr}"); + MessageContent content = node.as(); + + EXPECT_EQ("content", content.GetText()); + EXPECT_EQ(french, content.GetLanguage()); +} + +TEST(MessageContent, decodingFromYamlScalarShouldThrow) { + YAML::Node node = YAML::Load("scalar"); + + EXPECT_THROW(node.as(), YAML::RepresentationException); +} + +TEST(MessageContent, decodingFromYamlListShouldThrow) { + YAML::Node node = YAML::Load("[0, 1, 2]"); + + EXPECT_THROW(node.as(), YAML::RepresentationException); +} +} + +#endif diff --git a/src/tests/api/internals/metadata/yaml/message_test.h b/src/tests/api/internals/metadata/yaml/message_test.h new file mode 100644 index 00000000..bea735fe --- /dev/null +++ b/src/tests/api/internals/metadata/yaml/message_test.h @@ -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 +. +*/ + +#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 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()); +} + +TEST_F(MessageTest, encodingAsYamlShouldStoreWarningMessageTypeCorrectly) { + Message message(MessageType::warn, "content1"); + YAML::Node node; + node = message; + + EXPECT_EQ("warn", node["type"].as()); +} + +TEST_F(MessageTest, encodingAsYamlShouldStoreErrorMessageTypeCorrectly) { + Message message(MessageType::error, "content1"); + YAML::Node node; + node = message; + + EXPECT_EQ("error", node["type"].as()); +} + +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()); +} + +TEST_F(MessageTest, encodingAsYamlShouldStoreASingleContentStringInAVector) { + Message message(MessageType::say, "content1"); + YAML::Node node; + node = message; + + EXPECT_EQ(message.GetContent(), node["content"].as()); +} + +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()); +} + +TEST_F(MessageTest, decodingFromYamlShouldSetNoteTypeCorrectly) { + YAML::Node node = YAML::Load( + "type: say\n" + "content: content1"); + Message message = node.as(); + + EXPECT_EQ(MessageType::say, message.GetType()); +} + +TEST_F(MessageTest, decodingFromYamlShouldSetWarningTypeCorrectly) { + YAML::Node node = YAML::Load( + "type: warn\n" + "content: content1"); + Message message = node.as(); + + EXPECT_EQ(MessageType::warn, message.GetType()); +} + +TEST_F(MessageTest, decodingFromYamlShouldSetErrorTypeCorrectly) { + YAML::Node node = YAML::Load( + "type: error\n" + "content: content1"); + Message message = node.as(); + + EXPECT_EQ(MessageType::error, message.GetType()); +} + +TEST_F(MessageTest, decodingFromYamlShouldHandleAnUnrecognisedTypeAsANote) { + YAML::Node node = YAML::Load( + "type: invalid\n" + "content: content1"); + Message message = node.as(); + + EXPECT_EQ(MessageType::say, message.GetType()); +} + +TEST_F(MessageTest, + decodingFromYamlShouldLeaveTheConditionEmptyIfNoneIsPresent) { + YAML::Node node = YAML::Load( + "type: say\n" + "content: content1"); + Message message = node.as(); + + 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(); + + 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(); + 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(); + + 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()); +} + +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(), 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(); + + 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(); + + 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(), 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(); + + 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(); + + 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(), YAML::RepresentationException); +} + +TEST_F(MessageTest, decodingFromYamlShouldThrowIfAScalarIsGiven) { + YAML::Node node = YAML::Load("scalar"); + + EXPECT_THROW(node.as(), YAML::RepresentationException); +} + +TEST_F(MessageTest, decodingFromYamlShouldThrowIfAListIsGiven) { + YAML::Node node = YAML::Load("[0, 1, 2]"); + + EXPECT_THROW(node.as(), YAML::RepresentationException); +} +} + +#endif diff --git a/src/tests/api/internals/metadata/yaml/plugin_cleaning_data_test.h b/src/tests/api/internals/metadata/yaml/plugin_cleaning_data_test.h new file mode 100644 index 00000000..e10d9749 --- /dev/null +++ b/src/tests/api/internals/metadata/yaml/plugin_cleaning_data_test.h @@ -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 +. +*/ + +#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("info"), + })) {} + + const std::vector 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()); + EXPECT_EQ("cleaner", node["util"].as()); + EXPECT_EQ(info_, node["detail"].as>()); + 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()); + EXPECT_EQ("cleaner", node["util"].as()); + EXPECT_EQ(info_, node["detail"].as>()); + EXPECT_EQ(2u, node["itm"].as()); + EXPECT_EQ(10u, node["udr"].as()); + EXPECT_EQ(30u, node["nav"].as()); +} + +TEST_F(PluginCleaningDataTest, + decodingFromYamlShouldLeaveMissingFieldsWithZeroValues) { + YAML::Node node = YAML::Load("{crc: 0x12345678, util: cleaner}"); + PluginCleaningData info = node.as(); + + 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(); + + 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()); +} + +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(), YAML::RepresentationException); +} + +TEST_F(PluginCleaningDataTest, decodingFromYamlScalarShouldThrow) { + YAML::Node node = YAML::Load("scalar"); + + EXPECT_THROW(node.as(), YAML::RepresentationException); +} + +TEST_F(PluginCleaningDataTest, decodingFromYamlListShouldThrow) { + YAML::Node node = YAML::Load("[0, 1, 2]"); + + EXPECT_THROW(node.as(), YAML::RepresentationException); +} +} + +#endif diff --git a/src/tests/api/internals/metadata/plugin_metadata_test.h b/src/tests/api/internals/metadata/yaml/plugin_metadata_test.h similarity index 52% rename from src/tests/api/internals/metadata/plugin_metadata_test.h rename to src/tests/api/internals/metadata/yaml/plugin_metadata_test.h index 2a50962a..37facffa 100644 --- a/src/tests/api/internals/metadata/plugin_metadata_test.h +++ b/src/tests/api/internals/metadata/yaml/plugin_metadata_test.h @@ -22,15 +22,13 @@ along with LOOT. If not, see . */ -#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 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({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({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({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}), 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({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({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({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({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(), YAML::RepresentationException); } } -} #endif diff --git a/src/tests/api/internals/metadata/yaml/tag_test.h b/src/tests/api/internals/metadata/yaml/tag_test.h new file mode 100644 index 00000000..66508771 --- /dev/null +++ b/src/tests/api/internals/metadata/yaml/tag_test.h @@ -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 +. +*/ + +#ifndef LOOT_TESTS_API_INTERNALS_METADATA_YAML_TAG_TEST +#define LOOT_TESTS_API_INTERNALS_METADATA_YAML_TAG_TEST + +#include + +#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()); +} + +TEST( + Tag, + encodingAsYamlShouldOutputTheNameFieldWithAHyphenPrefixIfTheTagIsARemoval) { + Tag tag("name1", false); + YAML::Node node; + node = tag; + + EXPECT_EQ("-" + tag.GetName(), node["name"].as()); +} + +TEST( + Tag, + encodingAsYamlShouldOutputTheConditionFieldIfTheConditionStringIsNotEmpty) { + Tag tag("name1", true, "condition1"); + YAML::Node node; + node = tag; + + EXPECT_EQ(tag.GetName(), node["name"].as()); + EXPECT_EQ(tag.GetCondition(), node["condition"].as()); +} + +TEST(Tag, decodingFromYamlScalarShouldSetNameCorrectly) { + YAML::Node node = YAML::Load("name1"); + Tag tag = node.as(); + + 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(); + + 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(); + + 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(), YAML::RepresentationException); +} + +TEST(Tag, decodingFromYamlListShouldThrow) { + YAML::Node node = YAML::Load("[0, 1, 2]"); + + EXPECT_THROW(node.as(), YAML::RepresentationException); +} +} + +#endif