From 4ab442679de1c1ed036093a12767b377ae24980e Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Fri, 11 Mar 2016 23:51:38 +0000 Subject: [PATCH 01/38] Namespace C++ tests and rename test fixture classes Tests are now in the loot::tests namespace, and test fixture class names now end in Test to prevent name conflicts with the classes they test. --- src/tests/api/test_api.h | 1085 +++++----- src/tests/backend/game/test_game.h | 1178 +++++------ src/tests/backend/game/test_game_cache.h | 86 +- src/tests/backend/game/test_game_settings.h | 378 ++-- .../backend/game/test_load_order_handler.h | 176 +- src/tests/backend/helpers/test_git_helper.h | 186 +- src/tests/backend/helpers/test_helpers.h | 24 +- src/tests/backend/helpers/test_language.h | 100 +- .../backend/helpers/test_yaml_set_helpers.h | 164 +- .../backend/metadata/test_condition_grammar.h | 1240 +++++------ .../metadata/test_conditional_metadata.h | 80 +- src/tests/backend/metadata/test_file.h | 240 +-- src/tests/backend/metadata/test_location.h | 152 +- src/tests/backend/metadata/test_message.h | 655 +++--- .../backend/metadata/test_message_content.h | 127 +- .../backend/metadata/test_plugin_dirty_info.h | 338 +-- .../backend/metadata/test_plugin_metadata.h | 1836 +++++++++-------- src/tests/backend/metadata/test_tag.h | 240 +-- src/tests/backend/plugin/test_plugin.h | 442 ++-- src/tests/backend/test_masterlist.h | 202 +- src/tests/backend/test_metadata_list.h | 420 ++-- src/tests/backend/test_plugin_sorter.h | 470 ++--- src/tests/fixtures.h | 522 ++--- src/tests/gui/test_loot_settings.h | 68 +- src/tests/gui/test_loot_state.h | 16 +- src/tests/printers.h | 104 +- 26 files changed, 5302 insertions(+), 5227 deletions(-) diff --git a/src/tests/api/test_api.h b/src/tests/api/test_api.h index c58060f5..2c464f76 100644 --- a/src/tests/api/test_api.h +++ b/src/tests/api/test_api.h @@ -30,600 +30,605 @@ along with LOOT. If not, see #include -TEST(GetVersion, HandlesNullInput) { - unsigned int vMajor, vMinor, vPatch; - EXPECT_EQ(loot_error_invalid_args, loot_get_version(&vMajor, NULL, NULL)); - EXPECT_EQ(loot_error_invalid_args, loot_get_version(NULL, &vMinor, NULL)); - EXPECT_EQ(loot_error_invalid_args, loot_get_version(NULL, NULL, &vPatch)); - EXPECT_EQ(loot_error_invalid_args, loot_get_version(NULL, NULL, NULL)); -} +namespace loot { + namespace test { + TEST(GetVersion, HandlesNullInput) { + unsigned int vMajor, vMinor, vPatch; + EXPECT_EQ(loot_error_invalid_args, loot_get_version(&vMajor, NULL, NULL)); + EXPECT_EQ(loot_error_invalid_args, loot_get_version(NULL, &vMinor, NULL)); + EXPECT_EQ(loot_error_invalid_args, loot_get_version(NULL, NULL, &vPatch)); + EXPECT_EQ(loot_error_invalid_args, loot_get_version(NULL, NULL, NULL)); + } -TEST(GetVersion, HandlesValidInput) { - unsigned int vMajor, vMinor, vPatch; - EXPECT_EQ(loot_ok, loot_get_version(&vMajor, &vMinor, &vPatch)); -} + TEST(GetVersion, HandlesValidInput) { + unsigned int vMajor, vMinor, vPatch; + EXPECT_EQ(loot_ok, loot_get_version(&vMajor, &vMinor, &vPatch)); + } -TEST(GetBuildID, HandlesNullInput) { - EXPECT_EQ(loot_error_invalid_args, loot_get_build_id(NULL)); -} + TEST(GetBuildID, HandlesNullInput) { + EXPECT_EQ(loot_error_invalid_args, loot_get_build_id(NULL)); + } -TEST(GetBuildID, HandlesValidInput) { - const char * revision; - EXPECT_EQ(loot_ok, loot_get_build_id(&revision)); - EXPECT_STRNE(NULL, revision); - EXPECT_STRNE("@GIT_COMMIT_STRING@", revision); // The CMake placeholder. -} + TEST(GetBuildID, HandlesValidInput) { + const char * revision; + EXPECT_EQ(loot_ok, loot_get_build_id(&revision)); + EXPECT_STRNE(NULL, revision); + EXPECT_STRNE("@GIT_COMMIT_STRING@", revision); // The CMake placeholder. + } -TEST(IsCompatible, shouldReturnTrueWithEqualMajorAndMinorVersionsAndUnequalPatchVersion) { - unsigned int vMajor, vMinor, vPatch; - EXPECT_EQ(loot_ok, loot_get_version(&vMajor, &vMinor, &vPatch)); + TEST(IsCompatible, shouldReturnTrueWithEqualMajorAndMinorVersionsAndUnequalPatchVersion) { + unsigned int vMajor, vMinor, vPatch; + EXPECT_EQ(loot_ok, loot_get_version(&vMajor, &vMinor, &vPatch)); - EXPECT_TRUE(loot_is_compatible(vMajor, vMinor, vPatch + 1)); -} + EXPECT_TRUE(loot_is_compatible(vMajor, vMinor, vPatch + 1)); + } -TEST(IsCompatible, shouldReturnFalseWithEqualMajorVersionAndUnequalMinorAndPatchVersions) { - unsigned int vMajor, vMinor, vPatch; - EXPECT_EQ(loot_ok, loot_get_version(&vMajor, &vMinor, &vPatch)); + TEST(IsCompatible, shouldReturnFalseWithEqualMajorVersionAndUnequalMinorAndPatchVersions) { + unsigned int vMajor, vMinor, vPatch; + EXPECT_EQ(loot_ok, loot_get_version(&vMajor, &vMinor, &vPatch)); - EXPECT_FALSE(loot_is_compatible(vMajor, vMinor + 1, vPatch + 1)); -} + EXPECT_FALSE(loot_is_compatible(vMajor, vMinor + 1, vPatch + 1)); + } -TEST(GetErrorMessage, HandlesInputCorrectly) { - EXPECT_EQ(loot_error_invalid_args, loot_get_error_message(NULL)); + TEST(GetErrorMessage, HandlesInputCorrectly) { + EXPECT_EQ(loot_error_invalid_args, loot_get_error_message(NULL)); - const char * error; - EXPECT_EQ(loot_ok, loot_get_error_message(&error)); - ASSERT_STREQ("Null message pointer passed.", error); -} + const char * error; + EXPECT_EQ(loot_ok, loot_get_error_message(&error)); + ASSERT_STREQ("Null message pointer passed.", error); + } -TEST_F(OblivionTest, CreateDbHandlesValidInputs) { - EXPECT_EQ(loot_ok, loot_create_db(&db, loot_game_tes4, dataPath.parent_path().string().c_str(), localPath.string().c_str())); - ASSERT_NO_THROW(loot_destroy_db(db)); - db = nullptr; + TEST_F(OblivionTest, CreateDbHandlesValidInputs) { + EXPECT_EQ(loot_ok, loot_create_db(&db, loot_game_tes4, dataPath.parent_path().string().c_str(), localPath.string().c_str())); + ASSERT_NO_THROW(loot_destroy_db(db)); + db = nullptr; - // Also test absolute paths. - boost::filesystem::path game = boost::filesystem::current_path() / dataPath.parent_path(); - boost::filesystem::path local = boost::filesystem::current_path() / localPath; - EXPECT_EQ(loot_ok, loot_create_db(&db, loot_game_tes4, game.string().c_str(), local.string().c_str())); -} + // Also test absolute paths. + boost::filesystem::path game = boost::filesystem::current_path() / dataPath.parent_path(); + boost::filesystem::path local = boost::filesystem::current_path() / localPath; + EXPECT_EQ(loot_ok, loot_create_db(&db, loot_game_tes4, game.string().c_str(), local.string().c_str())); + } -TEST_F(OblivionTest, CreateDbHandlesInvalidHandleInput) { - EXPECT_EQ(loot_error_invalid_args, loot_create_db(NULL, loot_game_tes4, dataPath.parent_path().string().c_str(), localPath.string().c_str())); -} + TEST_F(OblivionTest, CreateDbHandlesInvalidHandleInput) { + EXPECT_EQ(loot_error_invalid_args, loot_create_db(NULL, loot_game_tes4, dataPath.parent_path().string().c_str(), localPath.string().c_str())); + } -TEST_F(OblivionTest, CreateDbHandlesInvalidGameType) { - EXPECT_EQ(loot_error_invalid_args, loot_create_db(&db, UINT_MAX, dataPath.parent_path().string().c_str(), localPath.string().c_str())); -} + TEST_F(OblivionTest, CreateDbHandlesInvalidGameType) { + EXPECT_EQ(loot_error_invalid_args, loot_create_db(&db, UINT_MAX, dataPath.parent_path().string().c_str(), localPath.string().c_str())); + } -TEST_F(OblivionTest, CreateDbHandlesInvalidGamePathInput) { - EXPECT_EQ(loot_error_invalid_args, loot_create_db(&db, loot_game_tes4, missingPath.string().c_str(), localPath.string().c_str())); -} + TEST_F(OblivionTest, CreateDbHandlesInvalidGamePathInput) { + EXPECT_EQ(loot_error_invalid_args, loot_create_db(&db, loot_game_tes4, missingPath.string().c_str(), localPath.string().c_str())); + } -TEST_F(OblivionTest, CreateDbHandlesInvalidLocalPathInput) { - EXPECT_EQ(loot_error_invalid_args, loot_create_db(&db, loot_game_tes4, dataPath.parent_path().string().c_str(), missingPath.string().c_str())); -} + TEST_F(OblivionTest, CreateDbHandlesInvalidLocalPathInput) { + EXPECT_EQ(loot_error_invalid_args, loot_create_db(&db, loot_game_tes4, dataPath.parent_path().string().c_str(), missingPath.string().c_str())); + } #ifdef _WIN32 -TEST_F(OblivionTest, CreateDbHandlesNullLocalPath) { - EXPECT_EQ(loot_ok, loot_create_db(&db, loot_game_tes4, dataPath.parent_path().string().c_str(), NULL)); -} + TEST_F(OblivionTest, CreateDbHandlesNullLocalPath) { + EXPECT_EQ(loot_ok, loot_create_db(&db, loot_game_tes4, dataPath.parent_path().string().c_str(), NULL)); + } #endif -TEST_F(SkyrimTest, CreateDbHandlesValidInputs) { - EXPECT_EQ(loot_ok, loot_create_db(&db, loot_game_tes5, dataPath.parent_path().string().c_str(), localPath.string().c_str())); - ASSERT_NO_THROW(loot_destroy_db(db)); - db = nullptr; + TEST_F(SkyrimTest, CreateDbHandlesValidInputs) { + EXPECT_EQ(loot_ok, loot_create_db(&db, loot_game_tes5, dataPath.parent_path().string().c_str(), localPath.string().c_str())); + ASSERT_NO_THROW(loot_destroy_db(db)); + db = nullptr; - // Also test absolute paths. - boost::filesystem::path game = boost::filesystem::current_path() / dataPath.parent_path(); - boost::filesystem::path local = boost::filesystem::current_path() / localPath; - EXPECT_EQ(loot_ok, loot_create_db(&db, loot_game_tes5, game.string().c_str(), local.string().c_str())); -} + // Also test absolute paths. + boost::filesystem::path game = boost::filesystem::current_path() / dataPath.parent_path(); + boost::filesystem::path local = boost::filesystem::current_path() / localPath; + EXPECT_EQ(loot_ok, loot_create_db(&db, loot_game_tes5, game.string().c_str(), local.string().c_str())); + } -TEST_F(SkyrimTest, CreateDbHandlesInvalidHandleInput) { - EXPECT_EQ(loot_error_invalid_args, loot_create_db(NULL, loot_game_tes5, dataPath.parent_path().string().c_str(), localPath.string().c_str())); -} + TEST_F(SkyrimTest, CreateDbHandlesInvalidHandleInput) { + EXPECT_EQ(loot_error_invalid_args, loot_create_db(NULL, loot_game_tes5, dataPath.parent_path().string().c_str(), localPath.string().c_str())); + } -TEST_F(SkyrimTest, CreateDbHandlesInvalidGameType) { - EXPECT_EQ(loot_error_invalid_args, loot_create_db(&db, UINT_MAX, dataPath.parent_path().string().c_str(), localPath.string().c_str())); -} + TEST_F(SkyrimTest, CreateDbHandlesInvalidGameType) { + EXPECT_EQ(loot_error_invalid_args, loot_create_db(&db, UINT_MAX, dataPath.parent_path().string().c_str(), localPath.string().c_str())); + } -TEST_F(SkyrimTest, CreateDbHandlesInvalidGamePathInput) { - EXPECT_EQ(loot_error_invalid_args, loot_create_db(&db, loot_game_tes5, missingPath.string().c_str(), localPath.string().c_str())); -} + TEST_F(SkyrimTest, CreateDbHandlesInvalidGamePathInput) { + EXPECT_EQ(loot_error_invalid_args, loot_create_db(&db, loot_game_tes5, missingPath.string().c_str(), localPath.string().c_str())); + } -TEST_F(SkyrimTest, CreateDbHandlesInvalidLocalPathInput) { - EXPECT_EQ(loot_error_invalid_args, loot_create_db(&db, loot_game_tes5, dataPath.parent_path().string().c_str(), missingPath.string().c_str())); -} + TEST_F(SkyrimTest, CreateDbHandlesInvalidLocalPathInput) { + EXPECT_EQ(loot_error_invalid_args, loot_create_db(&db, loot_game_tes5, dataPath.parent_path().string().c_str(), missingPath.string().c_str())); + } #ifdef _WIN32 -TEST_F(SkyrimTest, CreateDbHandlesNullLocalPath) { - EXPECT_EQ(loot_ok, loot_create_db(&db, loot_game_tes5, dataPath.parent_path().string().c_str(), NULL)); -} + TEST_F(SkyrimTest, CreateDbHandlesNullLocalPath) { + EXPECT_EQ(loot_ok, loot_create_db(&db, loot_game_tes5, dataPath.parent_path().string().c_str(), NULL)); + } #endif -TEST(GameHandleDestroyTest, HandledNullInput) { - ASSERT_NO_THROW(loot_destroy_db(NULL)); -} + TEST(GameHandleDestroyTest, HandledNullInput) { + ASSERT_NO_THROW(loot_destroy_db(NULL)); + } -TEST_F(OblivionAPIOperationsTest, UpdateMasterlist) { - bool updated; - EXPECT_EQ(loot_error_invalid_args, loot_update_masterlist(NULL, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "master", &updated)); - EXPECT_EQ(loot_error_invalid_args, loot_update_masterlist(db, NULL, "https://github.com/loot/testing-metadata.git", "master", &updated)); - EXPECT_EQ(loot_error_invalid_args, loot_update_masterlist(db, masterlistPath.string().c_str(), NULL, "master", &updated)); - EXPECT_EQ(loot_error_invalid_args, loot_update_masterlist(db, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", NULL, &updated)); - EXPECT_EQ(loot_error_invalid_args, loot_update_masterlist(db, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "master", NULL)); + TEST_F(OblivionAPIOperationsTest, UpdateMasterlist) { + bool updated; + EXPECT_EQ(loot_error_invalid_args, loot_update_masterlist(NULL, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "master", &updated)); + EXPECT_EQ(loot_error_invalid_args, loot_update_masterlist(db, NULL, "https://github.com/loot/testing-metadata.git", "master", &updated)); + EXPECT_EQ(loot_error_invalid_args, loot_update_masterlist(db, masterlistPath.string().c_str(), NULL, "master", &updated)); + EXPECT_EQ(loot_error_invalid_args, loot_update_masterlist(db, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", NULL, &updated)); + EXPECT_EQ(loot_error_invalid_args, loot_update_masterlist(db, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "master", NULL)); - EXPECT_EQ(loot_error_invalid_args, loot_update_masterlist(db, ";//\?", "https://github.com/loot/testing-metadata.git", "master", &updated)); - EXPECT_EQ(loot_error_invalid_args, loot_update_masterlist(db, "", "https://github.com/loot/testing-metadata.git", "master", &updated)); - EXPECT_EQ(loot_error_git_error, loot_update_masterlist(db, masterlistPath.string().c_str(), "https://github.com/loot/oblivion-does-not-exist.git", "master", &updated)); - EXPECT_EQ(loot_error_invalid_args, loot_update_masterlist(db, masterlistPath.string().c_str(), "", "master", &updated)); - EXPECT_EQ(loot_error_git_error, loot_update_masterlist(db, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "missing-branch", &updated)); - EXPECT_EQ(loot_error_invalid_args, loot_update_masterlist(db, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "", &updated)); + EXPECT_EQ(loot_error_invalid_args, loot_update_masterlist(db, ";//\?", "https://github.com/loot/testing-metadata.git", "master", &updated)); + EXPECT_EQ(loot_error_invalid_args, loot_update_masterlist(db, "", "https://github.com/loot/testing-metadata.git", "master", &updated)); + EXPECT_EQ(loot_error_git_error, loot_update_masterlist(db, masterlistPath.string().c_str(), "https://github.com/loot/oblivion-does-not-exist.git", "master", &updated)); + EXPECT_EQ(loot_error_invalid_args, loot_update_masterlist(db, masterlistPath.string().c_str(), "", "master", &updated)); + EXPECT_EQ(loot_error_git_error, loot_update_masterlist(db, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "missing-branch", &updated)); + EXPECT_EQ(loot_error_invalid_args, loot_update_masterlist(db, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "", &updated)); - // Test actual masterlist update. - EXPECT_EQ(loot_ok, loot_update_masterlist(db, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "master", &updated)); - EXPECT_TRUE(updated); + // Test actual masterlist update. + EXPECT_EQ(loot_ok, loot_update_masterlist(db, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "master", &updated)); + EXPECT_TRUE(updated); - // Test with an up-to-date masterlist. - EXPECT_EQ(loot_ok, loot_update_masterlist(db, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "master", &updated)); - EXPECT_FALSE(updated); -} + // Test with an up-to-date masterlist. + EXPECT_EQ(loot_ok, loot_update_masterlist(db, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "master", &updated)); + EXPECT_FALSE(updated); + } -TEST_F(OblivionAPIOperationsTest, GetMasterlistRevision) { - const char * revisionID; - const char * revisionDate; - bool isModified; - EXPECT_EQ(loot_error_invalid_args, loot_get_masterlist_revision(NULL, masterlistPath.string().c_str(), false, &revisionID, &revisionDate, &isModified)); - EXPECT_EQ(loot_error_invalid_args, loot_get_masterlist_revision(db, NULL, false, &revisionID, &revisionDate, &isModified)); - EXPECT_EQ(loot_error_invalid_args, loot_get_masterlist_revision(db, masterlistPath.string().c_str(), false, NULL, &revisionDate, &isModified)); - EXPECT_EQ(loot_error_invalid_args, loot_get_masterlist_revision(db, masterlistPath.string().c_str(), false, &revisionID, NULL, &isModified)); - EXPECT_EQ(loot_error_invalid_args, loot_get_masterlist_revision(db, masterlistPath.string().c_str(), false, &revisionID, &revisionDate, NULL)); + TEST_F(OblivionAPIOperationsTest, GetMasterlistRevision) { + const char * revisionID; + const char * revisionDate; + bool isModified; + EXPECT_EQ(loot_error_invalid_args, loot_get_masterlist_revision(NULL, masterlistPath.string().c_str(), false, &revisionID, &revisionDate, &isModified)); + EXPECT_EQ(loot_error_invalid_args, loot_get_masterlist_revision(db, NULL, false, &revisionID, &revisionDate, &isModified)); + EXPECT_EQ(loot_error_invalid_args, loot_get_masterlist_revision(db, masterlistPath.string().c_str(), false, NULL, &revisionDate, &isModified)); + EXPECT_EQ(loot_error_invalid_args, loot_get_masterlist_revision(db, masterlistPath.string().c_str(), false, &revisionID, NULL, &isModified)); + EXPECT_EQ(loot_error_invalid_args, loot_get_masterlist_revision(db, masterlistPath.string().c_str(), false, &revisionID, &revisionDate, NULL)); - // Test with no masterlist. - EXPECT_EQ(loot_ok, loot_get_masterlist_revision(db, masterlistPath.string().c_str(), false, &revisionID, &revisionDate, &isModified)); - EXPECT_EQ(NULL, revisionID); - EXPECT_EQ(NULL, revisionDate); - EXPECT_FALSE(isModified); + // Test with no masterlist. + EXPECT_EQ(loot_ok, loot_get_masterlist_revision(db, masterlistPath.string().c_str(), false, &revisionID, &revisionDate, &isModified)); + EXPECT_EQ(NULL, revisionID); + EXPECT_EQ(NULL, revisionDate); + EXPECT_FALSE(isModified); - // Test with a generated (non-revision-control) masterlist. - ASSERT_NO_THROW(GenerateMasterlist()); - EXPECT_EQ(loot_ok, loot_get_masterlist_revision(db, masterlistPath.string().c_str(), false, &revisionID, &revisionDate, &isModified)); - EXPECT_EQ(NULL, revisionID); - EXPECT_EQ(NULL, revisionDate); - EXPECT_FALSE(isModified); + // Test with a generated (non-revision-control) masterlist. + ASSERT_NO_THROW(GenerateMasterlist()); + EXPECT_EQ(loot_ok, loot_get_masterlist_revision(db, masterlistPath.string().c_str(), false, &revisionID, &revisionDate, &isModified)); + EXPECT_EQ(NULL, revisionID); + EXPECT_EQ(NULL, revisionDate); + EXPECT_FALSE(isModified); - // Update the masterlist and test. - bool updated; - ASSERT_EQ(loot_ok, loot_update_masterlist(db, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "master", &updated)); - ASSERT_TRUE(updated); - EXPECT_EQ(loot_ok, loot_get_masterlist_revision(db, masterlistPath.string().c_str(), false, &revisionID, &revisionDate, &isModified)); - EXPECT_STRNE(NULL, revisionID); - EXPECT_EQ(40, strlen(revisionID)); - EXPECT_STRNE(NULL, revisionDate); - EXPECT_EQ(10, strlen(revisionDate)); - EXPECT_FALSE(isModified); + // Update the masterlist and test. + bool updated; + ASSERT_EQ(loot_ok, loot_update_masterlist(db, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "master", &updated)); + ASSERT_TRUE(updated); + EXPECT_EQ(loot_ok, loot_get_masterlist_revision(db, masterlistPath.string().c_str(), false, &revisionID, &revisionDate, &isModified)); + EXPECT_STRNE(NULL, revisionID); + EXPECT_EQ(40, strlen(revisionID)); + EXPECT_STRNE(NULL, revisionDate); + EXPECT_EQ(10, strlen(revisionDate)); + EXPECT_FALSE(isModified); - // Test with a short revision string. - EXPECT_EQ(loot_ok, loot_get_masterlist_revision(db, masterlistPath.string().c_str(), true, &revisionID, &revisionDate, &isModified)); - EXPECT_STRNE(NULL, revisionID); - EXPECT_GE(size_t(40), strlen(revisionID)); - EXPECT_LE(size_t(7), strlen(revisionID)); - EXPECT_STRNE(NULL, revisionDate); - EXPECT_EQ(10, strlen(revisionDate)); - EXPECT_FALSE(isModified); + // Test with a short revision string. + EXPECT_EQ(loot_ok, loot_get_masterlist_revision(db, masterlistPath.string().c_str(), true, &revisionID, &revisionDate, &isModified)); + EXPECT_STRNE(NULL, revisionID); + EXPECT_GE(size_t(40), strlen(revisionID)); + EXPECT_LE(size_t(7), strlen(revisionID)); + EXPECT_STRNE(NULL, revisionDate); + EXPECT_EQ(10, strlen(revisionDate)); + EXPECT_FALSE(isModified); - // Overwrite the masterlist with a generated one. - ASSERT_NO_THROW(GenerateMasterlist()); - EXPECT_EQ(loot_ok, loot_get_masterlist_revision(db, masterlistPath.string().c_str(), false, &revisionID, &revisionDate, &isModified)); - EXPECT_STRNE(NULL, revisionID); - EXPECT_EQ(40, strlen(revisionID)); - EXPECT_STRNE(NULL, revisionDate); - EXPECT_EQ(10, strlen(revisionDate)); - EXPECT_TRUE(isModified); -} + // Overwrite the masterlist with a generated one. + ASSERT_NO_THROW(GenerateMasterlist()); + EXPECT_EQ(loot_ok, loot_get_masterlist_revision(db, masterlistPath.string().c_str(), false, &revisionID, &revisionDate, &isModified)); + EXPECT_STRNE(NULL, revisionID); + EXPECT_EQ(40, strlen(revisionID)); + EXPECT_STRNE(NULL, revisionDate); + EXPECT_EQ(10, strlen(revisionDate)); + EXPECT_TRUE(isModified); + } -TEST_F(OblivionAPIOperationsTest, LoadLists) { - EXPECT_EQ(loot_error_invalid_args, loot_load_lists(NULL, masterlistPath.string().c_str(), NULL)); - EXPECT_EQ(loot_error_invalid_args, loot_load_lists(db, NULL, NULL)); + TEST_F(OblivionAPIOperationsTest, LoadLists) { + EXPECT_EQ(loot_error_invalid_args, loot_load_lists(NULL, masterlistPath.string().c_str(), NULL)); + EXPECT_EQ(loot_error_invalid_args, loot_load_lists(db, NULL, NULL)); - EXPECT_EQ(loot_error_path_not_found, loot_load_lists(db, masterlistPath.string().c_str(), NULL)); - bool updated; - ASSERT_EQ(loot_ok, loot_update_masterlist(db, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "master", &updated)); - EXPECT_EQ(loot_error_path_not_found, loot_load_lists(db, masterlistPath.string().c_str(), userlistPath.string().c_str())); + EXPECT_EQ(loot_error_path_not_found, loot_load_lists(db, masterlistPath.string().c_str(), NULL)); + bool updated; + ASSERT_EQ(loot_ok, loot_update_masterlist(db, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "master", &updated)); + EXPECT_EQ(loot_error_path_not_found, loot_load_lists(db, masterlistPath.string().c_str(), userlistPath.string().c_str())); - ASSERT_NO_THROW(boost::filesystem::copy(masterlistPath, userlistPath)); - EXPECT_EQ(loot_ok, loot_load_lists(db, masterlistPath.string().c_str(), userlistPath.string().c_str())); -} + ASSERT_NO_THROW(boost::filesystem::copy(masterlistPath, userlistPath)); + EXPECT_EQ(loot_ok, loot_load_lists(db, masterlistPath.string().c_str(), userlistPath.string().c_str())); + } -TEST_F(SkyrimAPIOperationsTest, LoadLists) { - EXPECT_EQ(loot_error_invalid_args, loot_load_lists(NULL, masterlistPath.string().c_str(), NULL)); - EXPECT_EQ(loot_error_invalid_args, loot_load_lists(db, NULL, NULL)); + TEST_F(SkyrimAPIOperationsTest, LoadLists) { + EXPECT_EQ(loot_error_invalid_args, loot_load_lists(NULL, masterlistPath.string().c_str(), NULL)); + EXPECT_EQ(loot_error_invalid_args, loot_load_lists(db, NULL, NULL)); - EXPECT_EQ(loot_error_path_not_found, loot_load_lists(db, masterlistPath.string().c_str(), NULL)); - bool updated; - ASSERT_EQ(loot_ok, loot_update_masterlist(db, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "master", &updated)); - EXPECT_EQ(loot_error_path_not_found, loot_load_lists(db, masterlistPath.string().c_str(), userlistPath.string().c_str())); + EXPECT_EQ(loot_error_path_not_found, loot_load_lists(db, masterlistPath.string().c_str(), NULL)); + bool updated; + ASSERT_EQ(loot_ok, loot_update_masterlist(db, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "master", &updated)); + EXPECT_EQ(loot_error_path_not_found, loot_load_lists(db, masterlistPath.string().c_str(), userlistPath.string().c_str())); - ASSERT_NO_THROW(boost::filesystem::copy(masterlistPath, userlistPath)); - EXPECT_EQ(loot_ok, loot_load_lists(db, masterlistPath.string().c_str(), userlistPath.string().c_str())); -} + ASSERT_NO_THROW(boost::filesystem::copy(masterlistPath, userlistPath)); + EXPECT_EQ(loot_ok, loot_load_lists(db, masterlistPath.string().c_str(), userlistPath.string().c_str())); + } -TEST_F(OblivionAPIOperationsTest, EvalLists) { - // No lists loaded. - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_any)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_english)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_spanish)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_russian)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_french)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_chinese)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_polish)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_brazilian_portuguese)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_finnish)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_german)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_danish)); + TEST_F(OblivionAPIOperationsTest, EvalLists) { + // No lists loaded. + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_any)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_english)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_spanish)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_russian)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_french)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_chinese)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_polish)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_brazilian_portuguese)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_finnish)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_german)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_danish)); - // Invalid args. - EXPECT_EQ(loot_error_invalid_args, loot_eval_lists(NULL, loot_lang_any)); - EXPECT_EQ(loot_error_invalid_args, loot_eval_lists(db, UINT_MAX)); + // Invalid args. + EXPECT_EQ(loot_error_invalid_args, loot_eval_lists(NULL, loot_lang_any)); + EXPECT_EQ(loot_error_invalid_args, loot_eval_lists(db, UINT_MAX)); - // Now test different languages with a list loaded. - bool updated; - ASSERT_EQ(loot_ok, loot_update_masterlist(db, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "master", &updated)); - ASSERT_EQ(loot_ok, loot_load_lists(db, masterlistPath.string().c_str(), NULL)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_any)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_english)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_spanish)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_russian)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_french)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_chinese)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_polish)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_brazilian_portuguese)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_finnish)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_german)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_danish)); -} + // Now test different languages with a list loaded. + bool updated; + ASSERT_EQ(loot_ok, loot_update_masterlist(db, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "master", &updated)); + ASSERT_EQ(loot_ok, loot_load_lists(db, masterlistPath.string().c_str(), NULL)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_any)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_english)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_spanish)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_russian)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_french)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_chinese)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_polish)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_brazilian_portuguese)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_finnish)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_german)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_danish)); + } -TEST_F(SkyrimAPIOperationsTest, EvalLists) { - // No lists loaded. - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_any)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_english)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_spanish)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_russian)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_french)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_chinese)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_polish)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_brazilian_portuguese)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_finnish)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_german)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_danish)); + TEST_F(SkyrimAPIOperationsTest, EvalLists) { + // No lists loaded. + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_any)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_english)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_spanish)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_russian)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_french)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_chinese)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_polish)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_brazilian_portuguese)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_finnish)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_german)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_danish)); - // Invalid args. - EXPECT_EQ(loot_error_invalid_args, loot_eval_lists(NULL, loot_lang_any)); - EXPECT_EQ(loot_error_invalid_args, loot_eval_lists(db, UINT_MAX)); + // Invalid args. + EXPECT_EQ(loot_error_invalid_args, loot_eval_lists(NULL, loot_lang_any)); + EXPECT_EQ(loot_error_invalid_args, loot_eval_lists(db, UINT_MAX)); - // Now test different languages with a list loaded. - bool updated; - ASSERT_EQ(loot_ok, loot_update_masterlist(db, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "master", &updated)); - ASSERT_EQ(loot_ok, loot_load_lists(db, masterlistPath.string().c_str(), NULL)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_any)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_english)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_spanish)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_russian)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_french)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_chinese)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_polish)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_brazilian_portuguese)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_finnish)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_german)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_danish)); -} + // Now test different languages with a list loaded. + bool updated; + ASSERT_EQ(loot_ok, loot_update_masterlist(db, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "master", &updated)); + ASSERT_EQ(loot_ok, loot_load_lists(db, masterlistPath.string().c_str(), NULL)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_any)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_english)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_spanish)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_russian)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_french)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_chinese)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_polish)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_brazilian_portuguese)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_finnish)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_german)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_danish)); + } -TEST_F(OblivionAPIOperationsTest, SortPlugins) { - const char * const * sortedPlugins; - size_t numPlugins; - EXPECT_EQ(loot_error_invalid_args, loot_sort_plugins(NULL, &sortedPlugins, &numPlugins)); - EXPECT_EQ(loot_error_invalid_args, loot_sort_plugins(db, NULL, &numPlugins)); - EXPECT_EQ(loot_error_invalid_args, loot_sort_plugins(db, &sortedPlugins, NULL)); + TEST_F(OblivionAPIOperationsTest, SortPlugins) { + const char * const * sortedPlugins; + size_t numPlugins; + EXPECT_EQ(loot_error_invalid_args, loot_sort_plugins(NULL, &sortedPlugins, &numPlugins)); + EXPECT_EQ(loot_error_invalid_args, loot_sort_plugins(db, NULL, &numPlugins)); + EXPECT_EQ(loot_error_invalid_args, loot_sort_plugins(db, &sortedPlugins, NULL)); - EXPECT_EQ(loot_ok, loot_sort_plugins(db, &sortedPlugins, &numPlugins)); + EXPECT_EQ(loot_ok, loot_sort_plugins(db, &sortedPlugins, &numPlugins)); - // Expected order was obtained from running the API function once. - std::list expectedOrder = { - "Oblivion.esm", - "Blank.esm", - "Blank - Different.esm", - "Blank - Master Dependent.esm", - "Blank - Different Master Dependent.esm", - "Blank.esp", - "Blank - Different.esp", - "Blank - Master Dependent.esp", - "Blank - Different Master Dependent.esp", - "Blank - Plugin Dependent.esp", - "Blank - Different Plugin Dependent.esp", - }; - std::list actualOrder; - for (size_t i = 0; i < numPlugins; ++i) { - actualOrder.push_back(sortedPlugins[i]); + // Expected order was obtained from running the API function once. + std::list expectedOrder = { + "Oblivion.esm", + "Blank.esm", + "Blank - Different.esm", + "Blank - Master Dependent.esm", + "Blank - Different Master Dependent.esm", + "Blank.esp", + "Blank - Different.esp", + "Blank - Master Dependent.esp", + "Blank - Different Master Dependent.esp", + "Blank - Plugin Dependent.esp", + "Blank - Different Plugin Dependent.esp", + }; + std::list actualOrder; + for (size_t i = 0; i < numPlugins; ++i) { + actualOrder.push_back(sortedPlugins[i]); + } + EXPECT_EQ(11, numPlugins); + EXPECT_EQ(expectedOrder, actualOrder); + } + + TEST_F(SkyrimAPIOperationsTest, SortPlugins) { + const char * const * sortedPlugins; + size_t numPlugins; + EXPECT_EQ(loot_error_invalid_args, loot_sort_plugins(NULL, &sortedPlugins, &numPlugins)); + EXPECT_EQ(loot_error_invalid_args, loot_sort_plugins(db, NULL, &numPlugins)); + EXPECT_EQ(loot_error_invalid_args, loot_sort_plugins(db, &sortedPlugins, NULL)); + + EXPECT_EQ(loot_ok, loot_sort_plugins(db, &sortedPlugins, &numPlugins)); + + // Expected order was obtained from running the API function once. + std::list expectedOrder = { + "Skyrim.esm", + "Blank.esm", + "Blank - Different.esm", + "Blank - Master Dependent.esm", + "Blank - Different Master Dependent.esm", + "Blank.esp", + "Blank - Different.esp", + "Blank - Master Dependent.esp", + "Blank - Different Master Dependent.esp", + "Blank - Plugin Dependent.esp", + "Blank - Different Plugin Dependent.esp", + }; + std::list actualOrder; + for (size_t i = 0; i < numPlugins; ++i) { + actualOrder.push_back(sortedPlugins[i]); + } + EXPECT_EQ(11, numPlugins); + EXPECT_EQ(expectedOrder, actualOrder); + } + + TEST_F(OblivionAPIOperationsTest, ApplyLoadOrder) { + const char * loadOrder[11] = { + "Oblivion.esm", + "Blank.esm", + "Blank - Different.esm", + "Blank - Different Master Dependent.esm", + "Blank - Master Dependent.esm", + "Blank.esp", + "Blank - Different.esp", + "Blank - Different Master Dependent.esp", + "Blank - Different Plugin Dependent.esp", + "Blank - Master Dependent.esp", + "Blank - Plugin Dependent.esp", + }; + size_t numPlugins = 11; + EXPECT_EQ(loot_error_invalid_args, loot_apply_load_order(NULL, loadOrder, numPlugins)); + EXPECT_EQ(loot_error_invalid_args, loot_apply_load_order(db, NULL, numPlugins)); + + EXPECT_EQ(loot_ok, loot_apply_load_order(db, loadOrder, numPlugins)); + } + + TEST_F(SkyrimAPIOperationsTest, ApplyLoadOrder) { + const char * loadOrder[11] = { + "Skyrim.esm", + "Blank.esm", + "Blank - Different.esm", + "Blank - Different Master Dependent.esm", + "Blank - Master Dependent.esm", + "Blank.esp", + "Blank - Different.esp", + "Blank - Different Master Dependent.esp", + "Blank - Different Plugin Dependent.esp", + "Blank - Master Dependent.esp", + "Blank - Plugin Dependent.esp", + }; + size_t numPlugins = 11; + EXPECT_EQ(loot_error_invalid_args, loot_apply_load_order(NULL, loadOrder, numPlugins)); + EXPECT_EQ(loot_error_invalid_args, loot_apply_load_order(db, NULL, numPlugins)); + + EXPECT_EQ(loot_ok, loot_apply_load_order(db, loadOrder, numPlugins)); + } + + TEST_F(OblivionAPIOperationsTest, GetTagMap) { + const char * const * tagMap; + size_t numTags; + EXPECT_EQ(loot_error_invalid_args, loot_get_tag_map(NULL, &tagMap, &numTags)); + EXPECT_EQ(loot_error_invalid_args, loot_get_tag_map(db, NULL, &numTags)); + EXPECT_EQ(loot_error_invalid_args, loot_get_tag_map(db, &tagMap, NULL)); + + // Get tag map with no masterlist loaded: should have no tags. + EXPECT_EQ(loot_ok, loot_get_tag_map(db, &tagMap, &numTags)); + EXPECT_EQ(0, numTags); + EXPECT_EQ(NULL, tagMap); + + // Get a masterlist, then get tags from it. + ASSERT_NO_THROW(GenerateMasterlist()); + ASSERT_EQ(loot_ok, loot_load_lists(db, masterlistPath.string().c_str(), NULL)); + EXPECT_EQ(loot_ok, loot_get_tag_map(db, &tagMap, &numTags)); + ASSERT_EQ(22, numTags); + EXPECT_STREQ("Actors.ACBS", tagMap[0]); + EXPECT_STREQ("Actors.AIData", tagMap[1]); + EXPECT_STREQ("Actors.AIPackages", tagMap[2]); + EXPECT_STREQ("Actors.CombatStyle", tagMap[3]); + EXPECT_STREQ("Actors.DeathItem", tagMap[4]); + EXPECT_STREQ("Actors.Stats", tagMap[5]); + EXPECT_STREQ("C.Climate", tagMap[6]); + EXPECT_STREQ("C.Light", tagMap[7]); + EXPECT_STREQ("C.Music", tagMap[8]); + EXPECT_STREQ("C.Name", tagMap[9]); + EXPECT_STREQ("C.Owner", tagMap[10]); + EXPECT_STREQ("C.Water", tagMap[11]); + EXPECT_STREQ("Creatures.Blood", tagMap[12]); + EXPECT_STREQ("Delev", tagMap[13]); + EXPECT_STREQ("Factions", tagMap[14]); + EXPECT_STREQ("Invent", tagMap[15]); + EXPECT_STREQ("NPC.Class", tagMap[16]); + EXPECT_STREQ("Names", tagMap[17]); + EXPECT_STREQ("Relations", tagMap[18]); + EXPECT_STREQ("Relev", tagMap[19]); + EXPECT_STREQ("Scripts", tagMap[20]); + EXPECT_STREQ("Stats", tagMap[21]); + } + + TEST_F(OblivionAPIOperationsTest, GetPluginTags) { + const unsigned int * added; + const unsigned int * removed; + size_t numAdded, numRemoved; + bool modified; + EXPECT_EQ(loot_error_invalid_args, loot_get_plugin_tags(NULL, "Unofficial Oblivion Patch.esp", &added, &numAdded, &removed, &numRemoved, &modified)); + EXPECT_EQ(loot_error_invalid_args, loot_get_plugin_tags(db, NULL, &added, &numAdded, &removed, &numRemoved, &modified)); + EXPECT_EQ(loot_error_invalid_args, loot_get_plugin_tags(db, "Unofficial Oblivion Patch.esp", NULL, &numAdded, &removed, &numRemoved, &modified)); + EXPECT_EQ(loot_error_invalid_args, loot_get_plugin_tags(db, "Unofficial Oblivion Patch.esp", &added, NULL, &removed, &numRemoved, &modified)); + EXPECT_EQ(loot_error_invalid_args, loot_get_plugin_tags(db, "Unofficial Oblivion Patch.esp", &added, &numAdded, NULL, &numRemoved, &modified)); + EXPECT_EQ(loot_error_invalid_args, loot_get_plugin_tags(db, "Unofficial Oblivion Patch.esp", &added, &numAdded, &removed, NULL, &modified)); + EXPECT_EQ(loot_error_invalid_args, loot_get_plugin_tags(db, "Unofficial Oblivion Patch.esp", &added, &numAdded, &removed, &numRemoved, NULL)); + + // Get tags before getting a tag map. + EXPECT_EQ(loot_error_no_tag_map, loot_get_plugin_tags(db, "Unofficial Oblivion Patch.esp", &added, &numAdded, &removed, &numRemoved, &modified)); + + // Load tag map. + const char * const * tagMap; + size_t numTags; + ASSERT_NO_THROW(GenerateMasterlist()); + ASSERT_EQ(loot_ok, loot_load_lists(db, masterlistPath.string().c_str(), NULL)); + ASSERT_EQ(loot_ok, loot_get_tag_map(db, &tagMap, &numTags)); + + // Get tags for a plugin without any. + EXPECT_EQ(loot_ok, loot_get_plugin_tags(db, "Blank.esp", &added, &numAdded, &removed, &numRemoved, &modified)); + EXPECT_EQ(0, numAdded); + EXPECT_EQ(NULL, added); + EXPECT_EQ(0, numRemoved); + EXPECT_EQ(NULL, removed); + EXPECT_FALSE(modified); + + // Get tags for a plugin with some. + EXPECT_EQ(loot_ok, loot_get_plugin_tags(db, "Unofficial Oblivion Patch.esp", &added, &numAdded, &removed, &numRemoved, &modified)); + ASSERT_EQ(21, numAdded); + for (size_t i = 0; i < 11; ++i) { + EXPECT_EQ(i, added[i]); + } + for (size_t i = 11; i < 21; ++i) { + EXPECT_EQ(i + 1, added[i]); + } + + ASSERT_EQ(1, numRemoved); + EXPECT_EQ(11, removed[0]); + EXPECT_FALSE(modified); + + // Now load the masterlist as the userlist too, and check the modified flag. + ASSERT_NO_THROW(boost::filesystem::copy_file(masterlistPath, userlistPath)); + ASSERT_EQ(loot_ok, loot_load_lists(db, masterlistPath.string().c_str(), userlistPath.string().c_str())); + ASSERT_EQ(loot_ok, loot_get_tag_map(db, &tagMap, &numTags)); + + EXPECT_EQ(loot_ok, loot_get_plugin_tags(db, "Unofficial Oblivion Patch.esp", &added, &numAdded, &removed, &numRemoved, &modified)); + ASSERT_EQ(21, numAdded); + for (size_t i = 0; i < 11; ++i) { + EXPECT_EQ(i, added[i]); + } + for (size_t i = 11; i < 21; ++i) { + EXPECT_EQ(i + 1, added[i]); + } + EXPECT_EQ(0, added[0]); + ASSERT_EQ(1, numRemoved); + EXPECT_EQ(11, removed[0]); + EXPECT_TRUE(modified); + } + + TEST_F(OblivionAPIOperationsTest, GetPluginMessages) { + const loot_message * messages; + size_t numMessages; + EXPECT_EQ(loot_error_invalid_args, loot_get_plugin_messages(NULL, "EnhancedWeatherSIOnly.esm", &messages, &numMessages)); + EXPECT_EQ(loot_error_invalid_args, loot_get_plugin_messages(db, NULL, &messages, &numMessages)); + EXPECT_EQ(loot_error_invalid_args, loot_get_plugin_messages(db, "EnhancedWeatherSIOnly.esm", NULL, &numMessages)); + EXPECT_EQ(loot_error_invalid_args, loot_get_plugin_messages(db, "EnhancedWeatherSIOnly.esm", &messages, NULL)); + + // Fetch and load the metadata. + ASSERT_NO_THROW(GenerateMasterlist()); + ASSERT_EQ(loot_ok, loot_load_lists(db, masterlistPath.string().c_str(), NULL)); + + // Test for plugin with no messages. + EXPECT_EQ(loot_ok, loot_get_plugin_messages(db, "Silgrad_Tower.esm", &messages, &numMessages)); + EXPECT_EQ(0, numMessages); + EXPECT_EQ(NULL, messages); + + // Test for plugin with one note. + EXPECT_EQ(loot_ok, loot_get_plugin_messages(db, "No Lights Flicker.esm", &messages, &numMessages)); + EXPECT_EQ(1, numMessages); + EXPECT_EQ(loot_message_say, messages[0].type); + EXPECT_STREQ("Use Wrye Bash Bashed Patch tweak instead.", messages[0].message); + + // Test for plugin with one warning. + EXPECT_EQ(loot_ok, loot_get_plugin_messages(db, "bookplacing.esm", &messages, &numMessages)); + EXPECT_EQ(1, numMessages); + EXPECT_EQ(loot_message_warn, messages[0].type); + EXPECT_STREQ("Check you are using v2+. If not, Update. v1 has a severe bug with the Mystic Emporium disappearing.", messages[0].message); + + // Test for plugin with one error. + EXPECT_EQ(loot_ok, loot_get_plugin_messages(db, "EnhancedWeatherSIOnly.esm", &messages, &numMessages)); + EXPECT_EQ(1, numMessages); + EXPECT_EQ(loot_message_error, messages[0].type); + EXPECT_STREQ("Obsolete. Remove this and install Enhanced Weather.", messages[0].message); + + // Test for plugin with more than one message. + EXPECT_EQ(loot_ok, loot_get_plugin_messages(db, "nVidia Black Screen Fix.esp", &messages, &numMessages)); + EXPECT_EQ(2, numMessages); + EXPECT_EQ(loot_message_say, messages[0].type); + EXPECT_STREQ("Use Wrye Bash Bashed Patch tweak instead.", messages[0].message); + EXPECT_EQ(loot_message_say, messages[1].type); + EXPECT_STREQ("Alternatively, remove this and use UOP v3.0.1+ instead.", messages[1].message); + } + + TEST_F(OblivionAPIOperationsTest, GetDirtyInfo) { + unsigned int needsCleaning; + EXPECT_EQ(loot_error_invalid_args, loot_get_dirty_info(NULL, "Oblivion.esm", &needsCleaning)); + EXPECT_EQ(loot_error_invalid_args, loot_get_dirty_info(db, NULL, &needsCleaning)); + EXPECT_EQ(loot_error_invalid_args, loot_get_dirty_info(db, "Oblivion.esm", NULL)); + + // Fetch and load the metadata. + ASSERT_NO_THROW(GenerateMasterlist()); + ASSERT_EQ(loot_ok, loot_load_lists(db, masterlistPath.string().c_str(), NULL)); + + // A plugin with no metadata. + EXPECT_EQ(loot_ok, loot_get_dirty_info(db, "Oblivion.esm", &needsCleaning)); + EXPECT_EQ(loot_needs_cleaning_unknown, needsCleaning); + + // A plugin with dirty metadata. + EXPECT_EQ(loot_ok, loot_get_dirty_info(db, "Hammerfell.esm", &needsCleaning)); + EXPECT_EQ(loot_needs_cleaning_yes, needsCleaning); + + // A plugin with a standard "Do not clean" message. + EXPECT_EQ(loot_ok, loot_get_dirty_info(db, "Unofficial Oblivion Patch.esp", &needsCleaning)); + EXPECT_EQ(loot_needs_cleaning_no, needsCleaning); + } + + TEST_F(OblivionAPIOperationsTest, WriteMinimalList) { + std::string outputFile = (localPath / "minimal.yml").string(); + EXPECT_EQ(loot_error_invalid_args, loot_write_minimal_list(NULL, outputFile.c_str(), false)); + EXPECT_EQ(loot_error_invalid_args, loot_write_minimal_list(db, NULL, false)); + EXPECT_EQ(loot_error_file_write_fail, loot_write_minimal_list(db, "/:?*", false)); + + ASSERT_FALSE(boost::filesystem::exists(outputFile)); + EXPECT_EQ(loot_ok, loot_write_minimal_list(db, outputFile.c_str(), false)); + EXPECT_TRUE(boost::filesystem::exists(outputFile)); + EXPECT_EQ(loot_error_file_write_fail, loot_write_minimal_list(db, outputFile.c_str(), false)); + + EXPECT_EQ(loot_ok, loot_write_minimal_list(db, outputFile.c_str(), true)); + ASSERT_NO_THROW(boost::filesystem::remove(outputFile)); + EXPECT_EQ(loot_ok, loot_write_minimal_list(db, outputFile.c_str(), true)); + EXPECT_TRUE(boost::filesystem::exists(outputFile)); + ASSERT_NO_THROW(boost::filesystem::remove(outputFile)); + + // Check that Bash Tag removals get outputted correctly. + bool updated; + ASSERT_EQ(loot_ok, loot_update_masterlist(db, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "master", &updated)); + EXPECT_EQ(loot_ok, loot_load_lists(db, masterlistPath.string().c_str(), NULL)); + EXPECT_EQ(loot_ok, loot_write_minimal_list(db, outputFile.c_str(), false)); + + boost::filesystem::ifstream in(outputFile); + std::string line; + while (std::getline(in, line)) { + EXPECT_FALSE(boost::contains(line, "- \"-\"")); + } + in.close(); + ASSERT_NO_THROW(boost::filesystem::remove(outputFile)); + } } - EXPECT_EQ(11, numPlugins); - EXPECT_EQ(expectedOrder, actualOrder); } -TEST_F(SkyrimAPIOperationsTest, SortPlugins) { - const char * const * sortedPlugins; - size_t numPlugins; - EXPECT_EQ(loot_error_invalid_args, loot_sort_plugins(NULL, &sortedPlugins, &numPlugins)); - EXPECT_EQ(loot_error_invalid_args, loot_sort_plugins(db, NULL, &numPlugins)); - EXPECT_EQ(loot_error_invalid_args, loot_sort_plugins(db, &sortedPlugins, NULL)); - - EXPECT_EQ(loot_ok, loot_sort_plugins(db, &sortedPlugins, &numPlugins)); - - // Expected order was obtained from running the API function once. - std::list expectedOrder = { - "Skyrim.esm", - "Blank.esm", - "Blank - Different.esm", - "Blank - Master Dependent.esm", - "Blank - Different Master Dependent.esm", - "Blank.esp", - "Blank - Different.esp", - "Blank - Master Dependent.esp", - "Blank - Different Master Dependent.esp", - "Blank - Plugin Dependent.esp", - "Blank - Different Plugin Dependent.esp", - }; - std::list actualOrder; - for (size_t i = 0; i < numPlugins; ++i) { - actualOrder.push_back(sortedPlugins[i]); - } - EXPECT_EQ(11, numPlugins); - EXPECT_EQ(expectedOrder, actualOrder); -} - -TEST_F(OblivionAPIOperationsTest, ApplyLoadOrder) { - const char * loadOrder[11] = { - "Oblivion.esm", - "Blank.esm", - "Blank - Different.esm", - "Blank - Different Master Dependent.esm", - "Blank - Master Dependent.esm", - "Blank.esp", - "Blank - Different.esp", - "Blank - Different Master Dependent.esp", - "Blank - Different Plugin Dependent.esp", - "Blank - Master Dependent.esp", - "Blank - Plugin Dependent.esp", - }; - size_t numPlugins = 11; - EXPECT_EQ(loot_error_invalid_args, loot_apply_load_order(NULL, loadOrder, numPlugins)); - EXPECT_EQ(loot_error_invalid_args, loot_apply_load_order(db, NULL, numPlugins)); - - EXPECT_EQ(loot_ok, loot_apply_load_order(db, loadOrder, numPlugins)); -} - -TEST_F(SkyrimAPIOperationsTest, ApplyLoadOrder) { - const char * loadOrder[11] = { - "Skyrim.esm", - "Blank.esm", - "Blank - Different.esm", - "Blank - Different Master Dependent.esm", - "Blank - Master Dependent.esm", - "Blank.esp", - "Blank - Different.esp", - "Blank - Different Master Dependent.esp", - "Blank - Different Plugin Dependent.esp", - "Blank - Master Dependent.esp", - "Blank - Plugin Dependent.esp", - }; - size_t numPlugins = 11; - EXPECT_EQ(loot_error_invalid_args, loot_apply_load_order(NULL, loadOrder, numPlugins)); - EXPECT_EQ(loot_error_invalid_args, loot_apply_load_order(db, NULL, numPlugins)); - - EXPECT_EQ(loot_ok, loot_apply_load_order(db, loadOrder, numPlugins)); -} - -TEST_F(OblivionAPIOperationsTest, GetTagMap) { - const char * const * tagMap; - size_t numTags; - EXPECT_EQ(loot_error_invalid_args, loot_get_tag_map(NULL, &tagMap, &numTags)); - EXPECT_EQ(loot_error_invalid_args, loot_get_tag_map(db, NULL, &numTags)); - EXPECT_EQ(loot_error_invalid_args, loot_get_tag_map(db, &tagMap, NULL)); - - // Get tag map with no masterlist loaded: should have no tags. - EXPECT_EQ(loot_ok, loot_get_tag_map(db, &tagMap, &numTags)); - EXPECT_EQ(0, numTags); - EXPECT_EQ(NULL, tagMap); - - // Get a masterlist, then get tags from it. - ASSERT_NO_THROW(GenerateMasterlist()); - ASSERT_EQ(loot_ok, loot_load_lists(db, masterlistPath.string().c_str(), NULL)); - EXPECT_EQ(loot_ok, loot_get_tag_map(db, &tagMap, &numTags)); - ASSERT_EQ(22, numTags); - EXPECT_STREQ("Actors.ACBS", tagMap[0]); - EXPECT_STREQ("Actors.AIData", tagMap[1]); - EXPECT_STREQ("Actors.AIPackages", tagMap[2]); - EXPECT_STREQ("Actors.CombatStyle", tagMap[3]); - EXPECT_STREQ("Actors.DeathItem", tagMap[4]); - EXPECT_STREQ("Actors.Stats", tagMap[5]); - EXPECT_STREQ("C.Climate", tagMap[6]); - EXPECT_STREQ("C.Light", tagMap[7]); - EXPECT_STREQ("C.Music", tagMap[8]); - EXPECT_STREQ("C.Name", tagMap[9]); - EXPECT_STREQ("C.Owner", tagMap[10]); - EXPECT_STREQ("C.Water", tagMap[11]); - EXPECT_STREQ("Creatures.Blood", tagMap[12]); - EXPECT_STREQ("Delev", tagMap[13]); - EXPECT_STREQ("Factions", tagMap[14]); - EXPECT_STREQ("Invent", tagMap[15]); - EXPECT_STREQ("NPC.Class", tagMap[16]); - EXPECT_STREQ("Names", tagMap[17]); - EXPECT_STREQ("Relations", tagMap[18]); - EXPECT_STREQ("Relev", tagMap[19]); - EXPECT_STREQ("Scripts", tagMap[20]); - EXPECT_STREQ("Stats", tagMap[21]); -} - -TEST_F(OblivionAPIOperationsTest, GetPluginTags) { - const unsigned int * added; - const unsigned int * removed; - size_t numAdded, numRemoved; - bool modified; - EXPECT_EQ(loot_error_invalid_args, loot_get_plugin_tags(NULL, "Unofficial Oblivion Patch.esp", &added, &numAdded, &removed, &numRemoved, &modified)); - EXPECT_EQ(loot_error_invalid_args, loot_get_plugin_tags(db, NULL, &added, &numAdded, &removed, &numRemoved, &modified)); - EXPECT_EQ(loot_error_invalid_args, loot_get_plugin_tags(db, "Unofficial Oblivion Patch.esp", NULL, &numAdded, &removed, &numRemoved, &modified)); - EXPECT_EQ(loot_error_invalid_args, loot_get_plugin_tags(db, "Unofficial Oblivion Patch.esp", &added, NULL, &removed, &numRemoved, &modified)); - EXPECT_EQ(loot_error_invalid_args, loot_get_plugin_tags(db, "Unofficial Oblivion Patch.esp", &added, &numAdded, NULL, &numRemoved, &modified)); - EXPECT_EQ(loot_error_invalid_args, loot_get_plugin_tags(db, "Unofficial Oblivion Patch.esp", &added, &numAdded, &removed, NULL, &modified)); - EXPECT_EQ(loot_error_invalid_args, loot_get_plugin_tags(db, "Unofficial Oblivion Patch.esp", &added, &numAdded, &removed, &numRemoved, NULL)); - - // Get tags before getting a tag map. - EXPECT_EQ(loot_error_no_tag_map, loot_get_plugin_tags(db, "Unofficial Oblivion Patch.esp", &added, &numAdded, &removed, &numRemoved, &modified)); - - // Load tag map. - const char * const * tagMap; - size_t numTags; - ASSERT_NO_THROW(GenerateMasterlist()); - ASSERT_EQ(loot_ok, loot_load_lists(db, masterlistPath.string().c_str(), NULL)); - ASSERT_EQ(loot_ok, loot_get_tag_map(db, &tagMap, &numTags)); - - // Get tags for a plugin without any. - EXPECT_EQ(loot_ok, loot_get_plugin_tags(db, "Blank.esp", &added, &numAdded, &removed, &numRemoved, &modified)); - EXPECT_EQ(0, numAdded); - EXPECT_EQ(NULL, added); - EXPECT_EQ(0, numRemoved); - EXPECT_EQ(NULL, removed); - EXPECT_FALSE(modified); - - // Get tags for a plugin with some. - EXPECT_EQ(loot_ok, loot_get_plugin_tags(db, "Unofficial Oblivion Patch.esp", &added, &numAdded, &removed, &numRemoved, &modified)); - ASSERT_EQ(21, numAdded); - for (size_t i = 0; i < 11; ++i) { - EXPECT_EQ(i, added[i]); - } - for (size_t i = 11; i < 21; ++i) { - EXPECT_EQ(i + 1, added[i]); - } - - ASSERT_EQ(1, numRemoved); - EXPECT_EQ(11, removed[0]); - EXPECT_FALSE(modified); - - // Now load the masterlist as the userlist too, and check the modified flag. - ASSERT_NO_THROW(boost::filesystem::copy_file(masterlistPath, userlistPath)); - ASSERT_EQ(loot_ok, loot_load_lists(db, masterlistPath.string().c_str(), userlistPath.string().c_str())); - ASSERT_EQ(loot_ok, loot_get_tag_map(db, &tagMap, &numTags)); - - EXPECT_EQ(loot_ok, loot_get_plugin_tags(db, "Unofficial Oblivion Patch.esp", &added, &numAdded, &removed, &numRemoved, &modified)); - ASSERT_EQ(21, numAdded); - for (size_t i = 0; i < 11; ++i) { - EXPECT_EQ(i, added[i]); - } - for (size_t i = 11; i < 21; ++i) { - EXPECT_EQ(i + 1, added[i]); - } - EXPECT_EQ(0, added[0]); - ASSERT_EQ(1, numRemoved); - EXPECT_EQ(11, removed[0]); - EXPECT_TRUE(modified); -} - -TEST_F(OblivionAPIOperationsTest, GetPluginMessages) { - const loot_message * messages; - size_t numMessages; - EXPECT_EQ(loot_error_invalid_args, loot_get_plugin_messages(NULL, "EnhancedWeatherSIOnly.esm", &messages, &numMessages)); - EXPECT_EQ(loot_error_invalid_args, loot_get_plugin_messages(db, NULL, &messages, &numMessages)); - EXPECT_EQ(loot_error_invalid_args, loot_get_plugin_messages(db, "EnhancedWeatherSIOnly.esm", NULL, &numMessages)); - EXPECT_EQ(loot_error_invalid_args, loot_get_plugin_messages(db, "EnhancedWeatherSIOnly.esm", &messages, NULL)); - - // Fetch and load the metadata. - ASSERT_NO_THROW(GenerateMasterlist()); - ASSERT_EQ(loot_ok, loot_load_lists(db, masterlistPath.string().c_str(), NULL)); - - // Test for plugin with no messages. - EXPECT_EQ(loot_ok, loot_get_plugin_messages(db, "Silgrad_Tower.esm", &messages, &numMessages)); - EXPECT_EQ(0, numMessages); - EXPECT_EQ(NULL, messages); - - // Test for plugin with one note. - EXPECT_EQ(loot_ok, loot_get_plugin_messages(db, "No Lights Flicker.esm", &messages, &numMessages)); - EXPECT_EQ(1, numMessages); - EXPECT_EQ(loot_message_say, messages[0].type); - EXPECT_STREQ("Use Wrye Bash Bashed Patch tweak instead.", messages[0].message); - - // Test for plugin with one warning. - EXPECT_EQ(loot_ok, loot_get_plugin_messages(db, "bookplacing.esm", &messages, &numMessages)); - EXPECT_EQ(1, numMessages); - EXPECT_EQ(loot_message_warn, messages[0].type); - EXPECT_STREQ("Check you are using v2+. If not, Update. v1 has a severe bug with the Mystic Emporium disappearing.", messages[0].message); - - // Test for plugin with one error. - EXPECT_EQ(loot_ok, loot_get_plugin_messages(db, "EnhancedWeatherSIOnly.esm", &messages, &numMessages)); - EXPECT_EQ(1, numMessages); - EXPECT_EQ(loot_message_error, messages[0].type); - EXPECT_STREQ("Obsolete. Remove this and install Enhanced Weather.", messages[0].message); - - // Test for plugin with more than one message. - EXPECT_EQ(loot_ok, loot_get_plugin_messages(db, "nVidia Black Screen Fix.esp", &messages, &numMessages)); - EXPECT_EQ(2, numMessages); - EXPECT_EQ(loot_message_say, messages[0].type); - EXPECT_STREQ("Use Wrye Bash Bashed Patch tweak instead.", messages[0].message); - EXPECT_EQ(loot_message_say, messages[1].type); - EXPECT_STREQ("Alternatively, remove this and use UOP v3.0.1+ instead.", messages[1].message); -} - -TEST_F(OblivionAPIOperationsTest, GetDirtyInfo) { - unsigned int needsCleaning; - EXPECT_EQ(loot_error_invalid_args, loot_get_dirty_info(NULL, "Oblivion.esm", &needsCleaning)); - EXPECT_EQ(loot_error_invalid_args, loot_get_dirty_info(db, NULL, &needsCleaning)); - EXPECT_EQ(loot_error_invalid_args, loot_get_dirty_info(db, "Oblivion.esm", NULL)); - - // Fetch and load the metadata. - ASSERT_NO_THROW(GenerateMasterlist()); - ASSERT_EQ(loot_ok, loot_load_lists(db, masterlistPath.string().c_str(), NULL)); - - // A plugin with no metadata. - EXPECT_EQ(loot_ok, loot_get_dirty_info(db, "Oblivion.esm", &needsCleaning)); - EXPECT_EQ(loot_needs_cleaning_unknown, needsCleaning); - - // A plugin with dirty metadata. - EXPECT_EQ(loot_ok, loot_get_dirty_info(db, "Hammerfell.esm", &needsCleaning)); - EXPECT_EQ(loot_needs_cleaning_yes, needsCleaning); - - // A plugin with a standard "Do not clean" message. - EXPECT_EQ(loot_ok, loot_get_dirty_info(db, "Unofficial Oblivion Patch.esp", &needsCleaning)); - EXPECT_EQ(loot_needs_cleaning_no, needsCleaning); -} - -TEST_F(OblivionAPIOperationsTest, WriteMinimalList) { - std::string outputFile = (localPath / "minimal.yml").string(); - EXPECT_EQ(loot_error_invalid_args, loot_write_minimal_list(NULL, outputFile.c_str(), false)); - EXPECT_EQ(loot_error_invalid_args, loot_write_minimal_list(db, NULL, false)); - EXPECT_EQ(loot_error_file_write_fail, loot_write_minimal_list(db, "/:?*", false)); - - ASSERT_FALSE(boost::filesystem::exists(outputFile)); - EXPECT_EQ(loot_ok, loot_write_minimal_list(db, outputFile.c_str(), false)); - EXPECT_TRUE(boost::filesystem::exists(outputFile)); - EXPECT_EQ(loot_error_file_write_fail, loot_write_minimal_list(db, outputFile.c_str(), false)); - - EXPECT_EQ(loot_ok, loot_write_minimal_list(db, outputFile.c_str(), true)); - ASSERT_NO_THROW(boost::filesystem::remove(outputFile)); - EXPECT_EQ(loot_ok, loot_write_minimal_list(db, outputFile.c_str(), true)); - EXPECT_TRUE(boost::filesystem::exists(outputFile)); - ASSERT_NO_THROW(boost::filesystem::remove(outputFile)); - - // Check that Bash Tag removals get outputted correctly. - bool updated; - ASSERT_EQ(loot_ok, loot_update_masterlist(db, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "master", &updated)); - EXPECT_EQ(loot_ok, loot_load_lists(db, masterlistPath.string().c_str(), NULL)); - EXPECT_EQ(loot_ok, loot_write_minimal_list(db, outputFile.c_str(), false)); - - boost::filesystem::ifstream in(outputFile); - std::string line; - while (std::getline(in, line)) { - EXPECT_FALSE(boost::contains(line, "- \"-\"")); - } - in.close(); - ASSERT_NO_THROW(boost::filesystem::remove(outputFile)); -} #endif diff --git a/src/tests/backend/game/test_game.h b/src/tests/backend/game/test_game.h index 0bd22283..23d41620 100644 --- a/src/tests/backend/game/test_game.h +++ b/src/tests/backend/game/test_game.h @@ -31,628 +31,632 @@ along with LOOT. If not, see #include "tests/fixtures.h" -class Game : public SkyrimTest {}; +namespace loot { + namespace test { + class GameTest : public SkyrimTest {}; -TEST_F(Game, Constructors) { - // The constructors should just passthrough to the GameSettings - // members, so just check that is happening. - loot::Game game; - loot::GameSettings settings; + TEST_F(GameTest, Constructors) { + // The constructors should just passthrough to the GameSettings + // members, so just check that is happening. + Game game; + GameSettings settings; - EXPECT_EQ(loot::Game::autodetect, game.Id()); - EXPECT_EQ(settings.Name(), game.Name()); - EXPECT_EQ(settings.FolderName(), game.FolderName()); - EXPECT_EQ(settings.Master(), game.Master()); - EXPECT_EQ(settings.RegistryKey(), game.RegistryKey()); - EXPECT_EQ(settings.RepoURL(), game.RepoURL()); - EXPECT_EQ(settings.RepoBranch(), game.RepoBranch()); + EXPECT_EQ(Game::autodetect, game.Id()); + EXPECT_EQ(settings.Name(), game.Name()); + EXPECT_EQ(settings.FolderName(), game.FolderName()); + EXPECT_EQ(settings.Master(), game.Master()); + EXPECT_EQ(settings.RegistryKey(), game.RegistryKey()); + EXPECT_EQ(settings.RepoURL(), game.RepoURL()); + EXPECT_EQ(settings.RepoBranch(), game.RepoBranch()); - EXPECT_EQ(settings.GamePath(), game.GamePath()); - EXPECT_EQ(settings.DataPath(), game.DataPath()); - EXPECT_EQ(settings.MasterlistPath(), game.MasterlistPath()); - EXPECT_EQ(settings.UserlistPath(), game.UserlistPath()); + EXPECT_EQ(settings.GamePath(), game.GamePath()); + EXPECT_EQ(settings.DataPath(), game.DataPath()); + EXPECT_EQ(settings.MasterlistPath(), game.MasterlistPath()); + EXPECT_EQ(settings.UserlistPath(), game.UserlistPath()); - EXPECT_FALSE(game.ArePluginsFullyLoaded()); + EXPECT_FALSE(game.ArePluginsFullyLoaded()); - game = loot::Game(loot::Game::tes5); - settings = loot::GameSettings(loot::GameSettings::tes5); + game = Game(Game::tes5); + settings = GameSettings(GameSettings::tes5); - EXPECT_EQ(loot::Game::tes5, game.Id()); - EXPECT_EQ(settings.Name(), game.Name()); - EXPECT_EQ(settings.FolderName(), game.FolderName()); - EXPECT_EQ(settings.Master(), game.Master()); - EXPECT_EQ(settings.RegistryKey(), game.RegistryKey()); - EXPECT_EQ(settings.RepoURL(), game.RepoURL()); - EXPECT_EQ(settings.RepoBranch(), game.RepoBranch()); + EXPECT_EQ(Game::tes5, game.Id()); + EXPECT_EQ(settings.Name(), game.Name()); + EXPECT_EQ(settings.FolderName(), game.FolderName()); + EXPECT_EQ(settings.Master(), game.Master()); + EXPECT_EQ(settings.RegistryKey(), game.RegistryKey()); + EXPECT_EQ(settings.RepoURL(), game.RepoURL()); + EXPECT_EQ(settings.RepoBranch(), game.RepoBranch()); - EXPECT_EQ(settings.GamePath(), game.GamePath()); - EXPECT_EQ(settings.DataPath(), game.DataPath()); - EXPECT_EQ(settings.MasterlistPath(), game.MasterlistPath()); - EXPECT_EQ(settings.UserlistPath(), game.UserlistPath()); + EXPECT_EQ(settings.GamePath(), game.GamePath()); + EXPECT_EQ(settings.DataPath(), game.DataPath()); + EXPECT_EQ(settings.MasterlistPath(), game.MasterlistPath()); + EXPECT_EQ(settings.UserlistPath(), game.UserlistPath()); - EXPECT_FALSE(game.ArePluginsFullyLoaded()); + EXPECT_FALSE(game.ArePluginsFullyLoaded()); - game = loot::Game(loot::Game::tes5, "folder"); - settings = loot::GameSettings(loot::GameSettings::tes5, "folder"); + game = Game(Game::tes5, "folder"); + settings = GameSettings(GameSettings::tes5, "folder"); - EXPECT_EQ(loot::Game::tes5, game.Id()); - EXPECT_EQ(settings.Name(), game.Name()); - EXPECT_EQ(settings.FolderName(), game.FolderName()); - EXPECT_EQ(settings.Master(), game.Master()); - EXPECT_EQ(settings.RegistryKey(), game.RegistryKey()); - EXPECT_EQ(settings.RepoURL(), game.RepoURL()); - EXPECT_EQ(settings.RepoBranch(), game.RepoBranch()); + EXPECT_EQ(Game::tes5, game.Id()); + EXPECT_EQ(settings.Name(), game.Name()); + EXPECT_EQ(settings.FolderName(), game.FolderName()); + EXPECT_EQ(settings.Master(), game.Master()); + EXPECT_EQ(settings.RegistryKey(), game.RegistryKey()); + EXPECT_EQ(settings.RepoURL(), game.RepoURL()); + EXPECT_EQ(settings.RepoBranch(), game.RepoBranch()); - EXPECT_EQ(settings.GamePath(), game.GamePath()); - EXPECT_EQ(settings.DataPath(), game.DataPath()); - EXPECT_EQ(settings.MasterlistPath(), game.MasterlistPath()); - EXPECT_EQ(settings.UserlistPath(), game.UserlistPath()); + EXPECT_EQ(settings.GamePath(), game.GamePath()); + EXPECT_EQ(settings.DataPath(), game.DataPath()); + EXPECT_EQ(settings.MasterlistPath(), game.MasterlistPath()); + EXPECT_EQ(settings.UserlistPath(), game.UserlistPath()); - EXPECT_FALSE(game.ArePluginsFullyLoaded()); + EXPECT_FALSE(game.ArePluginsFullyLoaded()); - game = loot::Game(settings); + game = Game(settings); - EXPECT_EQ(loot::Game::tes5, game.Id()); - EXPECT_EQ(settings.Name(), game.Name()); - EXPECT_EQ(settings.FolderName(), game.FolderName()); - EXPECT_EQ(settings.Master(), game.Master()); - EXPECT_EQ(settings.RegistryKey(), game.RegistryKey()); - EXPECT_EQ(settings.RepoURL(), game.RepoURL()); - EXPECT_EQ(settings.RepoBranch(), game.RepoBranch()); + EXPECT_EQ(Game::tes5, game.Id()); + EXPECT_EQ(settings.Name(), game.Name()); + EXPECT_EQ(settings.FolderName(), game.FolderName()); + EXPECT_EQ(settings.Master(), game.Master()); + EXPECT_EQ(settings.RegistryKey(), game.RegistryKey()); + EXPECT_EQ(settings.RepoURL(), game.RepoURL()); + EXPECT_EQ(settings.RepoBranch(), game.RepoBranch()); - EXPECT_EQ(settings.GamePath(), game.GamePath()); - EXPECT_EQ(settings.DataPath(), game.DataPath()); - EXPECT_EQ(settings.MasterlistPath(), game.MasterlistPath()); - EXPECT_EQ(settings.UserlistPath(), game.UserlistPath()); + EXPECT_EQ(settings.GamePath(), game.GamePath()); + EXPECT_EQ(settings.DataPath(), game.DataPath()); + EXPECT_EQ(settings.MasterlistPath(), game.MasterlistPath()); + EXPECT_EQ(settings.UserlistPath(), game.UserlistPath()); - EXPECT_FALSE(game.ArePluginsFullyLoaded()); -} + EXPECT_FALSE(game.ArePluginsFullyLoaded()); + } -TEST_F(Game, Init) { - // Should throw for invalid ID. - loot::Game game; - EXPECT_THROW(game.Init(false), loot::error); - EXPECT_THROW(game.Init(true), loot::error); - EXPECT_THROW(game.Init(false, localPath), loot::error); - EXPECT_THROW(game.Init(true, localPath), loot::error); + TEST_F(GameTest, Init) { + // Should throw for invalid ID. + Game game; + EXPECT_THROW(game.Init(false), error); + EXPECT_THROW(game.Init(true), error); + EXPECT_THROW(game.Init(false, localPath), error); + EXPECT_THROW(game.Init(true, localPath), error); #ifndef _WIN32 // No point testing installation detection on Windows, because it will // find real installs, and the multi-game fixtures are set up so that they // won't get auto-detected. Test for failure on Linux though. - game = loot::Game(loot::Game::tes5); - EXPECT_THROW(game.Init(false), loot::error); - EXPECT_THROW(game.Init(true), loot::error); - EXPECT_THROW(game.Init(false, localPath), loot::error); - EXPECT_THROW(game.Init(true, localPath), loot::error); + game = Game(Game::tes5); + EXPECT_THROW(game.Init(false), error); + EXPECT_THROW(game.Init(true), error); + EXPECT_THROW(game.Init(false, localPath), error); + EXPECT_THROW(game.Init(true, localPath), error); - // No point testing LOOT folder creation on Windows, because there may be - // a real LOOT install. - // Not supplying a game local path on Linux should throw an exception. - game = loot::Game(loot::Game::tes5).SetGamePath(dataPath.parent_path()); - ASSERT_FALSE(boost::filesystem::exists(loot::g_path_local / game.FolderName())); - EXPECT_THROW(game.Init(false), loot::error); - EXPECT_FALSE(boost::filesystem::exists(loot::g_path_local / game.FolderName())); + // No point testing LOOT folder creation on Windows, because there may be + // a real LOOT install. + // Not supplying a game local path on Linux should throw an exception. + game = Game(Game::tes5).SetGamePath(dataPath.parent_path()); + ASSERT_FALSE(boost::filesystem::exists(g_path_local / game.FolderName())); + EXPECT_THROW(game.Init(false), error); + EXPECT_FALSE(boost::filesystem::exists(g_path_local / game.FolderName())); - game = loot::Game(loot::Game::tes5).SetGamePath(dataPath.parent_path()); - EXPECT_NO_THROW(game.Init(false, localPath)); - EXPECT_FALSE(boost::filesystem::exists(loot::g_path_local / game.FolderName())); - EXPECT_TRUE(game.IsPluginActive("Skyrim.esm")); - EXPECT_TRUE(game.IsPluginActive("skyrim.esm")); - EXPECT_TRUE(game.IsPluginActive("Blank.esm")); - EXPECT_FALSE(game.IsPluginActive("Blank - Different.esm")); - EXPECT_FALSE(game.IsPluginActive("Blank - Master Dependent.esm")); - EXPECT_FALSE(game.IsPluginActive("Blank - Different Master Dependent.esm")); - EXPECT_FALSE(game.IsPluginActive("Blank.esp")); - EXPECT_FALSE(game.IsPluginActive("Blank - Different.esp")); - EXPECT_FALSE(game.IsPluginActive("Blank - Master Dependent.esp")); - EXPECT_TRUE(game.IsPluginActive("Blank - Different Master Dependent.esp")); - EXPECT_FALSE(game.IsPluginActive("Blank - Plugin Dependent.esp")); - EXPECT_FALSE(game.IsPluginActive("Blank - Different Plugin Dependent.esp")); + game = Game(Game::tes5).SetGamePath(dataPath.parent_path()); + EXPECT_NO_THROW(game.Init(false, localPath)); + EXPECT_FALSE(boost::filesystem::exists(g_path_local / game.FolderName())); + EXPECT_TRUE(game.IsPluginActive("Skyrim.esm")); + EXPECT_TRUE(game.IsPluginActive("skyrim.esm")); + EXPECT_TRUE(game.IsPluginActive("Blank.esm")); + EXPECT_FALSE(game.IsPluginActive("Blank - Different.esm")); + EXPECT_FALSE(game.IsPluginActive("Blank - Master Dependent.esm")); + EXPECT_FALSE(game.IsPluginActive("Blank - Different Master Dependent.esm")); + EXPECT_FALSE(game.IsPluginActive("Blank.esp")); + EXPECT_FALSE(game.IsPluginActive("Blank - Different.esp")); + EXPECT_FALSE(game.IsPluginActive("Blank - Master Dependent.esp")); + EXPECT_TRUE(game.IsPluginActive("Blank - Different Master Dependent.esp")); + EXPECT_FALSE(game.IsPluginActive("Blank - Plugin Dependent.esp")); + EXPECT_FALSE(game.IsPluginActive("Blank - Different Plugin Dependent.esp")); - game = loot::Game(loot::Game::tes5).SetGamePath(dataPath.parent_path()); - EXPECT_NO_THROW(game.Init(true, localPath)); - EXPECT_TRUE(boost::filesystem::exists(loot::g_path_local / game.FolderName())); - EXPECT_TRUE(game.IsPluginActive("Skyrim.esm")); - EXPECT_TRUE(game.IsPluginActive("skyrim.esm")); - EXPECT_TRUE(game.IsPluginActive("Blank.esm")); - EXPECT_FALSE(game.IsPluginActive("Blank - Different.esm")); - EXPECT_FALSE(game.IsPluginActive("Blank - Master Dependent.esm")); - EXPECT_FALSE(game.IsPluginActive("Blank - Different Master Dependent.esm")); - EXPECT_FALSE(game.IsPluginActive("Blank.esp")); - EXPECT_FALSE(game.IsPluginActive("Blank - Different.esp")); - EXPECT_FALSE(game.IsPluginActive("Blank - Master Dependent.esp")); - EXPECT_TRUE(game.IsPluginActive("Blank - Different Master Dependent.esp")); - EXPECT_FALSE(game.IsPluginActive("Blank - Plugin Dependent.esp")); - EXPECT_FALSE(game.IsPluginActive("Blank - Different Plugin Dependent.esp")); + game = Game(Game::tes5).SetGamePath(dataPath.parent_path()); + EXPECT_NO_THROW(game.Init(true, localPath)); + EXPECT_TRUE(boost::filesystem::exists(g_path_local / game.FolderName())); + EXPECT_TRUE(game.IsPluginActive("Skyrim.esm")); + EXPECT_TRUE(game.IsPluginActive("skyrim.esm")); + EXPECT_TRUE(game.IsPluginActive("Blank.esm")); + EXPECT_FALSE(game.IsPluginActive("Blank - Different.esm")); + EXPECT_FALSE(game.IsPluginActive("Blank - Master Dependent.esm")); + EXPECT_FALSE(game.IsPluginActive("Blank - Different Master Dependent.esm")); + EXPECT_FALSE(game.IsPluginActive("Blank.esp")); + EXPECT_FALSE(game.IsPluginActive("Blank - Different.esp")); + EXPECT_FALSE(game.IsPluginActive("Blank - Master Dependent.esp")); + EXPECT_TRUE(game.IsPluginActive("Blank - Different Master Dependent.esp")); + EXPECT_FALSE(game.IsPluginActive("Blank - Plugin Dependent.esp")); + EXPECT_FALSE(game.IsPluginActive("Blank - Different Plugin Dependent.esp")); #else - game = loot::Game(loot::Game::tes5).SetGamePath(dataPath.parent_path()); - EXPECT_NO_THROW(game.Init(false)); + game = Game(Game::tes5).SetGamePath(dataPath.parent_path()); + EXPECT_NO_THROW(game.Init(false)); - game = loot::Game(loot::Game::tes5).SetGamePath(dataPath.parent_path()); - EXPECT_NO_THROW(game.Init(false, localPath)); + game = Game(Game::tes5).SetGamePath(dataPath.parent_path()); + EXPECT_NO_THROW(game.Init(false, localPath)); #endif -} + } -TEST_F(Game, RedatePlugins) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); + TEST_F(GameTest, RedatePlugins) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); - // Throw because game hasn't been initialised yet. - EXPECT_THROW(game.RedatePlugins(), loot::error); + // Throw because game hasn't been initialised yet. + EXPECT_THROW(game.RedatePlugins(), error); - game.Init(false, localPath); + game.Init(false, localPath); - std::vector loadOrder({ - "Skyrim.esm", - "Blank.esm", - "Blank - Different.esm", - "Blank - Master Dependent.esm.ghost", - "Blank - Different Master Dependent.esm", - "Blank.esp", - "Blank - Different.esp", - "Blank - Master Dependent.esp", - "Blank - Different Master Dependent.esp", - "Blank - Plugin Dependent.esp", - "Blank - Different Plugin Dependent.esp", - }); + std::vector loadOrder({ + "Skyrim.esm", + "Blank.esm", + "Blank - Different.esm", + "Blank - Master Dependent.esm.ghost", + "Blank - Different Master Dependent.esm", + "Blank.esp", + "Blank - Different.esp", + "Blank - Master Dependent.esp", + "Blank - Different Master Dependent.esp", + "Blank - Plugin Dependent.esp", + "Blank - Different Plugin Dependent.esp", + }); - time_t time = boost::filesystem::last_write_time(dataPath / "Skyrim.esm"); - // First set reverse timestamps to be sure. - for (size_t i = 1; i < loadOrder.size(); ++i) { - boost::filesystem::last_write_time(dataPath / loadOrder[i], time - i * 60); - ASSERT_EQ(time - i * 60, boost::filesystem::last_write_time(dataPath / loadOrder[i])); - } - EXPECT_NO_THROW(game.RedatePlugins()); - EXPECT_EQ(time, boost::filesystem::last_write_time(dataPath / "Skyrim.esm")); - for (size_t i = 1; i < loadOrder.size(); ++i) { - ASSERT_EQ(time + i * 60, boost::filesystem::last_write_time(dataPath / loadOrder[i])); + time_t time = boost::filesystem::last_write_time(dataPath / "Skyrim.esm"); + // First set reverse timestamps to be sure. + for (size_t i = 1; i < loadOrder.size(); ++i) { + boost::filesystem::last_write_time(dataPath / loadOrder[i], time - i * 60); + ASSERT_EQ(time - i * 60, boost::filesystem::last_write_time(dataPath / loadOrder[i])); + } + EXPECT_NO_THROW(game.RedatePlugins()); + EXPECT_EQ(time, boost::filesystem::last_write_time(dataPath / "Skyrim.esm")); + for (size_t i = 1; i < loadOrder.size(); ++i) { + ASSERT_EQ(time + i * 60, boost::filesystem::last_write_time(dataPath / loadOrder[i])); + } + } + + TEST_F(GameTest, LoadPlugins) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); + + EXPECT_NO_THROW(game.LoadPlugins(false)); + EXPECT_EQ(11, game.GetPlugins().size()); + + // Check that all the plugins' data have loaded correctly. + ASSERT_NO_THROW(game.GetPlugin("Skyrim.esm")); + Plugin plugin = game.GetPlugin("Skyrim.esm"); + EXPECT_EQ("Skyrim.esm", plugin.Name()); + EXPECT_FALSE(plugin.IsEmpty()); + EXPECT_TRUE(plugin.isMasterFile()); + EXPECT_EQ(std::set({ + libespm::FormId("Skyrim.esm", std::vector(), 0xCF0), + libespm::FormId("Skyrim.esm", std::vector(), 0xCF1), + libespm::FormId("Skyrim.esm", std::vector(), 0xCF2), + libespm::FormId("Skyrim.esm", std::vector(), 0xCF3), + libespm::FormId("Skyrim.esm", std::vector(), 0xCF4), + libespm::FormId("Skyrim.esm", std::vector(), 0xCF5), + libespm::FormId("Skyrim.esm", std::vector(), 0xCF6), + libespm::FormId("Skyrim.esm", std::vector(), 0xCF7), + libespm::FormId("Skyrim.esm", std::vector(), 0xCF8), + libespm::FormId("Skyrim.esm", std::vector(), 0xCF9), + }), plugin.getFormIds()); + EXPECT_TRUE(plugin.getMasters().empty()); + EXPECT_EQ("v5.0", plugin.getDescription()); + EXPECT_EQ(0x187BE342, plugin.Crc()); + EXPECT_EQ(0, plugin.NumOverrideFormIDs()); + + ASSERT_NO_THROW(game.GetPlugin("blank.esm")); + plugin = game.GetPlugin("blank.esm"); + EXPECT_EQ("Blank.esm", plugin.Name()); + EXPECT_FALSE(plugin.IsEmpty()); + EXPECT_TRUE(plugin.isMasterFile()); + EXPECT_EQ(std::set({ + libespm::FormId("Blank.esm", std::vector(), 0xCF0), + libespm::FormId("Blank.esm", std::vector(), 0xCF1), + libespm::FormId("Blank.esm", std::vector(), 0xCF2), + libespm::FormId("Blank.esm", std::vector(), 0xCF3), + libespm::FormId("Blank.esm", std::vector(), 0xCF4), + libespm::FormId("Blank.esm", std::vector(), 0xCF5), + libespm::FormId("Blank.esm", std::vector(), 0xCF6), + libespm::FormId("Blank.esm", std::vector(), 0xCF7), + libespm::FormId("Blank.esm", std::vector(), 0xCF8), + libespm::FormId("Blank.esm", std::vector(), 0xCF9), + }), plugin.getFormIds()); + EXPECT_TRUE(plugin.getMasters().empty()); + EXPECT_EQ("v5.0", plugin.getDescription()); + EXPECT_EQ(0x187BE342, plugin.Crc()); + EXPECT_EQ(0, plugin.NumOverrideFormIDs()); + + ASSERT_NO_THROW(game.GetPlugin("Blank - Different.esm")); + plugin = game.GetPlugin("Blank - Different.esm"); + EXPECT_EQ("Blank - Different.esm", plugin.Name()); + EXPECT_FALSE(plugin.IsEmpty()); + EXPECT_TRUE(plugin.isMasterFile()); + EXPECT_EQ(std::set({ + libespm::FormId("Blank - Different.esm", std::vector(), 0xCEF), + libespm::FormId("Blank - Different.esm", std::vector(), 0xCF0), + libespm::FormId("Blank - Different.esm", std::vector(), 0xCF1), + libespm::FormId("Blank - Different.esm", std::vector(), 0xCF2), + libespm::FormId("Blank - Different.esm", std::vector(), 0xCF3), + libespm::FormId("Blank - Different.esm", std::vector(), 0xCF4), + libespm::FormId("Blank - Different.esm", std::vector(), 0xCF5), + libespm::FormId("Blank - Different.esm", std::vector(), 0xCF6), + libespm::FormId("Blank - Different.esm", std::vector(), 0xCF7), + }), plugin.getFormIds()); + EXPECT_TRUE(plugin.getMasters().empty()); + EXPECT_EQ("", plugin.getDescription()); + EXPECT_EQ(0x64B9F757, plugin.Crc()); + EXPECT_EQ(0, plugin.NumOverrideFormIDs()); + + ASSERT_NO_THROW(game.GetPlugin("blank - master dependent.esm")); + plugin = game.GetPlugin("blank - master dependent.esm"); + EXPECT_EQ("Blank - Master Dependent.esm", plugin.Name()); + EXPECT_FALSE(plugin.IsEmpty()); + EXPECT_TRUE(plugin.isMasterFile()); + EXPECT_EQ(std::set({ + libespm::FormId("Blank.esm", std::vector(), 0xCF0), + libespm::FormId("Blank.esm", std::vector(), 0xCF1), + libespm::FormId("Blank.esm", std::vector(), 0xCF2), + libespm::FormId("Blank.esm", std::vector(), 0xCF3), + libespm::FormId("Blank - Master Dependent.esm", std::vector(), 0xCEA), + libespm::FormId("Blank - Master Dependent.esm", std::vector(), 0xCEB), + libespm::FormId("Blank - Master Dependent.esm", std::vector(), 0xCEC), + libespm::FormId("Blank - Master Dependent.esm", std::vector(), 0xCED), + }), plugin.getFormIds()); + EXPECT_EQ(std::vector({ + "Blank.esm" + }), plugin.getMasters()); + EXPECT_EQ("", plugin.getDescription()); + EXPECT_EQ(0xB2D4119E, plugin.Crc()); + EXPECT_EQ(4, plugin.NumOverrideFormIDs()); + + ASSERT_NO_THROW(game.GetPlugin("blank - different master dependent.esm")); + plugin = game.GetPlugin("blank - different master dependent.esm"); + EXPECT_EQ("Blank - Different Master Dependent.esm", plugin.Name()); + EXPECT_FALSE(plugin.IsEmpty()); + EXPECT_TRUE(plugin.isMasterFile()); + EXPECT_EQ(std::set({ + libespm::FormId("Blank - Different.esm", std::vector(), 0xCEF), + libespm::FormId("Blank - Different.esm", std::vector(), 0xCF0), + libespm::FormId("Blank - Different.esm", std::vector(), 0xCF1), + libespm::FormId("Blank - Different.esm", std::vector(), 0xCF2), + libespm::FormId("Blank - Different Master Dependent.esm", std::vector(), 0xCE9), + libespm::FormId("Blank - Different Master Dependent.esm", std::vector(), 0xCEA), + libespm::FormId("Blank - Different Master Dependent.esm", std::vector(), 0xCEB), + }), plugin.getFormIds()); + EXPECT_EQ(std::vector({ + "Blank - Different.esm" + }), plugin.getMasters()); + EXPECT_EQ("", plugin.getDescription()); + EXPECT_EQ(0xAADF6710, plugin.Crc()); + EXPECT_EQ(4, plugin.NumOverrideFormIDs()); + + ASSERT_NO_THROW(game.GetPlugin("blank.esp")); + plugin = game.GetPlugin("blank.esp"); + EXPECT_EQ("Blank.esp", plugin.Name()); + EXPECT_FALSE(plugin.IsEmpty()); + EXPECT_FALSE(plugin.isMasterFile()); + EXPECT_EQ(std::set({ + libespm::FormId("Blank.esp", std::vector(), 0xCEC), + libespm::FormId("Blank.esp", std::vector(), 0xCED), + libespm::FormId("Blank.esp", std::vector(), 0xCEE), + libespm::FormId("Blank.esp", std::vector(), 0xCEF), + libespm::FormId("Blank.esp", std::vector(), 0xCF0), + libespm::FormId("Blank.esp", std::vector(), 0xCF1), + }), plugin.getFormIds()); + EXPECT_TRUE(plugin.getMasters().empty()); + EXPECT_EQ("\xE2\x82\xAC\xC6\x92\xC5\xA0", plugin.getDescription()); + EXPECT_EQ(0x24F0E2A1, plugin.Crc()); + EXPECT_EQ(0, plugin.NumOverrideFormIDs()); + + ASSERT_NO_THROW(game.GetPlugin("blank - different.esp")); + plugin = game.GetPlugin("blank - different.esp"); + EXPECT_EQ("Blank - Different.esp", plugin.Name()); + EXPECT_FALSE(plugin.IsEmpty()); + EXPECT_FALSE(plugin.isMasterFile()); + EXPECT_EQ(std::set({ + libespm::FormId("Blank - Different.esp", std::vector(), 0xCEB), + libespm::FormId("Blank - Different.esp", std::vector(), 0xCEC), + libespm::FormId("Blank - Different.esp", std::vector(), 0xCED), + libespm::FormId("Blank - Different.esp", std::vector(), 0xCEE), + libespm::FormId("Blank - Different.esp", std::vector(), 0xCEF), + }), plugin.getFormIds()); + EXPECT_TRUE(plugin.getMasters().empty()); + EXPECT_EQ("", plugin.getDescription()); + EXPECT_EQ(0xD4C9B7AE, plugin.Crc()); + EXPECT_EQ(0, plugin.NumOverrideFormIDs()); + + ASSERT_NO_THROW(game.GetPlugin("blank - master dependent.esp")); + plugin = game.GetPlugin("blank - master dependent.esp"); + EXPECT_EQ("Blank - Master Dependent.esp", plugin.Name()); + EXPECT_FALSE(plugin.IsEmpty()); + EXPECT_FALSE(plugin.isMasterFile()); + EXPECT_EQ(std::set({ + libespm::FormId("Blank.esm", std::vector(), 0xCF0), + libespm::FormId("Blank.esm", std::vector(), 0xCF1), + libespm::FormId("Blank - Master Dependent.esp", std::vector(), 0xCE9), + libespm::FormId("Blank - Master Dependent.esp", std::vector(), 0xCEA), + }), plugin.getFormIds()); + EXPECT_EQ(std::vector({ + "Blank.esm" + }), plugin.getMasters()); + EXPECT_EQ("", plugin.getDescription()); + EXPECT_EQ(0x832152DC, plugin.Crc()); + EXPECT_EQ(2, plugin.NumOverrideFormIDs()); + + ASSERT_NO_THROW(game.GetPlugin("blank - different master dependent.esp")); + plugin = game.GetPlugin("blank - different master dependent.esp"); + EXPECT_EQ("Blank - Different Master Dependent.esp", plugin.Name()); + EXPECT_FALSE(plugin.IsEmpty()); + EXPECT_FALSE(plugin.isMasterFile()); + EXPECT_EQ(std::set({ + libespm::FormId("Blank - Different.esm", std::vector(), 0xCEF), + libespm::FormId("Blank - Different.esm", std::vector(), 0xCF0), + libespm::FormId("Blank - Different Master Dependent.esp", std::vector(), 0xCE7), + }), plugin.getFormIds()); + EXPECT_EQ(std::vector({ + "Blank - Different.esm" + }), plugin.getMasters()); + EXPECT_EQ("", plugin.getDescription()); + EXPECT_EQ(0x3AD17683, plugin.Crc()); + EXPECT_EQ(2, plugin.NumOverrideFormIDs()); + + ASSERT_NO_THROW(game.GetPlugin("blank - plugin dependent.esp")); + plugin = game.GetPlugin("blank - plugin dependent.esp"); + EXPECT_EQ("Blank - Plugin Dependent.esp", plugin.Name()); + EXPECT_FALSE(plugin.IsEmpty()); + EXPECT_FALSE(plugin.isMasterFile()); + EXPECT_EQ(std::set({ + libespm::FormId("Blank.esp", std::vector(), 0xCEC), + libespm::FormId("Blank - Plugin Dependent.esp", std::vector(), 0xCE7), + }), plugin.getFormIds()); + EXPECT_EQ(std::vector({ + "Blank.esp" + }), plugin.getMasters()); + EXPECT_EQ("", plugin.getDescription()); + EXPECT_EQ(0x28EF26DB, plugin.Crc()); + EXPECT_EQ(1, plugin.NumOverrideFormIDs()); + + ASSERT_NO_THROW(game.GetPlugin("blank - different plugin dependent.esp")); + plugin = game.GetPlugin("blank - different plugin dependent.esp"); + EXPECT_EQ("Blank - Different Plugin Dependent.esp", plugin.Name()); + EXPECT_FALSE(plugin.IsEmpty()); + EXPECT_FALSE(plugin.isMasterFile()); + EXPECT_EQ(std::set({ + libespm::FormId("Blank - Different.esp", std::vector(), 0xCEB), + }), plugin.getFormIds()); + EXPECT_EQ(std::vector({ + "Blank - Different.esp" + }), plugin.getMasters()); + EXPECT_EQ("", plugin.getDescription()); + EXPECT_EQ(0xEB47BE63, plugin.Crc()); + EXPECT_EQ(1, plugin.NumOverrideFormIDs()); + } + + TEST_F(GameTest, LoadPlugins_HeadersOnly) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); + + EXPECT_NO_THROW(game.LoadPlugins(true)); + EXPECT_EQ(11, game.GetPlugins().size()); + + // Check that all the plugins' data have loaded correctly. + ASSERT_NO_THROW(game.GetPlugin("Skyrim.esm")); + Plugin plugin = game.GetPlugin("Skyrim.esm"); + EXPECT_EQ("Skyrim.esm", plugin.Name()); + EXPECT_FALSE(plugin.IsEmpty()); + EXPECT_TRUE(plugin.isMasterFile()); + EXPECT_TRUE(plugin.getFormIds().empty()); + EXPECT_TRUE(plugin.getMasters().empty()); + EXPECT_EQ("v5.0", plugin.getDescription()); + EXPECT_EQ(0, plugin.Crc()); + EXPECT_EQ(0, plugin.NumOverrideFormIDs()); + + ASSERT_NO_THROW(game.GetPlugin("blank.esm")); + plugin = game.GetPlugin("blank.esm"); + EXPECT_EQ("Blank.esm", plugin.Name()); + EXPECT_FALSE(plugin.IsEmpty()); + EXPECT_TRUE(plugin.isMasterFile()); + EXPECT_TRUE(plugin.getFormIds().empty()); + EXPECT_TRUE(plugin.getMasters().empty()); + EXPECT_EQ("v5.0", plugin.getDescription()); + EXPECT_EQ(0, plugin.Crc()); + EXPECT_EQ(0, plugin.NumOverrideFormIDs()); + + ASSERT_NO_THROW(game.GetPlugin("Blank - Different.esm")); + plugin = game.GetPlugin("Blank - Different.esm"); + EXPECT_EQ("Blank - Different.esm", plugin.Name()); + EXPECT_FALSE(plugin.IsEmpty()); + EXPECT_TRUE(plugin.isMasterFile()); + EXPECT_TRUE(plugin.getFormIds().empty()); + EXPECT_TRUE(plugin.getMasters().empty()); + EXPECT_EQ("", plugin.getDescription()); + EXPECT_EQ(0, plugin.Crc()); + EXPECT_EQ(0, plugin.NumOverrideFormIDs()); + + ASSERT_NO_THROW(game.GetPlugin("blank - master dependent.esm")); + plugin = game.GetPlugin("blank - master dependent.esm"); + EXPECT_EQ("Blank - Master Dependent.esm", plugin.Name()); + EXPECT_FALSE(plugin.IsEmpty()); + EXPECT_TRUE(plugin.isMasterFile()); + EXPECT_TRUE(plugin.getFormIds().empty()); + EXPECT_EQ(std::vector({ + "Blank.esm" + }), plugin.getMasters()); + EXPECT_EQ("", plugin.getDescription()); + EXPECT_EQ(0, plugin.Crc()); + EXPECT_EQ(0, plugin.NumOverrideFormIDs()); + + ASSERT_NO_THROW(game.GetPlugin("blank - different master dependent.esm")); + plugin = game.GetPlugin("blank - different master dependent.esm"); + EXPECT_EQ("Blank - Different Master Dependent.esm", plugin.Name()); + EXPECT_FALSE(plugin.IsEmpty()); + EXPECT_TRUE(plugin.isMasterFile()); + EXPECT_TRUE(plugin.getFormIds().empty()); + EXPECT_EQ(std::vector({ + "Blank - Different.esm" + }), plugin.getMasters()); + EXPECT_EQ("", plugin.getDescription()); + EXPECT_EQ(0, plugin.Crc()); + EXPECT_EQ(0, plugin.NumOverrideFormIDs()); + + ASSERT_NO_THROW(game.GetPlugin("blank.esp")); + plugin = game.GetPlugin("blank.esp"); + EXPECT_EQ("Blank.esp", plugin.Name()); + EXPECT_FALSE(plugin.IsEmpty()); + EXPECT_FALSE(plugin.isMasterFile()); + EXPECT_TRUE(plugin.getFormIds().empty()); + EXPECT_TRUE(plugin.getMasters().empty()); + EXPECT_EQ("\xE2\x82\xAC\xC6\x92\xC5\xA0", plugin.getDescription()); + EXPECT_EQ(0, plugin.Crc()); + EXPECT_EQ(0, plugin.NumOverrideFormIDs()); + + ASSERT_NO_THROW(game.GetPlugin("blank - different.esp")); + plugin = game.GetPlugin("blank - different.esp"); + EXPECT_EQ("Blank - Different.esp", plugin.Name()); + EXPECT_FALSE(plugin.IsEmpty()); + EXPECT_FALSE(plugin.isMasterFile()); + EXPECT_TRUE(plugin.getFormIds().empty()); + EXPECT_TRUE(plugin.getMasters().empty()); + EXPECT_EQ("", plugin.getDescription()); + EXPECT_EQ(0, plugin.Crc()); + EXPECT_EQ(0, plugin.NumOverrideFormIDs()); + + ASSERT_NO_THROW(game.GetPlugin("blank - master dependent.esp")); + plugin = game.GetPlugin("blank - master dependent.esp"); + EXPECT_EQ("Blank - Master Dependent.esp", plugin.Name()); + EXPECT_FALSE(plugin.IsEmpty()); + EXPECT_FALSE(plugin.isMasterFile()); + EXPECT_TRUE(plugin.getFormIds().empty()); + EXPECT_EQ(std::vector({ + "Blank.esm" + }), plugin.getMasters()); + EXPECT_EQ("", plugin.getDescription()); + EXPECT_EQ(0, plugin.Crc()); + EXPECT_EQ(0, plugin.NumOverrideFormIDs()); + + ASSERT_NO_THROW(game.GetPlugin("blank - different master dependent.esp")); + plugin = game.GetPlugin("blank - different master dependent.esp"); + EXPECT_EQ("Blank - Different Master Dependent.esp", plugin.Name()); + EXPECT_FALSE(plugin.IsEmpty()); + EXPECT_FALSE(plugin.isMasterFile()); + EXPECT_TRUE(plugin.getFormIds().empty()); + EXPECT_EQ(std::vector({ + "Blank - Different.esm" + }), plugin.getMasters()); + EXPECT_EQ("", plugin.getDescription()); + EXPECT_EQ(0, plugin.Crc()); + EXPECT_EQ(0, plugin.NumOverrideFormIDs()); + + ASSERT_NO_THROW(game.GetPlugin("blank - plugin dependent.esp")); + plugin = game.GetPlugin("blank - plugin dependent.esp"); + EXPECT_EQ("Blank - Plugin Dependent.esp", plugin.Name()); + EXPECT_FALSE(plugin.IsEmpty()); + EXPECT_FALSE(plugin.isMasterFile()); + EXPECT_TRUE(plugin.getFormIds().empty()); + EXPECT_EQ(std::vector({ + "Blank.esp" + }), plugin.getMasters()); + EXPECT_EQ("", plugin.getDescription()); + EXPECT_EQ(0, plugin.Crc()); + EXPECT_EQ(0, plugin.NumOverrideFormIDs()); + + ASSERT_NO_THROW(game.GetPlugin("blank - different plugin dependent.esp")); + plugin = game.GetPlugin("blank - different plugin dependent.esp"); + EXPECT_EQ("Blank - Different Plugin Dependent.esp", plugin.Name()); + EXPECT_FALSE(plugin.IsEmpty()); + EXPECT_FALSE(plugin.isMasterFile()); + EXPECT_TRUE(plugin.getFormIds().empty()); + EXPECT_EQ(std::vector({ + "Blank - Different.esp" + }), plugin.getMasters()); + EXPECT_EQ("", plugin.getDescription()); + EXPECT_EQ(0, plugin.Crc()); + EXPECT_EQ(0, plugin.NumOverrideFormIDs()); + } + + TEST_F(GameTest, ArePluginsFullyLoaded) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); + EXPECT_FALSE(game.ArePluginsFullyLoaded()); + + ASSERT_NO_THROW(game.LoadPlugins(false)); + EXPECT_TRUE(game.ArePluginsFullyLoaded()); + } + + TEST_F(GameTest, shouldThrowIfCheckingIfPluginThatIsntLoadedIsActiveAndGameHasNotBeenInitialised) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); + + EXPECT_ANY_THROW(game.IsPluginActive("Blank.esm")); + } + + TEST_F(GameTest, shouldShowBlankEsmAsActiveIfItHasNotBeenLoadedAndTheGameHasBeenInitialised) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); + ASSERT_NO_THROW(game.Init(false, localPath)); + + EXPECT_TRUE(game.IsPluginActive("Blank.esm")); + } + + TEST_F(GameTest, shouldShowBlankEspAsInctiveIfItHasNotBeenLoadedAndTheGameHasBeenInitialised) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); + ASSERT_NO_THROW(game.Init(false, localPath)); + + EXPECT_FALSE(game.IsPluginActive("Blank.esp")); + } + + TEST_F(GameTest, shouldShowBlankEsmAsInactiveIfItsHeaderHasBeenLoadedAndGameHasNotBeenInitialised) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); + ASSERT_NO_THROW(game.LoadPlugins(true)); + + EXPECT_FALSE(game.IsPluginActive("Blank.esm")); + } + + TEST_F(GameTest, shouldShowBlankEspAsActiveIfItsHeaderHasBeenLoadedAndGameHasNotBeenInitialised) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); + ASSERT_NO_THROW(game.LoadPlugins(true)); + + EXPECT_FALSE(game.IsPluginActive("Blank.esp")); + } + + TEST_F(GameTest, shouldShowBlankEsmAsActiveIfItsHeaderHasBeenLoadedAndTheGameHasBeenInitialised) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); + ASSERT_NO_THROW(game.Init(false, localPath)); + ASSERT_NO_THROW(game.LoadPlugins(true)); + + EXPECT_TRUE(game.IsPluginActive("Blank.esm")); + } + + TEST_F(GameTest, shouldShowBlankEspAsActiveIfItsHeaderHasBeenLoadedAndTheGameHasBeenInitialised) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); + ASSERT_NO_THROW(game.Init(false, localPath)); + ASSERT_NO_THROW(game.LoadPlugins(true)); + + EXPECT_FALSE(game.IsPluginActive("Blank.esp")); + } + + TEST_F(GameTest, shouldShowBlankEsmAsActiveIfItHasBeenFullyLoadedAndTheGameHasBeenInitialised) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); + ASSERT_NO_THROW(game.Init(false, localPath)); + ASSERT_NO_THROW(game.LoadPlugins(false)); + + EXPECT_TRUE(game.IsPluginActive("Blank.esm")); + } + + TEST_F(GameTest, shouldShowBlankEspAsActiveIfItHasBeenFullyLoadedAndTheGameHasBeenInitialised) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); + ASSERT_NO_THROW(game.Init(false, localPath)); + ASSERT_NO_THROW(game.LoadPlugins(false)); + + EXPECT_FALSE(game.IsPluginActive("Blank.esp")); + } } } -TEST_F(Game, LoadPlugins) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - - EXPECT_NO_THROW(game.LoadPlugins(false)); - EXPECT_EQ(11, game.GetPlugins().size()); - - // Check that all the plugins' data have loaded correctly. - ASSERT_NO_THROW(game.GetPlugin("Skyrim.esm")); - loot::Plugin plugin = game.GetPlugin("Skyrim.esm"); - EXPECT_EQ("Skyrim.esm", plugin.Name()); - EXPECT_FALSE(plugin.IsEmpty()); - EXPECT_TRUE(plugin.isMasterFile()); - EXPECT_EQ(std::set({ - libespm::FormId("Skyrim.esm", std::vector(), 0xCF0), - libespm::FormId("Skyrim.esm", std::vector(), 0xCF1), - libespm::FormId("Skyrim.esm", std::vector(), 0xCF2), - libespm::FormId("Skyrim.esm", std::vector(), 0xCF3), - libespm::FormId("Skyrim.esm", std::vector(), 0xCF4), - libespm::FormId("Skyrim.esm", std::vector(), 0xCF5), - libespm::FormId("Skyrim.esm", std::vector(), 0xCF6), - libespm::FormId("Skyrim.esm", std::vector(), 0xCF7), - libespm::FormId("Skyrim.esm", std::vector(), 0xCF8), - libespm::FormId("Skyrim.esm", std::vector(), 0xCF9), - }), plugin.getFormIds()); - EXPECT_TRUE(plugin.getMasters().empty()); - EXPECT_EQ("v5.0", plugin.getDescription()); - EXPECT_EQ(0x187BE342, plugin.Crc()); - EXPECT_EQ(0, plugin.NumOverrideFormIDs()); - - ASSERT_NO_THROW(game.GetPlugin("blank.esm")); - plugin = game.GetPlugin("blank.esm"); - EXPECT_EQ("Blank.esm", plugin.Name()); - EXPECT_FALSE(plugin.IsEmpty()); - EXPECT_TRUE(plugin.isMasterFile()); - EXPECT_EQ(std::set({ - libespm::FormId("Blank.esm", std::vector(), 0xCF0), - libespm::FormId("Blank.esm", std::vector(), 0xCF1), - libespm::FormId("Blank.esm", std::vector(), 0xCF2), - libespm::FormId("Blank.esm", std::vector(), 0xCF3), - libespm::FormId("Blank.esm", std::vector(), 0xCF4), - libespm::FormId("Blank.esm", std::vector(), 0xCF5), - libespm::FormId("Blank.esm", std::vector(), 0xCF6), - libespm::FormId("Blank.esm", std::vector(), 0xCF7), - libespm::FormId("Blank.esm", std::vector(), 0xCF8), - libespm::FormId("Blank.esm", std::vector(), 0xCF9), - }), plugin.getFormIds()); - EXPECT_TRUE(plugin.getMasters().empty()); - EXPECT_EQ("v5.0", plugin.getDescription()); - EXPECT_EQ(0x187BE342, plugin.Crc()); - EXPECT_EQ(0, plugin.NumOverrideFormIDs()); - - ASSERT_NO_THROW(game.GetPlugin("Blank - Different.esm")); - plugin = game.GetPlugin("Blank - Different.esm"); - EXPECT_EQ("Blank - Different.esm", plugin.Name()); - EXPECT_FALSE(plugin.IsEmpty()); - EXPECT_TRUE(plugin.isMasterFile()); - EXPECT_EQ(std::set({ - libespm::FormId("Blank - Different.esm", std::vector(), 0xCEF), - libespm::FormId("Blank - Different.esm", std::vector(), 0xCF0), - libespm::FormId("Blank - Different.esm", std::vector(), 0xCF1), - libespm::FormId("Blank - Different.esm", std::vector(), 0xCF2), - libespm::FormId("Blank - Different.esm", std::vector(), 0xCF3), - libespm::FormId("Blank - Different.esm", std::vector(), 0xCF4), - libespm::FormId("Blank - Different.esm", std::vector(), 0xCF5), - libespm::FormId("Blank - Different.esm", std::vector(), 0xCF6), - libespm::FormId("Blank - Different.esm", std::vector(), 0xCF7), - }), plugin.getFormIds()); - EXPECT_TRUE(plugin.getMasters().empty()); - EXPECT_EQ("", plugin.getDescription()); - EXPECT_EQ(0x64B9F757, plugin.Crc()); - EXPECT_EQ(0, plugin.NumOverrideFormIDs()); - - ASSERT_NO_THROW(game.GetPlugin("blank - master dependent.esm")); - plugin = game.GetPlugin("blank - master dependent.esm"); - EXPECT_EQ("Blank - Master Dependent.esm", plugin.Name()); - EXPECT_FALSE(plugin.IsEmpty()); - EXPECT_TRUE(plugin.isMasterFile()); - EXPECT_EQ(std::set({ - libespm::FormId("Blank.esm", std::vector(), 0xCF0), - libespm::FormId("Blank.esm", std::vector(), 0xCF1), - libespm::FormId("Blank.esm", std::vector(), 0xCF2), - libespm::FormId("Blank.esm", std::vector(), 0xCF3), - libespm::FormId("Blank - Master Dependent.esm", std::vector(), 0xCEA), - libespm::FormId("Blank - Master Dependent.esm", std::vector(), 0xCEB), - libespm::FormId("Blank - Master Dependent.esm", std::vector(), 0xCEC), - libespm::FormId("Blank - Master Dependent.esm", std::vector(), 0xCED), - }), plugin.getFormIds()); - EXPECT_EQ(std::vector({ - "Blank.esm" - }), plugin.getMasters()); - EXPECT_EQ("", plugin.getDescription()); - EXPECT_EQ(0xB2D4119E, plugin.Crc()); - EXPECT_EQ(4, plugin.NumOverrideFormIDs()); - - ASSERT_NO_THROW(game.GetPlugin("blank - different master dependent.esm")); - plugin = game.GetPlugin("blank - different master dependent.esm"); - EXPECT_EQ("Blank - Different Master Dependent.esm", plugin.Name()); - EXPECT_FALSE(plugin.IsEmpty()); - EXPECT_TRUE(plugin.isMasterFile()); - EXPECT_EQ(std::set({ - libespm::FormId("Blank - Different.esm", std::vector(), 0xCEF), - libespm::FormId("Blank - Different.esm", std::vector(), 0xCF0), - libespm::FormId("Blank - Different.esm", std::vector(), 0xCF1), - libespm::FormId("Blank - Different.esm", std::vector(), 0xCF2), - libespm::FormId("Blank - Different Master Dependent.esm", std::vector(), 0xCE9), - libespm::FormId("Blank - Different Master Dependent.esm", std::vector(), 0xCEA), - libespm::FormId("Blank - Different Master Dependent.esm", std::vector(), 0xCEB), - }), plugin.getFormIds()); - EXPECT_EQ(std::vector({ - "Blank - Different.esm" - }), plugin.getMasters()); - EXPECT_EQ("", plugin.getDescription()); - EXPECT_EQ(0xAADF6710, plugin.Crc()); - EXPECT_EQ(4, plugin.NumOverrideFormIDs()); - - ASSERT_NO_THROW(game.GetPlugin("blank.esp")); - plugin = game.GetPlugin("blank.esp"); - EXPECT_EQ("Blank.esp", plugin.Name()); - EXPECT_FALSE(plugin.IsEmpty()); - EXPECT_FALSE(plugin.isMasterFile()); - EXPECT_EQ(std::set({ - libespm::FormId("Blank.esp", std::vector(), 0xCEC), - libespm::FormId("Blank.esp", std::vector(), 0xCED), - libespm::FormId("Blank.esp", std::vector(), 0xCEE), - libespm::FormId("Blank.esp", std::vector(), 0xCEF), - libespm::FormId("Blank.esp", std::vector(), 0xCF0), - libespm::FormId("Blank.esp", std::vector(), 0xCF1), - }), plugin.getFormIds()); - EXPECT_TRUE(plugin.getMasters().empty()); - EXPECT_EQ("\xE2\x82\xAC\xC6\x92\xC5\xA0", plugin.getDescription()); - EXPECT_EQ(0x24F0E2A1, plugin.Crc()); - EXPECT_EQ(0, plugin.NumOverrideFormIDs()); - - ASSERT_NO_THROW(game.GetPlugin("blank - different.esp")); - plugin = game.GetPlugin("blank - different.esp"); - EXPECT_EQ("Blank - Different.esp", plugin.Name()); - EXPECT_FALSE(plugin.IsEmpty()); - EXPECT_FALSE(plugin.isMasterFile()); - EXPECT_EQ(std::set({ - libespm::FormId("Blank - Different.esp", std::vector(), 0xCEB), - libespm::FormId("Blank - Different.esp", std::vector(), 0xCEC), - libespm::FormId("Blank - Different.esp", std::vector(), 0xCED), - libespm::FormId("Blank - Different.esp", std::vector(), 0xCEE), - libespm::FormId("Blank - Different.esp", std::vector(), 0xCEF), - }), plugin.getFormIds()); - EXPECT_TRUE(plugin.getMasters().empty()); - EXPECT_EQ("", plugin.getDescription()); - EXPECT_EQ(0xD4C9B7AE, plugin.Crc()); - EXPECT_EQ(0, plugin.NumOverrideFormIDs()); - - ASSERT_NO_THROW(game.GetPlugin("blank - master dependent.esp")); - plugin = game.GetPlugin("blank - master dependent.esp"); - EXPECT_EQ("Blank - Master Dependent.esp", plugin.Name()); - EXPECT_FALSE(plugin.IsEmpty()); - EXPECT_FALSE(plugin.isMasterFile()); - EXPECT_EQ(std::set({ - libespm::FormId("Blank.esm", std::vector(), 0xCF0), - libespm::FormId("Blank.esm", std::vector(), 0xCF1), - libespm::FormId("Blank - Master Dependent.esp", std::vector(), 0xCE9), - libespm::FormId("Blank - Master Dependent.esp", std::vector(), 0xCEA), - }), plugin.getFormIds()); - EXPECT_EQ(std::vector({ - "Blank.esm" - }), plugin.getMasters()); - EXPECT_EQ("", plugin.getDescription()); - EXPECT_EQ(0x832152DC, plugin.Crc()); - EXPECT_EQ(2, plugin.NumOverrideFormIDs()); - - ASSERT_NO_THROW(game.GetPlugin("blank - different master dependent.esp")); - plugin = game.GetPlugin("blank - different master dependent.esp"); - EXPECT_EQ("Blank - Different Master Dependent.esp", plugin.Name()); - EXPECT_FALSE(plugin.IsEmpty()); - EXPECT_FALSE(plugin.isMasterFile()); - EXPECT_EQ(std::set({ - libespm::FormId("Blank - Different.esm", std::vector(), 0xCEF), - libespm::FormId("Blank - Different.esm", std::vector(), 0xCF0), - libespm::FormId("Blank - Different Master Dependent.esp", std::vector(), 0xCE7), - }), plugin.getFormIds()); - EXPECT_EQ(std::vector({ - "Blank - Different.esm" - }), plugin.getMasters()); - EXPECT_EQ("", plugin.getDescription()); - EXPECT_EQ(0x3AD17683, plugin.Crc()); - EXPECT_EQ(2, plugin.NumOverrideFormIDs()); - - ASSERT_NO_THROW(game.GetPlugin("blank - plugin dependent.esp")); - plugin = game.GetPlugin("blank - plugin dependent.esp"); - EXPECT_EQ("Blank - Plugin Dependent.esp", plugin.Name()); - EXPECT_FALSE(plugin.IsEmpty()); - EXPECT_FALSE(plugin.isMasterFile()); - EXPECT_EQ(std::set({ - libespm::FormId("Blank.esp", std::vector(), 0xCEC), - libespm::FormId("Blank - Plugin Dependent.esp", std::vector(), 0xCE7), - }), plugin.getFormIds()); - EXPECT_EQ(std::vector({ - "Blank.esp" - }), plugin.getMasters()); - EXPECT_EQ("", plugin.getDescription()); - EXPECT_EQ(0x28EF26DB, plugin.Crc()); - EXPECT_EQ(1, plugin.NumOverrideFormIDs()); - - ASSERT_NO_THROW(game.GetPlugin("blank - different plugin dependent.esp")); - plugin = game.GetPlugin("blank - different plugin dependent.esp"); - EXPECT_EQ("Blank - Different Plugin Dependent.esp", plugin.Name()); - EXPECT_FALSE(plugin.IsEmpty()); - EXPECT_FALSE(plugin.isMasterFile()); - EXPECT_EQ(std::set({ - libespm::FormId("Blank - Different.esp", std::vector(), 0xCEB), - }), plugin.getFormIds()); - EXPECT_EQ(std::vector({ - "Blank - Different.esp" - }), plugin.getMasters()); - EXPECT_EQ("", plugin.getDescription()); - EXPECT_EQ(0xEB47BE63, plugin.Crc()); - EXPECT_EQ(1, plugin.NumOverrideFormIDs()); -} - -TEST_F(Game, LoadPlugins_HeadersOnly) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - - EXPECT_NO_THROW(game.LoadPlugins(true)); - EXPECT_EQ(11, game.GetPlugins().size()); - - // Check that all the plugins' data have loaded correctly. - ASSERT_NO_THROW(game.GetPlugin("Skyrim.esm")); - loot::Plugin plugin = game.GetPlugin("Skyrim.esm"); - EXPECT_EQ("Skyrim.esm", plugin.Name()); - EXPECT_FALSE(plugin.IsEmpty()); - EXPECT_TRUE(plugin.isMasterFile()); - EXPECT_TRUE(plugin.getFormIds().empty()); - EXPECT_TRUE(plugin.getMasters().empty()); - EXPECT_EQ("v5.0", plugin.getDescription()); - EXPECT_EQ(0, plugin.Crc()); - EXPECT_EQ(0, plugin.NumOverrideFormIDs()); - - ASSERT_NO_THROW(game.GetPlugin("blank.esm")); - plugin = game.GetPlugin("blank.esm"); - EXPECT_EQ("Blank.esm", plugin.Name()); - EXPECT_FALSE(plugin.IsEmpty()); - EXPECT_TRUE(plugin.isMasterFile()); - EXPECT_TRUE(plugin.getFormIds().empty()); - EXPECT_TRUE(plugin.getMasters().empty()); - EXPECT_EQ("v5.0", plugin.getDescription()); - EXPECT_EQ(0, plugin.Crc()); - EXPECT_EQ(0, plugin.NumOverrideFormIDs()); - - ASSERT_NO_THROW(game.GetPlugin("Blank - Different.esm")); - plugin = game.GetPlugin("Blank - Different.esm"); - EXPECT_EQ("Blank - Different.esm", plugin.Name()); - EXPECT_FALSE(plugin.IsEmpty()); - EXPECT_TRUE(plugin.isMasterFile()); - EXPECT_TRUE(plugin.getFormIds().empty()); - EXPECT_TRUE(plugin.getMasters().empty()); - EXPECT_EQ("", plugin.getDescription()); - EXPECT_EQ(0, plugin.Crc()); - EXPECT_EQ(0, plugin.NumOverrideFormIDs()); - - ASSERT_NO_THROW(game.GetPlugin("blank - master dependent.esm")); - plugin = game.GetPlugin("blank - master dependent.esm"); - EXPECT_EQ("Blank - Master Dependent.esm", plugin.Name()); - EXPECT_FALSE(plugin.IsEmpty()); - EXPECT_TRUE(plugin.isMasterFile()); - EXPECT_TRUE(plugin.getFormIds().empty()); - EXPECT_EQ(std::vector({ - "Blank.esm" - }), plugin.getMasters()); - EXPECT_EQ("", plugin.getDescription()); - EXPECT_EQ(0, plugin.Crc()); - EXPECT_EQ(0, plugin.NumOverrideFormIDs()); - - ASSERT_NO_THROW(game.GetPlugin("blank - different master dependent.esm")); - plugin = game.GetPlugin("blank - different master dependent.esm"); - EXPECT_EQ("Blank - Different Master Dependent.esm", plugin.Name()); - EXPECT_FALSE(plugin.IsEmpty()); - EXPECT_TRUE(plugin.isMasterFile()); - EXPECT_TRUE(plugin.getFormIds().empty()); - EXPECT_EQ(std::vector({ - "Blank - Different.esm" - }), plugin.getMasters()); - EXPECT_EQ("", plugin.getDescription()); - EXPECT_EQ(0, plugin.Crc()); - EXPECT_EQ(0, plugin.NumOverrideFormIDs()); - - ASSERT_NO_THROW(game.GetPlugin("blank.esp")); - plugin = game.GetPlugin("blank.esp"); - EXPECT_EQ("Blank.esp", plugin.Name()); - EXPECT_FALSE(plugin.IsEmpty()); - EXPECT_FALSE(plugin.isMasterFile()); - EXPECT_TRUE(plugin.getFormIds().empty()); - EXPECT_TRUE(plugin.getMasters().empty()); - EXPECT_EQ("\xE2\x82\xAC\xC6\x92\xC5\xA0", plugin.getDescription()); - EXPECT_EQ(0, plugin.Crc()); - EXPECT_EQ(0, plugin.NumOverrideFormIDs()); - - ASSERT_NO_THROW(game.GetPlugin("blank - different.esp")); - plugin = game.GetPlugin("blank - different.esp"); - EXPECT_EQ("Blank - Different.esp", plugin.Name()); - EXPECT_FALSE(plugin.IsEmpty()); - EXPECT_FALSE(plugin.isMasterFile()); - EXPECT_TRUE(plugin.getFormIds().empty()); - EXPECT_TRUE(plugin.getMasters().empty()); - EXPECT_EQ("", plugin.getDescription()); - EXPECT_EQ(0, plugin.Crc()); - EXPECT_EQ(0, plugin.NumOverrideFormIDs()); - - ASSERT_NO_THROW(game.GetPlugin("blank - master dependent.esp")); - plugin = game.GetPlugin("blank - master dependent.esp"); - EXPECT_EQ("Blank - Master Dependent.esp", plugin.Name()); - EXPECT_FALSE(plugin.IsEmpty()); - EXPECT_FALSE(plugin.isMasterFile()); - EXPECT_TRUE(plugin.getFormIds().empty()); - EXPECT_EQ(std::vector({ - "Blank.esm" - }), plugin.getMasters()); - EXPECT_EQ("", plugin.getDescription()); - EXPECT_EQ(0, plugin.Crc()); - EXPECT_EQ(0, plugin.NumOverrideFormIDs()); - - ASSERT_NO_THROW(game.GetPlugin("blank - different master dependent.esp")); - plugin = game.GetPlugin("blank - different master dependent.esp"); - EXPECT_EQ("Blank - Different Master Dependent.esp", plugin.Name()); - EXPECT_FALSE(plugin.IsEmpty()); - EXPECT_FALSE(plugin.isMasterFile()); - EXPECT_TRUE(plugin.getFormIds().empty()); - EXPECT_EQ(std::vector({ - "Blank - Different.esm" - }), plugin.getMasters()); - EXPECT_EQ("", plugin.getDescription()); - EXPECT_EQ(0, plugin.Crc()); - EXPECT_EQ(0, plugin.NumOverrideFormIDs()); - - ASSERT_NO_THROW(game.GetPlugin("blank - plugin dependent.esp")); - plugin = game.GetPlugin("blank - plugin dependent.esp"); - EXPECT_EQ("Blank - Plugin Dependent.esp", plugin.Name()); - EXPECT_FALSE(plugin.IsEmpty()); - EXPECT_FALSE(plugin.isMasterFile()); - EXPECT_TRUE(plugin.getFormIds().empty()); - EXPECT_EQ(std::vector({ - "Blank.esp" - }), plugin.getMasters()); - EXPECT_EQ("", plugin.getDescription()); - EXPECT_EQ(0, plugin.Crc()); - EXPECT_EQ(0, plugin.NumOverrideFormIDs()); - - ASSERT_NO_THROW(game.GetPlugin("blank - different plugin dependent.esp")); - plugin = game.GetPlugin("blank - different plugin dependent.esp"); - EXPECT_EQ("Blank - Different Plugin Dependent.esp", plugin.Name()); - EXPECT_FALSE(plugin.IsEmpty()); - EXPECT_FALSE(plugin.isMasterFile()); - EXPECT_TRUE(plugin.getFormIds().empty()); - EXPECT_EQ(std::vector({ - "Blank - Different.esp" - }), plugin.getMasters()); - EXPECT_EQ("", plugin.getDescription()); - EXPECT_EQ(0, plugin.Crc()); - EXPECT_EQ(0, plugin.NumOverrideFormIDs()); -} - -TEST_F(Game, ArePluginsFullyLoaded) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - EXPECT_FALSE(game.ArePluginsFullyLoaded()); - - ASSERT_NO_THROW(game.LoadPlugins(false)); - EXPECT_TRUE(game.ArePluginsFullyLoaded()); -} - -TEST_F(Game, shouldThrowIfCheckingIfPluginThatIsntLoadedIsActiveAndGameHasNotBeenInitialised) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - - EXPECT_ANY_THROW(game.IsPluginActive("Blank.esm")); -} - -TEST_F(Game, shouldShowBlankEsmAsActiveIfItHasNotBeenLoadedAndTheGameHasBeenInitialised) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); - - EXPECT_TRUE(game.IsPluginActive("Blank.esm")); -} - -TEST_F(Game, shouldShowBlankEspAsInctiveIfItHasNotBeenLoadedAndTheGameHasBeenInitialised) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); - - EXPECT_FALSE(game.IsPluginActive("Blank.esp")); -} - -TEST_F(Game, shouldShowBlankEsmAsInactiveIfItsHeaderHasBeenLoadedAndGameHasNotBeenInitialised) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.LoadPlugins(true)); - - EXPECT_FALSE(game.IsPluginActive("Blank.esm")); -} - -TEST_F(Game, shouldShowBlankEspAsActiveIfItsHeaderHasBeenLoadedAndGameHasNotBeenInitialised) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.LoadPlugins(true)); - - EXPECT_FALSE(game.IsPluginActive("Blank.esp")); -} - -TEST_F(Game, shouldShowBlankEsmAsActiveIfItsHeaderHasBeenLoadedAndTheGameHasBeenInitialised) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); - ASSERT_NO_THROW(game.LoadPlugins(true)); - - EXPECT_TRUE(game.IsPluginActive("Blank.esm")); -} - -TEST_F(Game, shouldShowBlankEspAsActiveIfItsHeaderHasBeenLoadedAndTheGameHasBeenInitialised) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); - ASSERT_NO_THROW(game.LoadPlugins(true)); - - EXPECT_FALSE(game.IsPluginActive("Blank.esp")); -} - -TEST_F(Game, shouldShowBlankEsmAsActiveIfItHasBeenFullyLoadedAndTheGameHasBeenInitialised) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); - ASSERT_NO_THROW(game.LoadPlugins(false)); - - EXPECT_TRUE(game.IsPluginActive("Blank.esm")); -} - -TEST_F(Game, shouldShowBlankEspAsActiveIfItHasBeenFullyLoadedAndTheGameHasBeenInitialised) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); - ASSERT_NO_THROW(game.LoadPlugins(false)); - - EXPECT_FALSE(game.IsPluginActive("Blank.esp")); -} - #endif diff --git a/src/tests/backend/game/test_game_cache.h b/src/tests/backend/game/test_game_cache.h index 6a6f734d..aa718c68 100644 --- a/src/tests/backend/game/test_game_cache.h +++ b/src/tests/backend/game/test_game_cache.h @@ -31,120 +31,120 @@ along with LOOT. If not, see namespace loot { namespace test { - class GameCache : public SkyrimTest { + class GameCacheTest : public SkyrimTest { protected: - loot::GameCache cache; + GameCache cache; }; - TEST_F(GameCache, copyConstructorShouldCopyCachedData) { - loot::Game game(loot::Game::tes5); + TEST_F(GameCacheTest, copyConstructorShouldCopyCachedData) { + Game game(Game::tes5); game.SetGamePath(dataPath.parent_path()); ASSERT_NO_THROW(game.Init(false, localPath)); cache.CacheCondition("True Condition", true); - cache.AddPlugin(loot::Plugin(game, "Blank.esm", true)); + cache.AddPlugin(Plugin(game, "Blank.esm", true)); Message expectedMessage(Message::say, "1"); cache.AppendMessage(expectedMessage); cache.SetLoadOrderSorted(true); - loot::GameCache otherCache(cache); + GameCache otherCache(cache); EXPECT_EQ(std::make_pair(true, true), otherCache.GetCachedCondition("true Condition")); EXPECT_EQ("Blank.esm", otherCache.GetPlugin("Blank.esm").Name()); ASSERT_EQ(1, otherCache.GetMessages().size()); EXPECT_EQ(expectedMessage, otherCache.GetMessages()[0]); } - TEST_F(GameCache, assignmentOperatorShouldCopyCachedData) { - loot::Game game(loot::Game::tes5); + TEST_F(GameCacheTest, assignmentOperatorShouldCopyCachedData) { + Game game(Game::tes5); game.SetGamePath(dataPath.parent_path()); ASSERT_NO_THROW(game.Init(false, localPath)); cache.CacheCondition("True Condition", true); - cache.AddPlugin(loot::Plugin(game, "Blank.esm", true)); + cache.AddPlugin(Plugin(game, "Blank.esm", true)); Message expectedMessage(Message::say, "1"); cache.AppendMessage(expectedMessage); cache.SetLoadOrderSorted(true); - loot::GameCache otherCache = cache; + GameCache otherCache = cache; EXPECT_EQ(std::make_pair(true, true), otherCache.GetCachedCondition("true Condition")); EXPECT_EQ("Blank.esm", otherCache.GetPlugin("Blank.esm").Name()); ASSERT_EQ(1, otherCache.GetMessages().size()); EXPECT_EQ(expectedMessage, otherCache.GetMessages()[0]); } - TEST_F(GameCache, gettingATrueConditionShouldReturnATrueTruePair) { + TEST_F(GameCacheTest, gettingATrueConditionShouldReturnATrueTruePair) { EXPECT_NO_THROW(cache.CacheCondition("True Condition", true)); EXPECT_EQ(std::make_pair(true, true), cache.GetCachedCondition("true Condition")); } - TEST_F(GameCache, gettingAFalseConditionShouldReturnAFalseTruePair) { + TEST_F(GameCacheTest, gettingAFalseConditionShouldReturnAFalseTruePair) { EXPECT_NO_THROW(cache.CacheCondition("False Condition", false)); EXPECT_EQ(std::make_pair(false, true), cache.GetCachedCondition("false Condition")); } - TEST_F(GameCache, gettingANonCachedConditionShouldReturnAFalseFalsePair) { + TEST_F(GameCacheTest, gettingANonCachedConditionShouldReturnAFalseFalsePair) { EXPECT_EQ(std::make_pair(false, false), cache.GetCachedCondition("true missing Condition")); } - TEST_F(GameCache, addingAPluginThatDoesNotExistShouldSucceed) { - loot::Game game(loot::Game::tes5); + TEST_F(GameCacheTest, addingAPluginThatDoesNotExistShouldSucceed) { + Game game(Game::tes5); game.SetGamePath(dataPath.parent_path()); ASSERT_NO_THROW(game.Init(false, localPath)); - cache.AddPlugin(loot::Plugin(game, "Blank.esm", true)); + cache.AddPlugin(Plugin(game, "Blank.esm", true)); EXPECT_EQ("Blank.esm", cache.GetPlugin("Blank.esm").Name()); } - TEST_F(GameCache, addingAPluginThatIsAlreadyCachedShouldOverwriteExistingEntry) { - loot::Game game(loot::Game::tes5); + TEST_F(GameCacheTest, addingAPluginThatIsAlreadyCachedShouldOverwriteExistingEntry) { + Game game(Game::tes5); game.SetGamePath(dataPath.parent_path()); ASSERT_NO_THROW(game.Init(false, localPath)); - cache.AddPlugin(loot::Plugin(game, "Blank.esm", true)); + cache.AddPlugin(Plugin(game, "Blank.esm", true)); EXPECT_EQ(0, cache.GetPlugin("Blank.esm").Crc()); - cache.AddPlugin(loot::Plugin(game, "Blank.esm", false)); + cache.AddPlugin(Plugin(game, "Blank.esm", false)); EXPECT_EQ(0x187BE342, cache.GetPlugin("Blank.esm").Crc()); } - TEST_F(GameCache, gettingAPluginThatIsNotCachedShouldThrow) { + TEST_F(GameCacheTest, gettingAPluginThatIsNotCachedShouldThrow) { EXPECT_ANY_THROW(cache.GetPlugin("Blank.esm")); } - TEST_F(GameCache, gettingAPluginShouldBeCaseInsensitive) { - loot::Game game(loot::Game::tes5); + TEST_F(GameCacheTest, gettingAPluginShouldBeCaseInsensitive) { + Game game(Game::tes5); game.SetGamePath(dataPath.parent_path()); ASSERT_NO_THROW(game.Init(false, localPath)); - cache.AddPlugin(loot::Plugin(game, "Blank.esm", true)); + cache.AddPlugin(Plugin(game, "Blank.esm", true)); EXPECT_EQ("Blank.esm", cache.GetPlugin("blanK.esm").Name()); } - TEST_F(GameCache, gettingPluginsShouldReturnAnEmptySetIfNoPluginsHaveBeenCached) { + TEST_F(GameCacheTest, gettingPluginsShouldReturnAnEmptySetIfNoPluginsHaveBeenCached) { EXPECT_TRUE(cache.GetPlugins().empty()); } - TEST_F(GameCache, gettingPluginsShouldReturnASetOfCachedPluginsIfPluginsHaveBeenCached) { - loot::Game game(loot::Game::tes5); + TEST_F(GameCacheTest, gettingPluginsShouldReturnASetOfCachedPluginsIfPluginsHaveBeenCached) { + Game game(Game::tes5); game.SetGamePath(dataPath.parent_path()); ASSERT_NO_THROW(game.Init(false, localPath)); - cache.AddPlugin(loot::Plugin(game, "Blank.esm", true)); - cache.AddPlugin(loot::Plugin(game, "Blank - Master Dependent.esp", true)); + cache.AddPlugin(Plugin(game, "Blank.esm", true)); + cache.AddPlugin(Plugin(game, "Blank - Master Dependent.esp", true)); - EXPECT_EQ(std::set({ - loot::Plugin(game, "Blank.esm", true), - loot::Plugin(game, "Blank - Master Dependent.esp", true), + EXPECT_EQ(std::set({ + Plugin(game, "Blank.esm", true), + Plugin(game, "Blank - Master Dependent.esp", true), }), cache.GetPlugins()); } - TEST_F(GameCache, clearingCachedConditionsShouldNotThrowIfNoConditionsAreCached) { + TEST_F(GameCacheTest, clearingCachedConditionsShouldNotThrowIfNoConditionsAreCached) { EXPECT_NO_THROW(cache.ClearCachedConditions()); } - TEST_F(GameCache, clearingCachedConditionsShouldClearAnyCachedConditions) { + TEST_F(GameCacheTest, clearingCachedConditionsShouldClearAnyCachedConditions) { EXPECT_NO_THROW(cache.CacheCondition("True Condition", true)); EXPECT_NO_THROW(cache.ClearCachedConditions()); @@ -152,32 +152,32 @@ namespace loot { EXPECT_EQ(std::make_pair(false, false), cache.GetCachedCondition("true Condition")); } - TEST_F(GameCache, clearingCachedPluginsShouldNotThrowIfNoPluginsAreCached) { + TEST_F(GameCacheTest, clearingCachedPluginsShouldNotThrowIfNoPluginsAreCached) { EXPECT_NO_THROW(cache.ClearCachedPlugins()); } - TEST_F(GameCache, clearingCachedPluginsShouldClearAnyCachedPlugins) { - loot::Game game(loot::Game::tes5); + TEST_F(GameCacheTest, clearingCachedPluginsShouldClearAnyCachedPlugins) { + Game game(Game::tes5); game.SetGamePath(dataPath.parent_path()); ASSERT_NO_THROW(game.Init(false, localPath)); - cache.AddPlugin(loot::Plugin(game, "Blank.esm", true)); + cache.AddPlugin(Plugin(game, "Blank.esm", true)); cache.ClearCachedPlugins(); EXPECT_TRUE(cache.GetPlugins().empty()); } - TEST_F(GameCache, aMessageShouldBeCachedByDefault) { + TEST_F(GameCacheTest, aMessageShouldBeCachedByDefault) { ASSERT_EQ(1, cache.GetMessages().size()); } - TEST_F(GameCache, settingLoadOrderSortedToTrueShouldSupressDefaultCachedMessage) { + TEST_F(GameCacheTest, settingLoadOrderSortedToTrueShouldSupressDefaultCachedMessage) { cache.SetLoadOrderSorted(true); ASSERT_TRUE(cache.GetMessages().empty()); } - TEST_F(GameCache, settingLoadOrderSortedToFalseShouldReverseTheDefaultCachedMessageSuppression) { + TEST_F(GameCacheTest, settingLoadOrderSortedToFalseShouldReverseTheDefaultCachedMessageSuppression) { auto expectedMessages = cache.GetMessages(); cache.SetLoadOrderSorted(true); cache.SetLoadOrderSorted(false); @@ -185,7 +185,7 @@ namespace loot { ASSERT_EQ(expectedMessages, cache.GetMessages()); } - TEST_F(GameCache, appendingMessagesShouldStoreThemInTheGivenOrder) { + TEST_F(GameCacheTest, appendingMessagesShouldStoreThemInTheGivenOrder) { std::vector messages({ Message(Message::say, "1"), Message(Message::error, "2"), @@ -198,7 +198,7 @@ namespace loot { EXPECT_EQ(messages[1], cache.GetMessages()[1]); } - TEST_F(GameCache, clearingMessagesShouldRemoveAllAppendedMessages) { + TEST_F(GameCacheTest, clearingMessagesShouldRemoveAllAppendedMessages) { std::vector messages({ Message(Message::say, "1"), Message(Message::error, "2"), diff --git a/src/tests/backend/game/test_game_settings.h b/src/tests/backend/game/test_game_settings.h index e6f95691..6b90b3bc 100644 --- a/src/tests/backend/game/test_game_settings.h +++ b/src/tests/backend/game/test_game_settings.h @@ -29,226 +29,230 @@ along with LOOT. If not, see #include "backend/game/game_settings.h" #include "tests/fixtures.h" -class GameSettings : public SkyrimTest {}; +namespace loot { + namespace test { + class GameSettingsTest : public SkyrimTest {}; -TEST_F(GameSettings, ConstructorsAndDataAccess) { - loot::GameSettings game; + TEST_F(GameSettingsTest, ConstructorsAndDataAccess) { + GameSettings game; - EXPECT_EQ(loot::GameSettings::autodetect, game.Id()); - EXPECT_EQ("", game.Name()); - EXPECT_EQ("", game.FolderName()); - EXPECT_EQ("", game.Master()); - EXPECT_EQ("", game.RegistryKey()); - EXPECT_EQ("", game.RepoURL()); - EXPECT_EQ("", game.RepoBranch()); + EXPECT_EQ(GameSettings::autodetect, game.Id()); + EXPECT_EQ("", game.Name()); + EXPECT_EQ("", game.FolderName()); + EXPECT_EQ("", game.Master()); + EXPECT_EQ("", game.RegistryKey()); + EXPECT_EQ("", game.RepoURL()); + EXPECT_EQ("", game.RepoBranch()); - EXPECT_EQ("", game.GamePath()); - EXPECT_EQ("", game.DataPath()); - EXPECT_EQ("", game.MasterlistPath()); - EXPECT_EQ("", game.UserlistPath()); + EXPECT_EQ("", game.GamePath()); + EXPECT_EQ("", game.DataPath()); + EXPECT_EQ("", game.MasterlistPath()); + EXPECT_EQ("", game.UserlistPath()); - game = loot::GameSettings(loot::GameSettings::tes5); + game = GameSettings(GameSettings::tes5); - EXPECT_EQ(loot::GameSettings::tes5, game.Id()); - EXPECT_EQ("TES V: Skyrim", game.Name()); - EXPECT_EQ("Skyrim", game.FolderName()); - EXPECT_EQ("Skyrim.esm", game.Master()); - EXPECT_EQ("Software\\Bethesda Softworks\\Skyrim\\Installed Path", game.RegistryKey()); - EXPECT_EQ("https://github.com/loot/skyrim.git", game.RepoURL()); - // Repo branch changes between LOOT versions, so don't check an exact value. - EXPECT_NE("", game.RepoBranch()); + EXPECT_EQ(GameSettings::tes5, game.Id()); + EXPECT_EQ("TES V: Skyrim", game.Name()); + EXPECT_EQ("Skyrim", game.FolderName()); + EXPECT_EQ("Skyrim.esm", game.Master()); + EXPECT_EQ("Software\\Bethesda Softworks\\Skyrim\\Installed Path", game.RegistryKey()); + EXPECT_EQ("https://github.com/loot/skyrim.git", game.RepoURL()); + // Repo branch changes between LOOT versions, so don't check an exact value. + EXPECT_NE("", game.RepoBranch()); - EXPECT_EQ("", game.GamePath()); - EXPECT_EQ("", game.DataPath()); - EXPECT_EQ(loot::g_path_local / "Skyrim" / "masterlist.yaml", game.MasterlistPath()); - EXPECT_EQ(loot::g_path_local / "Skyrim" / "userlist.yaml", game.UserlistPath()); + EXPECT_EQ("", game.GamePath()); + EXPECT_EQ("", game.DataPath()); + EXPECT_EQ(g_path_local / "Skyrim" / "masterlist.yaml", game.MasterlistPath()); + EXPECT_EQ(g_path_local / "Skyrim" / "userlist.yaml", game.UserlistPath()); - game = loot::GameSettings(loot::GameSettings::tes5, "folder"); + game = GameSettings(GameSettings::tes5, "folder"); - EXPECT_EQ(loot::GameSettings::tes5, game.Id()); - EXPECT_EQ("TES V: Skyrim", game.Name()); - EXPECT_EQ("folder", game.FolderName()); - EXPECT_EQ("Skyrim.esm", game.Master()); - EXPECT_EQ("Software\\Bethesda Softworks\\Skyrim\\Installed Path", game.RegistryKey()); - EXPECT_EQ("https://github.com/loot/skyrim.git", game.RepoURL()); - // Repo branch changes between LOOT versions, so don't check an exact value. - EXPECT_NE("", game.RepoBranch()); + EXPECT_EQ(GameSettings::tes5, game.Id()); + EXPECT_EQ("TES V: Skyrim", game.Name()); + EXPECT_EQ("folder", game.FolderName()); + EXPECT_EQ("Skyrim.esm", game.Master()); + EXPECT_EQ("Software\\Bethesda Softworks\\Skyrim\\Installed Path", game.RegistryKey()); + EXPECT_EQ("https://github.com/loot/skyrim.git", game.RepoURL()); + // Repo branch changes between LOOT versions, so don't check an exact value. + EXPECT_NE("", game.RepoBranch()); - EXPECT_EQ("", game.GamePath()); - EXPECT_EQ("", game.DataPath()); - EXPECT_EQ(loot::g_path_local / "folder" / "masterlist.yaml", game.MasterlistPath()); - EXPECT_EQ(loot::g_path_local / "folder" / "userlist.yaml", game.UserlistPath()); -} + EXPECT_EQ("", game.GamePath()); + EXPECT_EQ("", game.DataPath()); + EXPECT_EQ(g_path_local / "folder" / "masterlist.yaml", game.MasterlistPath()); + EXPECT_EQ(g_path_local / "folder" / "userlist.yaml", game.UserlistPath()); + } -TEST_F(GameSettings, IsInstalled) { - loot::GameSettings game; - EXPECT_FALSE(game.IsInstalled()); + TEST_F(GameSettingsTest, IsInstalled) { + GameSettings game; + EXPECT_FALSE(game.IsInstalled()); - game = loot::GameSettings(loot::GameSettings::tes5); - game.SetGamePath(dataPath.parent_path()); - EXPECT_TRUE(game.IsInstalled()); - EXPECT_EQ(dataPath.parent_path(), game.GamePath()); + game = GameSettings(GameSettings::tes5); + game.SetGamePath(dataPath.parent_path()); + EXPECT_TRUE(game.IsInstalled()); + EXPECT_EQ(dataPath.parent_path(), game.GamePath()); - game = loot::GameSettings(loot::GameSettings::fo3); - EXPECT_FALSE(game.IsInstalled()); -} + game = GameSettings(GameSettings::fo3); + EXPECT_FALSE(game.IsInstalled()); + } -TEST_F(GameSettings, EqualityOperators) { - loot::GameSettings game1, game2; - EXPECT_TRUE(game1 == game2); + TEST_F(GameSettingsTest, EqualityOperators) { + GameSettings game1, game2; + EXPECT_TRUE(game1 == game2); - game1 = loot::GameSettings(loot::GameSettings::tes5); - game2 = loot::GameSettings(loot::GameSettings::tes5); - EXPECT_TRUE(game1 == game2); + game1 = GameSettings(GameSettings::tes5); + game2 = GameSettings(GameSettings::tes5); + EXPECT_TRUE(game1 == game2); - game1 = loot::GameSettings(loot::GameSettings::tes5, "game1") - .SetMaster("master1") - .SetRegistryKey("key1") - .SetRepoURL("url1") - .SetRepoBranch("branch1") - .SetGamePath("path1"); - game2 = loot::GameSettings(loot::GameSettings::tes5, "game2") - .SetMaster("master2") - .SetRegistryKey("key2") - .SetRepoURL("url2") - .SetRepoBranch("branch2") - .SetGamePath("path2"); - EXPECT_TRUE(game1 == game2); + game1 = GameSettings(GameSettings::tes5, "game1") + .SetMaster("master1") + .SetRegistryKey("key1") + .SetRepoURL("url1") + .SetRepoBranch("branch1") + .SetGamePath("path1"); + game2 = GameSettings(GameSettings::tes5, "game2") + .SetMaster("master2") + .SetRegistryKey("key2") + .SetRepoURL("url2") + .SetRepoBranch("branch2") + .SetGamePath("path2"); + EXPECT_TRUE(game1 == game2); - game1 = loot::GameSettings(loot::GameSettings::tes4) - .SetName("name"); - game2 = loot::GameSettings(loot::GameSettings::tes5) - .SetName("name"); - EXPECT_TRUE(game1 == game2); + game1 = GameSettings(GameSettings::tes4) + .SetName("name"); + game2 = GameSettings(GameSettings::tes5) + .SetName("name"); + EXPECT_TRUE(game1 == game2); - game1 = loot::GameSettings(loot::GameSettings::tes4); - game2 = loot::GameSettings(loot::GameSettings::tes5); - EXPECT_FALSE(game1 == game2); -} + game1 = GameSettings(GameSettings::tes4); + game2 = GameSettings(GameSettings::tes5); + EXPECT_FALSE(game1 == game2); + } -TEST_F(GameSettings, SetName) { - loot::GameSettings game; - game.SetName("name"); - EXPECT_EQ("name", game.Name()); -} + TEST_F(GameSettingsTest, SetName) { + GameSettings game; + game.SetName("name"); + EXPECT_EQ("name", game.Name()); + } -TEST_F(GameSettings, SetMaster) { - loot::GameSettings game; - game.SetMaster("master"); - EXPECT_EQ("master", game.Master()); -} + TEST_F(GameSettingsTest, SetMaster) { + GameSettings game; + game.SetMaster("master"); + EXPECT_EQ("master", game.Master()); + } -TEST_F(GameSettings, SetRegistryKey) { - loot::GameSettings game; - game.SetRegistryKey("key"); - EXPECT_EQ("key", game.RegistryKey()); -} + TEST_F(GameSettingsTest, SetRegistryKey) { + GameSettings game; + game.SetRegistryKey("key"); + EXPECT_EQ("key", game.RegistryKey()); + } -TEST_F(GameSettings, SetRepoURL) { - loot::GameSettings game; - game.SetRepoURL("url"); - EXPECT_EQ("url", game.RepoURL()); -} + TEST_F(GameSettingsTest, SetRepoURL) { + GameSettings game; + game.SetRepoURL("url"); + EXPECT_EQ("url", game.RepoURL()); + } -TEST_F(GameSettings, SetRepoBranch) { - loot::GameSettings game; - game.SetRepoBranch("branch"); - EXPECT_EQ("branch", game.RepoBranch()); -} + TEST_F(GameSettingsTest, SetRepoBranch) { + GameSettings game; + game.SetRepoBranch("branch"); + EXPECT_EQ("branch", game.RepoBranch()); + } -TEST_F(GameSettings, SetGamePath) { - loot::GameSettings game; - game.SetGamePath("path"); - EXPECT_EQ("path", game.GamePath().string()); - EXPECT_EQ(boost::filesystem::path("path") / "Data", game.DataPath()); -} + TEST_F(GameSettingsTest, SetGamePath) { + GameSettings game; + game.SetGamePath("path"); + EXPECT_EQ("path", game.GamePath().string()); + EXPECT_EQ(boost::filesystem::path("path") / "Data", game.DataPath()); + } -TEST_F(GameSettings, YamlEmitter) { - loot::GameSettings game(loot::GameSettings::tes5, "folder1"); - game.SetName("name1") - .SetMaster("master1") - .SetRegistryKey("key1") - .SetRepoURL("url1") - .SetRepoBranch("branch1") - .SetGamePath("path1"); + TEST_F(GameSettingsTest, YamlEmitter) { + GameSettings game(GameSettings::tes5, "folder1"); + game.SetName("name1") + .SetMaster("master1") + .SetRegistryKey("key1") + .SetRepoURL("url1") + .SetRepoBranch("branch1") + .SetGamePath("path1"); - YAML::Emitter e; - e << game; - EXPECT_STREQ("type: 'Skyrim'\n" - "folder: 'folder1'\n" - "name: 'name1'\n" - "master: 'master1'\n" - "repo: 'url1'\n" - "branch: 'branch1'\n" - "path: 'path1'\n" - "registry: 'key1'", e.c_str()); -} + YAML::Emitter e; + e << game; + EXPECT_STREQ("type: 'Skyrim'\n" + "folder: 'folder1'\n" + "name: 'name1'\n" + "master: 'master1'\n" + "repo: 'url1'\n" + "branch: 'branch1'\n" + "path: 'path1'\n" + "registry: 'key1'", e.c_str()); + } -TEST_F(GameSettings, YamlEncode) { - loot::GameSettings game(loot::GameSettings::tes5, "folder1"); - game.SetName("name1") - .SetMaster("master1") - .SetRegistryKey("key1") - .SetRepoURL("url1") - .SetRepoBranch("branch1") - .SetGamePath("path1"); + TEST_F(GameSettingsTest, YamlEncode) { + GameSettings game(GameSettings::tes5, "folder1"); + game.SetName("name1") + .SetMaster("master1") + .SetRegistryKey("key1") + .SetRepoURL("url1") + .SetRepoBranch("branch1") + .SetGamePath("path1"); - YAML::Node node; - node = game; - EXPECT_EQ("Skyrim", node["type"].as()); - EXPECT_EQ("folder1", node["folder"].as()); - EXPECT_EQ("name1", node["name"].as()); - EXPECT_EQ("master1", node["master"].as()); - EXPECT_EQ("url1", node["repo"].as()); - EXPECT_EQ("branch1", node["branch"].as()); - EXPECT_EQ("path1", node["path"].as()); - EXPECT_EQ("key1", node["registry"].as()); -} + YAML::Node node; + node = game; + EXPECT_EQ("Skyrim", node["type"].as()); + EXPECT_EQ("folder1", node["folder"].as()); + EXPECT_EQ("name1", node["name"].as()); + EXPECT_EQ("master1", node["master"].as()); + EXPECT_EQ("url1", node["repo"].as()); + EXPECT_EQ("branch1", node["branch"].as()); + EXPECT_EQ("path1", node["path"].as()); + EXPECT_EQ("key1", node["registry"].as()); + } -TEST_F(GameSettings, YamlDecode) { - YAML::Node node = YAML::Load("type: 'Skyrim'\n" - "folder: 'folder1'\n" - "name: 'name1'\n" - "master: 'master1'\n" - "repo: 'url1'\n" - "branch: 'branch1'\n" - "path: 'path1'\n" - "registry: 'key1'"); + TEST_F(GameSettingsTest, YamlDecode) { + YAML::Node node = YAML::Load("type: 'Skyrim'\n" + "folder: 'folder1'\n" + "name: 'name1'\n" + "master: 'master1'\n" + "repo: 'url1'\n" + "branch: 'branch1'\n" + "path: 'path1'\n" + "registry: 'key1'"); - loot::GameSettings game = node.as(); - EXPECT_EQ(loot::GameSettings::tes5, game.Id()); - EXPECT_EQ("name1", game.Name()); - EXPECT_EQ("folder1", game.FolderName()); - EXPECT_EQ("master1", game.Master()); - EXPECT_EQ("key1", game.RegistryKey()); - EXPECT_EQ("url1", game.RepoURL()); - EXPECT_EQ("branch1", game.RepoBranch()); - EXPECT_EQ("path1", game.GamePath()); + GameSettings game = node.as(); + EXPECT_EQ(GameSettings::tes5, game.Id()); + EXPECT_EQ("name1", game.Name()); + EXPECT_EQ("folder1", game.FolderName()); + EXPECT_EQ("master1", game.Master()); + EXPECT_EQ("key1", game.RegistryKey()); + EXPECT_EQ("url1", game.RepoURL()); + EXPECT_EQ("branch1", game.RepoBranch()); + EXPECT_EQ("path1", game.GamePath()); - node = YAML::Load("type: 'Invalid'\n"); - EXPECT_ANY_THROW(node.as()); + node = YAML::Load("type: 'Invalid'\n"); + EXPECT_ANY_THROW(node.as()); - node = YAML::Load("scalar"); - EXPECT_ANY_THROW(node.as()); + node = YAML::Load("scalar"); + EXPECT_ANY_THROW(node.as()); - node = YAML::Load("[0, 1, 2]"); - EXPECT_ANY_THROW(node.as()); + node = YAML::Load("[0, 1, 2]"); + EXPECT_ANY_THROW(node.as()); - // Test inheritance of unspecified settings. - node = YAML::Load("type: 'Skyrim'\n" - "folder: 'folder1'\n" - "master: 'master1'\n" - "repo: 'url1'\n" - "branch: 'branch1'\n"); + // Test inheritance of unspecified settings. + node = YAML::Load("type: 'Skyrim'\n" + "folder: 'folder1'\n" + "master: 'master1'\n" + "repo: 'url1'\n" + "branch: 'branch1'\n"); - game = node.as(); - EXPECT_EQ(loot::GameSettings::tes5, game.Id()); - EXPECT_EQ("TES V: Skyrim", game.Name()); - EXPECT_EQ("folder1", game.FolderName()); - EXPECT_EQ("master1", game.Master()); - EXPECT_EQ("Software\\Bethesda Softworks\\Skyrim\\Installed Path", game.RegistryKey()); - EXPECT_EQ("url1", game.RepoURL()); - EXPECT_EQ("branch1", game.RepoBranch()); - EXPECT_EQ("", game.GamePath()); + game = node.as(); + EXPECT_EQ(GameSettings::tes5, game.Id()); + EXPECT_EQ("TES V: Skyrim", game.Name()); + EXPECT_EQ("folder1", game.FolderName()); + EXPECT_EQ("master1", game.Master()); + EXPECT_EQ("Software\\Bethesda Softworks\\Skyrim\\Installed Path", game.RegistryKey()); + EXPECT_EQ("url1", game.RepoURL()); + EXPECT_EQ("branch1", game.RepoBranch()); + EXPECT_EQ("", game.GamePath()); + } + } } #endif diff --git a/src/tests/backend/game/test_load_order_handler.h b/src/tests/backend/game/test_load_order_handler.h index 0e076195..41f07aaf 100644 --- a/src/tests/backend/game/test_load_order_handler.h +++ b/src/tests/backend/game/test_load_order_handler.h @@ -30,113 +30,117 @@ along with LOOT. If not, see #include "tests/fixtures.h" -class LoadOrderHandler : public SkyrimTest {}; +namespace loot { + namespace test { + class LoadOrderHandlerTest : public SkyrimTest {}; -TEST_F(LoadOrderHandler, Constructors) { - loot::LoadOrderHandler * loh = nullptr; - EXPECT_NO_THROW(loh = new loot::LoadOrderHandler); - EXPECT_NO_THROW(delete loh); -} + TEST_F(LoadOrderHandlerTest, Constructors) { + LoadOrderHandler * loh = nullptr; + EXPECT_NO_THROW(loh = new LoadOrderHandler); + EXPECT_NO_THROW(delete loh); + } -TEST_F(LoadOrderHandler, Init) { - // Should throw for invalid game settings ID. - loot::LoadOrderHandler loh; - loot::GameSettings game(loot::GameSettings::autodetect); - EXPECT_THROW(loh.Init(game), loot::error); - EXPECT_THROW(loh.Init(game), loot::error); - EXPECT_THROW(loh.Init(game, localPath), loot::error); - EXPECT_THROW(loh.Init(game, localPath), loot::error); + TEST_F(LoadOrderHandlerTest, Init) { + // Should throw for invalid game settings ID. + LoadOrderHandler loh; + GameSettings game(GameSettings::autodetect); + EXPECT_THROW(loh.Init(game), error); + EXPECT_THROW(loh.Init(game), error); + EXPECT_THROW(loh.Init(game, localPath), error); + EXPECT_THROW(loh.Init(game, localPath), error); - // Should throw an exception if no game path has been set. - game = loot::GameSettings(loot::GameSettings::tes5); - EXPECT_THROW(loh.Init(game), loot::error); - EXPECT_THROW(loh.Init(game), loot::error); - EXPECT_THROW(loh.Init(game, localPath), loot::error); - EXPECT_THROW(loh.Init(game, localPath), loot::error); + // Should throw an exception if no game path has been set. + game = GameSettings(GameSettings::tes5); + EXPECT_THROW(loh.Init(game), error); + EXPECT_THROW(loh.Init(game), error); + EXPECT_THROW(loh.Init(game, localPath), error); + EXPECT_THROW(loh.Init(game, localPath), error); #ifndef _WIN32 // Should throw on Linux if no game local app data path is given. - game = loot::GameSettings(loot::GameSettings::tes5) - .SetGamePath(dataPath.parent_path()); - EXPECT_THROW(loh.Init(game), loot::error); + game = GameSettings(GameSettings::tes5) + .SetGamePath(dataPath.parent_path()); + EXPECT_THROW(loh.Init(game), error); #endif - game = loot::GameSettings(loot::GameSettings::tes5) - .SetGamePath(dataPath.parent_path()); - EXPECT_NO_THROW(loh.Init(game, localPath)); -} + game = GameSettings(GameSettings::tes5) + .SetGamePath(dataPath.parent_path()); + EXPECT_NO_THROW(loh.Init(game, localPath)); + } -TEST_F(LoadOrderHandler, IsPluginActive) { - loot::LoadOrderHandler loh; - loot::GameSettings game(loot::GameSettings::tes5); - game.SetGamePath(dataPath.parent_path()); + TEST_F(LoadOrderHandlerTest, IsPluginActive) { + LoadOrderHandler loh; + GameSettings game(GameSettings::tes5); + game.SetGamePath(dataPath.parent_path()); - EXPECT_THROW(loh.IsPluginActive("Skyrim.esm"), loot::error); + EXPECT_THROW(loh.IsPluginActive("Skyrim.esm"), error); - ASSERT_NO_THROW(loh.Init(game, localPath)); + ASSERT_NO_THROW(loh.Init(game, localPath)); - EXPECT_TRUE(loh.IsPluginActive("Skyrim.esm")); - EXPECT_TRUE(loh.IsPluginActive("Blank.esm")); - EXPECT_TRUE(loh.IsPluginActive("Blank - Different Master Dependent.esp")); - EXPECT_FALSE(loh.IsPluginActive("Blank.esp")); -} + EXPECT_TRUE(loh.IsPluginActive("Skyrim.esm")); + EXPECT_TRUE(loh.IsPluginActive("Blank.esm")); + EXPECT_TRUE(loh.IsPluginActive("Blank - Different Master Dependent.esp")); + EXPECT_FALSE(loh.IsPluginActive("Blank.esp")); + } -TEST_F(LoadOrderHandler, GetLoadOrder) { - loot::LoadOrderHandler loh; - loot::GameSettings game(loot::GameSettings::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(loh.Init(game, localPath)); + TEST_F(LoadOrderHandlerTest, GetLoadOrder) { + LoadOrderHandler loh; + GameSettings game(GameSettings::tes5); + game.SetGamePath(dataPath.parent_path()); + ASSERT_NO_THROW(loh.Init(game, localPath)); - std::list expected({ - "Skyrim.esm", - "Blank.esm", - "Blank - Different.esm", - "Blank - Master Dependent.esm", - "Blank - Different Master Dependent.esm", - "Blank.esp", - "Blank - Different.esp", - "Blank - Master Dependent.esp", - "Blank - Different Master Dependent.esp", - "Blank - Plugin Dependent.esp", - "Blank - Different Plugin Dependent.esp" - }); + std::list expected({ + "Skyrim.esm", + "Blank.esm", + "Blank - Different.esm", + "Blank - Master Dependent.esm", + "Blank - Different Master Dependent.esm", + "Blank.esp", + "Blank - Different.esp", + "Blank - Master Dependent.esp", + "Blank - Different Master Dependent.esp", + "Blank - Plugin Dependent.esp", + "Blank - Different Plugin Dependent.esp" + }); - EXPECT_EQ(expected, loh.GetLoadOrder()); -} + EXPECT_EQ(expected, loh.GetLoadOrder()); + } -TEST_F(LoadOrderHandler, SetLoadOrder) { - loot::LoadOrderHandler loh; - loot::GameSettings game(loot::GameSettings::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(loh.Init(game, localPath)); + TEST_F(LoadOrderHandlerTest, SetLoadOrder) { + LoadOrderHandler loh; + GameSettings game(GameSettings::tes5); + game.SetGamePath(dataPath.parent_path()); + ASSERT_NO_THROW(loh.Init(game, localPath)); - std::list loadOrder({ - "Skyrim.esm", - "Blank.esm", - "Blank - Master Dependent.esm", - "Blank - Different.esm", - "Blank - Different Master Dependent.esm", - "Blank - Different.esp", - "Blank - Different Plugin Dependent.esp", - "Blank.esp", - "Blank - Master Dependent.esp", - "Blank - Different Master Dependent.esp", - "Blank - Plugin Dependent.esp", - }); + std::list loadOrder({ + "Skyrim.esm", + "Blank.esm", + "Blank - Master Dependent.esm", + "Blank - Different.esm", + "Blank - Different Master Dependent.esm", + "Blank - Different.esp", + "Blank - Different Plugin Dependent.esp", + "Blank.esp", + "Blank - Master Dependent.esp", + "Blank - Different Master Dependent.esp", + "Blank - Plugin Dependent.esp", + }); - EXPECT_NO_THROW(loh.SetLoadOrder(loadOrder)); + EXPECT_NO_THROW(loh.SetLoadOrder(loadOrder)); - std::list actual; - boost::filesystem::ifstream in(localPath / "loadorder.txt"); - while (in) { - std::string line; - std::getline(in, line); + std::list actual; + boost::filesystem::ifstream in(localPath / "loadorder.txt"); + while (in) { + std::string line; + std::getline(in, line); - if (!line.empty()) - actual.push_back(line); + if (!line.empty()) + actual.push_back(line); + } + + EXPECT_EQ(loadOrder, actual); + } } - - EXPECT_EQ(loadOrder, actual); } #endif diff --git a/src/tests/backend/helpers/test_git_helper.h b/src/tests/backend/helpers/test_git_helper.h index e680ae33..aee0a226 100644 --- a/src/tests/backend/helpers/test_git_helper.h +++ b/src/tests/backend/helpers/test_git_helper.h @@ -29,107 +29,109 @@ along with LOOT. If not, see #include "backend/helpers/git_helper.h" #include "tests/fixtures.h" -using loot::GitHelper; - +namespace loot { + namespace test { #ifdef _WIN32 -boost::filesystem::path parentRepoRoot = boost::filesystem::current_path().parent_path().parent_path(); + boost::filesystem::path parentRepoRoot = boost::filesystem::current_path().parent_path().parent_path(); #else -boost::filesystem::path parentRepoRoot = boost::filesystem::current_path().parent_path(); + boost::filesystem::path parentRepoRoot = boost::filesystem::current_path().parent_path(); #endif -TEST(GitHelper, ConstructorAndDestructor) { - GitHelper * git = new GitHelper(); - EXPECT_EQ(nullptr, git->repo); + TEST(GitHelper, ConstructorAndDestructor) { + GitHelper * git = new GitHelper(); + EXPECT_EQ(nullptr, git->repo); - EXPECT_EQ(2, git_libgit2_init()); - delete git; - EXPECT_EQ(0, git_libgit2_shutdown()); -} + EXPECT_EQ(2, git_libgit2_init()); + delete git; + EXPECT_EQ(0, git_libgit2_shutdown()); + } -TEST(GitHelper, Call) { - GitHelper git; - EXPECT_NO_THROW(git.Call(0)); - EXPECT_THROW(git.Call(1), loot::error); - EXPECT_THROW(git.Call(-1), loot::error); -} + TEST(GitHelper, Call) { + GitHelper git; + EXPECT_NO_THROW(git.Call(0)); + EXPECT_THROW(git.Call(1), error); + EXPECT_THROW(git.Call(-1), error); + } -TEST(GitHelper, SetErrorMessage) { - GitHelper git; - git.SetErrorMessage("test message"); + TEST(GitHelper, SetErrorMessage) { + GitHelper git; + git.SetErrorMessage("test message"); - try { - git.Call(1); - ADD_FAILURE() << "An exception should have been thrown."; + try { + git.Call(1); + ADD_FAILURE() << "An exception should have been thrown."; + } + catch (error& e) { + EXPECT_NE(nullptr, strstr(e.what(), "test message")); + } + } + + TEST(GitHelper, Free) { + // Initialise buffer member, it's simplest to test with. + GitHelper git; + git_buf_set(&git.buf, "foo", 4); + EXPECT_NE(nullptr, git.buf.ptr); + EXPECT_EQ(4, git.buf.size); + + git.Free(); + EXPECT_EQ(nullptr, git.buf.ptr); + EXPECT_EQ(0, git.buf.size); + } + + TEST(GitHelper, IsRepository) { + GitHelper git; + + ASSERT_TRUE(boost::filesystem::exists(parentRepoRoot)); + EXPECT_TRUE(git.IsRepository(parentRepoRoot)); + EXPECT_FALSE(git.IsRepository(boost::filesystem::current_path())); + } + + class IsFileDifferentTest : public ::testing::Test { + inline virtual void SetUp() { + GitHelper git; + ASSERT_TRUE(git.IsRepository(parentRepoRoot)); + ASSERT_FALSE(git.IsRepository(boost::filesystem::current_path())); + + ASSERT_TRUE(boost::filesystem::exists(parentRepoRoot / "README.md")); + + // Create a backup of CONTRIBUTING.md. + ASSERT_TRUE(boost::filesystem::exists(parentRepoRoot / "CONTRIBUTING.md")); + ASSERT_FALSE(boost::filesystem::exists(parentRepoRoot / "CONTRIBUTING.md.copy")); + ASSERT_NO_THROW(boost::filesystem::copy(parentRepoRoot / "CONTRIBUTING.md", parentRepoRoot / "CONTRIBUTING.md.copy")); + ASSERT_TRUE(boost::filesystem::exists(parentRepoRoot / "CONTRIBUTING.md.copy")); + + // Edit CONTRIBUTING.md + boost::filesystem::ofstream out(parentRepoRoot / "CONTRIBUTING.md"); + out.close(); + } + + inline virtual void TearDown() { + // Restore original CONTRIBUTING.md + ASSERT_NO_THROW(boost::filesystem::remove(parentRepoRoot / "CONTRIBUTING.md")); + ASSERT_NO_THROW(boost::filesystem::rename(parentRepoRoot / "CONTRIBUTING.md.copy", parentRepoRoot / "CONTRIBUTING.md")); + ASSERT_TRUE(boost::filesystem::exists(parentRepoRoot / "CONTRIBUTING.md")); + ASSERT_FALSE(boost::filesystem::exists(parentRepoRoot / "CONTRIBUTING.md.copy")); + } + }; + + TEST_F(IsFileDifferentTest, InvalidRepository) { + EXPECT_THROW(IsFileDifferent(boost::filesystem::current_path(), "README.md"), error); + } + + TEST_F(IsFileDifferentTest, SameFile) { + EXPECT_FALSE(IsFileDifferent(parentRepoRoot, "README.md")); + } + + TEST_F(IsFileDifferentTest, NewFile) { + // New files not in the index are not tracked by Git, so aren't considered + // different. + EXPECT_FALSE(IsFileDifferent(parentRepoRoot, "CONTRIBUTING.md.copy")); + } + + TEST_F(IsFileDifferentTest, DifferentFile) { + EXPECT_TRUE(IsFileDifferent(parentRepoRoot, "CONTRIBUTING.md")); + } } - catch (loot::error& e) { - EXPECT_NE(nullptr, strstr(e.what(), "test message")); - } -} - -TEST(GitHelper, Free) { - // Initialise buffer member, it's simplest to test with. - GitHelper git; - git_buf_set(&git.buf, "foo", 4); - EXPECT_NE(nullptr, git.buf.ptr); - EXPECT_EQ(4, git.buf.size); - - git.Free(); - EXPECT_EQ(nullptr, git.buf.ptr); - EXPECT_EQ(0, git.buf.size); -} - -TEST(GitHelper, IsRepository) { - GitHelper git; - - ASSERT_TRUE(boost::filesystem::exists(parentRepoRoot)); - EXPECT_TRUE(git.IsRepository(parentRepoRoot)); - EXPECT_FALSE(git.IsRepository(boost::filesystem::current_path())); -} - -class IsFileDifferent : public ::testing::Test { - inline virtual void SetUp() { - GitHelper git; - ASSERT_TRUE(git.IsRepository(parentRepoRoot)); - ASSERT_FALSE(git.IsRepository(boost::filesystem::current_path())); - - ASSERT_TRUE(boost::filesystem::exists(parentRepoRoot / "README.md")); - - // Create a backup of CONTRIBUTING.md. - ASSERT_TRUE(boost::filesystem::exists(parentRepoRoot / "CONTRIBUTING.md")); - ASSERT_FALSE(boost::filesystem::exists(parentRepoRoot / "CONTRIBUTING.md.copy")); - ASSERT_NO_THROW(boost::filesystem::copy(parentRepoRoot / "CONTRIBUTING.md", parentRepoRoot / "CONTRIBUTING.md.copy")); - ASSERT_TRUE(boost::filesystem::exists(parentRepoRoot / "CONTRIBUTING.md.copy")); - - // Edit CONTRIBUTING.md - boost::filesystem::ofstream out(parentRepoRoot / "CONTRIBUTING.md"); - out.close(); - } - - inline virtual void TearDown() { - // Restore original CONTRIBUTING.md - ASSERT_NO_THROW(boost::filesystem::remove(parentRepoRoot / "CONTRIBUTING.md")); - ASSERT_NO_THROW(boost::filesystem::rename(parentRepoRoot / "CONTRIBUTING.md.copy", parentRepoRoot / "CONTRIBUTING.md")); - ASSERT_TRUE(boost::filesystem::exists(parentRepoRoot / "CONTRIBUTING.md")); - ASSERT_FALSE(boost::filesystem::exists(parentRepoRoot / "CONTRIBUTING.md.copy")); - } -}; - -TEST_F(IsFileDifferent, InvalidRepository) { - EXPECT_THROW(loot::IsFileDifferent(boost::filesystem::current_path(), "README.md"), loot::error); -} - -TEST_F(IsFileDifferent, SameFile) { - EXPECT_FALSE(loot::IsFileDifferent(parentRepoRoot, "README.md")); -} - -TEST_F(IsFileDifferent, NewFile) { - // New files not in the index are not tracked by Git, so aren't considered - // different. - EXPECT_FALSE(loot::IsFileDifferent(parentRepoRoot, "CONTRIBUTING.md.copy")); -} - -TEST_F(IsFileDifferent, DifferentFile) { - EXPECT_TRUE(loot::IsFileDifferent(parentRepoRoot, "CONTRIBUTING.md")); } #endif diff --git a/src/tests/backend/helpers/test_helpers.h b/src/tests/backend/helpers/test_helpers.h index ee917d8d..cceea1cc 100644 --- a/src/tests/backend/helpers/test_helpers.h +++ b/src/tests/backend/helpers/test_helpers.h @@ -29,19 +29,23 @@ along with LOOT. If not, see #include "backend/error.h" #include "tests/fixtures.h" -class GetCrc32 : public SkyrimTest {}; +namespace loot { + namespace test { + class GetCrc32Test : public SkyrimTest {}; -TEST_F(GetCrc32, MissingFile) { - EXPECT_THROW(loot::GetCrc32(dataPath / "Blank.missing.esp"), loot::error); -} + TEST_F(GetCrc32Test, MissingFile) { + EXPECT_THROW(GetCrc32(dataPath / "Blank.missing.esp"), error); + } -TEST_F(GetCrc32, ValidFile) { - EXPECT_EQ(0x24F0E2A1, loot::GetCrc32(dataPath / "Blank.esp")); -} + TEST_F(GetCrc32Test, ValidFile) { + EXPECT_EQ(0x24F0E2A1, GetCrc32(dataPath / "Blank.esp")); + } -TEST(IntToHexString, PositiveAndZeroValues) { - EXPECT_EQ("14", loot::IntToHexString(20)); - EXPECT_EQ("0", loot::IntToHexString(0)); + TEST(IntToHexString, PositiveAndZeroValues) { + EXPECT_EQ("14", IntToHexString(20)); + EXPECT_EQ("0", IntToHexString(0)); + } + } } #endif diff --git a/src/tests/backend/helpers/test_language.h b/src/tests/backend/helpers/test_language.h index 681a4eee..3a2f2f49 100644 --- a/src/tests/backend/helpers/test_language.h +++ b/src/tests/backend/helpers/test_language.h @@ -28,61 +28,63 @@ along with LOOT. If not, see #include "backend/helpers/language.h" #include "tests/fixtures.h" -using loot::Language; +namespace loot { + namespace test { + TEST(Language, ConstructorsAndDataAccess) { + // Test English code and locale. + Language lang(Language::english); + EXPECT_EQ(Language::english, lang.Code()); + EXPECT_EQ("English", lang.Name()); + EXPECT_EQ("en", lang.Locale()); -TEST(Language, ConstructorsAndDataAccess) { - // Test English code and locale. - Language lang(Language::english); - EXPECT_EQ(Language::english, lang.Code()); - EXPECT_EQ("English", lang.Name()); - EXPECT_EQ("en", lang.Locale()); + lang = Language("en"); + EXPECT_EQ(Language::english, lang.Code()); + EXPECT_EQ("English", lang.Name()); + EXPECT_EQ("en", lang.Locale()); - lang = Language("en"); - EXPECT_EQ(Language::english, lang.Code()); - EXPECT_EQ("English", lang.Name()); - EXPECT_EQ("en", lang.Locale()); + // Test code and locale for a couple of other languages, in case English + // is wrongly being used for everything. No point testing all languages, + // because that would just be copying the class code. + lang = Language(Language::polish); + EXPECT_EQ(Language::polish, lang.Code()); + EXPECT_EQ("Polski", lang.Name()); + EXPECT_EQ("pl", lang.Locale()); - // Test code and locale for a couple of other languages, in case English - // is wrongly being used for everything. No point testing all languages, - // because that would just be copying the class code. - lang = Language(Language::polish); - EXPECT_EQ(Language::polish, lang.Code()); - EXPECT_EQ("Polski", lang.Name()); - EXPECT_EQ("pl", lang.Locale()); + lang = Language("de"); + EXPECT_EQ(Language::german, lang.Code()); + EXPECT_EQ("Deutsch", lang.Name()); + EXPECT_EQ("de", lang.Locale()); - lang = Language("de"); - EXPECT_EQ(Language::german, lang.Code()); - EXPECT_EQ("Deutsch", lang.Name()); - EXPECT_EQ("de", lang.Locale()); + // Test that invalid values get treated as English. + lang = Language(1000); + EXPECT_EQ(Language::english, lang.Code()); + EXPECT_EQ("English", lang.Name()); + EXPECT_EQ("en", lang.Locale()); - // Test that invalid values get treated as English. - lang = Language(1000); - EXPECT_EQ(Language::english, lang.Code()); - EXPECT_EQ("English", lang.Name()); - EXPECT_EQ("en", lang.Locale()); + lang = Language("foo"); + EXPECT_EQ(Language::english, lang.Code()); + EXPECT_EQ("English", lang.Name()); + EXPECT_EQ("en", lang.Locale()); + } - lang = Language("foo"); - EXPECT_EQ(Language::english, lang.Code()); - EXPECT_EQ("English", lang.Name()); - EXPECT_EQ("en", lang.Locale()); -} - -TEST(Language, Codes) { - // Check that all the expected codes are given. - std::vector codes = { - Language::english, - Language::spanish, - Language::russian, - Language::french, - Language::chinese, - Language::polish, - Language::brazilian_portuguese, - Language::finnish, - Language::german, - Language::danish, - Language::korean - }; - EXPECT_EQ(Language::Codes, codes); + TEST(Language, Codes) { + // Check that all the expected codes are given. + std::vector codes = { + Language::english, + Language::spanish, + Language::russian, + Language::french, + Language::chinese, + Language::polish, + Language::brazilian_portuguese, + Language::finnish, + Language::german, + Language::danish, + Language::korean + }; + EXPECT_EQ(Language::Codes, codes); + } + } } #endif diff --git a/src/tests/backend/helpers/test_yaml_set_helpers.h b/src/tests/backend/helpers/test_yaml_set_helpers.h index a863c3b0..296b3577 100644 --- a/src/tests/backend/helpers/test_yaml_set_helpers.h +++ b/src/tests/backend/helpers/test_yaml_set_helpers.h @@ -28,92 +28,96 @@ along with LOOT. If not, see #include "backend/helpers/yaml_set_helpers.h" #include "tests/fixtures.h" -TEST(set, YamlEncode) { - YAML::Node node; - std::set stringSet({"a", "b", "c"}); - node = stringSet; - EXPECT_EQ("a", node[0].as()); - EXPECT_EQ("b", node[1].as()); - EXPECT_EQ("c", node[2].as()); -} +namespace loot { + namespace test { + TEST(set, YamlEncode) { + YAML::Node node; + std::set stringSet({"a", "b", "c"}); + node = stringSet; + EXPECT_EQ("a", node[0].as()); + EXPECT_EQ("b", node[1].as()); + EXPECT_EQ("c", node[2].as()); + } -TEST(set, YamlDecode) { - YAML::Node node; - std::set stringSet; + TEST(set, YamlDecode) { + YAML::Node node; + std::set stringSet; - node = YAML::Load("[a, b, c]"); - stringSet = node.as>(); - EXPECT_EQ(stringSet.begin(), stringSet.find("a")); - EXPECT_EQ(++stringSet.begin(), stringSet.find("b")); - EXPECT_EQ(--stringSet.end(), stringSet.find("c")); + node = YAML::Load("[a, b, c]"); + stringSet = node.as>(); + EXPECT_EQ(stringSet.begin(), stringSet.find("a")); + EXPECT_EQ(++stringSet.begin(), stringSet.find("b")); + EXPECT_EQ(--stringSet.end(), stringSet.find("c")); - node = YAML::Load("[a, b, c, c]"); - EXPECT_ANY_THROW(node.as>()); -} + node = YAML::Load("[a, b, c, c]"); + EXPECT_ANY_THROW(node.as>()); + } -TEST(set, YamlEmitter) { - std::set stringSet({"a", "b", "c"}); - YAML::Emitter e1; - e1 << stringSet; - EXPECT_STREQ("- a\n- b\n- c", e1.c_str()); -} + TEST(set, YamlEmitter) { + std::set stringSet({"a", "b", "c"}); + YAML::Emitter e1; + e1 << stringSet; + EXPECT_STREQ("- a\n- b\n- c", e1.c_str()); + } -bool nodeContains(const std::string& value, const YAML::Node& node) { - for (const auto& element : node) { - if (element.as() == value) - return true; + bool nodeContains(const std::string& value, const YAML::Node& node) { + for (const auto& element : node) { + if (element.as() == value) + return true; + } + return false; + } + + TEST(unordered_set, YamlEncode) { + YAML::Node node; + std::unordered_set stringSet({"a", "b", "c"}); + node = stringSet; + // Check that the values are all present in the node. + EXPECT_PRED2(nodeContains, "a", node); + EXPECT_PRED2(nodeContains, "b", node); + EXPECT_PRED2(nodeContains, "c", node); + } + + TEST(unordered_set, YAMLDecode) { + YAML::Node node; + std::unordered_set stringSet; + + node = YAML::Load("[a, b, c]"); + stringSet = node.as>(); + EXPECT_EQ(1, stringSet.count("a")); + EXPECT_EQ(1, stringSet.count("b")); + EXPECT_EQ(1, stringSet.count("c")); + + node = YAML::Load("[a, b, c, c]"); + EXPECT_ANY_THROW(node.as>()); + } + + bool sequenceOf(const char val1, + const char val2, + const char val3, + const std::string& seq) { + if (seq.substr(0, 2) != "- " + || seq.substr(3, 3) != "\n- " + || seq.substr(7, 3) != "\n- ") + return false; + + std::list values({val1, val2, val3}); + std::list found({seq[2], seq[6], seq[10]}); + + values.sort(); + found.sort(); + + return values == found; + } + + TEST(unordered_set, YamlEmitter) { + std::unordered_set stringSet({"a", "b", "c"}); + YAML::Emitter e1; + e1 << stringSet; + ASSERT_EQ(11, e1.size()); + EXPECT_PRED4(sequenceOf, 'a', 'b', 'c', e1.c_str()); + } } - return false; -} - -TEST(unordered_set, YamlEncode) { - YAML::Node node; - std::unordered_set stringSet({"a", "b", "c"}); - node = stringSet; - // Check that the values are all present in the node. - EXPECT_PRED2(nodeContains, "a", node); - EXPECT_PRED2(nodeContains, "b", node); - EXPECT_PRED2(nodeContains, "c", node); -} - -TEST(unordered_set, YAMLDecode) { - YAML::Node node; - std::unordered_set stringSet; - - node = YAML::Load("[a, b, c]"); - stringSet = node.as>(); - EXPECT_EQ(1, stringSet.count("a")); - EXPECT_EQ(1, stringSet.count("b")); - EXPECT_EQ(1, stringSet.count("c")); - - node = YAML::Load("[a, b, c, c]"); - EXPECT_ANY_THROW(node.as>()); -} - -bool sequenceOf(const char val1, - const char val2, - const char val3, - const std::string& seq) { - if (seq.substr(0, 2) != "- " - || seq.substr(3, 3) != "\n- " - || seq.substr(7, 3) != "\n- ") - return false; - - std::list values({val1, val2, val3}); - std::list found({seq[2], seq[6], seq[10]}); - - values.sort(); - found.sort(); - - return values == found; -} - -TEST(unordered_set, YamlEmitter) { - std::unordered_set stringSet({"a", "b", "c"}); - YAML::Emitter e1; - e1 << stringSet; - ASSERT_EQ(11, e1.size()); - EXPECT_PRED4(sequenceOf, 'a', 'b', 'c', e1.c_str()); } #endif diff --git a/src/tests/backend/metadata/test_condition_grammar.h b/src/tests/backend/metadata/test_condition_grammar.h index 876eaab4..61031f61 100644 --- a/src/tests/backend/metadata/test_condition_grammar.h +++ b/src/tests/backend/metadata/test_condition_grammar.h @@ -29,632 +29,636 @@ along with LOOT. If not, see #include "backend/metadata/condition_grammar.h" #include "tests/fixtures.h" -class ConditionGrammar : public SkyrimTest {}; +namespace loot { + namespace test { + class ConditionGrammarTest : public SkyrimTest {}; -typedef loot::ConditionGrammar Grammar; + typedef ConditionGrammar Grammar; -TEST_F(ConditionGrammar, Constructor) { - EXPECT_NO_THROW(Grammar cg(nullptr)); + TEST_F(ConditionGrammarTest, Constructor) { + EXPECT_NO_THROW(Grammar cg(nullptr)); - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); - EXPECT_NO_THROW(Grammar cg(&game)); -} + EXPECT_NO_THROW(Grammar cg(&game)); + } -TEST_F(ConditionGrammar, InvalidSyntax) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); + TEST_F(ConditionGrammarTest, InvalidSyntax) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); - boost::spirit::qi::space_type skipper; - bool eval = false; - bool r = false; - Grammar cg(&game); + boost::spirit::qi::space_type skipper; + bool eval = false; + bool r = false; + Grammar cg(&game); + + std::string condition("file(foo)"); + std::string::const_iterator begin = condition.begin(); + std::string::const_iterator end = condition.end(); + + EXPECT_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval), error); + } - std::string condition("file(foo)"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); + TEST_F(ConditionGrammarTest, EmptyCondition) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); - EXPECT_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval), loot::error); -} - -TEST_F(ConditionGrammar, EmptyCondition) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - - boost::spirit::qi::space_type skipper; - bool eval = false; - bool r = false; - Grammar cg(&game); - - std::string condition(""); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval), loot::error); -} - -TEST_F(ConditionGrammar, FileConditionTrue) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - - boost::spirit::qi::space_type skipper; - bool eval = false; - bool r = false; - Grammar cg(&game); - - std::string condition("file(\"Blank.esm\")"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval); - EXPECT_TRUE(r); - EXPECT_TRUE(eval); -} - -TEST_F(ConditionGrammar, FileConditionFalse) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - - boost::spirit::qi::space_type skipper; - bool eval = true; - bool r = false; - Grammar cg(&game); - - std::string condition("file(\"Blank.missing.esm\")"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_FALSE(eval); -} - -TEST_F(ConditionGrammar, UnsafePath) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - - boost::spirit::qi::space_type skipper; - bool eval = false; - bool r = false; - Grammar cg(&game); - - std::string condition("file(\"../../Blank.esm\")"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval), loot::error); -} - -TEST_F(ConditionGrammar, RegexConditionTrue) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - - boost::spirit::qi::space_type skipper; - bool eval = false; - bool r = false; - Grammar cg(&game); - - std::string condition("regex(\"Blank.+\\.esm\")"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_TRUE(eval); -} - -TEST_F(ConditionGrammar, RegexConditionFalse) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - - boost::spirit::qi::space_type skipper; - bool eval = true; - bool r = false; - Grammar cg(&game); - - std::string condition("regex(\"Blank\\.m.+\\.esm\")"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_FALSE(eval); -} - -TEST_F(ConditionGrammar, RegexCondition_Subfolder) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - - boost::spirit::qi::space_type skipper; - bool eval = true; - bool r = false; - Grammar cg(&game); - - std::string condition("regex(\"resource\\\\detail\\\\resource\\.txt\")"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_TRUE(eval); -} - -TEST_F(ConditionGrammar, ManyConditionTrue) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - - boost::spirit::qi::space_type skipper; - bool eval = false; - bool r = false; - Grammar cg(&game); - - std::string condition("many(\"Blank.+\\.esm\")"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_TRUE(eval); -} - -TEST_F(ConditionGrammar, ManyConditionFalse) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - - boost::spirit::qi::space_type skipper; - bool eval = true; - bool r = false; - Grammar cg(&game); - - std::string condition("many(\"Blank\\.esm\")"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_FALSE(eval); -} - -TEST_F(ConditionGrammar, ChecksumConditionTrue) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); - - boost::spirit::qi::space_type skipper; - bool eval = false; - bool r = false; - Grammar cg(&game); - - std::string condition("checksum(\"Blank.esp\", 24F0E2A1)"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_TRUE(eval); -} - -TEST_F(ConditionGrammar, ChecksumConditionFalse) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); - - boost::spirit::qi::space_type skipper; - bool eval = true; - bool r = false; - Grammar cg(&game); - - std::string condition("checksum(\"Blank.esp\", DEADBEEF)"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_FALSE(eval); -} - -TEST_F(ConditionGrammar, VersionConditionEqualTrue) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); - ASSERT_NO_THROW(game.LoadPlugins(true)); - - boost::spirit::qi::space_type skipper; - bool eval = false; - bool r = false; - Grammar cg(&game); - - std::string condition("version(\"Blank.esm\", \"5.0\", ==)"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_TRUE(eval); -} - -TEST_F(ConditionGrammar, VersionConditionEqualFalse) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); - ASSERT_NO_THROW(game.LoadPlugins(true)); - - boost::spirit::qi::space_type skipper; - bool eval = true; - bool r = false; - Grammar cg(&game); - - std::string condition("version(\"Blank.esm\", \"6.0\", ==)"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_FALSE(eval); -} - -TEST_F(ConditionGrammar, VersionConditionNotEqualTrue) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); - ASSERT_NO_THROW(game.LoadPlugins(true)); - - boost::spirit::qi::space_type skipper; - bool eval = false; - bool r = false; - Grammar cg(&game); - - std::string condition("version(\"Blank.esm\", \"6.0\", !=)"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_TRUE(eval); -} - -TEST_F(ConditionGrammar, VersionConditionNotEqualFalse) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); - ASSERT_NO_THROW(game.LoadPlugins(true)); - - boost::spirit::qi::space_type skipper; - bool eval = true; - bool r = false; - Grammar cg(&game); - - std::string condition("version(\"Blank.esm\", \"5.0\", !=)"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_FALSE(eval); -} - -TEST_F(ConditionGrammar, VersionConditionLessThanTrue) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); - ASSERT_NO_THROW(game.LoadPlugins(true)); - - boost::spirit::qi::space_type skipper; - bool eval = false; - bool r = false; - Grammar cg(&game); - - std::string condition("version(\"Blank.esm\", \"6.0\", <)"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_TRUE(eval); -} - -TEST_F(ConditionGrammar, VersionConditionLessThanFalse) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); - ASSERT_NO_THROW(game.LoadPlugins(true)); - - boost::spirit::qi::space_type skipper; - bool eval = true; - bool r = false; - Grammar cg(&game); - - std::string condition("version(\"Blank.esm\", \"5.0\", <)"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_FALSE(eval); -} - -TEST_F(ConditionGrammar, VersionConditionGreaterThanTrue) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); - ASSERT_NO_THROW(game.LoadPlugins(true)); - - boost::spirit::qi::space_type skipper; - bool eval = false; - bool r = false; - Grammar cg(&game); - - std::string condition("version(\"Blank.esm\", \"4.0\", >)"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_TRUE(eval); -} - -TEST_F(ConditionGrammar, VersionConditionGreaterThanFalse) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); - ASSERT_NO_THROW(game.LoadPlugins(true)); - - boost::spirit::qi::space_type skipper; - bool eval = true; - bool r = false; - Grammar cg(&game); - - std::string condition("version(\"Blank.esm\", \"5.0\", >)"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_FALSE(eval); -} - -TEST_F(ConditionGrammar, VersionConditionLETrue) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); - ASSERT_NO_THROW(game.LoadPlugins(true)); - - boost::spirit::qi::space_type skipper; - bool eval = false; - bool r = false; - Grammar cg(&game); - - std::string condition("version(\"Blank.esm\", \"5.0\", <=)"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_TRUE(eval); -} - -TEST_F(ConditionGrammar, VersionConditionLEFalse) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); - ASSERT_NO_THROW(game.LoadPlugins(true)); - - boost::spirit::qi::space_type skipper; - bool eval = true; - bool r = false; - Grammar cg(&game); - - std::string condition("version(\"Blank.esm\", \"4.0\", <=)"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_FALSE(eval); -} - -TEST_F(ConditionGrammar, VersionConditionGETrue) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); - ASSERT_NO_THROW(game.LoadPlugins(true)); - - boost::spirit::qi::space_type skipper; - bool eval = false; - bool r = false; - Grammar cg(&game); - - std::string condition("version(\"Blank.esm\", \"5.0\", >=)"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_TRUE(eval); -} - -TEST_F(ConditionGrammar, VersionConditionGEFalse) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.LoadPlugins(true)); - - boost::spirit::qi::space_type skipper; - bool eval = true; - bool r = false; - Grammar cg(&game); - - std::string condition("version(\"Blank.esm\", \"6.0\", >=)"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_FALSE(eval); -} - -TEST_F(ConditionGrammar, ActiveConditionTrue) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); - - boost::spirit::qi::space_type skipper; - bool eval = false; - bool r = false; - Grammar cg(&game); - - std::string condition("active(\"Blank.esm\")"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_TRUE(eval); -} - -TEST_F(ConditionGrammar, ActiveConditionFalse) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); - - boost::spirit::qi::space_type skipper; - bool eval = true; - bool r = false; - Grammar cg(&game); - - std::string condition("active(\"Blank.esp\")"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_FALSE(eval); -} - -TEST_F(ConditionGrammar, NegatorTrue) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - - boost::spirit::qi::space_type skipper; - bool eval = false; - bool r = false; - Grammar cg(&game); - - std::string condition("not file(\"Blank.missing.esm\")"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_TRUE(eval); -} - -TEST_F(ConditionGrammar, NegatorFalse) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - - boost::spirit::qi::space_type skipper; - bool eval = true; - bool r = false; - Grammar cg(&game); - - std::string condition("not file(\"Blank.esm\")"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_FALSE(eval); -} - -TEST_F(ConditionGrammar, CompoundAndTrue) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - - boost::spirit::qi::space_type skipper; - bool eval = true; - bool r = false; - Grammar cg(&game); - - std::string condition("file(\"Blank.esm\") and file(\"Blank.esp\")"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_TRUE(eval); -} - -TEST_F(ConditionGrammar, CompoundAndFalse) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - - boost::spirit::qi::space_type skipper; - bool eval = true; - bool r = false; - Grammar cg(&game); - - std::string condition("file(\"Blank.esm\") and file(\"Blank.missing.esp\")"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_FALSE(eval); -} - -TEST_F(ConditionGrammar, CompoundOrTrue) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - - boost::spirit::qi::space_type skipper; - bool eval = true; - bool r = false; - Grammar cg(&game); - - std::string condition("file(\"Blank.missing.esm\") or file(\"Blank.esp\")"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_TRUE(eval); -} - -TEST_F(ConditionGrammar, CompoundOrFalse) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - - boost::spirit::qi::space_type skipper; - bool eval = true; - bool r = false; - Grammar cg(&game); - - std::string condition("file(\"Blank.missing.esm\") or file(\"Blank.missing.esp\")"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_FALSE(eval); -} - -TEST_F(ConditionGrammar, OrderOfEvaluation) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - - boost::spirit::qi::space_type skipper; - bool eval = true; - bool r = false; - Grammar cg(&game); - - std::string condition("file(\"Blank.esm\") and ( not file(\"Blank.esm\") or file(\"Blank.esp\") ) or file(\"Blank.missing.esp\")"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_TRUE(eval); + boost::spirit::qi::space_type skipper; + bool eval = false; + bool r = false; + Grammar cg(&game); + + std::string condition(""); + std::string::const_iterator begin = condition.begin(); + std::string::const_iterator end = condition.end(); + + EXPECT_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval), error); + } + + TEST_F(ConditionGrammarTest, FileConditionTrue) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); + + boost::spirit::qi::space_type skipper; + bool eval = false; + bool r = false; + Grammar cg(&game); + + std::string condition("file(\"Blank.esm\")"); + std::string::const_iterator begin = condition.begin(); + std::string::const_iterator end = condition.end(); + + r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval); + EXPECT_TRUE(r); + EXPECT_TRUE(eval); + } + + TEST_F(ConditionGrammarTest, FileConditionFalse) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); + + boost::spirit::qi::space_type skipper; + bool eval = true; + bool r = false; + Grammar cg(&game); + + std::string condition("file(\"Blank.missing.esm\")"); + std::string::const_iterator begin = condition.begin(); + std::string::const_iterator end = condition.end(); + + EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); + EXPECT_TRUE(r); + EXPECT_FALSE(eval); + } + + TEST_F(ConditionGrammarTest, UnsafePath) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); + + boost::spirit::qi::space_type skipper; + bool eval = false; + bool r = false; + Grammar cg(&game); + + std::string condition("file(\"../../Blank.esm\")"); + std::string::const_iterator begin = condition.begin(); + std::string::const_iterator end = condition.end(); + + EXPECT_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval), error); + } + + TEST_F(ConditionGrammarTest, RegexConditionTrue) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); + + boost::spirit::qi::space_type skipper; + bool eval = false; + bool r = false; + Grammar cg(&game); + + std::string condition("regex(\"Blank.+\\.esm\")"); + std::string::const_iterator begin = condition.begin(); + std::string::const_iterator end = condition.end(); + + EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); + EXPECT_TRUE(r); + EXPECT_TRUE(eval); + } + + TEST_F(ConditionGrammarTest, RegexConditionFalse) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); + + boost::spirit::qi::space_type skipper; + bool eval = true; + bool r = false; + Grammar cg(&game); + + std::string condition("regex(\"Blank\\.m.+\\.esm\")"); + std::string::const_iterator begin = condition.begin(); + std::string::const_iterator end = condition.end(); + + EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); + EXPECT_TRUE(r); + EXPECT_FALSE(eval); + } + + TEST_F(ConditionGrammarTest, RegexCondition_Subfolder) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); + + boost::spirit::qi::space_type skipper; + bool eval = true; + bool r = false; + Grammar cg(&game); + + std::string condition("regex(\"resource\\\\detail\\\\resource\\.txt\")"); + std::string::const_iterator begin = condition.begin(); + std::string::const_iterator end = condition.end(); + + EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); + EXPECT_TRUE(r); + EXPECT_TRUE(eval); + } + + TEST_F(ConditionGrammarTest, ManyConditionTrue) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); + + boost::spirit::qi::space_type skipper; + bool eval = false; + bool r = false; + Grammar cg(&game); + + std::string condition("many(\"Blank.+\\.esm\")"); + std::string::const_iterator begin = condition.begin(); + std::string::const_iterator end = condition.end(); + + EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); + EXPECT_TRUE(r); + EXPECT_TRUE(eval); + } + + TEST_F(ConditionGrammarTest, ManyConditionFalse) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); + + boost::spirit::qi::space_type skipper; + bool eval = true; + bool r = false; + Grammar cg(&game); + + std::string condition("many(\"Blank\\.esm\")"); + std::string::const_iterator begin = condition.begin(); + std::string::const_iterator end = condition.end(); + + EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); + EXPECT_TRUE(r); + EXPECT_FALSE(eval); + } + + TEST_F(ConditionGrammarTest, ChecksumConditionTrue) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); + ASSERT_NO_THROW(game.Init(false, localPath)); + + boost::spirit::qi::space_type skipper; + bool eval = false; + bool r = false; + Grammar cg(&game); + + std::string condition("checksum(\"Blank.esp\", 24F0E2A1)"); + std::string::const_iterator begin = condition.begin(); + std::string::const_iterator end = condition.end(); + + EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); + EXPECT_TRUE(r); + EXPECT_TRUE(eval); + } + + TEST_F(ConditionGrammarTest, ChecksumConditionFalse) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); + ASSERT_NO_THROW(game.Init(false, localPath)); + + boost::spirit::qi::space_type skipper; + bool eval = true; + bool r = false; + Grammar cg(&game); + + std::string condition("checksum(\"Blank.esp\", DEADBEEF)"); + std::string::const_iterator begin = condition.begin(); + std::string::const_iterator end = condition.end(); + + EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); + EXPECT_TRUE(r); + EXPECT_FALSE(eval); + } + + TEST_F(ConditionGrammarTest, VersionConditionEqualTrue) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); + ASSERT_NO_THROW(game.Init(false, localPath)); + ASSERT_NO_THROW(game.LoadPlugins(true)); + + boost::spirit::qi::space_type skipper; + bool eval = false; + bool r = false; + Grammar cg(&game); + + std::string condition("version(\"Blank.esm\", \"5.0\", ==)"); + std::string::const_iterator begin = condition.begin(); + std::string::const_iterator end = condition.end(); + + EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); + EXPECT_TRUE(r); + EXPECT_TRUE(eval); + } + + TEST_F(ConditionGrammarTest, VersionConditionEqualFalse) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); + ASSERT_NO_THROW(game.Init(false, localPath)); + ASSERT_NO_THROW(game.LoadPlugins(true)); + + boost::spirit::qi::space_type skipper; + bool eval = true; + bool r = false; + Grammar cg(&game); + + std::string condition("version(\"Blank.esm\", \"6.0\", ==)"); + std::string::const_iterator begin = condition.begin(); + std::string::const_iterator end = condition.end(); + + EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); + EXPECT_TRUE(r); + EXPECT_FALSE(eval); + } + + TEST_F(ConditionGrammarTest, VersionConditionNotEqualTrue) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); + ASSERT_NO_THROW(game.Init(false, localPath)); + ASSERT_NO_THROW(game.LoadPlugins(true)); + + boost::spirit::qi::space_type skipper; + bool eval = false; + bool r = false; + Grammar cg(&game); + + std::string condition("version(\"Blank.esm\", \"6.0\", !=)"); + std::string::const_iterator begin = condition.begin(); + std::string::const_iterator end = condition.end(); + + EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); + EXPECT_TRUE(r); + EXPECT_TRUE(eval); + } + + TEST_F(ConditionGrammarTest, VersionConditionNotEqualFalse) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); + ASSERT_NO_THROW(game.Init(false, localPath)); + ASSERT_NO_THROW(game.LoadPlugins(true)); + + boost::spirit::qi::space_type skipper; + bool eval = true; + bool r = false; + Grammar cg(&game); + + std::string condition("version(\"Blank.esm\", \"5.0\", !=)"); + std::string::const_iterator begin = condition.begin(); + std::string::const_iterator end = condition.end(); + + EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); + EXPECT_TRUE(r); + EXPECT_FALSE(eval); + } + + TEST_F(ConditionGrammarTest, VersionConditionLessThanTrue) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); + ASSERT_NO_THROW(game.Init(false, localPath)); + ASSERT_NO_THROW(game.LoadPlugins(true)); + + boost::spirit::qi::space_type skipper; + bool eval = false; + bool r = false; + Grammar cg(&game); + + std::string condition("version(\"Blank.esm\", \"6.0\", <)"); + std::string::const_iterator begin = condition.begin(); + std::string::const_iterator end = condition.end(); + + EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); + EXPECT_TRUE(r); + EXPECT_TRUE(eval); + } + + TEST_F(ConditionGrammarTest, VersionConditionLessThanFalse) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); + ASSERT_NO_THROW(game.Init(false, localPath)); + ASSERT_NO_THROW(game.LoadPlugins(true)); + + boost::spirit::qi::space_type skipper; + bool eval = true; + bool r = false; + Grammar cg(&game); + + std::string condition("version(\"Blank.esm\", \"5.0\", <)"); + std::string::const_iterator begin = condition.begin(); + std::string::const_iterator end = condition.end(); + + EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); + EXPECT_TRUE(r); + EXPECT_FALSE(eval); + } + + TEST_F(ConditionGrammarTest, VersionConditionGreaterThanTrue) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); + ASSERT_NO_THROW(game.Init(false, localPath)); + ASSERT_NO_THROW(game.LoadPlugins(true)); + + boost::spirit::qi::space_type skipper; + bool eval = false; + bool r = false; + Grammar cg(&game); + + std::string condition("version(\"Blank.esm\", \"4.0\", >)"); + std::string::const_iterator begin = condition.begin(); + std::string::const_iterator end = condition.end(); + + EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); + EXPECT_TRUE(r); + EXPECT_TRUE(eval); + } + + TEST_F(ConditionGrammarTest, VersionConditionGreaterThanFalse) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); + ASSERT_NO_THROW(game.Init(false, localPath)); + ASSERT_NO_THROW(game.LoadPlugins(true)); + + boost::spirit::qi::space_type skipper; + bool eval = true; + bool r = false; + Grammar cg(&game); + + std::string condition("version(\"Blank.esm\", \"5.0\", >)"); + std::string::const_iterator begin = condition.begin(); + std::string::const_iterator end = condition.end(); + + EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); + EXPECT_TRUE(r); + EXPECT_FALSE(eval); + } + + TEST_F(ConditionGrammarTest, VersionConditionLETrue) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); + ASSERT_NO_THROW(game.Init(false, localPath)); + ASSERT_NO_THROW(game.LoadPlugins(true)); + + boost::spirit::qi::space_type skipper; + bool eval = false; + bool r = false; + Grammar cg(&game); + + std::string condition("version(\"Blank.esm\", \"5.0\", <=)"); + std::string::const_iterator begin = condition.begin(); + std::string::const_iterator end = condition.end(); + + EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); + EXPECT_TRUE(r); + EXPECT_TRUE(eval); + } + + TEST_F(ConditionGrammarTest, VersionConditionLEFalse) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); + ASSERT_NO_THROW(game.Init(false, localPath)); + ASSERT_NO_THROW(game.LoadPlugins(true)); + + boost::spirit::qi::space_type skipper; + bool eval = true; + bool r = false; + Grammar cg(&game); + + std::string condition("version(\"Blank.esm\", \"4.0\", <=)"); + std::string::const_iterator begin = condition.begin(); + std::string::const_iterator end = condition.end(); + + EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); + EXPECT_TRUE(r); + EXPECT_FALSE(eval); + } + + TEST_F(ConditionGrammarTest, VersionConditionGETrue) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); + ASSERT_NO_THROW(game.Init(false, localPath)); + ASSERT_NO_THROW(game.LoadPlugins(true)); + + boost::spirit::qi::space_type skipper; + bool eval = false; + bool r = false; + Grammar cg(&game); + + std::string condition("version(\"Blank.esm\", \"5.0\", >=)"); + std::string::const_iterator begin = condition.begin(); + std::string::const_iterator end = condition.end(); + + EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); + EXPECT_TRUE(r); + EXPECT_TRUE(eval); + } + + TEST_F(ConditionGrammarTest, VersionConditionGEFalse) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); + ASSERT_NO_THROW(game.LoadPlugins(true)); + + boost::spirit::qi::space_type skipper; + bool eval = true; + bool r = false; + Grammar cg(&game); + + std::string condition("version(\"Blank.esm\", \"6.0\", >=)"); + std::string::const_iterator begin = condition.begin(); + std::string::const_iterator end = condition.end(); + + EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); + EXPECT_TRUE(r); + EXPECT_FALSE(eval); + } + + TEST_F(ConditionGrammarTest, ActiveConditionTrue) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); + ASSERT_NO_THROW(game.Init(false, localPath)); + + boost::spirit::qi::space_type skipper; + bool eval = false; + bool r = false; + Grammar cg(&game); + + std::string condition("active(\"Blank.esm\")"); + std::string::const_iterator begin = condition.begin(); + std::string::const_iterator end = condition.end(); + + EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); + EXPECT_TRUE(r); + EXPECT_TRUE(eval); + } + + TEST_F(ConditionGrammarTest, ActiveConditionFalse) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); + ASSERT_NO_THROW(game.Init(false, localPath)); + + boost::spirit::qi::space_type skipper; + bool eval = true; + bool r = false; + Grammar cg(&game); + + std::string condition("active(\"Blank.esp\")"); + std::string::const_iterator begin = condition.begin(); + std::string::const_iterator end = condition.end(); + + EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); + EXPECT_TRUE(r); + EXPECT_FALSE(eval); + } + + TEST_F(ConditionGrammarTest, NegatorTrue) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); + + boost::spirit::qi::space_type skipper; + bool eval = false; + bool r = false; + Grammar cg(&game); + + std::string condition("not file(\"Blank.missing.esm\")"); + std::string::const_iterator begin = condition.begin(); + std::string::const_iterator end = condition.end(); + + EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); + EXPECT_TRUE(r); + EXPECT_TRUE(eval); + } + + TEST_F(ConditionGrammarTest, NegatorFalse) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); + + boost::spirit::qi::space_type skipper; + bool eval = true; + bool r = false; + Grammar cg(&game); + + std::string condition("not file(\"Blank.esm\")"); + std::string::const_iterator begin = condition.begin(); + std::string::const_iterator end = condition.end(); + + EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); + EXPECT_TRUE(r); + EXPECT_FALSE(eval); + } + + TEST_F(ConditionGrammarTest, CompoundAndTrue) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); + + boost::spirit::qi::space_type skipper; + bool eval = true; + bool r = false; + Grammar cg(&game); + + std::string condition("file(\"Blank.esm\") and file(\"Blank.esp\")"); + std::string::const_iterator begin = condition.begin(); + std::string::const_iterator end = condition.end(); + + EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); + EXPECT_TRUE(r); + EXPECT_TRUE(eval); + } + + TEST_F(ConditionGrammarTest, CompoundAndFalse) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); + + boost::spirit::qi::space_type skipper; + bool eval = true; + bool r = false; + Grammar cg(&game); + + std::string condition("file(\"Blank.esm\") and file(\"Blank.missing.esp\")"); + std::string::const_iterator begin = condition.begin(); + std::string::const_iterator end = condition.end(); + + EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); + EXPECT_TRUE(r); + EXPECT_FALSE(eval); + } + + TEST_F(ConditionGrammarTest, CompoundOrTrue) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); + + boost::spirit::qi::space_type skipper; + bool eval = true; + bool r = false; + Grammar cg(&game); + + std::string condition("file(\"Blank.missing.esm\") or file(\"Blank.esp\")"); + std::string::const_iterator begin = condition.begin(); + std::string::const_iterator end = condition.end(); + + EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); + EXPECT_TRUE(r); + EXPECT_TRUE(eval); + } + + TEST_F(ConditionGrammarTest, CompoundOrFalse) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); + + boost::spirit::qi::space_type skipper; + bool eval = true; + bool r = false; + Grammar cg(&game); + + std::string condition("file(\"Blank.missing.esm\") or file(\"Blank.missing.esp\")"); + std::string::const_iterator begin = condition.begin(); + std::string::const_iterator end = condition.end(); + + EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); + EXPECT_TRUE(r); + EXPECT_FALSE(eval); + } + + TEST_F(ConditionGrammarTest, OrderOfEvaluation) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); + + boost::spirit::qi::space_type skipper; + bool eval = true; + bool r = false; + Grammar cg(&game); + + std::string condition("file(\"Blank.esm\") and ( not file(\"Blank.esm\") or file(\"Blank.esp\") ) or file(\"Blank.missing.esp\")"); + std::string::const_iterator begin = condition.begin(); + std::string::const_iterator end = condition.end(); + + EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); + EXPECT_TRUE(r); + EXPECT_TRUE(eval); + } + } } #endif diff --git a/src/tests/backend/metadata/test_conditional_metadata.h b/src/tests/backend/metadata/test_conditional_metadata.h index 2d9ad8ce..e3c9b317 100644 --- a/src/tests/backend/metadata/test_conditional_metadata.h +++ b/src/tests/backend/metadata/test_conditional_metadata.h @@ -29,58 +29,62 @@ along with LOOT. If not, see #include "backend/metadata/conditional_metadata.h" #include "tests/fixtures.h" -class ConditionalMetadata : public SkyrimTest {}; +namespace loot { + namespace test { + class ConditionalMetadataTest : public SkyrimTest {}; -TEST_F(ConditionalMetadata, ConstructorAndDataAccess) { - loot::ConditionalMetadata cm; - EXPECT_EQ("", cm.Condition()); + TEST_F(ConditionalMetadataTest, ConstructorAndDataAccess) { + ConditionalMetadata cm; + EXPECT_EQ("", cm.Condition()); - cm = loot::ConditionalMetadata("condition"); - EXPECT_EQ("condition", cm.Condition()); -} + cm = ConditionalMetadata("condition"); + EXPECT_EQ("condition", cm.Condition()); + } -TEST_F(ConditionalMetadata, IsConditional) { - loot::ConditionalMetadata cm; - EXPECT_FALSE(cm.IsConditional()); + TEST_F(ConditionalMetadataTest, IsConditional) { + ConditionalMetadata cm; + EXPECT_FALSE(cm.IsConditional()); - cm = loot::ConditionalMetadata("condition"); - EXPECT_TRUE(cm.IsConditional()); -} + cm = ConditionalMetadata("condition"); + EXPECT_TRUE(cm.IsConditional()); + } -TEST_F(ConditionalMetadata, EvalCondition) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); + TEST_F(ConditionalMetadataTest, EvalCondition) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); + ASSERT_NO_THROW(game.Init(false, localPath)); - loot::ConditionalMetadata cm; - EXPECT_TRUE(cm.EvalCondition(game)); + ConditionalMetadata cm; + EXPECT_TRUE(cm.EvalCondition(game)); - cm = loot::ConditionalMetadata("condition"); - EXPECT_THROW(cm.EvalCondition(game), loot::error); + cm = ConditionalMetadata("condition"); + EXPECT_THROW(cm.EvalCondition(game), error); - cm = loot::ConditionalMetadata("file(\"Blank.esm\")"); - EXPECT_TRUE(cm.EvalCondition(game)); + cm = ConditionalMetadata("file(\"Blank.esm\")"); + EXPECT_TRUE(cm.EvalCondition(game)); - cm = loot::ConditionalMetadata("file(\"Blank.missing.esm\")"); - EXPECT_FALSE(cm.EvalCondition(game)); -} + cm = ConditionalMetadata("file(\"Blank.missing.esm\")"); + EXPECT_FALSE(cm.EvalCondition(game)); + } -TEST_F(ConditionalMetadata, ParseCondition) { - loot::ConditionalMetadata cm; - EXPECT_NO_THROW(cm.ParseCondition()); + TEST_F(ConditionalMetadataTest, ParseCondition) { + ConditionalMetadata cm; + EXPECT_NO_THROW(cm.ParseCondition()); - cm = loot::ConditionalMetadata("condition"); - EXPECT_THROW(cm.ParseCondition(), loot::error); + cm = ConditionalMetadata("condition"); + EXPECT_THROW(cm.ParseCondition(), error); - // Check that invalid regex also throws. - cm = loot::ConditionalMetadata("regex(\"RagnvaldBook(Farengar(+Ragnvald)?)?\\.esp\")"); - EXPECT_THROW(cm.ParseCondition(), loot::error); + // Check that invalid regex also throws. + cm = ConditionalMetadata("regex(\"RagnvaldBook(Farengar(+Ragnvald)?)?\\.esp\")"); + EXPECT_THROW(cm.ParseCondition(), error); - cm = loot::ConditionalMetadata("file(\"Blank.esm\")"); - EXPECT_NO_THROW(cm.ParseCondition()); + cm = ConditionalMetadata("file(\"Blank.esm\")"); + EXPECT_NO_THROW(cm.ParseCondition()); - cm = loot::ConditionalMetadata("file(\"Blank.missing.esm\")"); - EXPECT_NO_THROW(cm.ParseCondition()); + cm = ConditionalMetadata("file(\"Blank.missing.esm\")"); + EXPECT_NO_THROW(cm.ParseCondition()); + } + } } #endif diff --git a/src/tests/backend/metadata/test_file.h b/src/tests/backend/metadata/test_file.h index 65ede729..d9addd36 100644 --- a/src/tests/backend/metadata/test_file.h +++ b/src/tests/backend/metadata/test_file.h @@ -28,151 +28,153 @@ along with LOOT. If not, see #include "backend/metadata/file.h" #include "tests/fixtures.h" -using loot::File; +namespace loot { + namespace test { + TEST(File, ConstructorsAndDataAccess) { + File file; + EXPECT_EQ("", file.Name()); + EXPECT_EQ("", file.DisplayName()); + EXPECT_EQ("", file.Condition()); -TEST(File, ConstructorsAndDataAccess) { - File file; - EXPECT_EQ("", file.Name()); - EXPECT_EQ("", file.DisplayName()); - EXPECT_EQ("", file.Condition()); + file = File("name"); + EXPECT_EQ("name", file.Name()); + EXPECT_EQ("name", file.DisplayName()); + EXPECT_EQ("", file.Condition()); - file = File("name"); - EXPECT_EQ("name", file.Name()); - EXPECT_EQ("name", file.DisplayName()); - EXPECT_EQ("", file.Condition()); + file = File("name", "display"); + EXPECT_EQ("name", file.Name()); + EXPECT_EQ("display", file.DisplayName()); + EXPECT_EQ("", file.Condition()); - file = File("name", "display"); - EXPECT_EQ("name", file.Name()); - EXPECT_EQ("display", file.DisplayName()); - EXPECT_EQ("", file.Condition()); + // Not a valid condition, but not evaluating it in this test. + file = File("name", "display", "condition"); + EXPECT_EQ("name", file.Name()); + EXPECT_EQ("display", file.DisplayName()); + EXPECT_EQ("condition", file.Condition()); + } - // Not a valid condition, but not evaluating it in this test. - file = File("name", "display", "condition"); - EXPECT_EQ("name", file.Name()); - EXPECT_EQ("display", file.DisplayName()); - EXPECT_EQ("condition", file.Condition()); -} + TEST(File, EqualityOperator) { + File file1, file2; + EXPECT_TRUE(file1 == file2); -TEST(File, EqualityOperator) { - File file1, file2; - EXPECT_TRUE(file1 == file2); + // Not valid conditions, but not evaluating them in this test. + file1 = File("name", "display1", "condition1"); + file2 = File("name", "display2", "condition2"); + EXPECT_TRUE(file1 == file2); - // Not valid conditions, but not evaluating them in this test. - file1 = File("name", "display1", "condition1"); - file2 = File("name", "display2", "condition2"); - EXPECT_TRUE(file1 == file2); + file1 = File("name1"); + file2 = File("name2"); + EXPECT_FALSE(file1 == file2); + } - file1 = File("name1"); - file2 = File("name2"); - EXPECT_FALSE(file1 == file2); -} + TEST(File, LessThanOperator) { + File file1, file2; + EXPECT_FALSE(file1 < file2); + EXPECT_FALSE(file2 < file1); -TEST(File, LessThanOperator) { - File file1, file2; - EXPECT_FALSE(file1 < file2); - EXPECT_FALSE(file2 < file1); + file1 = File("name", "display1", "condition1"); + file2 = File("name", "display2", "condition2"); + EXPECT_FALSE(file1 < file2); + EXPECT_FALSE(file2 < file1); - file1 = File("name", "display1", "condition1"); - file2 = File("name", "display2", "condition2"); - EXPECT_FALSE(file1 < file2); - EXPECT_FALSE(file2 < file1); + file1 = File("name1"); + file2 = File("name2"); + EXPECT_TRUE(file1 < file2); + EXPECT_FALSE(file2 < file1); + } - file1 = File("name1"); - file2 = File("name2"); - EXPECT_TRUE(file1 < file2); - EXPECT_FALSE(file2 < file1); -} + TEST(File, YamlEmitter) { + File file("name1", "display1", "condition1"); -TEST(File, YamlEmitter) { - File file("name1", "display1", "condition1"); + YAML::Emitter e1; + e1 << file; + EXPECT_STREQ("name: 'name1'\ncondition: 'condition1'\ndisplay: 'display1'", e1.c_str()); - YAML::Emitter e1; - e1 << file; - EXPECT_STREQ("name: 'name1'\ncondition: 'condition1'\ndisplay: 'display1'", e1.c_str()); + file = File("name1"); + YAML::Emitter e2; + e2 << file; + EXPECT_STREQ("'name1'", e2.c_str()); - file = File("name1"); - YAML::Emitter e2; - e2 << file; - EXPECT_STREQ("'name1'", e2.c_str()); + file = File("name1", "", "condition1"); + YAML::Emitter e3; + e3 << file; + EXPECT_STREQ("name: 'name1'\ncondition: 'condition1'", e3.c_str()); - file = File("name1", "", "condition1"); - YAML::Emitter e3; - e3 << file; - EXPECT_STREQ("name: 'name1'\ncondition: 'condition1'", e3.c_str()); + file = File("name1", "display1"); + YAML::Emitter e4; + e4 << file; + EXPECT_STREQ("name: 'name1'\ndisplay: 'display1'", e4.c_str()); - file = File("name1", "display1"); - YAML::Emitter e4; - e4 << file; - EXPECT_STREQ("name: 'name1'\ndisplay: 'display1'", e4.c_str()); + file = File("name1", "name1"); + YAML::Emitter e5; + e5 << file; + EXPECT_STREQ("'name1'", e5.c_str()); - file = File("name1", "name1"); - YAML::Emitter e5; - e5 << file; - EXPECT_STREQ("'name1'", e5.c_str()); + file = File("name1", "name1", "condition1"); + YAML::Emitter e6; + e6 << file; + EXPECT_STREQ("name: 'name1'\ncondition: 'condition1'", e6.c_str()); + } - file = File("name1", "name1", "condition1"); - YAML::Emitter e6; - e6 << file; - EXPECT_STREQ("name: 'name1'\ncondition: 'condition1'", e6.c_str()); -} + TEST(File, YamlEncode) { + File file("name1", "display1", "condition1"); + YAML::Node node; + node = file; + EXPECT_EQ("name1", node["name"].as()); + EXPECT_EQ("display1", node["display"].as()); + EXPECT_EQ("condition1", node["condition"].as()); -TEST(File, YamlEncode) { - File file("name1", "display1", "condition1"); - YAML::Node node; - node = file; - EXPECT_EQ("name1", node["name"].as()); - EXPECT_EQ("display1", node["display"].as()); - EXPECT_EQ("condition1", node["condition"].as()); + file = File("name1"); + node = file; + EXPECT_EQ("name1", node["name"].as()); + EXPECT_FALSE(node["display"]); + EXPECT_FALSE(node["condition"]); - file = File("name1"); - node = file; - EXPECT_EQ("name1", node["name"].as()); - EXPECT_FALSE(node["display"]); - EXPECT_FALSE(node["condition"]); + file = File("name1", "name1"); + node = file; + EXPECT_EQ("name1", node["name"].as()); + EXPECT_FALSE(node["display"]); + EXPECT_FALSE(node["condition"]); - file = File("name1", "name1"); - node = file; - EXPECT_EQ("name1", node["name"].as()); - EXPECT_FALSE(node["display"]); - EXPECT_FALSE(node["condition"]); + file = File("name1", "display1"); + node = file; + EXPECT_EQ("name1", node["name"].as()); + EXPECT_EQ("display1", node["display"].as()); + EXPECT_FALSE(node["condition"]); + } - file = File("name1", "display1"); - node = file; - EXPECT_EQ("name1", node["name"].as()); - EXPECT_EQ("display1", node["display"].as()); - EXPECT_FALSE(node["condition"]); -} + TEST(File, YamlDecode) { + YAML::Node node = YAML::Load("{name: name1, display: display1, condition: 'file(\"Foo.esp\")'}"); + File file = node.as(); + EXPECT_EQ("name1", file.Name()); + EXPECT_EQ("display1", file.DisplayName()); + EXPECT_EQ("file(\"Foo.esp\")", file.Condition()); -TEST(File, YamlDecode) { - YAML::Node node = YAML::Load("{name: name1, display: display1, condition: 'file(\"Foo.esp\")'}"); - File file = node.as(); - EXPECT_EQ("name1", file.Name()); - EXPECT_EQ("display1", file.DisplayName()); - EXPECT_EQ("file(\"Foo.esp\")", file.Condition()); + node = YAML::Load("name1"); + file = node.as(); + EXPECT_EQ("name1", file.Name()); + EXPECT_EQ("name1", file.DisplayName()); + EXPECT_EQ("", file.Condition()); - node = YAML::Load("name1"); - file = node.as(); - EXPECT_EQ("name1", file.Name()); - EXPECT_EQ("name1", file.DisplayName()); - EXPECT_EQ("", file.Condition()); + node = YAML::Load("{name: name1, display: display1}"); + file = node.as(); + EXPECT_EQ("name1", file.Name()); + EXPECT_EQ("display1", file.DisplayName()); + EXPECT_EQ("", file.Condition()); - node = YAML::Load("{name: name1, display: display1}"); - file = node.as(); - EXPECT_EQ("name1", file.Name()); - EXPECT_EQ("display1", file.DisplayName()); - EXPECT_EQ("", file.Condition()); + node = YAML::Load("{name: name1, condition: 'file(\"Foo.esp\")'}"); + file = node.as(); + EXPECT_EQ("name1", file.Name()); + EXPECT_EQ("name1", file.DisplayName()); + EXPECT_EQ("file(\"Foo.esp\")", file.Condition()); - node = YAML::Load("{name: name1, condition: 'file(\"Foo.esp\")'}"); - file = node.as(); - EXPECT_EQ("name1", file.Name()); - EXPECT_EQ("name1", file.DisplayName()); - EXPECT_EQ("file(\"Foo.esp\")", file.Condition()); + node = YAML::Load("{name: name1, condition: invalid}"); + EXPECT_THROW(node.as(), YAML::RepresentationException); - node = YAML::Load("{name: name1, condition: invalid}"); - EXPECT_THROW(node.as(), YAML::RepresentationException); - - node = YAML::Load("[0, 1, 2]"); - EXPECT_ANY_THROW(node.as()); + node = YAML::Load("[0, 1, 2]"); + EXPECT_ANY_THROW(node.as()); + } + } } #endif diff --git a/src/tests/backend/metadata/test_location.h b/src/tests/backend/metadata/test_location.h index 2a25d5d0..f822f51e 100644 --- a/src/tests/backend/metadata/test_location.h +++ b/src/tests/backend/metadata/test_location.h @@ -28,100 +28,102 @@ along with LOOT. If not, see #include "backend/metadata/location.h" #include "tests/fixtures.h" -using loot::Location; +namespace loot { + namespace test { + TEST(Location, ConstructorsAndDataAccess) { + Location loc; + EXPECT_EQ("", loc.URL()); -TEST(Location, ConstructorsAndDataAccess) { - Location loc; - EXPECT_EQ("", loc.URL()); + loc = Location("http://www.example.com"); + EXPECT_EQ("http://www.example.com", loc.URL()); - loc = Location("http://www.example.com"); - EXPECT_EQ("http://www.example.com", loc.URL()); + loc = Location("http://www.example.com", "example"); + EXPECT_EQ("http://www.example.com", loc.URL()); + EXPECT_EQ("example", loc.Name()); + } - loc = Location("http://www.example.com", "example"); - EXPECT_EQ("http://www.example.com", loc.URL()); - EXPECT_EQ("example", loc.Name()); -} + TEST(Location, EqualityOperator) { + Location loc1, loc2; + EXPECT_TRUE(loc1 == loc2); -TEST(Location, EqualityOperator) { - Location loc1, loc2; - EXPECT_TRUE(loc1 == loc2); + loc1 = Location("http://www.example.com"); + loc2 = Location("HTTP://WWW.EXAMPLE.COM"); + EXPECT_TRUE(loc1 == loc2); - loc1 = Location("http://www.example.com"); - loc2 = Location("HTTP://WWW.EXAMPLE.COM"); - EXPECT_TRUE(loc1 == loc2); + loc1 = Location("http://www.example.com", "example1"); + loc2 = Location("http://www.example.com", "example2"); + EXPECT_TRUE(loc1 == loc2); - loc1 = Location("http://www.example.com", "example1"); - loc2 = Location("http://www.example.com", "example2"); - EXPECT_TRUE(loc1 == loc2); + loc1 = Location("http://www.example1.com"); + loc2 = Location("http://www.example2.com"); + EXPECT_FALSE(loc1 == loc2); + } - loc1 = Location("http://www.example1.com"); - loc2 = Location("http://www.example2.com"); - EXPECT_FALSE(loc1 == loc2); -} + TEST(Location, LessThanOperator) { + Location loc1, loc2; + EXPECT_FALSE(loc1 < loc2); + EXPECT_FALSE(loc2 < loc1); -TEST(Location, LessThanOperator) { - Location loc1, loc2; - EXPECT_FALSE(loc1 < loc2); - EXPECT_FALSE(loc2 < loc1); + loc1 = Location("http://www.example.com"); + loc2 = Location("HTTP://WWW.EXAMPLE.COM"); + EXPECT_FALSE(loc1 < loc2); + EXPECT_FALSE(loc2 < loc1); - loc1 = Location("http://www.example.com"); - loc2 = Location("HTTP://WWW.EXAMPLE.COM"); - EXPECT_FALSE(loc1 < loc2); - EXPECT_FALSE(loc2 < loc1); + loc1 = Location("http://www.example.com", "example1"); + loc2 = Location("http://www.example.com", "example2"); + EXPECT_FALSE(loc1 < loc2); + EXPECT_FALSE(loc2 < loc1); - loc1 = Location("http://www.example.com", "example1"); - loc2 = Location("http://www.example.com", "example2"); - EXPECT_FALSE(loc1 < loc2); - EXPECT_FALSE(loc2 < loc1); + loc1 = Location("http://www.example1.com"); + loc2 = Location("http://www.example2.com"); + EXPECT_TRUE(loc1 < loc2); + EXPECT_FALSE(loc2 < loc1); + } - loc1 = Location("http://www.example1.com"); - loc2 = Location("http://www.example2.com"); - EXPECT_TRUE(loc1 < loc2); - EXPECT_FALSE(loc2 < loc1); -} + TEST(Location, YamlEmitter) { + Location loc("http://www.example.com"); + YAML::Emitter e1; + e1 << loc; + EXPECT_STREQ("'http://www.example.com'", e1.c_str()); -TEST(Location, YamlEmitter) { - Location loc("http://www.example.com"); - YAML::Emitter e1; - e1 << loc; - EXPECT_STREQ("'http://www.example.com'", e1.c_str()); + loc = Location("http://www.example.com", "example"); + YAML::Emitter e2; + e2 << loc; + EXPECT_STREQ("link: 'http://www.example.com'\nname: 'example'", e2.c_str()); + } - loc = Location("http://www.example.com", "example"); - YAML::Emitter e2; - e2 << loc; - EXPECT_STREQ("link: 'http://www.example.com'\nname: 'example'", e2.c_str()); -} + TEST(Location, YamlEncode) { + YAML::Node node; -TEST(Location, YamlEncode) { - YAML::Node node; + Location loc("http://www.example.com"); + node = loc; + EXPECT_EQ("http://www.example.com", node["link"].as()); + EXPECT_FALSE(node["name"]); - Location loc("http://www.example.com"); - node = loc; - EXPECT_EQ("http://www.example.com", node["link"].as()); - EXPECT_FALSE(node["name"]); + loc = Location("http://www.example.com", "example"); + node = loc; + EXPECT_EQ("http://www.example.com", node["link"].as()); + EXPECT_EQ("example", node["name"].as()); + } - loc = Location("http://www.example.com", "example"); - node = loc; - EXPECT_EQ("http://www.example.com", node["link"].as()); - EXPECT_EQ("example", node["name"].as()); -} + TEST(Location, YamlDecode) { + YAML::Node node; + Location loc; -TEST(Location, YamlDecode) { - YAML::Node node; - Location loc; + node = YAML::Load("http://www.example.com"); + loc = node.as(); + EXPECT_EQ("http://www.example.com", loc.URL()); + EXPECT_EQ("", loc.Name()); - node = YAML::Load("http://www.example.com"); - loc = node.as(); - EXPECT_EQ("http://www.example.com", loc.URL()); - EXPECT_EQ("", loc.Name()); + node = YAML::Load("{link: http://www.example.com, name: example}"); + loc = node.as(); + EXPECT_EQ("http://www.example.com", loc.URL()); + EXPECT_EQ("example", loc.Name()); - node = YAML::Load("{link: http://www.example.com, name: example}"); - loc = node.as(); - EXPECT_EQ("http://www.example.com", loc.URL()); - EXPECT_EQ("example", loc.Name()); - - node = YAML::Load("[0, 1, 2]"); - EXPECT_ANY_THROW(node.as()); + node = YAML::Load("[0, 1, 2]"); + EXPECT_ANY_THROW(node.as()); + } + } } #endif diff --git a/src/tests/backend/metadata/test_message.h b/src/tests/backend/metadata/test_message.h index 7d379c0a..666e5880 100644 --- a/src/tests/backend/metadata/test_message.h +++ b/src/tests/backend/metadata/test_message.h @@ -28,393 +28,394 @@ along with LOOT. If not, see #include "backend/metadata/message.h" #include "tests/fixtures.h" -class Message : public SkyrimTest {}; +namespace loot { + namespace test { + class MessageTest : public SkyrimTest {}; -using loot::MessageContent; -using loot::Language; + typedef std::vector MessageContents; -typedef std::vector MessageContents; + TEST_F(MessageTest, ConstructorsAndDataAccess) { + Message message; + EXPECT_EQ(Message::say, message.Type()); + EXPECT_EQ(MessageContents(), message.Content()); -TEST_F(Message, ConstructorsAndDataAccess) { - loot::Message message; - EXPECT_EQ(loot::Message::say, message.Type()); - EXPECT_EQ(MessageContents(), message.Content()); + message = Message(Message::say, "content1", "condition1"); + EXPECT_EQ(Message::say, message.Type()); + EXPECT_EQ(MessageContents({ + MessageContent("content1", Language::english) + }), message.Content()); + EXPECT_EQ("condition1", message.Condition()); - message = loot::Message(loot::Message::say, "content1", "condition1"); - EXPECT_EQ(loot::Message::say, message.Type()); - EXPECT_EQ(MessageContents({ - MessageContent("content1", Language::english) - }), message.Content()); - EXPECT_EQ("condition1", message.Condition()); + MessageContents mc({MessageContent("content1", Language::english)}); + message = Message(Message::say, mc, "condition1"); + EXPECT_EQ(Message::say, message.Type()); + EXPECT_EQ(mc, message.Content()); + EXPECT_EQ("condition1", message.Condition()); + } - MessageContents mc({MessageContent("content1", Language::english)}); - message = loot::Message(loot::Message::say, mc, "condition1"); - EXPECT_EQ(loot::Message::say, message.Type()); - EXPECT_EQ(mc, message.Content()); - EXPECT_EQ("condition1", message.Condition()); -} + TEST_F(MessageTest, EqualityOperator) { + Message message1, message2; + EXPECT_TRUE(message1 == message2); -TEST_F(Message, EqualityOperator) { - loot::Message message1, message2; - EXPECT_TRUE(message1 == message2); + message1 = Message(Message::say, "content1", "condition1"); + message2 = Message(Message::say, "content1", "condition2"); + EXPECT_TRUE(message1 == message2); - message1 = loot::Message(loot::Message::say, "content1", "condition1"); - message2 = loot::Message(loot::Message::say, "content1", "condition2"); - EXPECT_TRUE(message1 == message2); + message1 = Message(Message::say, "content1", "condition1"); + message2 = Message(Message::say, "content2", "condition1"); + EXPECT_FALSE(message1 == message2); - message1 = loot::Message(loot::Message::say, "content1", "condition1"); - message2 = loot::Message(loot::Message::say, "content2", "condition1"); - EXPECT_FALSE(message1 == message2); + message1 = Message(Message::say, "content1", "condition1"); + message2 = Message(Message::warn, "content1", "condition1"); + EXPECT_TRUE(message1 == message2); - message1 = loot::Message(loot::Message::say, "content1", "condition1"); - message2 = loot::Message(loot::Message::warn, "content1", "condition1"); - EXPECT_TRUE(message1 == message2); + message1 = Message(Message::say, "content1", "condition1"); + message2 = Message(Message::say, MessageContents({MessageContent("content1", Language::english)}), "condition1"); + EXPECT_TRUE(message1 == message2); - message1 = loot::Message(loot::Message::say, "content1", "condition1"); - message2 = loot::Message(loot::Message::say, MessageContents({MessageContent("content1", Language::english)}), "condition1"); - EXPECT_TRUE(message1 == message2); + message1 = Message(Message::say, "content1", "condition1"); + message2 = Message(Message::say, MessageContents({MessageContent("content2", Language::english)}), "condition1"); + EXPECT_FALSE(message1 == message2); - message1 = loot::Message(loot::Message::say, "content1", "condition1"); - message2 = loot::Message(loot::Message::say, MessageContents({MessageContent("content2", Language::english)}), "condition1"); - EXPECT_FALSE(message1 == message2); + message1 = Message(Message::say, MessageContents({MessageContent("content1", Language::english)}), "condition1"); + message2 = Message(Message::say, MessageContents({MessageContent("content1", Language::english)}), "condition1"); + EXPECT_TRUE(message1 == message2); - message1 = loot::Message(loot::Message::say, MessageContents({MessageContent("content1", Language::english)}), "condition1"); - message2 = loot::Message(loot::Message::say, MessageContents({MessageContent("content1", Language::english)}), "condition1"); - EXPECT_TRUE(message1 == message2); + message1 = Message(Message::say, MessageContents({MessageContent("content1", Language::english)}), "condition1"); + message2 = Message(Message::say, MessageContents({MessageContent("content2", Language::english)}), "condition1"); + EXPECT_FALSE(message1 == message2); - message1 = loot::Message(loot::Message::say, MessageContents({MessageContent("content1", Language::english)}), "condition1"); - message2 = loot::Message(loot::Message::say, MessageContents({MessageContent("content2", Language::english)}), "condition1"); - EXPECT_FALSE(message1 == message2); + message1 = Message(Message::say, MessageContents({MessageContent("content1", Language::english)}), "condition1"); + message2 = Message(Message::say, MessageContents({MessageContent("content1", Language::french)}), "condition1"); + EXPECT_TRUE(message1 == message2); + } - message1 = loot::Message(loot::Message::say, MessageContents({MessageContent("content1", Language::english)}), "condition1"); - message2 = loot::Message(loot::Message::say, MessageContents({MessageContent("content1", Language::french)}), "condition1"); - EXPECT_TRUE(message1 == message2); -} + TEST_F(MessageTest, LessThanOperator) { + Message message1, message2; + EXPECT_FALSE(message1 < message2); + EXPECT_FALSE(message2 < message1); -TEST_F(Message, LessThanOperator) { - loot::Message message1, message2; - EXPECT_FALSE(message1 < message2); - EXPECT_FALSE(message2 < message1); + message1 = Message(Message::say, "content1", "condition1"); + message2 = Message(Message::say, "content1", "condition1"); + EXPECT_FALSE(message1 < message2); + EXPECT_FALSE(message2 < message1); - message1 = loot::Message(loot::Message::say, "content1", "condition1"); - message2 = loot::Message(loot::Message::say, "content1", "condition1"); - EXPECT_FALSE(message1 < message2); - EXPECT_FALSE(message2 < message1); + message1 = Message(Message::say, "content1", "condition1"); + message2 = Message(Message::say, "content1", "condition2"); + EXPECT_FALSE(message1 < message2); + EXPECT_FALSE(message2 < message1); - message1 = loot::Message(loot::Message::say, "content1", "condition1"); - message2 = loot::Message(loot::Message::say, "content1", "condition2"); - EXPECT_FALSE(message1 < message2); - EXPECT_FALSE(message2 < message1); + message1 = Message(Message::say, "content1", "condition1"); + message2 = Message(Message::warn, "content1", "condition1"); + EXPECT_FALSE(message1 < message2); + EXPECT_FALSE(message2 < message1); - message1 = loot::Message(loot::Message::say, "content1", "condition1"); - message2 = loot::Message(loot::Message::warn, "content1", "condition1"); - EXPECT_FALSE(message1 < message2); - EXPECT_FALSE(message2 < message1); + message1 = Message(Message::say, "", "condition1"); + message2 = Message(Message::say, "content1", "condition1"); + EXPECT_TRUE(message1 < message2); + EXPECT_FALSE(message2 < message1); - message1 = loot::Message(loot::Message::say, "", "condition1"); - message2 = loot::Message(loot::Message::say, "content1", "condition1"); - EXPECT_TRUE(message1 < message2); - EXPECT_FALSE(message2 < message1); + message1 = Message(Message::say, "content1", "condition1"); + message2 = Message(Message::say, "", "condition1"); + EXPECT_FALSE(message1 < message2); + EXPECT_TRUE(message2 < message1); - message1 = loot::Message(loot::Message::say, "content1", "condition1"); - message2 = loot::Message(loot::Message::say, "", "condition1"); - EXPECT_FALSE(message1 < message2); - EXPECT_TRUE(message2 < message1); + message1 = Message(Message::say, "content1", "condition1"); + message2 = Message(Message::say, MessageContents({MessageContent("content1", Language::english)}), "condition1"); + EXPECT_FALSE(message1 < message2); + EXPECT_FALSE(message2 < message1); - message1 = loot::Message(loot::Message::say, "content1", "condition1"); - message2 = loot::Message(loot::Message::say, MessageContents({MessageContent("content1", Language::english)}), "condition1"); - EXPECT_FALSE(message1 < message2); - EXPECT_FALSE(message2 < message1); + message1 = Message(Message::say, "content1", "condition1"); + message2 = Message(Message::say, MessageContents({MessageContent("content2", Language::english)}), "condition1"); + EXPECT_TRUE(message1 < message2); + EXPECT_FALSE(message2 < message1); - message1 = loot::Message(loot::Message::say, "content1", "condition1"); - message2 = loot::Message(loot::Message::say, MessageContents({MessageContent("content2", Language::english)}), "condition1"); - EXPECT_TRUE(message1 < message2); - EXPECT_FALSE(message2 < message1); + message1 = Message(Message::say, MessageContents({MessageContent("content1", Language::english)}), "condition1"); + message2 = Message(Message::say, MessageContents({MessageContent("content1", Language::english)}), "condition1"); + EXPECT_FALSE(message1 < message2); + EXPECT_FALSE(message2 < message1); - message1 = loot::Message(loot::Message::say, MessageContents({MessageContent("content1", Language::english)}), "condition1"); - message2 = loot::Message(loot::Message::say, MessageContents({MessageContent("content1", Language::english)}), "condition1"); - EXPECT_FALSE(message1 < message2); - EXPECT_FALSE(message2 < message1); + message1 = Message(Message::say, MessageContents({MessageContent("content1", Language::english)}), "condition1"); + message2 = Message(Message::say, MessageContents({MessageContent("content2", Language::english)}), "condition1"); + EXPECT_TRUE(message1 < message2); + EXPECT_FALSE(message2 < message1); - message1 = loot::Message(loot::Message::say, MessageContents({MessageContent("content1", Language::english)}), "condition1"); - message2 = loot::Message(loot::Message::say, MessageContents({MessageContent("content2", Language::english)}), "condition1"); - EXPECT_TRUE(message1 < message2); - EXPECT_FALSE(message2 < message1); + message1 = Message(Message::say, MessageContents({MessageContent("content1", Language::english)}), "condition1"); + message2 = Message(Message::say, MessageContents({MessageContent("content1", Language::french)}), "condition1"); + EXPECT_FALSE(message1 < message2); + EXPECT_FALSE(message2 < message1); + } - message1 = loot::Message(loot::Message::say, MessageContents({MessageContent("content1", Language::english)}), "condition1"); - message2 = loot::Message(loot::Message::say, MessageContents({MessageContent("content1", Language::french)}), "condition1"); - EXPECT_FALSE(message1 < message2); - EXPECT_FALSE(message2 < message1); -} + TEST_F(MessageTest, EvalCondition) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); + ASSERT_NO_THROW(game.Init(false, localPath)); -TEST_F(Message, EvalCondition) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); + Message message; + EXPECT_TRUE(message.EvalCondition(game, Language::any)); + EXPECT_EQ(1, message.Content().size()); - loot::Message message; - EXPECT_TRUE(message.EvalCondition(game, Language::any)); - EXPECT_EQ(1, message.Content().size()); + message = Message(Message::say, MessageContents({ + MessageContent("content1", Language::german), + MessageContent("content1", Language::english), + MessageContent("content1", Language::french), + })); + EXPECT_TRUE(message.EvalCondition(game, Language::french)); + EXPECT_EQ(1, message.Content().size()); + } - message = loot::Message(loot::Message::say, MessageContents({ - MessageContent("content1", Language::german), - MessageContent("content1", Language::english), - MessageContent("content1", Language::french), - })); - EXPECT_TRUE(message.EvalCondition(game, Language::french)); - EXPECT_EQ(1, message.Content().size()); -} + TEST_F(MessageTest, ChooseContent) { + MessageContent mc; + Message message; + EXPECT_EQ(mc, message.ChooseContent(Language::any)); + EXPECT_EQ(mc, message.ChooseContent(Language::french)); + EXPECT_EQ(mc, message.ChooseContent(Language::english)); -TEST_F(Message, ChooseContent) { - MessageContent mc; - loot::Message message; - EXPECT_EQ(mc, message.ChooseContent(Language::any)); - EXPECT_EQ(mc, message.ChooseContent(Language::french)); - EXPECT_EQ(mc, message.ChooseContent(Language::english)); + mc = MessageContent("content1", Language::english); + message = Message(Message::say, "content1"); + EXPECT_EQ(mc, message.ChooseContent(Language::any)); + EXPECT_EQ(mc, message.ChooseContent(Language::french)); + EXPECT_EQ(mc, message.ChooseContent(Language::english)); - mc = MessageContent("content1", Language::english); - message = loot::Message(loot::Message::say, "content1"); - EXPECT_EQ(mc, message.ChooseContent(Language::any)); - EXPECT_EQ(mc, message.ChooseContent(Language::french)); - EXPECT_EQ(mc, message.ChooseContent(Language::english)); + mc = MessageContent("content1", Language::english); + message = Message(Message::say, MessageContents({mc})); + EXPECT_EQ(mc, message.ChooseContent(Language::any)); + EXPECT_EQ(mc, message.ChooseContent(Language::french)); + EXPECT_EQ(mc, message.ChooseContent(Language::english)); - mc = MessageContent("content1", Language::english); - message = loot::Message(loot::Message::say, MessageContents({mc})); - EXPECT_EQ(mc, message.ChooseContent(Language::any)); - EXPECT_EQ(mc, message.ChooseContent(Language::french)); - EXPECT_EQ(mc, message.ChooseContent(Language::english)); + mc = MessageContent("content1", Language::english); + message = Message(Message::say, MessageContents({ + MessageContent("content1", Language::english), + MessageContent("content1", Language::german), + })); + EXPECT_EQ(mc, message.ChooseContent(Language::any)); + EXPECT_EQ(mc, message.ChooseContent(Language::french)); + EXPECT_EQ(mc, message.ChooseContent(Language::english)); - mc = MessageContent("content1", Language::english); - message = loot::Message(loot::Message::say, MessageContents({ - MessageContent("content1", Language::english), - MessageContent("content1", Language::german), - })); - EXPECT_EQ(mc, message.ChooseContent(Language::any)); - EXPECT_EQ(mc, message.ChooseContent(Language::french)); - EXPECT_EQ(mc, message.ChooseContent(Language::english)); + message = Message(Message::say, MessageContents({ + MessageContent("content1", Language::german), + MessageContent("content1", Language::english), + MessageContent("content1", Language::french), + })); + EXPECT_EQ(MessageContent("content1", Language::german), message.ChooseContent(Language::any)); + EXPECT_EQ(MessageContent("content1", Language::french), message.ChooseContent(Language::french)); + EXPECT_EQ(MessageContent("content1", Language::english), message.ChooseContent(Language::english)); - message = loot::Message(loot::Message::say, MessageContents({ - MessageContent("content1", Language::german), - MessageContent("content1", Language::english), - MessageContent("content1", Language::french), - })); - EXPECT_EQ(MessageContent("content1", Language::german), message.ChooseContent(Language::any)); - EXPECT_EQ(MessageContent("content1", Language::french), message.ChooseContent(Language::french)); - EXPECT_EQ(MessageContent("content1", Language::english), message.ChooseContent(Language::english)); + mc = MessageContent("content1", Language::german); + message = Message(Message::say, MessageContents({mc})); + EXPECT_EQ(mc, message.ChooseContent(Language::any)); + EXPECT_EQ(mc, message.ChooseContent(Language::french)); + } - mc = MessageContent("content1", Language::german); - message = loot::Message(loot::Message::say, MessageContents({mc})); - EXPECT_EQ(mc, message.ChooseContent(Language::any)); - EXPECT_EQ(mc, message.ChooseContent(Language::french)); -} + TEST_F(MessageTest, YamlEmitter) { + Message message(Message::say, "content1"); + YAML::Emitter e1; + e1 << message; + EXPECT_STREQ("type: say\n" + "content: 'content1'", e1.c_str()); -TEST_F(Message, YamlEmitter) { - loot::Message message(loot::Message::say, "content1"); - YAML::Emitter e1; - e1 << message; - EXPECT_STREQ("type: say\n" - "content: 'content1'", e1.c_str()); + message = Message(Message::warn, "content1"); + YAML::Emitter e2; + e2 << message; + EXPECT_STREQ("type: warn\n" + "content: 'content1'", e2.c_str()); - message = loot::Message(loot::Message::warn, "content1"); - YAML::Emitter e2; - e2 << message; - EXPECT_STREQ("type: warn\n" - "content: 'content1'", e2.c_str()); + message = Message(Message::error, "content1"); + YAML::Emitter e3; + e3 << message; + EXPECT_STREQ("type: error\n" + "content: 'content1'", e3.c_str()); - message = loot::Message(loot::Message::error, "content1"); - YAML::Emitter e3; - e3 << message; - EXPECT_STREQ("type: error\n" - "content: 'content1'", e3.c_str()); + message = Message(Message::say, "content1", "condition1"); + YAML::Emitter e4; + e4 << message; + EXPECT_STREQ("type: say\n" + "content: 'content1'\n" + "condition: 'condition1'", e4.c_str()); - message = loot::Message(loot::Message::say, "content1", "condition1"); - YAML::Emitter e4; - e4 << message; - EXPECT_STREQ("type: say\n" - "content: 'content1'\n" - "condition: 'condition1'", e4.c_str()); + message = Message(Message::say, MessageContents({ + MessageContent("content1", Language::english), + })); + YAML::Emitter e5; + e5 << message; + EXPECT_STREQ("type: say\n" + "content: 'content1'", e5.c_str()); - message = loot::Message(loot::Message::say, MessageContents({ - MessageContent("content1", Language::english), - })); - YAML::Emitter e5; - e5 << message; - EXPECT_STREQ("type: say\n" - "content: 'content1'", e5.c_str()); + message = Message(Message::say, MessageContents({ + MessageContent("content1", Language::english), + MessageContent("content2", Language::german) + })); + YAML::Emitter e6; + e6 << message; + EXPECT_STREQ("type: say\n" + "content:\n" + " - lang: en\n" + " str: 'content1'\n" + " - lang: de\n" + " str: 'content2'", e6.c_str()); + } - message = loot::Message(loot::Message::say, MessageContents({ - MessageContent("content1", Language::english), - MessageContent("content2", Language::german) - })); - YAML::Emitter e6; - e6 << message; - EXPECT_STREQ("type: say\n" - "content:\n" - " - lang: en\n" - " str: 'content1'\n" - " - lang: de\n" - " str: 'content2'", e6.c_str()); -} + TEST_F(MessageTest, YamlEncode) { + YAML::Node node; -TEST_F(Message, YamlEncode) { - YAML::Node node; + MessageContents mcs({MessageContent("content1", Language::english)}); + Message message(Message::say, "content1"); + node = message; + EXPECT_EQ("say", node["type"].as()); + EXPECT_EQ(mcs, node["content"].as()); + EXPECT_FALSE(node["condition"]); - MessageContents mcs({MessageContent("content1", Language::english)}); - loot::Message message(loot::Message::say, "content1"); - node = message; - EXPECT_EQ("say", node["type"].as()); - EXPECT_EQ(mcs, node["content"].as()); - EXPECT_FALSE(node["condition"]); + message = Message(Message::warn, "content1"); + node = message; + EXPECT_EQ("warn", node["type"].as()); + EXPECT_EQ(mcs, node["content"].as()); + EXPECT_FALSE(node["condition"]); - message = loot::Message(loot::Message::warn, "content1"); - node = message; - EXPECT_EQ("warn", node["type"].as()); - EXPECT_EQ(mcs, node["content"].as()); - EXPECT_FALSE(node["condition"]); + message = Message(Message::error, "content1"); + node = message; + EXPECT_EQ("error", node["type"].as()); + EXPECT_EQ(mcs, node["content"].as()); + EXPECT_FALSE(node["condition"]); - message = loot::Message(loot::Message::error, "content1"); - node = message; - EXPECT_EQ("error", node["type"].as()); - EXPECT_EQ(mcs, node["content"].as()); - EXPECT_FALSE(node["condition"]); + message = Message(Message::say, "content1", "condition1"); + node = message; + EXPECT_EQ("say", node["type"].as()); + EXPECT_EQ(mcs, node["content"].as()); + EXPECT_EQ("condition1", node["condition"].as()); - message = loot::Message(loot::Message::say, "content1", "condition1"); - node = message; - EXPECT_EQ("say", node["type"].as()); - EXPECT_EQ(mcs, node["content"].as()); - EXPECT_EQ("condition1", node["condition"].as()); + mcs = MessageContents({ + MessageContent("content1", Language::english), + MessageContent("content2", Language::french), + }); + message = Message(Message::say, mcs); + node = message; + EXPECT_EQ("say", node["type"].as()); + EXPECT_EQ(mcs, node["content"].as()); + EXPECT_FALSE(node["condition"]); + } - mcs = MessageContents({ - MessageContent("content1", Language::english), - MessageContent("content2", Language::french), - }); - message = loot::Message(loot::Message::say, mcs); - node = message; - EXPECT_EQ("say", node["type"].as()); - EXPECT_EQ(mcs, node["content"].as()); - EXPECT_FALSE(node["condition"]); -} + TEST_F(MessageTest, YamlDecode) { + YAML::Node node = YAML::Load("type: say\n" + "content: content1"); + Message message = node.as(); + EXPECT_EQ(Message::say, message.Type()); + EXPECT_EQ(MessageContents({MessageContent("content1", Language::english)}), message.Content()); + EXPECT_EQ("", message.Condition()); -TEST_F(Message, YamlDecode) { - YAML::Node node = YAML::Load("type: say\n" - "content: content1"); - loot::Message message = node.as(); - EXPECT_EQ(loot::Message::say, message.Type()); - EXPECT_EQ(MessageContents({MessageContent("content1", Language::english)}), message.Content()); - EXPECT_EQ("", message.Condition()); + node = YAML::Load("type: warn\n" + "content: content1"); + message = node.as(); + EXPECT_EQ(Message::warn, message.Type()); + EXPECT_EQ(MessageContents({MessageContent("content1", Language::english)}), message.Content()); + EXPECT_EQ("", message.Condition()); - node = YAML::Load("type: warn\n" - "content: content1"); - message = node.as(); - EXPECT_EQ(loot::Message::warn, message.Type()); - EXPECT_EQ(MessageContents({MessageContent("content1", Language::english)}), message.Content()); - EXPECT_EQ("", message.Condition()); + node = YAML::Load("type: error\n" + "content: content1"); + message = node.as(); + EXPECT_EQ(Message::error, message.Type()); + EXPECT_EQ(MessageContents({MessageContent("content1", Language::english)}), message.Content()); + EXPECT_EQ("", message.Condition()); - node = YAML::Load("type: error\n" - "content: content1"); - message = node.as(); - EXPECT_EQ(loot::Message::error, message.Type()); - EXPECT_EQ(MessageContents({MessageContent("content1", Language::english)}), message.Content()); - EXPECT_EQ("", message.Condition()); + node = YAML::Load("type: invalid\n" + "content: content1"); + message = node.as(); + EXPECT_EQ(Message::say, message.Type()); + EXPECT_EQ(MessageContents({MessageContent("content1", Language::english)}), message.Content()); + EXPECT_EQ("", message.Condition()); - node = YAML::Load("type: invalid\n" - "content: content1"); - message = node.as(); - EXPECT_EQ(loot::Message::say, message.Type()); - EXPECT_EQ(MessageContents({MessageContent("content1", Language::english)}), message.Content()); - EXPECT_EQ("", message.Condition()); + node = YAML::Load("type: say\n" + "content: content1\n" + "condition: 'file(\"Foo.esp\")'"); + message = node.as(); + EXPECT_EQ(Message::say, message.Type()); + EXPECT_EQ(MessageContents({MessageContent("content1", Language::english)}), message.Content()); + EXPECT_EQ("file(\"Foo.esp\")", message.Condition()); - node = YAML::Load("type: say\n" - "content: content1\n" - "condition: 'file(\"Foo.esp\")'"); - message = node.as(); - EXPECT_EQ(loot::Message::say, message.Type()); - EXPECT_EQ(MessageContents({MessageContent("content1", Language::english)}), message.Content()); - EXPECT_EQ("file(\"Foo.esp\")", message.Condition()); + node = YAML::Load("type: say\n" + "content:\n" + " - lang: en\n" + " str: content1\n" + " - lang: de\n" + " str: content2"); + message = node.as(); + EXPECT_EQ(Message::say, message.Type()); + EXPECT_EQ(MessageContents({ + MessageContent("content1", Language::english), + MessageContent("content2", Language::german), + }), message.Content()); + EXPECT_EQ("", message.Condition()); - node = YAML::Load("type: say\n" - "content:\n" - " - lang: en\n" - " str: content1\n" - " - lang: de\n" - " str: content2"); - message = node.as(); - EXPECT_EQ(loot::Message::say, message.Type()); - EXPECT_EQ(MessageContents({ - MessageContent("content1", Language::english), - MessageContent("content2", Language::german), - }), message.Content()); - EXPECT_EQ("", message.Condition()); + node = YAML::Load("type: say\n" + "content:\n" + " - lang: fr\n" + " str: content1"); + message = node.as(); + EXPECT_EQ(Message::say, message.Type()); + EXPECT_EQ(MessageContents({MessageContent("content1", Language::french)}), message.Content()); + EXPECT_EQ("", message.Condition()); - node = YAML::Load("type: say\n" - "content:\n" - " - lang: fr\n" - " str: content1"); - message = node.as(); - EXPECT_EQ(loot::Message::say, message.Type()); - EXPECT_EQ(MessageContents({MessageContent("content1", Language::french)}), message.Content()); - EXPECT_EQ("", message.Condition()); + // Throw because no English string is given in a multilingual message. + node = YAML::Load("type: say\n" + "content:\n" + " - lang: de\n" + " str: content1\n" + " - lang: fr\n" + " str: content2"); + EXPECT_THROW(node.as(), YAML::RepresentationException); - // Throw because no English string is given in a multilingual message. - node = YAML::Load("type: say\n" - "content:\n" - " - lang: de\n" - " str: content1\n" - " - lang: fr\n" - " str: content2"); - EXPECT_THROW(node.as(), YAML::RepresentationException); + node = YAML::Load("type: say\n" + "content: con%1%tent1\n" + "subs:\n" + " - sub1"); + message = node.as(); + EXPECT_EQ(Message::say, message.Type()); + EXPECT_EQ(MessageContents({MessageContent("consub1tent1", Language::english)}), message.Content()); + EXPECT_EQ("", message.Condition()); - node = YAML::Load("type: say\n" - "content: con%1%tent1\n" - "subs:\n" - " - sub1"); - message = node.as(); - EXPECT_EQ(loot::Message::say, message.Type()); - EXPECT_EQ(MessageContents({MessageContent("consub1tent1", Language::english)}), message.Content()); - EXPECT_EQ("", message.Condition()); + // Check that subs apply to all languages of a multilingual message. + node = YAML::Load("type: say\n" + "content:\n" + " - lang: en\n" + " str: content1 %1%\n" + " - lang: de\n" + " str: content2 %1%\n" + "subs:\n" + " - sub"); + message = node.as(); + EXPECT_EQ(Message::say, message.Type()); + EXPECT_EQ(MessageContents({ + MessageContent("content1 sub", Language::english), + MessageContent("content2 sub", Language::german), + }), message.Content()); + EXPECT_EQ("", message.Condition()); - // Check that subs apply to all languages of a multilingual message. - node = YAML::Load("type: say\n" - "content:\n" - " - lang: en\n" - " str: content1 %1%\n" - " - lang: de\n" - " str: content2 %1%\n" - "subs:\n" - " - sub"); - message = node.as(); - EXPECT_EQ(loot::Message::say, message.Type()); - EXPECT_EQ(MessageContents({ - MessageContent("content1 sub", Language::english), - MessageContent("content2 sub", Language::german), - }), message.Content()); - EXPECT_EQ("", message.Condition()); + // Throw because there aren't the same number of subs as referred to in the content string. + node = YAML::Load("type: say\n" + "content: '%1% %2%'\n" + "subs:\n" + " - sub1"); + EXPECT_THROW(node.as(), YAML::RepresentationException); - // Throw because there aren't the same number of subs as referred to in the content string. - node = YAML::Load("type: say\n" - "content: '%1% %2%'\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. + node = YAML::Load("type: say\n" + "content: con%1%tent1\n"); + message = node.as(); + EXPECT_EQ(Message::say, message.Type()); + EXPECT_EQ(MessageContents({MessageContent("con%1%tent1", Language::english)}), message.Content()); + EXPECT_EQ("", message.Condition()); - // Don't throw because no subs are given, so none are expected in the content string. - node = YAML::Load("type: say\n" - "content: con%1%tent1\n"); - message = node.as(); - EXPECT_EQ(loot::Message::say, message.Type()); - EXPECT_EQ(MessageContents({MessageContent("con%1%tent1", Language::english)}), message.Content()); - EXPECT_EQ("", message.Condition()); + node = YAML::Load("type: say\n" + "content: content1\n" + "condition: invalid"); + EXPECT_THROW(node.as(), YAML::RepresentationException); - node = YAML::Load("type: say\n" - "content: content1\n" - "condition: invalid"); - EXPECT_THROW(node.as(), YAML::RepresentationException); + node = YAML::Load("scalar"); + EXPECT_THROW(node.as(), YAML::RepresentationException); - node = YAML::Load("scalar"); - EXPECT_THROW(node.as(), YAML::RepresentationException); - - node = YAML::Load("[0, 1, 2]"); - EXPECT_THROW(node.as(), YAML::RepresentationException); + node = YAML::Load("[0, 1, 2]"); + EXPECT_THROW(node.as(), YAML::RepresentationException); + } + } } #endif diff --git a/src/tests/backend/metadata/test_message_content.h b/src/tests/backend/metadata/test_message_content.h index dba1ff40..daa7251c 100644 --- a/src/tests/backend/metadata/test_message_content.h +++ b/src/tests/backend/metadata/test_message_content.h @@ -28,84 +28,85 @@ along with LOOT. If not, see #include "backend/metadata/message_content.h" #include "tests/fixtures.h" -using loot::Language; -using loot::MessageContent; +namespace loot { + namespace test { + TEST(MessageContent, ConstructorsAndDataAccess) { + MessageContent mc; + EXPECT_EQ("", mc.Str()); + EXPECT_EQ(Language::english, mc.Language()); -TEST(MessageContent, ConstructorsAndDataAccess) { - MessageContent mc; - EXPECT_EQ("", mc.Str()); - EXPECT_EQ(Language::english, mc.Language()); + mc = MessageContent("content", Language::french); + EXPECT_EQ("content", mc.Str()); + EXPECT_EQ(Language::french, mc.Language()); + } - mc = MessageContent("content", Language::french); - EXPECT_EQ("content", mc.Str()); - EXPECT_EQ(Language::french, mc.Language()); -} + TEST(MessageContent, EqualityOperator) { + MessageContent mc1, mc2; + EXPECT_TRUE(mc1 == mc2); -TEST(MessageContent, EqualityOperator) { - MessageContent mc1, mc2; - EXPECT_TRUE(mc1 == mc2); + mc1 = MessageContent("content", Language::french); + mc2 = MessageContent("Content", Language::french); + EXPECT_TRUE(mc1 == mc2); - mc1 = MessageContent("content", Language::french); - mc2 = MessageContent("Content", Language::french); - EXPECT_TRUE(mc1 == mc2); + mc1 = MessageContent("content1", Language::french); + mc2 = MessageContent("content2", Language::french); + EXPECT_FALSE(mc1 == mc2); - mc1 = MessageContent("content1", Language::french); - mc2 = MessageContent("content2", Language::french); - EXPECT_FALSE(mc1 == mc2); + mc1 = MessageContent("content", Language::english); + mc2 = MessageContent("Content", Language::french); + EXPECT_TRUE(mc1 == mc2); + } - mc1 = MessageContent("content", Language::english); - mc2 = MessageContent("Content", Language::french); - EXPECT_TRUE(mc1 == mc2); -} + TEST(MessageContent, LessThanOperator) { + MessageContent mc1, mc2; + EXPECT_FALSE(mc1 < mc2); + EXPECT_FALSE(mc2 < mc1); -TEST(MessageContent, LessThanOperator) { - MessageContent mc1, mc2; - EXPECT_FALSE(mc1 < mc2); - EXPECT_FALSE(mc2 < mc1); + mc1 = MessageContent("content", Language::french); + mc2 = MessageContent("Content", Language::french); + EXPECT_FALSE(mc1 < mc2); + EXPECT_FALSE(mc2 < mc1); - mc1 = MessageContent("content", Language::french); - mc2 = MessageContent("Content", Language::french); - EXPECT_FALSE(mc1 < mc2); - EXPECT_FALSE(mc2 < mc1); + mc1 = MessageContent("content", Language::english); + mc2 = MessageContent("content", Language::french); + EXPECT_FALSE(mc1 < mc2); + EXPECT_FALSE(mc2 < mc1); - mc1 = MessageContent("content", Language::english); - mc2 = MessageContent("content", Language::french); - EXPECT_FALSE(mc1 < mc2); - EXPECT_FALSE(mc2 < mc1); + mc1 = MessageContent("content1", Language::english); + mc2 = MessageContent("content2", Language::english); + EXPECT_TRUE(mc1 < mc2); + EXPECT_FALSE(mc2 < mc1); + } - mc1 = MessageContent("content1", Language::english); - mc2 = MessageContent("content2", Language::english); - EXPECT_TRUE(mc1 < mc2); - EXPECT_FALSE(mc2 < mc1); -} + TEST(MessageContent, YamlEmitter) { + MessageContent mc("content", Language::french); + YAML::Emitter e1; + e1 << mc; + EXPECT_STREQ("lang: fr\nstr: 'content'", e1.c_str()); + } -TEST(MessageContent, YamlEmitter) { - MessageContent mc("content", Language::french); - YAML::Emitter e1; - e1 << mc; - EXPECT_STREQ("lang: fr\nstr: 'content'", e1.c_str()); -} + TEST(MessageContent, YamlEncode) { + YAML::Node node; -TEST(MessageContent, YamlEncode) { - YAML::Node node; + MessageContent mc("content", Language::french); + node = mc; + EXPECT_EQ("content", node["str"].as()); + EXPECT_EQ("fr", node["lang"].as()); + } - MessageContent mc("content", Language::french); - node = mc; - EXPECT_EQ("content", node["str"].as()); - EXPECT_EQ("fr", node["lang"].as()); -} + TEST(MessageContent, YamlDecode) { + YAML::Node node = YAML::Load("{str: content, lang: de}"); + MessageContent mc = node.as(); + EXPECT_EQ("content", mc.Str()); + EXPECT_EQ(Language::german, mc.Language()); -TEST(MessageContent, YamlDecode) { - YAML::Node node = YAML::Load("{str: content, lang: de}"); - MessageContent mc = node.as(); - EXPECT_EQ("content", mc.Str()); - EXPECT_EQ(Language::german, mc.Language()); + node = YAML::Load("scalar"); + EXPECT_ANY_THROW(node.as()); - node = YAML::Load("scalar"); - EXPECT_ANY_THROW(node.as()); - - node = YAML::Load("[0, 1, 2]"); - EXPECT_ANY_THROW(node.as()); + node = YAML::Load("[0, 1, 2]"); + EXPECT_ANY_THROW(node.as()); + } + } } #endif diff --git a/src/tests/backend/metadata/test_plugin_dirty_info.h b/src/tests/backend/metadata/test_plugin_dirty_info.h index 3cbd248e..d632885c 100644 --- a/src/tests/backend/metadata/test_plugin_dirty_info.h +++ b/src/tests/backend/metadata/test_plugin_dirty_info.h @@ -28,212 +28,216 @@ along with LOOT. If not, see #include "backend/metadata/plugin_dirty_info.h" #include "tests/fixtures.h" -class PluginDirtyInfo : public SkyrimTest {}; +namespace loot { + namespace test { + class PluginDirtyInfoTest : public SkyrimTest {}; -TEST_F(PluginDirtyInfo, ConstructorsAndDataAccess) { - loot::PluginDirtyInfo info; - EXPECT_EQ(0, info.CRC()); - EXPECT_EQ(0, info.ITMs()); - EXPECT_EQ(0, info.DeletedRefs()); - EXPECT_EQ(0, info.DeletedNavmeshes()); - EXPECT_EQ("", info.CleaningUtility()); + TEST_F(PluginDirtyInfoTest, ConstructorsAndDataAccess) { + PluginDirtyInfo info; + EXPECT_EQ(0, info.CRC()); + EXPECT_EQ(0, info.ITMs()); + EXPECT_EQ(0, info.DeletedRefs()); + EXPECT_EQ(0, info.DeletedNavmeshes()); + EXPECT_EQ("", info.CleaningUtility()); - info = loot::PluginDirtyInfo(0x12345678, 2, 10, 30, "cleaner"); - EXPECT_EQ(0x12345678, info.CRC()); - EXPECT_EQ(2, info.ITMs()); - EXPECT_EQ(10, info.DeletedRefs()); - EXPECT_EQ(30, info.DeletedNavmeshes()); - EXPECT_EQ("cleaner", info.CleaningUtility()); -} + info = PluginDirtyInfo(0x12345678, 2, 10, 30, "cleaner"); + EXPECT_EQ(0x12345678, info.CRC()); + EXPECT_EQ(2, info.ITMs()); + EXPECT_EQ(10, info.DeletedRefs()); + EXPECT_EQ(30, info.DeletedNavmeshes()); + EXPECT_EQ("cleaner", info.CleaningUtility()); + } -TEST_F(PluginDirtyInfo, MessageOutput) { - loot::Message message; + TEST_F(PluginDirtyInfoTest, MessageOutput) { + Message message; - message = loot::PluginDirtyInfo(0x12345678, 2, 10, 30, "cleaner").AsMessage(); - EXPECT_EQ(loot::Message::warn, message.Type()); - EXPECT_EQ("Contains 2 ITM records, 10 deleted references and 30 deleted navmeshes. Clean with cleaner.", message.ChooseContent(Language::any).Str()); + message = PluginDirtyInfo(0x12345678, 2, 10, 30, "cleaner").AsMessage(); + EXPECT_EQ(Message::warn, message.Type()); + EXPECT_EQ("Contains 2 ITM records, 10 deleted references and 30 deleted navmeshes. Clean with cleaner.", message.ChooseContent(Language::any).Str()); - message = loot::PluginDirtyInfo(0x12345678, 0, 0, 0, "cleaner").AsMessage(); - EXPECT_EQ(loot::Message::warn, message.Type()); - EXPECT_EQ("Clean with cleaner.", message.ChooseContent(Language::any).Str()); + message = PluginDirtyInfo(0x12345678, 0, 0, 0, "cleaner").AsMessage(); + EXPECT_EQ(Message::warn, message.Type()); + EXPECT_EQ("Clean with cleaner.", message.ChooseContent(Language::any).Str()); - message = loot::PluginDirtyInfo(0x12345678, 0, 10, 30, "cleaner").AsMessage(); - EXPECT_EQ(loot::Message::warn, message.Type()); - EXPECT_EQ("Contains 10 deleted references and 30 deleted navmeshes. Clean with cleaner.", message.ChooseContent(Language::any).Str()); + message = PluginDirtyInfo(0x12345678, 0, 10, 30, "cleaner").AsMessage(); + EXPECT_EQ(Message::warn, message.Type()); + EXPECT_EQ("Contains 10 deleted references and 30 deleted navmeshes. Clean with cleaner.", message.ChooseContent(Language::any).Str()); - message = loot::PluginDirtyInfo(0x12345678, 0, 0, 30, "cleaner").AsMessage(); - EXPECT_EQ(loot::Message::warn, message.Type()); - EXPECT_EQ("Contains 30 deleted navmeshes. Clean with cleaner.", message.ChooseContent(Language::any).Str()); + message = PluginDirtyInfo(0x12345678, 0, 0, 30, "cleaner").AsMessage(); + EXPECT_EQ(Message::warn, message.Type()); + EXPECT_EQ("Contains 30 deleted navmeshes. Clean with cleaner.", message.ChooseContent(Language::any).Str()); - message = loot::PluginDirtyInfo(0x12345678, 0, 10, 0, "cleaner").AsMessage(); - EXPECT_EQ(loot::Message::warn, message.Type()); - EXPECT_EQ("Contains 10 deleted references. Clean with cleaner.", message.ChooseContent(Language::any).Str()); + message = PluginDirtyInfo(0x12345678, 0, 10, 0, "cleaner").AsMessage(); + EXPECT_EQ(Message::warn, message.Type()); + EXPECT_EQ("Contains 10 deleted references. Clean with cleaner.", message.ChooseContent(Language::any).Str()); - message = loot::PluginDirtyInfo(0x12345678, 2, 0, 30, "cleaner").AsMessage(); - EXPECT_EQ(loot::Message::warn, message.Type()); - EXPECT_EQ("Contains 2 ITM records and 30 deleted navmeshes. Clean with cleaner.", message.ChooseContent(Language::any).Str()); + message = PluginDirtyInfo(0x12345678, 2, 0, 30, "cleaner").AsMessage(); + EXPECT_EQ(Message::warn, message.Type()); + EXPECT_EQ("Contains 2 ITM records and 30 deleted navmeshes. Clean with cleaner.", message.ChooseContent(Language::any).Str()); - message = loot::PluginDirtyInfo(0x12345678, 2, 0, 0, "cleaner").AsMessage(); - EXPECT_EQ(loot::Message::warn, message.Type()); - EXPECT_EQ("Contains 2 ITM records. Clean with cleaner.", message.ChooseContent(Language::any).Str()); + message = PluginDirtyInfo(0x12345678, 2, 0, 0, "cleaner").AsMessage(); + EXPECT_EQ(Message::warn, message.Type()); + EXPECT_EQ("Contains 2 ITM records. Clean with cleaner.", message.ChooseContent(Language::any).Str()); - message = loot::PluginDirtyInfo(0x12345678, 2, 10, 0, "cleaner").AsMessage(); - EXPECT_EQ(loot::Message::warn, message.Type()); - EXPECT_EQ("Contains 2 ITM records and 10 deleted references. Clean with cleaner.", message.ChooseContent(Language::any).Str()); -} + message = PluginDirtyInfo(0x12345678, 2, 10, 0, "cleaner").AsMessage(); + EXPECT_EQ(Message::warn, message.Type()); + EXPECT_EQ("Contains 2 ITM records and 10 deleted references. Clean with cleaner.", message.ChooseContent(Language::any).Str()); + } -TEST_F(PluginDirtyInfo, EqualityOperator) { - loot::PluginDirtyInfo info1, info2; - EXPECT_TRUE(info1 == info2); + TEST_F(PluginDirtyInfoTest, EqualityOperator) { + PluginDirtyInfo info1, info2; + EXPECT_TRUE(info1 == info2); - info1 = loot::PluginDirtyInfo(0x12345678, 2, 10, 30, "cleaner1"); - info2 = loot::PluginDirtyInfo(0x12345678, 4, 20, 60, "cleaner2"); - EXPECT_TRUE(info1 == info2); + info1 = PluginDirtyInfo(0x12345678, 2, 10, 30, "cleaner1"); + info2 = PluginDirtyInfo(0x12345678, 4, 20, 60, "cleaner2"); + EXPECT_TRUE(info1 == info2); - info1 = loot::PluginDirtyInfo(0x12345678, 2, 10, 30, "cleaner"); - info2 = loot::PluginDirtyInfo(0x87654321, 2, 10, 30, "cleaner"); - EXPECT_FALSE(info1 == info2); -} + info1 = PluginDirtyInfo(0x12345678, 2, 10, 30, "cleaner"); + info2 = PluginDirtyInfo(0x87654321, 2, 10, 30, "cleaner"); + EXPECT_FALSE(info1 == info2); + } -TEST_F(PluginDirtyInfo, LessThanOperator) { - loot::PluginDirtyInfo info1, info2; - EXPECT_FALSE(info1 < info2); - EXPECT_FALSE(info2 < info1); + TEST_F(PluginDirtyInfoTest, LessThanOperator) { + PluginDirtyInfo info1, info2; + EXPECT_FALSE(info1 < info2); + EXPECT_FALSE(info2 < info1); - info1 = loot::PluginDirtyInfo(0x12345678, 2, 10, 30, "cleaner1"); - info2 = loot::PluginDirtyInfo(0x12345678, 4, 20, 60, "cleaner2"); - EXPECT_FALSE(info1 < info2); - EXPECT_FALSE(info2 < info1); + info1 = PluginDirtyInfo(0x12345678, 2, 10, 30, "cleaner1"); + info2 = PluginDirtyInfo(0x12345678, 4, 20, 60, "cleaner2"); + EXPECT_FALSE(info1 < info2); + EXPECT_FALSE(info2 < info1); - info1 = loot::PluginDirtyInfo(0x12345678, 2, 10, 30, "cleaner"); - info2 = loot::PluginDirtyInfo(0x87654321, 2, 10, 30, "cleaner"); - EXPECT_TRUE(info1 < info2); - EXPECT_FALSE(info2 < info1); -} + info1 = PluginDirtyInfo(0x12345678, 2, 10, 30, "cleaner"); + info2 = PluginDirtyInfo(0x87654321, 2, 10, 30, "cleaner"); + EXPECT_TRUE(info1 < info2); + EXPECT_FALSE(info2 < info1); + } -TEST_F(PluginDirtyInfo, EvalConditionTrue) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); + TEST_F(PluginDirtyInfoTest, EvalConditionTrue) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); + ASSERT_NO_THROW(game.Init(false, localPath)); - loot::PluginDirtyInfo dirtyInfo = loot::PluginDirtyInfo(0x24F0E2A1, 2, 10, 30, "cleaner"); - EXPECT_TRUE(dirtyInfo.EvalCondition(game, "Blank.esp")); -} + PluginDirtyInfo dirtyInfo = PluginDirtyInfo(0x24F0E2A1, 2, 10, 30, "cleaner"); + EXPECT_TRUE(dirtyInfo.EvalCondition(game, "Blank.esp")); + } -TEST_F(PluginDirtyInfo, EvalConditionFalse) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); + TEST_F(PluginDirtyInfoTest, EvalConditionFalse) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); + ASSERT_NO_THROW(game.Init(false, localPath)); - loot::PluginDirtyInfo dirtyInfo; - EXPECT_FALSE(dirtyInfo.EvalCondition(game, "")); + PluginDirtyInfo dirtyInfo; + EXPECT_FALSE(dirtyInfo.EvalCondition(game, "")); - dirtyInfo = loot::PluginDirtyInfo(0xDEADBEEF, 2, 10, 30, "cleaner"); - EXPECT_FALSE(dirtyInfo.EvalCondition(game, "Blank.esp")); -} + dirtyInfo = PluginDirtyInfo(0xDEADBEEF, 2, 10, 30, "cleaner"); + EXPECT_FALSE(dirtyInfo.EvalCondition(game, "Blank.esp")); + } -TEST_F(PluginDirtyInfo, YamlEmitter) { - loot::PluginDirtyInfo info; + TEST_F(PluginDirtyInfoTest, YamlEmitter) { + PluginDirtyInfo info; - info = loot::PluginDirtyInfo(0x12345678, 0, 0, 0, "cleaner"); - YAML::Emitter e1; - e1 << info; - EXPECT_STREQ("crc: 0x12345678\nutil: 'cleaner'", e1.c_str()); + info = PluginDirtyInfo(0x12345678, 0, 0, 0, "cleaner"); + YAML::Emitter e1; + e1 << info; + EXPECT_STREQ("crc: 0x12345678\nutil: 'cleaner'", e1.c_str()); - info = loot::PluginDirtyInfo(0x12345678, 2, 0, 0, "cleaner"); - YAML::Emitter e2; - e2 << info; - EXPECT_STREQ("crc: 0x12345678\nutil: 'cleaner'\nitm: 2", e2.c_str()); + info = PluginDirtyInfo(0x12345678, 2, 0, 0, "cleaner"); + YAML::Emitter e2; + e2 << info; + EXPECT_STREQ("crc: 0x12345678\nutil: 'cleaner'\nitm: 2", e2.c_str()); - info = loot::PluginDirtyInfo(0x12345678, 2, 10, 0, "cleaner"); - YAML::Emitter e3; - e3 << info; - EXPECT_STREQ("crc: 0x12345678\nutil: 'cleaner'\nitm: 2\nudr: 10", e3.c_str()); + info = PluginDirtyInfo(0x12345678, 2, 10, 0, "cleaner"); + YAML::Emitter e3; + e3 << info; + EXPECT_STREQ("crc: 0x12345678\nutil: 'cleaner'\nitm: 2\nudr: 10", e3.c_str()); - info = loot::PluginDirtyInfo(0x12345678, 2, 10, 30, "cleaner"); - YAML::Emitter e4; - e4 << info; - EXPECT_STREQ("crc: 0x12345678\nutil: 'cleaner'\nitm: 2\nudr: 10\nnav: 30", e4.c_str()); -} + info = PluginDirtyInfo(0x12345678, 2, 10, 30, "cleaner"); + YAML::Emitter e4; + e4 << info; + EXPECT_STREQ("crc: 0x12345678\nutil: 'cleaner'\nitm: 2\nudr: 10\nnav: 30", e4.c_str()); + } -TEST_F(PluginDirtyInfo, YamlEncode) { - YAML::Node node; - loot::PluginDirtyInfo info; + TEST_F(PluginDirtyInfoTest, YamlEncode) { + YAML::Node node; + PluginDirtyInfo info; - info = loot::PluginDirtyInfo(0x12345678, 0, 0, 0, "cleaner"); - node = info; - EXPECT_EQ(0x12345678, node["crc"].as()); - EXPECT_EQ("cleaner", node["util"].as()); - EXPECT_FALSE(node["itm"]); - EXPECT_FALSE(node["udr"]); - EXPECT_FALSE(node["nav"]); + info = PluginDirtyInfo(0x12345678, 0, 0, 0, "cleaner"); + node = info; + EXPECT_EQ(0x12345678, node["crc"].as()); + EXPECT_EQ("cleaner", node["util"].as()); + EXPECT_FALSE(node["itm"]); + EXPECT_FALSE(node["udr"]); + EXPECT_FALSE(node["nav"]); - info = loot::PluginDirtyInfo(0x12345678, 2, 0, 0, "cleaner"); - node = info; - EXPECT_EQ(0x12345678, node["crc"].as()); - EXPECT_EQ("cleaner", node["util"].as()); - EXPECT_EQ(2, node["itm"].as()); - EXPECT_FALSE(node["udr"]); - EXPECT_FALSE(node["nav"]); + info = PluginDirtyInfo(0x12345678, 2, 0, 0, "cleaner"); + node = info; + EXPECT_EQ(0x12345678, node["crc"].as()); + EXPECT_EQ("cleaner", node["util"].as()); + EXPECT_EQ(2, node["itm"].as()); + EXPECT_FALSE(node["udr"]); + EXPECT_FALSE(node["nav"]); - info = loot::PluginDirtyInfo(0x12345678, 2, 10, 0, "cleaner"); - node = info; - EXPECT_EQ(0x12345678, node["crc"].as()); - EXPECT_EQ("cleaner", node["util"].as()); - EXPECT_EQ(2, node["itm"].as()); - EXPECT_EQ(10, node["udr"].as()); - EXPECT_FALSE(node["nav"]); + info = PluginDirtyInfo(0x12345678, 2, 10, 0, "cleaner"); + node = info; + EXPECT_EQ(0x12345678, node["crc"].as()); + EXPECT_EQ("cleaner", node["util"].as()); + EXPECT_EQ(2, node["itm"].as()); + EXPECT_EQ(10, node["udr"].as()); + EXPECT_FALSE(node["nav"]); - info = loot::PluginDirtyInfo(0x12345678, 2, 10, 30, "cleaner"); - node = info; - EXPECT_EQ(0x12345678, node["crc"].as()); - EXPECT_EQ("cleaner", node["util"].as()); - EXPECT_EQ(2, node["itm"].as()); - EXPECT_EQ(10, node["udr"].as()); - EXPECT_EQ(30, node["nav"].as()); -} + info = PluginDirtyInfo(0x12345678, 2, 10, 30, "cleaner"); + node = info; + EXPECT_EQ(0x12345678, node["crc"].as()); + EXPECT_EQ("cleaner", node["util"].as()); + EXPECT_EQ(2, node["itm"].as()); + EXPECT_EQ(10, node["udr"].as()); + EXPECT_EQ(30, node["nav"].as()); + } -TEST_F(PluginDirtyInfo, YamlDecode) { - YAML::Node node; - loot::PluginDirtyInfo info; + TEST_F(PluginDirtyInfoTest, YamlDecode) { + YAML::Node node; + PluginDirtyInfo info; - node = YAML::Load("{crc: 0x12345678, util: cleaner}"); - info = node.as(); - EXPECT_EQ(0x12345678, info.CRC()); - EXPECT_EQ(0, info.ITMs()); - EXPECT_EQ(0, info.DeletedRefs()); - EXPECT_EQ(0, info.DeletedNavmeshes()); - EXPECT_EQ("cleaner", info.CleaningUtility()); + node = YAML::Load("{crc: 0x12345678, util: cleaner}"); + info = node.as(); + EXPECT_EQ(0x12345678, info.CRC()); + EXPECT_EQ(0, info.ITMs()); + EXPECT_EQ(0, info.DeletedRefs()); + EXPECT_EQ(0, info.DeletedNavmeshes()); + EXPECT_EQ("cleaner", info.CleaningUtility()); - node = YAML::Load("{crc: 0x12345678, util: cleaner, itm: 2}"); - info = node.as(); - EXPECT_EQ(0x12345678, info.CRC()); - EXPECT_EQ(2, info.ITMs()); - EXPECT_EQ(0, info.DeletedRefs()); - EXPECT_EQ(0, info.DeletedNavmeshes()); - EXPECT_EQ("cleaner", info.CleaningUtility()); + node = YAML::Load("{crc: 0x12345678, util: cleaner, itm: 2}"); + info = node.as(); + EXPECT_EQ(0x12345678, info.CRC()); + EXPECT_EQ(2, info.ITMs()); + EXPECT_EQ(0, info.DeletedRefs()); + EXPECT_EQ(0, info.DeletedNavmeshes()); + EXPECT_EQ("cleaner", info.CleaningUtility()); - node = YAML::Load("{crc: 0x12345678, util: cleaner, itm: 2, udr: 10}"); - info = node.as(); - EXPECT_EQ(0x12345678, info.CRC()); - EXPECT_EQ(2, info.ITMs()); - EXPECT_EQ(10, info.DeletedRefs()); - EXPECT_EQ(0, info.DeletedNavmeshes()); - EXPECT_EQ("cleaner", info.CleaningUtility()); + node = YAML::Load("{crc: 0x12345678, util: cleaner, itm: 2, udr: 10}"); + info = node.as(); + EXPECT_EQ(0x12345678, info.CRC()); + EXPECT_EQ(2, info.ITMs()); + EXPECT_EQ(10, info.DeletedRefs()); + EXPECT_EQ(0, info.DeletedNavmeshes()); + EXPECT_EQ("cleaner", info.CleaningUtility()); - node = YAML::Load("{crc: 0x12345678, util: cleaner, itm: 2, udr: 10, nav: 30}"); - info = node.as(); - EXPECT_EQ(0x12345678, info.CRC()); - EXPECT_EQ(2, info.ITMs()); - EXPECT_EQ(10, info.DeletedRefs()); - EXPECT_EQ(30, info.DeletedNavmeshes()); - EXPECT_EQ("cleaner", info.CleaningUtility()); + node = YAML::Load("{crc: 0x12345678, util: cleaner, itm: 2, udr: 10, nav: 30}"); + info = node.as(); + EXPECT_EQ(0x12345678, info.CRC()); + EXPECT_EQ(2, info.ITMs()); + EXPECT_EQ(10, info.DeletedRefs()); + EXPECT_EQ(30, info.DeletedNavmeshes()); + EXPECT_EQ("cleaner", info.CleaningUtility()); - node = YAML::Load("scalar"); - EXPECT_ANY_THROW(node.as()); + node = YAML::Load("scalar"); + EXPECT_ANY_THROW(node.as()); - node = YAML::Load("[0, 1, 2]"); - EXPECT_ANY_THROW(node.as()); + node = YAML::Load("[0, 1, 2]"); + EXPECT_ANY_THROW(node.as()); + } + } } #endif diff --git a/src/tests/backend/metadata/test_plugin_metadata.h b/src/tests/backend/metadata/test_plugin_metadata.h index 8353e2de..d1d8f323 100644 --- a/src/tests/backend/metadata/test_plugin_metadata.h +++ b/src/tests/backend/metadata/test_plugin_metadata.h @@ -28,922 +28,926 @@ along with LOOT. If not, see #include "backend/metadata/plugin_metadata.h" #include "tests/fixtures.h" -class PluginMetadata : public SkyrimTest {}; - -TEST_F(PluginMetadata, Constructors) { - loot::PluginMetadata pm; - EXPECT_TRUE(pm.Enabled()); - EXPECT_FALSE(pm.IsPriorityExplicit()); - EXPECT_FALSE(pm.IsPriorityGlobal()); - EXPECT_EQ(0, pm.Priority()); - - pm = loot::PluginMetadata("Blank.esm"); - EXPECT_EQ("Blank.esm", pm.Name()); - EXPECT_TRUE(pm.Enabled()); - EXPECT_FALSE(pm.IsPriorityExplicit()); - EXPECT_FALSE(pm.IsPriorityGlobal()); - EXPECT_EQ(0, pm.Priority()); -} - -TEST_F(PluginMetadata, EqualityOperator) { - loot::PluginMetadata pm1, pm2; - EXPECT_TRUE(pm1 == pm2); - - pm1 = loot::PluginMetadata("Blank.esm"); - pm2 = loot::PluginMetadata("blank.esm"); - EXPECT_TRUE(pm1 == pm2); - - pm1 = loot::PluginMetadata("Blank.esm"); - pm2 = loot::PluginMetadata("Blan.\\.esm"); - EXPECT_TRUE(pm1 == pm2); - EXPECT_TRUE(pm2 == pm1); - - pm1 = loot::PluginMetadata("Blan.esm"); - pm2 = loot::PluginMetadata("Blan.\\.esm"); - EXPECT_FALSE(pm1 == pm2); - EXPECT_FALSE(pm2 == pm1); - - pm1 = loot::PluginMetadata("Blan.\\.esm"); - pm2 = loot::PluginMetadata("Blan.\\.esm"); - EXPECT_TRUE(pm1 == pm2); - EXPECT_TRUE(pm2 == pm1); - - pm1 = loot::PluginMetadata("Blan(k|p).esm"); - pm2 = loot::PluginMetadata("Blan.\\.esm"); - EXPECT_FALSE(pm1 == pm2); - EXPECT_FALSE(pm2 == pm1); -} - -TEST_F(PluginMetadata, MergeMetadata) { - loot::PluginMetadata pm1(YAML::Load( - "name: 'Blank.esp'\n" - "enabled: false\n" - "priority: 5\n" - "after:\n" - " - 'Blank.esm'\n" - "req:\n" - " - 'Blank.esm'\n" - "inc:\n" - " - 'Blank.esm'\n" - "msg:\n" - " - type: say\n" - " content: 'content'\n" - "tag:\n" - " - Relev\n" - "dirty:\n" - " - crc: 0x5\n" - " util: 'utility'\n" - " udr: 1\n" - " nav: 2\n" - "url:\n" - " - 'http://www.example.com'" - ).as()); - - loot::PluginMetadata pm2(YAML::Load( - "name: 'Blank - Different.esp'\n" - "after:\n" - " - 'Blank.esm'\n" - " - 'Blank.esp'\n" - "req:\n" - " - 'Blank.esm'\n" - " - 'Blank.esp'\n" - "inc:\n" - " - 'Blank.esm'\n" - " - 'Blank.esp'\n" - "msg:\n" - " - type: say\n" - " content: 'content'\n" - "tag:\n" - " - Relev\n" - " - -Relev\n" - " - Delev\n" - "dirty:\n" - " - crc: 0x5\n" - " util: 'utility'\n" - " udr: 1\n" - " nav: 2\n" - " - crc: 0x9\n" - " util: 'utility'\n" - " udr: 1\n" - " nav: 2\n" - "url:\n" - " - 'http://www.example.com'\n" - " - 'http://www.example2.com'" - ).as()); - - EXPECT_NO_THROW(pm1.MergeMetadata(pm2)); - EXPECT_EQ("Blank.esp", pm1.Name()); - EXPECT_TRUE(pm1.Enabled()); - EXPECT_EQ(5, pm1.Priority()); - EXPECT_TRUE(pm1.IsPriorityExplicit()); - EXPECT_FALSE(pm1.IsPriorityGlobal()); - EXPECT_EQ(std::set({ - loot::File("Blank.esm"), - loot::File("Blank.esp"), - }), pm1.LoadAfter()); - EXPECT_EQ(std::set({ - loot::File("Blank.esm"), - loot::File("Blank.esp"), - }), pm1.Reqs()); - EXPECT_EQ(std::set({ - loot::File("Blank.esm"), - loot::File("Blank.esp"), - }), pm1.Incs()); - EXPECT_EQ(std::list({ - loot::Message(loot::Message::say, "content"), - loot::Message(loot::Message::say, "content"), - }), pm1.Messages()); - EXPECT_EQ(std::set({ - loot::Tag("Relev"), - loot::Tag("Relev", false), - loot::Tag("Delev"), - }), pm1.Tags()); - EXPECT_EQ(std::set({ - loot::PluginDirtyInfo(5, 0, 1, 2, "utility"), - loot::PluginDirtyInfo(9, 0, 1, 2, "utility"), - }), pm1.DirtyInfo()); - EXPECT_EQ(std::set({ - loot::Location("http://www.example.com"), - loot::Location("http://www.example2.com"), - }), pm1.Locations()); - - pm2.SetPriorityExplicit(true); - EXPECT_NO_THROW(pm1.MergeMetadata(pm2)); - EXPECT_EQ(0, pm1.Priority()); - EXPECT_TRUE(pm1.IsPriorityExplicit()); - EXPECT_FALSE(pm1.IsPriorityGlobal()); -} - -TEST_F(PluginMetadata, DiffMetadata) { - loot::PluginMetadata pm1(YAML::Load( - "name: 'Blank.esp'\n" - "enabled: false\n" - "after:\n" - " - 'Blank.esm'\n" - " - 'Blank - Different.esm'\n" - "req:\n" - " - 'Blank.esm'\n" - " - 'Blank - Different.esm'\n" - "inc:\n" - " - 'Blank.esm'\n" - " - 'Blank - Different.esm'\n" - "msg:\n" - " - type: say\n" - " content: 'content'\n" - " - type: say\n" - " content: 'content2'\n" - "tag:\n" - " - Relev\n" - " - NoMerge\n" - "dirty:\n" - " - crc: 0x5\n" - " util: 'utility'\n" - " udr: 1\n" - " nav: 2\n" - " - crc: 0x1\n" - " util: 'utility'\n" - " udr: 1\n" - " nav: 2\n" - "url:\n" - " - 'http://www.example.com'\n" - " - 'http://www.other-example.com'" - ).as()); - - loot::PluginMetadata pm2(YAML::Load( - "name: 'Blank - Different.esp'\n" - "after:\n" - " - 'Blank.esm'\n" - " - 'Blank.esp'\n" - "req:\n" - " - 'Blank.esm'\n" - " - 'Blank.esp'\n" - "inc:\n" - " - 'Blank.esm'\n" - " - 'Blank.esp'\n" - "msg:\n" - " - type: say\n" - " content: 'content'\n" - " - type: say\n" - " content: 'content3'\n" - "tag:\n" - " - Relev\n" - " - -Relev\n" - " - Delev\n" - "dirty:\n" - " - crc: 0x5\n" - " util: 'utility'\n" - " udr: 1\n" - " nav: 2\n" - " - crc: 0x9\n" - " util: 'utility'\n" - " udr: 1\n" - " nav: 2\n" - "url:\n" - " - 'http://www.example.com'\n" - " - 'http://www.example2.com'" - ).as()); - - loot::PluginMetadata result = pm1.DiffMetadata(pm2); - EXPECT_EQ("Blank.esp", result.Name()); - EXPECT_FALSE(result.Enabled()); - EXPECT_EQ(0, result.Priority()); - EXPECT_FALSE(result.IsPriorityExplicit()); - EXPECT_FALSE(result.IsPriorityGlobal()); - EXPECT_EQ(std::set({ - loot::File("Blank.esp"), - loot::File("Blank - Different.esm"), - }), result.LoadAfter()); - EXPECT_EQ(std::set({ - loot::File("Blank.esp"), - loot::File("Blank - Different.esm"), - }), result.Reqs()); - EXPECT_EQ(std::set({ - loot::File("Blank.esp"), - loot::File("Blank - Different.esm"), - }), result.Incs()); - EXPECT_EQ(std::list({ - loot::Message(loot::Message::say, "content2"), - loot::Message(loot::Message::say, "content3"), - }), result.Messages()); - EXPECT_EQ(std::set({ - loot::Tag("Relev", false), - loot::Tag("Delev"), - loot::Tag("NoMerge"), - }), result.Tags()); - EXPECT_EQ(std::set({ - loot::PluginDirtyInfo(9, 0, 1, 2, "utility"), - loot::PluginDirtyInfo(1, 0, 1, 2, "utility"), - }), result.DirtyInfo()); - EXPECT_EQ(std::set({ - loot::Location("http://www.example2.com"), - loot::Location("http://www.other-example.com"), - }), result.Locations()); - - pm1.Priority(5); - result = pm1.DiffMetadata(pm2); - - EXPECT_EQ(5, result.Priority()); - EXPECT_TRUE(result.IsPriorityExplicit()); - EXPECT_FALSE(result.IsPriorityGlobal()); -} - -TEST_F(PluginMetadata, NewMetadata) { - loot::PluginMetadata pm1(YAML::Load( - "name: 'Blank.esp'\n" - "enabled: false\n" - "after:\n" - " - 'Blank.esm'\n" - " - 'Blank - Different.esm'\n" - "req:\n" - " - 'Blank.esm'\n" - " - 'Blank - Different.esm'\n" - "inc:\n" - " - 'Blank.esm'\n" - " - 'Blank - Different.esm'\n" - "msg:\n" - " - type: say\n" - " content: 'content'\n" - " - type: say\n" - " content: 'content2'\n" - "tag:\n" - " - Relev\n" - " - NoMerge\n" - "dirty:\n" - " - crc: 0x5\n" - " util: 'utility'\n" - " udr: 1\n" - " nav: 2\n" - " - crc: 0x1\n" - " util: 'utility'\n" - " udr: 1\n" - " nav: 2\n" - "url:\n" - " - 'http://www.example.com'\n" - " - 'http://www.other-example.com'" - ).as()); - - loot::PluginMetadata pm2(YAML::Load( - "name: 'Blank - Different.esp'\n" - "after:\n" - " - 'Blank.esm'\n" - " - 'Blank.esp'\n" - "req:\n" - " - 'Blank.esm'\n" - " - 'Blank.esp'\n" - "inc:\n" - " - 'Blank.esm'\n" - " - 'Blank.esp'\n" - "msg:\n" - " - type: say\n" - " content: 'content'\n" - " - type: say\n" - " content: 'content3'\n" - "tag:\n" - " - Relev\n" - " - -Relev\n" - " - Delev\n" - "dirty:\n" - " - crc: 0x5\n" - " util: 'utility'\n" - " udr: 1\n" - " nav: 2\n" - " - crc: 0x9\n" - " util: 'utility'\n" - " udr: 1\n" - " nav: 2\n" - "url:\n" - " - 'http://www.example.com'\n" - " - 'http://www.example2.com'" - ).as()); - - loot::PluginMetadata result = pm2.NewMetadata(pm1); - EXPECT_EQ("Blank - Different.esp", result.Name()); - EXPECT_TRUE(result.Enabled()); - EXPECT_EQ(0, result.Priority()); - EXPECT_FALSE(result.IsPriorityExplicit()); - EXPECT_FALSE(result.IsPriorityGlobal()); - EXPECT_EQ(std::set({ - loot::File("Blank.esp") - }), result.LoadAfter()); - EXPECT_EQ(std::set({ - loot::File("Blank.esp") - }), result.Reqs()); - EXPECT_EQ(std::set({ - loot::File("Blank.esp") - }), result.Incs()); - EXPECT_EQ(std::list({ - loot::Message(loot::Message::say, "content3"), - }), result.Messages()); - EXPECT_EQ(std::set({ - loot::Tag("Relev", false), - loot::Tag("Delev"), - }), result.Tags()); - EXPECT_EQ(std::set({ - loot::PluginDirtyInfo(9, 0, 1, 2, "utility") - }), result.DirtyInfo()); - EXPECT_EQ(std::set({ - loot::Location("http://www.example2.com") - }), result.Locations()); - - pm1.Priority(5); - result = pm2.NewMetadata(pm1); - - EXPECT_EQ(0, result.Priority()); - EXPECT_FALSE(result.IsPriorityExplicit()); - EXPECT_FALSE(result.IsPriorityGlobal()); -} - -TEST_F(PluginMetadata, Enabled) { - loot::PluginMetadata pm; - ASSERT_TRUE(pm.Enabled()); - pm.Enabled(false); - EXPECT_FALSE(pm.Enabled()); -} - -TEST_F(PluginMetadata, SetPriorityExplicit) { - loot::PluginMetadata pm; - ASSERT_FALSE(pm.IsPriorityExplicit()); - pm.SetPriorityExplicit(true); - EXPECT_TRUE(pm.IsPriorityExplicit()); -} - -TEST_F(PluginMetadata, Priority) { - loot::PluginMetadata pm; - ASSERT_NE(10, pm.Priority()); - pm.Priority(10); - EXPECT_EQ(10, pm.Priority()); -} - -TEST_F(PluginMetadata, settingPriorityWithAbsoluteValueGreaterOrEqualToGlobalPriorityDivisorShouldThrow) { - loot::PluginMetadata pm; - EXPECT_ANY_THROW(pm.Priority(loot::yamlGlobalPriorityDivisor)); - EXPECT_ANY_THROW(pm.Priority(loot::yamlGlobalPriorityDivisor + 1)); - EXPECT_ANY_THROW(pm.Priority(-loot::yamlGlobalPriorityDivisor)); - EXPECT_ANY_THROW(pm.Priority(-loot::yamlGlobalPriorityDivisor - 1)); -} - -TEST_F(PluginMetadata, settingPriorityAsGlobalShouldSucceed) { - loot::PluginMetadata pm; - ASSERT_FALSE(pm.IsPriorityGlobal()); - pm.SetPriorityGlobal(true); - EXPECT_TRUE(pm.IsPriorityGlobal()); -} - -TEST_F(PluginMetadata, settingPriorityAsNotGlobalShouldSucceed) { - loot::PluginMetadata pm; - pm.SetPriorityGlobal(true); - ASSERT_TRUE(pm.IsPriorityGlobal()); - pm.SetPriorityGlobal(false); - EXPECT_FALSE(pm.IsPriorityGlobal()); -} - -TEST_F(PluginMetadata, gettingYamlPriorityValueForAGlobalPriorityShouldReturnValueWithGlobalFlagSet) { - loot::PluginMetadata pm; - pm.Priority(10); - pm.SetPriorityGlobal(true); - EXPECT_EQ(1000010, pm.GetYamlPriorityValue()); - - pm.Priority(-20); - EXPECT_EQ(-1000020, pm.GetYamlPriorityValue()); -} - -TEST_F(PluginMetadata, gettingYamlPriorityValueForANonGlobalPriorityShouldReturnValueWithGlobalFlagNotSet) { - loot::PluginMetadata pm; - pm.Priority(10); - EXPECT_EQ(10, pm.GetYamlPriorityValue()); - - pm.Priority(-20); - EXPECT_EQ(-20, pm.GetYamlPriorityValue()); -} - -TEST_F(PluginMetadata, LoadAfter) { - loot::PluginMetadata pm; - ASSERT_TRUE(pm.LoadAfter().empty()); - pm.LoadAfter({ - loot::File("Blank.esm") - }); - EXPECT_EQ(std::set({ - loot::File("Blank.esm") - }), pm.LoadAfter()); -} - -TEST_F(PluginMetadata, Reqs) { - loot::PluginMetadata pm; - ASSERT_TRUE(pm.Reqs().empty()); - pm.Reqs({ - loot::File("Blank.esm") - }); - EXPECT_EQ(std::set({ - loot::File("Blank.esm") - }), pm.Reqs()); -} - -TEST_F(PluginMetadata, Incs) { - loot::PluginMetadata pm; - ASSERT_TRUE(pm.Incs().empty()); - pm.Incs({ - loot::File("Blank.esm") - }); - EXPECT_EQ(std::set({ - loot::File("Blank.esm") - }), pm.Incs()); -} - -TEST_F(PluginMetadata, Messages) { - loot::PluginMetadata pm; - ASSERT_TRUE(pm.Messages().empty()); - pm.Messages({ - loot::Message(loot::Message::say, "content") - }); - EXPECT_EQ(std::list({ - loot::Message(loot::Message::say, "content") - }), pm.Messages()); -} - -TEST_F(PluginMetadata, Tags) { - loot::PluginMetadata pm; - ASSERT_TRUE(pm.Tags().empty()); - pm.Tags({ - loot::Tag("Relev") - }); - EXPECT_EQ(std::set({ - loot::Tag("Relev") - }), pm.Tags()); -} - -TEST_F(PluginMetadata, DirtyInfo) { - loot::PluginMetadata pm; - ASSERT_TRUE(pm.DirtyInfo().empty()); - pm.DirtyInfo({ - loot::PluginDirtyInfo(5, 0, 1, 2, "utility") - }); - EXPECT_EQ(std::set({ - loot::PluginDirtyInfo(5, 0, 1, 2, "utility") - }), pm.DirtyInfo()); -} - -TEST_F(PluginMetadata, Locations) { - loot::PluginMetadata pm; - ASSERT_TRUE(pm.Locations().empty()); - pm.Locations({ - loot::Location("http://www.example.com") - }); - EXPECT_EQ(std::set({ - loot::Location("http://www.example.com") - }), pm.Locations()); -} - -TEST_F(PluginMetadata, EvalAllConditions) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); - - loot::PluginMetadata pm(YAML::Load( - "name: 'Blank.esp'\n" - "after:\n" - " - name: 'Blank.esm'\n" - " condition: 'file(\"Blank.esm\")'\n" - "req:\n" - " - name: 'Blank.esm'\n" - " condition: 'file(\"Blank.missing.esm\")'\n" - "inc:\n" - " - name: 'Blank.esm'\n" - " condition: 'file(\"Blank.esm\")'\n" - "msg:\n" - " - type: say\n" - " content: 'content'\n" - "tag:\n" - " - name: Relev\n" - " condition: 'file(\"Blank.missing.esm\")'\n" - "dirty:\n" - " - crc: 0x24F0E2A1\n" - " util: 'utility'\n" - " udr: 1\n" - " nav: 2\n" - " - crc: 0xDEADBEEF\n" - " util: 'utility'\n" - " udr: 1\n" - " nav: 2" - ).as()); - - pm.Messages({loot::Message(loot::Message::say, "content")}); - EXPECT_NO_THROW(pm.EvalAllConditions(game, loot::Language::english)); - EXPECT_EQ(std::set({ - loot::File("Blank.esm", "", "file(\"Blank.esm\")") - }), pm.LoadAfter()); - EXPECT_TRUE(pm.Reqs().empty()); - EXPECT_EQ(std::set({ - loot::File("Blank.esm", "", "file(\"Blank.esm\")") - }), pm.Incs()); - EXPECT_EQ(std::list({ - loot::Message(loot::Message::say, "content") - }), pm.Messages()); - EXPECT_TRUE(pm.Tags().empty()); - EXPECT_EQ(std::set({ - loot::PluginDirtyInfo(0x24F0E2A1, 0, 1, 2, "utility") - }), pm.DirtyInfo()); -} - -TEST_F(PluginMetadata, HasNameOnly) { - loot::PluginMetadata pm; - EXPECT_TRUE(pm.HasNameOnly()); - - pm = loot::PluginMetadata("Blank.esp"); - EXPECT_TRUE(pm.HasNameOnly()); - - pm = loot::PluginMetadata("Blank.esp"); - pm.Enabled(false); - EXPECT_TRUE(pm.HasNameOnly()); - - pm = loot::PluginMetadata("Blank.esp"); - pm.SetPriorityExplicit(true); - EXPECT_FALSE(pm.HasNameOnly()); - - pm = loot::PluginMetadata("Blank.esp"); - pm.LoadAfter({loot::File("Blank.esm")}); - EXPECT_FALSE(pm.HasNameOnly()); - - pm = loot::PluginMetadata("Blank.esp"); - pm.Reqs({loot::File("Blank.esm")}); - EXPECT_FALSE(pm.HasNameOnly()); - - pm = loot::PluginMetadata("Blank.esp"); - pm.Incs({loot::File("Blank.esm")}); - EXPECT_FALSE(pm.HasNameOnly()); - - pm = loot::PluginMetadata("Blank.esp"); - pm.Messages({loot::Message(loot::Message::say, "content")}); - EXPECT_FALSE(pm.HasNameOnly()); - - pm = loot::PluginMetadata("Blank.esp"); - pm.Tags({loot::Tag("Relev")}); - EXPECT_FALSE(pm.HasNameOnly()); - - pm = loot::PluginMetadata("Blank.esp"); - pm.DirtyInfo({loot::PluginDirtyInfo(5, 0, 1, 2, "utility")}); - EXPECT_FALSE(pm.HasNameOnly()); - - pm = loot::PluginMetadata("Blank.esp"); - pm.Locations({loot::Location("http://www.example.com")}); - EXPECT_FALSE(pm.HasNameOnly()); -} - -TEST_F(PluginMetadata, IsRegexPlugin) { - loot::PluginMetadata pm; - EXPECT_FALSE(pm.IsRegexPlugin()); - - pm = loot::PluginMetadata("Blank.esm"); - EXPECT_FALSE(pm.IsRegexPlugin()); - - pm = loot::PluginMetadata("Blank[[:blank:]]- Different.esm"); - EXPECT_TRUE(pm.IsRegexPlugin()); - - pm = loot::PluginMetadata("Blank\\.esm"); - EXPECT_TRUE(pm.IsRegexPlugin()); - - pm = loot::PluginMetadata("Blank - (Different )*Master Dependent.esm"); - EXPECT_TRUE(pm.IsRegexPlugin()); - - pm = loot::PluginMetadata("Blank - (Different )?Master Dependent.esm"); - EXPECT_TRUE(pm.IsRegexPlugin()); - - pm = loot::PluginMetadata("Blank.es(p|m)"); - EXPECT_TRUE(pm.IsRegexPlugin()); -} - -TEST_F(PluginMetadata, YamlEmitter) { - loot::PluginMetadata pm("Blank.esp"); - YAML::Emitter e1; - e1 << pm; - EXPECT_STREQ("", e1.c_str()); - - pm.SetPriorityExplicit(true); - YAML::Emitter e2; - e2 << pm; - EXPECT_STREQ("name: 'Blank.esp'\n" - "priority: 0", e2.c_str()); - - pm.Enabled(false); - YAML::Emitter e3; - e3 << pm; - EXPECT_STREQ("name: 'Blank.esp'\n" - "priority: 0\n" - "enabled: false", e3.c_str()); - - pm.LoadAfter({loot::File("Blank.esm")}); - YAML::Emitter e4; - e4 << pm; - EXPECT_STREQ("name: 'Blank.esp'\n" - "priority: 0\n" - "enabled: false\n" - "after:\n" - " - 'Blank.esm'", e4.c_str()); - - pm.Reqs({loot::File("Blank.esm")}); - YAML::Emitter e5; - e5 << pm; - EXPECT_STREQ("name: 'Blank.esp'\n" - "priority: 0\n" - "enabled: false\n" - "after:\n" - " - 'Blank.esm'\n" - "req:\n" - " - 'Blank.esm'", e5.c_str()); - - pm.Incs({loot::File("Blank.esm")}); - YAML::Emitter e6; - e6 << pm; - EXPECT_STREQ("name: 'Blank.esp'\n" - "priority: 0\n" - "enabled: false\n" - "after:\n" - " - 'Blank.esm'\n" - "req:\n" - " - 'Blank.esm'\n" - "inc:\n" - " - 'Blank.esm'", e6.c_str()); - - pm.Messages({loot::Message(loot::Message::say, "content")}); - YAML::Emitter e7; - e7 << pm; - EXPECT_STREQ("name: 'Blank.esp'\n" - "priority: 0\n" - "enabled: false\n" - "after:\n" - " - 'Blank.esm'\n" - "req:\n" - " - 'Blank.esm'\n" - "inc:\n" - " - 'Blank.esm'\n" - "msg:\n" - " - type: say\n" - " content: 'content'", e7.c_str()); - - pm.Tags({loot::Tag("Relev")}); - YAML::Emitter e8; - e8 << pm; - EXPECT_STREQ("name: 'Blank.esp'\n" - "priority: 0\n" - "enabled: false\n" - "after:\n" - " - 'Blank.esm'\n" - "req:\n" - " - 'Blank.esm'\n" - "inc:\n" - " - 'Blank.esm'\n" - "msg:\n" - " - type: say\n" - " content: 'content'\n" - "tag:\n" - " - Relev", e8.c_str()); - - pm.DirtyInfo({loot::PluginDirtyInfo(5, 0, 1, 2, "utility")}); - YAML::Emitter e9; - e9 << pm; - EXPECT_STREQ("name: 'Blank.esp'\n" - "priority: 0\n" - "enabled: false\n" - "after:\n" - " - 'Blank.esm'\n" - "req:\n" - " - 'Blank.esm'\n" - "inc:\n" - " - 'Blank.esm'\n" - "msg:\n" - " - type: say\n" - " content: 'content'\n" - "tag:\n" - " - Relev\n" - "dirty:\n" - " - crc: 0x5\n" - " util: 'utility'\n" - " udr: 1\n" - " nav: 2", e9.c_str()); - - pm.Locations({loot::Location("http://www.example.com")}); - YAML::Emitter e10; - e10 << pm; - EXPECT_STREQ("name: 'Blank.esp'\n" - "priority: 0\n" - "enabled: false\n" - "after:\n" - " - 'Blank.esm'\n" - "req:\n" - " - 'Blank.esm'\n" - "inc:\n" - " - 'Blank.esm'\n" - "msg:\n" - " - type: say\n" - " content: 'content'\n" - "tag:\n" - " - Relev\n" - "dirty:\n" - " - crc: 0x5\n" - " util: 'utility'\n" - " udr: 1\n" - " nav: 2\n" - "url:\n" - " - 'http://www.example.com'", e10.c_str()); -} - -TEST_F(PluginMetadata, YamlEncode) { - YAML::Node node; - - loot::PluginMetadata pm("Blank.esp"); - node = pm; - EXPECT_EQ("Blank.esp", node["name"].as()); - EXPECT_FALSE(node["enabled"]); - EXPECT_FALSE(node["priority"]); - EXPECT_FALSE(node["after"]); - EXPECT_FALSE(node["req"]); - EXPECT_FALSE(node["inc"]); - EXPECT_FALSE(node["msg"]); - EXPECT_FALSE(node["tag"]); - EXPECT_FALSE(node["dirty"]); - EXPECT_FALSE(node["url"]); - - pm.SetPriorityExplicit(true); - node = pm; - EXPECT_EQ(0, node["priority"].as()); - - pm.Enabled(false); - node = pm; - EXPECT_FALSE(node["enabled"].as()); - - pm.LoadAfter({loot::File("Blank.esm")}); - node = pm; - EXPECT_EQ(pm.LoadAfter(), node["after"].as>()); - - pm.Reqs({loot::File("Blank.esm")}); - node = pm; - EXPECT_EQ(pm.Reqs(), node["req"].as>()); - - pm.Incs({loot::File("Blank.esm")}); - node = pm; - EXPECT_EQ(pm.Incs(), node["inc"].as>()); - - pm.Messages({loot::Message(loot::Message::say, "content")}); - node = pm; - EXPECT_EQ(pm.Messages(), node["msg"].as>()); - - pm.Tags({loot::Tag("Relev")}); - node = pm; - EXPECT_EQ(pm.Tags(), node["tag"].as>()); - - pm.DirtyInfo({loot::PluginDirtyInfo(5, 0, 1, 2, "utility")}); - node = pm; - EXPECT_EQ(pm.DirtyInfo(), node["dirty"].as>()); - - pm.Locations({loot::Location("http://www.example.com")}); - node = pm; - EXPECT_EQ(pm.Locations(), node["url"].as>()); -} - -TEST_F(PluginMetadata, YamlDecode) { - YAML::Node node; - loot::PluginMetadata pm; - - node = YAML::Load("name: Blank.esp"); - pm = node.as(); - EXPECT_EQ("Blank.esp", pm.Name()); - EXPECT_EQ(0, pm.Priority()); - EXPECT_FALSE(pm.IsPriorityExplicit()); - EXPECT_FALSE(pm.IsPriorityGlobal()); - - node = YAML::Load("name: 'Blank.esp'\n" - "priority: 5\n" - "enabled: false\n" - "after:\n" - " - 'Blank.esm'\n" - "req:\n" - " - 'Blank.esm'\n" - "inc:\n" - " - 'Blank.esm'\n" - "msg:\n" - " - type: say\n" - " content: 'content'\n" - "tag:\n" - " - Relev\n" - "dirty:\n" - " - crc: 0x5\n" - " util: 'utility'\n" - " udr: 1\n" - " nav: 2\n" - "url:\n" - " - 'http://www.example.com'"); - pm = node.as(); - EXPECT_EQ("Blank.esp", pm.Name()); - EXPECT_EQ(5, pm.Priority()); - EXPECT_TRUE(pm.IsPriorityExplicit()); - EXPECT_FALSE(pm.IsPriorityGlobal()); - EXPECT_FALSE(pm.Enabled()); - EXPECT_EQ(std::set({ - loot::File("Blank.esm") - }), pm.LoadAfter()); - EXPECT_EQ(std::set({ - loot::File("Blank.esm") - }), pm.Reqs()); - EXPECT_EQ(std::set({ - loot::File("Blank.esm") - }), pm.Incs()); - EXPECT_EQ(std::list({ - loot::Message(loot::Message::say, "content") - }), pm.Messages()); - EXPECT_EQ(std::set({ - loot::Tag("Relev") - }), pm.Tags()); - EXPECT_EQ(std::set({ - loot::PluginDirtyInfo(5, 0, 1, 2, "utility") - }), pm.DirtyInfo()); - EXPECT_EQ(std::set({ - loot::Location("http://www.example.com") - }), pm.Locations()); - - // Don't allow dirty metadata in regex entries. - node = YAML::Load("name: 'Blank\\.esp'\n" - "dirty:\n" - " - crc: 0x5\n" - " util: 'utility'\n" - " udr: 1\n" - " nav: 2"); - EXPECT_THROW(node.as(), YAML::RepresentationException); - - // Don't allow invalid regex. - node = YAML::Load("name: 'RagnvaldBook(Farengar(+Ragnvald)?)?\\.esp'\n" - "dirty:\n" - " - crc: 0x5\n" - " util: 'utility'\n" - " udr: 1\n" - " nav: 2"); - EXPECT_THROW(node.as(), YAML::RepresentationException); - - // Catch condition syntax errors. - node = YAML::Load( - "name: 'Blank.esp'\n" - "after:\n" - " - name: 'Blank.esm'\n" - " condition: 'file(\"Blank.esm\")'\n" - "req:\n" - " - name: 'Blank.esm'\n" - " condition: 'file(\"Blank.missing.esm\")'\n" - "inc:\n" - " - name: 'Blank.esm'\n" - " condition: 'file(\"Blank.esm\")'\n" - "msg:\n" - " - type: say\n" - " content: 'content'\n" - " condition: 'condition'\n" - "tag:\n" - " - name: Relev\n" - " condition: 'file(\"Blank.missing.esm\")'" - ); - EXPECT_THROW(node.as(), YAML::RepresentationException); - - node = YAML::Load("scalar"); - EXPECT_THROW(node.as(), YAML::RepresentationException); - - node = YAML::Load("[0, 1, 2]"); - EXPECT_THROW(node.as(), YAML::RepresentationException); +namespace loot { + namespace test { + class PluginMetadataTest : public SkyrimTest {}; + + TEST_F(PluginMetadataTest, Constructors) { + PluginMetadata pm; + EXPECT_TRUE(pm.Enabled()); + EXPECT_FALSE(pm.IsPriorityExplicit()); + EXPECT_FALSE(pm.IsPriorityGlobal()); + EXPECT_EQ(0, pm.Priority()); + + pm = PluginMetadata("Blank.esm"); + EXPECT_EQ("Blank.esm", pm.Name()); + EXPECT_TRUE(pm.Enabled()); + EXPECT_FALSE(pm.IsPriorityExplicit()); + EXPECT_FALSE(pm.IsPriorityGlobal()); + EXPECT_EQ(0, pm.Priority()); + } + + TEST_F(PluginMetadataTest, EqualityOperator) { + PluginMetadata pm1, pm2; + EXPECT_TRUE(pm1 == pm2); + + pm1 = PluginMetadata("Blank.esm"); + pm2 = PluginMetadata("blank.esm"); + EXPECT_TRUE(pm1 == pm2); + + pm1 = PluginMetadata("Blank.esm"); + pm2 = PluginMetadata("Blan.\\.esm"); + EXPECT_TRUE(pm1 == pm2); + EXPECT_TRUE(pm2 == pm1); + + pm1 = PluginMetadata("Blan.esm"); + pm2 = PluginMetadata("Blan.\\.esm"); + EXPECT_FALSE(pm1 == pm2); + EXPECT_FALSE(pm2 == pm1); + + pm1 = PluginMetadata("Blan.\\.esm"); + pm2 = PluginMetadata("Blan.\\.esm"); + EXPECT_TRUE(pm1 == pm2); + EXPECT_TRUE(pm2 == pm1); + + pm1 = PluginMetadata("Blan(k|p).esm"); + pm2 = PluginMetadata("Blan.\\.esm"); + EXPECT_FALSE(pm1 == pm2); + EXPECT_FALSE(pm2 == pm1); + } + + TEST_F(PluginMetadataTest, MergeMetadata) { + PluginMetadata pm1(YAML::Load( + "name: 'Blank.esp'\n" + "enabled: false\n" + "priority: 5\n" + "after:\n" + " - 'Blank.esm'\n" + "req:\n" + " - 'Blank.esm'\n" + "inc:\n" + " - 'Blank.esm'\n" + "msg:\n" + " - type: say\n" + " content: 'content'\n" + "tag:\n" + " - Relev\n" + "dirty:\n" + " - crc: 0x5\n" + " util: 'utility'\n" + " udr: 1\n" + " nav: 2\n" + "url:\n" + " - 'http://www.example.com'" + ).as()); + + PluginMetadata pm2(YAML::Load( + "name: 'Blank - Different.esp'\n" + "after:\n" + " - 'Blank.esm'\n" + " - 'Blank.esp'\n" + "req:\n" + " - 'Blank.esm'\n" + " - 'Blank.esp'\n" + "inc:\n" + " - 'Blank.esm'\n" + " - 'Blank.esp'\n" + "msg:\n" + " - type: say\n" + " content: 'content'\n" + "tag:\n" + " - Relev\n" + " - -Relev\n" + " - Delev\n" + "dirty:\n" + " - crc: 0x5\n" + " util: 'utility'\n" + " udr: 1\n" + " nav: 2\n" + " - crc: 0x9\n" + " util: 'utility'\n" + " udr: 1\n" + " nav: 2\n" + "url:\n" + " - 'http://www.example.com'\n" + " - 'http://www.example2.com'" + ).as()); + + EXPECT_NO_THROW(pm1.MergeMetadata(pm2)); + EXPECT_EQ("Blank.esp", pm1.Name()); + EXPECT_TRUE(pm1.Enabled()); + EXPECT_EQ(5, pm1.Priority()); + EXPECT_TRUE(pm1.IsPriorityExplicit()); + EXPECT_FALSE(pm1.IsPriorityGlobal()); + EXPECT_EQ(std::set({ + File("Blank.esm"), + File("Blank.esp"), + }), pm1.LoadAfter()); + EXPECT_EQ(std::set({ + File("Blank.esm"), + File("Blank.esp"), + }), pm1.Reqs()); + EXPECT_EQ(std::set({ + File("Blank.esm"), + File("Blank.esp"), + }), pm1.Incs()); + EXPECT_EQ(std::list({ + Message(Message::say, "content"), + Message(Message::say, "content"), + }), pm1.Messages()); + EXPECT_EQ(std::set({ + Tag("Relev"), + Tag("Relev", false), + Tag("Delev"), + }), pm1.Tags()); + EXPECT_EQ(std::set({ + PluginDirtyInfo(5, 0, 1, 2, "utility"), + PluginDirtyInfo(9, 0, 1, 2, "utility"), + }), pm1.DirtyInfo()); + EXPECT_EQ(std::set({ + Location("http://www.example.com"), + Location("http://www.example2.com"), + }), pm1.Locations()); + + pm2.SetPriorityExplicit(true); + EXPECT_NO_THROW(pm1.MergeMetadata(pm2)); + EXPECT_EQ(0, pm1.Priority()); + EXPECT_TRUE(pm1.IsPriorityExplicit()); + EXPECT_FALSE(pm1.IsPriorityGlobal()); + } + + TEST_F(PluginMetadataTest, DiffMetadata) { + PluginMetadata pm1(YAML::Load( + "name: 'Blank.esp'\n" + "enabled: false\n" + "after:\n" + " - 'Blank.esm'\n" + " - 'Blank - Different.esm'\n" + "req:\n" + " - 'Blank.esm'\n" + " - 'Blank - Different.esm'\n" + "inc:\n" + " - 'Blank.esm'\n" + " - 'Blank - Different.esm'\n" + "msg:\n" + " - type: say\n" + " content: 'content'\n" + " - type: say\n" + " content: 'content2'\n" + "tag:\n" + " - Relev\n" + " - NoMerge\n" + "dirty:\n" + " - crc: 0x5\n" + " util: 'utility'\n" + " udr: 1\n" + " nav: 2\n" + " - crc: 0x1\n" + " util: 'utility'\n" + " udr: 1\n" + " nav: 2\n" + "url:\n" + " - 'http://www.example.com'\n" + " - 'http://www.other-example.com'" + ).as()); + + PluginMetadata pm2(YAML::Load( + "name: 'Blank - Different.esp'\n" + "after:\n" + " - 'Blank.esm'\n" + " - 'Blank.esp'\n" + "req:\n" + " - 'Blank.esm'\n" + " - 'Blank.esp'\n" + "inc:\n" + " - 'Blank.esm'\n" + " - 'Blank.esp'\n" + "msg:\n" + " - type: say\n" + " content: 'content'\n" + " - type: say\n" + " content: 'content3'\n" + "tag:\n" + " - Relev\n" + " - -Relev\n" + " - Delev\n" + "dirty:\n" + " - crc: 0x5\n" + " util: 'utility'\n" + " udr: 1\n" + " nav: 2\n" + " - crc: 0x9\n" + " util: 'utility'\n" + " udr: 1\n" + " nav: 2\n" + "url:\n" + " - 'http://www.example.com'\n" + " - 'http://www.example2.com'" + ).as()); + + PluginMetadata result = pm1.DiffMetadata(pm2); + EXPECT_EQ("Blank.esp", result.Name()); + EXPECT_FALSE(result.Enabled()); + EXPECT_EQ(0, result.Priority()); + EXPECT_FALSE(result.IsPriorityExplicit()); + EXPECT_FALSE(result.IsPriorityGlobal()); + EXPECT_EQ(std::set({ + File("Blank.esp"), + File("Blank - Different.esm"), + }), result.LoadAfter()); + EXPECT_EQ(std::set({ + File("Blank.esp"), + File("Blank - Different.esm"), + }), result.Reqs()); + EXPECT_EQ(std::set({ + File("Blank.esp"), + File("Blank - Different.esm"), + }), result.Incs()); + EXPECT_EQ(std::list({ + Message(Message::say, "content2"), + Message(Message::say, "content3"), + }), result.Messages()); + EXPECT_EQ(std::set({ + Tag("Relev", false), + Tag("Delev"), + Tag("NoMerge"), + }), result.Tags()); + EXPECT_EQ(std::set({ + PluginDirtyInfo(9, 0, 1, 2, "utility"), + PluginDirtyInfo(1, 0, 1, 2, "utility"), + }), result.DirtyInfo()); + EXPECT_EQ(std::set({ + Location("http://www.example2.com"), + Location("http://www.other-example.com"), + }), result.Locations()); + + pm1.Priority(5); + result = pm1.DiffMetadata(pm2); + + EXPECT_EQ(5, result.Priority()); + EXPECT_TRUE(result.IsPriorityExplicit()); + EXPECT_FALSE(result.IsPriorityGlobal()); + } + + TEST_F(PluginMetadataTest, NewMetadata) { + PluginMetadata pm1(YAML::Load( + "name: 'Blank.esp'\n" + "enabled: false\n" + "after:\n" + " - 'Blank.esm'\n" + " - 'Blank - Different.esm'\n" + "req:\n" + " - 'Blank.esm'\n" + " - 'Blank - Different.esm'\n" + "inc:\n" + " - 'Blank.esm'\n" + " - 'Blank - Different.esm'\n" + "msg:\n" + " - type: say\n" + " content: 'content'\n" + " - type: say\n" + " content: 'content2'\n" + "tag:\n" + " - Relev\n" + " - NoMerge\n" + "dirty:\n" + " - crc: 0x5\n" + " util: 'utility'\n" + " udr: 1\n" + " nav: 2\n" + " - crc: 0x1\n" + " util: 'utility'\n" + " udr: 1\n" + " nav: 2\n" + "url:\n" + " - 'http://www.example.com'\n" + " - 'http://www.other-example.com'" + ).as()); + + PluginMetadata pm2(YAML::Load( + "name: 'Blank - Different.esp'\n" + "after:\n" + " - 'Blank.esm'\n" + " - 'Blank.esp'\n" + "req:\n" + " - 'Blank.esm'\n" + " - 'Blank.esp'\n" + "inc:\n" + " - 'Blank.esm'\n" + " - 'Blank.esp'\n" + "msg:\n" + " - type: say\n" + " content: 'content'\n" + " - type: say\n" + " content: 'content3'\n" + "tag:\n" + " - Relev\n" + " - -Relev\n" + " - Delev\n" + "dirty:\n" + " - crc: 0x5\n" + " util: 'utility'\n" + " udr: 1\n" + " nav: 2\n" + " - crc: 0x9\n" + " util: 'utility'\n" + " udr: 1\n" + " nav: 2\n" + "url:\n" + " - 'http://www.example.com'\n" + " - 'http://www.example2.com'" + ).as()); + + PluginMetadata result = pm2.NewMetadata(pm1); + EXPECT_EQ("Blank - Different.esp", result.Name()); + EXPECT_TRUE(result.Enabled()); + EXPECT_EQ(0, result.Priority()); + EXPECT_FALSE(result.IsPriorityExplicit()); + EXPECT_FALSE(result.IsPriorityGlobal()); + EXPECT_EQ(std::set({ + File("Blank.esp") + }), result.LoadAfter()); + EXPECT_EQ(std::set({ + File("Blank.esp") + }), result.Reqs()); + EXPECT_EQ(std::set({ + File("Blank.esp") + }), result.Incs()); + EXPECT_EQ(std::list({ + Message(Message::say, "content3"), + }), result.Messages()); + EXPECT_EQ(std::set({ + Tag("Relev", false), + Tag("Delev"), + }), result.Tags()); + EXPECT_EQ(std::set({ + PluginDirtyInfo(9, 0, 1, 2, "utility") + }), result.DirtyInfo()); + EXPECT_EQ(std::set({ + Location("http://www.example2.com") + }), result.Locations()); + + pm1.Priority(5); + result = pm2.NewMetadata(pm1); + + EXPECT_EQ(0, result.Priority()); + EXPECT_FALSE(result.IsPriorityExplicit()); + EXPECT_FALSE(result.IsPriorityGlobal()); + } + + TEST_F(PluginMetadataTest, Enabled) { + PluginMetadata pm; + ASSERT_TRUE(pm.Enabled()); + pm.Enabled(false); + EXPECT_FALSE(pm.Enabled()); + } + + TEST_F(PluginMetadataTest, SetPriorityExplicit) { + PluginMetadata pm; + ASSERT_FALSE(pm.IsPriorityExplicit()); + pm.SetPriorityExplicit(true); + EXPECT_TRUE(pm.IsPriorityExplicit()); + } + + TEST_F(PluginMetadataTest, Priority) { + PluginMetadata pm; + ASSERT_NE(10, pm.Priority()); + pm.Priority(10); + EXPECT_EQ(10, pm.Priority()); + } + + TEST_F(PluginMetadataTest, settingPriorityWithAbsoluteValueGreaterOrEqualToGlobalPriorityDivisorShouldThrow) { + PluginMetadata pm; + EXPECT_ANY_THROW(pm.Priority(yamlGlobalPriorityDivisor)); + EXPECT_ANY_THROW(pm.Priority(yamlGlobalPriorityDivisor + 1)); + EXPECT_ANY_THROW(pm.Priority(-yamlGlobalPriorityDivisor)); + EXPECT_ANY_THROW(pm.Priority(-yamlGlobalPriorityDivisor - 1)); + } + + TEST_F(PluginMetadataTest, settingPriorityAsGlobalShouldSucceed) { + PluginMetadata pm; + ASSERT_FALSE(pm.IsPriorityGlobal()); + pm.SetPriorityGlobal(true); + EXPECT_TRUE(pm.IsPriorityGlobal()); + } + + TEST_F(PluginMetadataTest, settingPriorityAsNotGlobalShouldSucceed) { + PluginMetadata pm; + pm.SetPriorityGlobal(true); + ASSERT_TRUE(pm.IsPriorityGlobal()); + pm.SetPriorityGlobal(false); + EXPECT_FALSE(pm.IsPriorityGlobal()); + } + + TEST_F(PluginMetadataTest, gettingYamlPriorityValueForAGlobalPriorityShouldReturnValueWithGlobalFlagSet) { + PluginMetadata pm; + pm.Priority(10); + pm.SetPriorityGlobal(true); + EXPECT_EQ(1000010, pm.GetYamlPriorityValue()); + + pm.Priority(-20); + EXPECT_EQ(-1000020, pm.GetYamlPriorityValue()); + } + + TEST_F(PluginMetadataTest, gettingYamlPriorityValueForANonGlobalPriorityShouldReturnValueWithGlobalFlagNotSet) { + PluginMetadata pm; + pm.Priority(10); + EXPECT_EQ(10, pm.GetYamlPriorityValue()); + + pm.Priority(-20); + EXPECT_EQ(-20, pm.GetYamlPriorityValue()); + } + + TEST_F(PluginMetadataTest, LoadAfter) { + PluginMetadata pm; + ASSERT_TRUE(pm.LoadAfter().empty()); + pm.LoadAfter({ + File("Blank.esm") + }); + EXPECT_EQ(std::set({ + File("Blank.esm") + }), pm.LoadAfter()); + } + + TEST_F(PluginMetadataTest, Reqs) { + PluginMetadata pm; + ASSERT_TRUE(pm.Reqs().empty()); + pm.Reqs({ + File("Blank.esm") + }); + EXPECT_EQ(std::set({ + File("Blank.esm") + }), pm.Reqs()); + } + + TEST_F(PluginMetadataTest, Incs) { + PluginMetadata pm; + ASSERT_TRUE(pm.Incs().empty()); + pm.Incs({ + File("Blank.esm") + }); + EXPECT_EQ(std::set({ + File("Blank.esm") + }), pm.Incs()); + } + + TEST_F(PluginMetadataTest, Messages) { + PluginMetadata pm; + ASSERT_TRUE(pm.Messages().empty()); + pm.Messages({ + Message(Message::say, "content") + }); + EXPECT_EQ(std::list({ + Message(Message::say, "content") + }), pm.Messages()); + } + + TEST_F(PluginMetadataTest, Tags) { + PluginMetadata pm; + ASSERT_TRUE(pm.Tags().empty()); + pm.Tags({ + Tag("Relev") + }); + EXPECT_EQ(std::set({ + Tag("Relev") + }), pm.Tags()); + } + + TEST_F(PluginMetadataTest, DirtyInfo) { + PluginMetadata pm; + ASSERT_TRUE(pm.DirtyInfo().empty()); + pm.DirtyInfo({ + PluginDirtyInfo(5, 0, 1, 2, "utility") + }); + EXPECT_EQ(std::set({ + PluginDirtyInfo(5, 0, 1, 2, "utility") + }), pm.DirtyInfo()); + } + + TEST_F(PluginMetadataTest, Locations) { + PluginMetadata pm; + ASSERT_TRUE(pm.Locations().empty()); + pm.Locations({ + Location("http://www.example.com") + }); + EXPECT_EQ(std::set({ + Location("http://www.example.com") + }), pm.Locations()); + } + + TEST_F(PluginMetadataTest, EvalAllConditions) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); + ASSERT_NO_THROW(game.Init(false, localPath)); + + PluginMetadata pm(YAML::Load( + "name: 'Blank.esp'\n" + "after:\n" + " - name: 'Blank.esm'\n" + " condition: 'file(\"Blank.esm\")'\n" + "req:\n" + " - name: 'Blank.esm'\n" + " condition: 'file(\"Blank.missing.esm\")'\n" + "inc:\n" + " - name: 'Blank.esm'\n" + " condition: 'file(\"Blank.esm\")'\n" + "msg:\n" + " - type: say\n" + " content: 'content'\n" + "tag:\n" + " - name: Relev\n" + " condition: 'file(\"Blank.missing.esm\")'\n" + "dirty:\n" + " - crc: 0x24F0E2A1\n" + " util: 'utility'\n" + " udr: 1\n" + " nav: 2\n" + " - crc: 0xDEADBEEF\n" + " util: 'utility'\n" + " udr: 1\n" + " nav: 2" + ).as()); + + pm.Messages({Message(Message::say, "content")}); + EXPECT_NO_THROW(pm.EvalAllConditions(game, Language::english)); + EXPECT_EQ(std::set({ + File("Blank.esm", "", "file(\"Blank.esm\")") + }), pm.LoadAfter()); + EXPECT_TRUE(pm.Reqs().empty()); + EXPECT_EQ(std::set({ + File("Blank.esm", "", "file(\"Blank.esm\")") + }), pm.Incs()); + EXPECT_EQ(std::list({ + Message(Message::say, "content") + }), pm.Messages()); + EXPECT_TRUE(pm.Tags().empty()); + EXPECT_EQ(std::set({ + PluginDirtyInfo(0x24F0E2A1, 0, 1, 2, "utility") + }), pm.DirtyInfo()); + } + + TEST_F(PluginMetadataTest, HasNameOnly) { + PluginMetadata pm; + EXPECT_TRUE(pm.HasNameOnly()); + + pm = PluginMetadata("Blank.esp"); + EXPECT_TRUE(pm.HasNameOnly()); + + pm = PluginMetadata("Blank.esp"); + pm.Enabled(false); + EXPECT_TRUE(pm.HasNameOnly()); + + pm = PluginMetadata("Blank.esp"); + pm.SetPriorityExplicit(true); + EXPECT_FALSE(pm.HasNameOnly()); + + pm = PluginMetadata("Blank.esp"); + pm.LoadAfter({File("Blank.esm")}); + EXPECT_FALSE(pm.HasNameOnly()); + + pm = PluginMetadata("Blank.esp"); + pm.Reqs({File("Blank.esm")}); + EXPECT_FALSE(pm.HasNameOnly()); + + pm = PluginMetadata("Blank.esp"); + pm.Incs({File("Blank.esm")}); + EXPECT_FALSE(pm.HasNameOnly()); + + pm = PluginMetadata("Blank.esp"); + pm.Messages({Message(Message::say, "content")}); + EXPECT_FALSE(pm.HasNameOnly()); + + pm = PluginMetadata("Blank.esp"); + pm.Tags({Tag("Relev")}); + EXPECT_FALSE(pm.HasNameOnly()); + + pm = PluginMetadata("Blank.esp"); + pm.DirtyInfo({PluginDirtyInfo(5, 0, 1, 2, "utility")}); + EXPECT_FALSE(pm.HasNameOnly()); + + pm = PluginMetadata("Blank.esp"); + pm.Locations({Location("http://www.example.com")}); + EXPECT_FALSE(pm.HasNameOnly()); + } + + TEST_F(PluginMetadataTest, IsRegexPlugin) { + PluginMetadata pm; + EXPECT_FALSE(pm.IsRegexPlugin()); + + pm = PluginMetadata("Blank.esm"); + EXPECT_FALSE(pm.IsRegexPlugin()); + + pm = PluginMetadata("Blank[[:blank:]]- Different.esm"); + EXPECT_TRUE(pm.IsRegexPlugin()); + + pm = PluginMetadata("Blank\\.esm"); + EXPECT_TRUE(pm.IsRegexPlugin()); + + pm = PluginMetadata("Blank - (Different )*Master Dependent.esm"); + EXPECT_TRUE(pm.IsRegexPlugin()); + + pm = PluginMetadata("Blank - (Different )?Master Dependent.esm"); + EXPECT_TRUE(pm.IsRegexPlugin()); + + pm = PluginMetadata("Blank.es(p|m)"); + EXPECT_TRUE(pm.IsRegexPlugin()); + } + + TEST_F(PluginMetadataTest, YamlEmitter) { + PluginMetadata pm("Blank.esp"); + YAML::Emitter e1; + e1 << pm; + EXPECT_STREQ("", e1.c_str()); + + pm.SetPriorityExplicit(true); + YAML::Emitter e2; + e2 << pm; + EXPECT_STREQ("name: 'Blank.esp'\n" + "priority: 0", e2.c_str()); + + pm.Enabled(false); + YAML::Emitter e3; + e3 << pm; + EXPECT_STREQ("name: 'Blank.esp'\n" + "priority: 0\n" + "enabled: false", e3.c_str()); + + pm.LoadAfter({File("Blank.esm")}); + YAML::Emitter e4; + e4 << pm; + EXPECT_STREQ("name: 'Blank.esp'\n" + "priority: 0\n" + "enabled: false\n" + "after:\n" + " - 'Blank.esm'", e4.c_str()); + + pm.Reqs({File("Blank.esm")}); + YAML::Emitter e5; + e5 << pm; + EXPECT_STREQ("name: 'Blank.esp'\n" + "priority: 0\n" + "enabled: false\n" + "after:\n" + " - 'Blank.esm'\n" + "req:\n" + " - 'Blank.esm'", e5.c_str()); + + pm.Incs({File("Blank.esm")}); + YAML::Emitter e6; + e6 << pm; + EXPECT_STREQ("name: 'Blank.esp'\n" + "priority: 0\n" + "enabled: false\n" + "after:\n" + " - 'Blank.esm'\n" + "req:\n" + " - 'Blank.esm'\n" + "inc:\n" + " - 'Blank.esm'", e6.c_str()); + + pm.Messages({Message(Message::say, "content")}); + YAML::Emitter e7; + e7 << pm; + EXPECT_STREQ("name: 'Blank.esp'\n" + "priority: 0\n" + "enabled: false\n" + "after:\n" + " - 'Blank.esm'\n" + "req:\n" + " - 'Blank.esm'\n" + "inc:\n" + " - 'Blank.esm'\n" + "msg:\n" + " - type: say\n" + " content: 'content'", e7.c_str()); + + pm.Tags({Tag("Relev")}); + YAML::Emitter e8; + e8 << pm; + EXPECT_STREQ("name: 'Blank.esp'\n" + "priority: 0\n" + "enabled: false\n" + "after:\n" + " - 'Blank.esm'\n" + "req:\n" + " - 'Blank.esm'\n" + "inc:\n" + " - 'Blank.esm'\n" + "msg:\n" + " - type: say\n" + " content: 'content'\n" + "tag:\n" + " - Relev", e8.c_str()); + + pm.DirtyInfo({PluginDirtyInfo(5, 0, 1, 2, "utility")}); + YAML::Emitter e9; + e9 << pm; + EXPECT_STREQ("name: 'Blank.esp'\n" + "priority: 0\n" + "enabled: false\n" + "after:\n" + " - 'Blank.esm'\n" + "req:\n" + " - 'Blank.esm'\n" + "inc:\n" + " - 'Blank.esm'\n" + "msg:\n" + " - type: say\n" + " content: 'content'\n" + "tag:\n" + " - Relev\n" + "dirty:\n" + " - crc: 0x5\n" + " util: 'utility'\n" + " udr: 1\n" + " nav: 2", e9.c_str()); + + pm.Locations({Location("http://www.example.com")}); + YAML::Emitter e10; + e10 << pm; + EXPECT_STREQ("name: 'Blank.esp'\n" + "priority: 0\n" + "enabled: false\n" + "after:\n" + " - 'Blank.esm'\n" + "req:\n" + " - 'Blank.esm'\n" + "inc:\n" + " - 'Blank.esm'\n" + "msg:\n" + " - type: say\n" + " content: 'content'\n" + "tag:\n" + " - Relev\n" + "dirty:\n" + " - crc: 0x5\n" + " util: 'utility'\n" + " udr: 1\n" + " nav: 2\n" + "url:\n" + " - 'http://www.example.com'", e10.c_str()); + } + + TEST_F(PluginMetadataTest, YamlEncode) { + YAML::Node node; + + PluginMetadata pm("Blank.esp"); + node = pm; + EXPECT_EQ("Blank.esp", node["name"].as()); + EXPECT_FALSE(node["enabled"]); + EXPECT_FALSE(node["priority"]); + EXPECT_FALSE(node["after"]); + EXPECT_FALSE(node["req"]); + EXPECT_FALSE(node["inc"]); + EXPECT_FALSE(node["msg"]); + EXPECT_FALSE(node["tag"]); + EXPECT_FALSE(node["dirty"]); + EXPECT_FALSE(node["url"]); + + pm.SetPriorityExplicit(true); + node = pm; + EXPECT_EQ(0, node["priority"].as()); + + pm.Enabled(false); + node = pm; + EXPECT_FALSE(node["enabled"].as()); + + pm.LoadAfter({File("Blank.esm")}); + node = pm; + EXPECT_EQ(pm.LoadAfter(), node["after"].as>()); + + pm.Reqs({File("Blank.esm")}); + node = pm; + EXPECT_EQ(pm.Reqs(), node["req"].as>()); + + pm.Incs({File("Blank.esm")}); + node = pm; + EXPECT_EQ(pm.Incs(), node["inc"].as>()); + + pm.Messages({Message(Message::say, "content")}); + node = pm; + EXPECT_EQ(pm.Messages(), node["msg"].as>()); + + pm.Tags({Tag("Relev")}); + node = pm; + EXPECT_EQ(pm.Tags(), node["tag"].as>()); + + pm.DirtyInfo({PluginDirtyInfo(5, 0, 1, 2, "utility")}); + node = pm; + EXPECT_EQ(pm.DirtyInfo(), node["dirty"].as>()); + + pm.Locations({Location("http://www.example.com")}); + node = pm; + EXPECT_EQ(pm.Locations(), node["url"].as>()); + } + + TEST_F(PluginMetadataTest, YamlDecode) { + YAML::Node node; + PluginMetadata pm; + + node = YAML::Load("name: Blank.esp"); + pm = node.as(); + EXPECT_EQ("Blank.esp", pm.Name()); + EXPECT_EQ(0, pm.Priority()); + EXPECT_FALSE(pm.IsPriorityExplicit()); + EXPECT_FALSE(pm.IsPriorityGlobal()); + + node = YAML::Load("name: 'Blank.esp'\n" + "priority: 5\n" + "enabled: false\n" + "after:\n" + " - 'Blank.esm'\n" + "req:\n" + " - 'Blank.esm'\n" + "inc:\n" + " - 'Blank.esm'\n" + "msg:\n" + " - type: say\n" + " content: 'content'\n" + "tag:\n" + " - Relev\n" + "dirty:\n" + " - crc: 0x5\n" + " util: 'utility'\n" + " udr: 1\n" + " nav: 2\n" + "url:\n" + " - 'http://www.example.com'"); + pm = node.as(); + EXPECT_EQ("Blank.esp", pm.Name()); + EXPECT_EQ(5, pm.Priority()); + EXPECT_TRUE(pm.IsPriorityExplicit()); + EXPECT_FALSE(pm.IsPriorityGlobal()); + EXPECT_FALSE(pm.Enabled()); + EXPECT_EQ(std::set({ + File("Blank.esm") + }), pm.LoadAfter()); + EXPECT_EQ(std::set({ + File("Blank.esm") + }), pm.Reqs()); + EXPECT_EQ(std::set({ + File("Blank.esm") + }), pm.Incs()); + EXPECT_EQ(std::list({ + Message(Message::say, "content") + }), pm.Messages()); + EXPECT_EQ(std::set({ + Tag("Relev") + }), pm.Tags()); + EXPECT_EQ(std::set({ + PluginDirtyInfo(5, 0, 1, 2, "utility") + }), pm.DirtyInfo()); + EXPECT_EQ(std::set({ + Location("http://www.example.com") + }), pm.Locations()); + + // Don't allow dirty metadata in regex entries. + node = YAML::Load("name: 'Blank\\.esp'\n" + "dirty:\n" + " - crc: 0x5\n" + " util: 'utility'\n" + " udr: 1\n" + " nav: 2"); + EXPECT_THROW(node.as(), YAML::RepresentationException); + + // Don't allow invalid regex. + node = YAML::Load("name: 'RagnvaldBook(Farengar(+Ragnvald)?)?\\.esp'\n" + "dirty:\n" + " - crc: 0x5\n" + " util: 'utility'\n" + " udr: 1\n" + " nav: 2"); + EXPECT_THROW(node.as(), YAML::RepresentationException); + + // Catch condition syntax errors. + node = YAML::Load( + "name: 'Blank.esp'\n" + "after:\n" + " - name: 'Blank.esm'\n" + " condition: 'file(\"Blank.esm\")'\n" + "req:\n" + " - name: 'Blank.esm'\n" + " condition: 'file(\"Blank.missing.esm\")'\n" + "inc:\n" + " - name: 'Blank.esm'\n" + " condition: 'file(\"Blank.esm\")'\n" + "msg:\n" + " - type: say\n" + " content: 'content'\n" + " condition: 'condition'\n" + "tag:\n" + " - name: Relev\n" + " condition: 'file(\"Blank.missing.esm\")'" + ); + EXPECT_THROW(node.as(), YAML::RepresentationException); + + node = YAML::Load("scalar"); + EXPECT_THROW(node.as(), YAML::RepresentationException); + + node = YAML::Load("[0, 1, 2]"); + EXPECT_THROW(node.as(), YAML::RepresentationException); + } + } } #endif diff --git a/src/tests/backend/metadata/test_tag.h b/src/tests/backend/metadata/test_tag.h index 2b112997..89f7cfea 100644 --- a/src/tests/backend/metadata/test_tag.h +++ b/src/tests/backend/metadata/test_tag.h @@ -28,153 +28,155 @@ along with LOOT. If not, see #include "backend/metadata/tag.h" #include "tests/fixtures.h" -using loot::Tag; +namespace loot { + namespace test { + TEST(Tag, ConstructorsAndDataAccess) { + Tag tag; + EXPECT_EQ("", tag.Name()); + EXPECT_TRUE(tag.IsAddition()); + EXPECT_EQ("", tag.Condition()); -TEST(Tag, ConstructorsAndDataAccess) { - Tag tag; - EXPECT_EQ("", tag.Name()); - EXPECT_TRUE(tag.IsAddition()); - EXPECT_EQ("", tag.Condition()); + tag = Tag("name"); + EXPECT_EQ("name", tag.Name()); + EXPECT_TRUE(tag.IsAddition()); + EXPECT_EQ("", tag.Condition()); - tag = Tag("name"); - EXPECT_EQ("name", tag.Name()); - EXPECT_TRUE(tag.IsAddition()); - EXPECT_EQ("", tag.Condition()); + tag = Tag("name", false); + EXPECT_EQ("name", tag.Name()); + EXPECT_FALSE(tag.IsAddition()); + EXPECT_EQ("", tag.Condition()); - tag = Tag("name", false); - EXPECT_EQ("name", tag.Name()); - EXPECT_FALSE(tag.IsAddition()); - EXPECT_EQ("", tag.Condition()); + // Not a valid condition, but not evaluating it in this test. + tag = Tag("name", false, "condition"); + EXPECT_EQ("name", tag.Name()); + EXPECT_FALSE(tag.IsAddition()); + EXPECT_EQ("condition", tag.Condition()); + } - // Not a valid condition, but not evaluating it in this test. - tag = Tag("name", false, "condition"); - EXPECT_EQ("name", tag.Name()); - EXPECT_FALSE(tag.IsAddition()); - EXPECT_EQ("condition", tag.Condition()); -} + TEST(Tag, EqualityOperator) { + Tag tag1, tag2; + EXPECT_TRUE(tag1 == tag2); -TEST(Tag, EqualityOperator) { - Tag tag1, tag2; - EXPECT_TRUE(tag1 == tag2); + // Not valid conditions, but not evaluating them in this test. + tag1 = Tag("name", true, "condition1"); + tag2 = Tag("name", true, "condition2"); + EXPECT_TRUE(tag1 == tag2); - // Not valid conditions, but not evaluating them in this test. - tag1 = Tag("name", true, "condition1"); - tag2 = Tag("name", true, "condition2"); - EXPECT_TRUE(tag1 == tag2); + tag1 = Tag("name"); + tag2 = Tag("Name"); + EXPECT_TRUE(tag1 == tag2); - tag1 = Tag("name"); - tag2 = Tag("Name"); - EXPECT_TRUE(tag1 == tag2); + tag1 = Tag("name", true); + tag2 = Tag("name", false); + EXPECT_FALSE(tag1 == tag2); - tag1 = Tag("name", true); - tag2 = Tag("name", false); - EXPECT_FALSE(tag1 == tag2); + tag1 = Tag("name1"); + tag2 = Tag("name2"); + EXPECT_FALSE(tag1 == tag2); + } - tag1 = Tag("name1"); - tag2 = Tag("name2"); - EXPECT_FALSE(tag1 == tag2); -} + TEST(Tag, LessThanOperator) { + Tag tag1, tag2; + EXPECT_FALSE(tag1 < tag2); + EXPECT_FALSE(tag2 < tag1); -TEST(Tag, LessThanOperator) { - Tag tag1, tag2; - EXPECT_FALSE(tag1 < tag2); - EXPECT_FALSE(tag2 < tag1); + tag1 = Tag("name", true, "condition1"); + tag2 = Tag("name", true, "condition2"); + EXPECT_FALSE(tag1 < tag2); + EXPECT_FALSE(tag2 < tag1); - tag1 = Tag("name", true, "condition1"); - tag2 = Tag("name", true, "condition2"); - EXPECT_FALSE(tag1 < tag2); - EXPECT_FALSE(tag2 < tag1); + tag1 = Tag("name"); + tag2 = Tag("Name"); + EXPECT_FALSE(tag1 < tag2); + EXPECT_FALSE(tag2 < tag1); - tag1 = Tag("name"); - tag2 = Tag("Name"); - EXPECT_FALSE(tag1 < tag2); - EXPECT_FALSE(tag2 < tag1); + tag1 = Tag("name1"); + tag2 = Tag("name2"); + EXPECT_TRUE(tag1 < tag2); + EXPECT_FALSE(tag2 < tag1); - tag1 = Tag("name1"); - tag2 = Tag("name2"); - EXPECT_TRUE(tag1 < tag2); - EXPECT_FALSE(tag2 < tag1); + tag1 = Tag("name", true); + tag2 = Tag("name", false); + EXPECT_TRUE(tag1 < tag2); + EXPECT_FALSE(tag2 < tag1); + } - tag1 = Tag("name", true); - tag2 = Tag("name", false); - EXPECT_TRUE(tag1 < tag2); - EXPECT_FALSE(tag2 < tag1); -} + TEST(Tag, YamlEmitter) { + Tag tag("name1"); + YAML::Emitter e1; + e1 << tag; + EXPECT_STREQ("name1", e1.c_str()); -TEST(Tag, YamlEmitter) { - Tag tag("name1"); - YAML::Emitter e1; - e1 << tag; - EXPECT_STREQ("name1", e1.c_str()); + tag = Tag("name1", false); + YAML::Emitter e2; + e2 << tag; + EXPECT_STREQ("-name1", e2.c_str()); - tag = Tag("name1", false); - YAML::Emitter e2; - e2 << tag; - EXPECT_STREQ("-name1", e2.c_str()); + tag = Tag("name1", true, "condition1"); + YAML::Emitter e3; + e3 << tag; + EXPECT_STREQ("name: name1\ncondition: 'condition1'", e3.c_str()); - tag = Tag("name1", true, "condition1"); - YAML::Emitter e3; - e3 << tag; - EXPECT_STREQ("name: name1\ncondition: 'condition1'", e3.c_str()); + tag = Tag("name1", false, "condition1"); + YAML::Emitter e4; + e4 << tag; + EXPECT_STREQ("name: -name1\ncondition: 'condition1'", e4.c_str()); + } - tag = Tag("name1", false, "condition1"); - YAML::Emitter e4; - e4 << tag; - EXPECT_STREQ("name: -name1\ncondition: 'condition1'", e4.c_str()); -} + TEST(Tag, YamlEncode) { + YAML::Node node; -TEST(Tag, YamlEncode) { - YAML::Node node; + Tag tag("name1"); + node = tag; + EXPECT_EQ("name1", node["name"].as()); + EXPECT_FALSE(node["condition"]); - Tag tag("name1"); - node = tag; - EXPECT_EQ("name1", node["name"].as()); - EXPECT_FALSE(node["condition"]); + tag = Tag("name1", false); + node = tag; + EXPECT_EQ("-name1", node["name"].as()); + EXPECT_FALSE(node["condition"]); - tag = Tag("name1", false); - node = tag; - EXPECT_EQ("-name1", node["name"].as()); - EXPECT_FALSE(node["condition"]); + tag = Tag("name1", false, "condition1"); + node = tag; + EXPECT_EQ("-name1", node["name"].as()); + EXPECT_EQ("condition1", node["condition"].as()); + } - tag = Tag("name1", false, "condition1"); - node = tag; - EXPECT_EQ("-name1", node["name"].as()); - EXPECT_EQ("condition1", node["condition"].as()); -} + TEST(Tag, YamlDecode) { + YAML::Node node; + Tag tag; -TEST(Tag, YamlDecode) { - YAML::Node node; - Tag tag; + node = YAML::Load("name1"); + tag = node.as(); + EXPECT_EQ("name1", tag.Name()); + EXPECT_TRUE(tag.IsAddition()); + EXPECT_EQ("", tag.Condition()); - node = YAML::Load("name1"); - tag = node.as(); - EXPECT_EQ("name1", tag.Name()); - EXPECT_TRUE(tag.IsAddition()); - EXPECT_EQ("", tag.Condition()); + node = YAML::Load("-name1"); + tag = node.as(); + EXPECT_EQ("name1", tag.Name()); + EXPECT_FALSE(tag.IsAddition()); + EXPECT_EQ("", tag.Condition()); - node = YAML::Load("-name1"); - tag = node.as(); - EXPECT_EQ("name1", tag.Name()); - EXPECT_FALSE(tag.IsAddition()); - EXPECT_EQ("", tag.Condition()); + node = YAML::Load("{name: -name1}"); + tag = node.as(); + EXPECT_EQ("name1", tag.Name()); + EXPECT_FALSE(tag.IsAddition()); + EXPECT_EQ("", tag.Condition()); - node = YAML::Load("{name: -name1}"); - tag = node.as(); - EXPECT_EQ("name1", tag.Name()); - EXPECT_FALSE(tag.IsAddition()); - EXPECT_EQ("", tag.Condition()); + node = YAML::Load("{name: name1, condition: 'file(\"Foo.esp\")'}"); + tag = node.as(); + EXPECT_EQ("name1", tag.Name()); + EXPECT_TRUE(tag.IsAddition()); + EXPECT_EQ("file(\"Foo.esp\")", tag.Condition()); - node = YAML::Load("{name: name1, condition: 'file(\"Foo.esp\")'}"); - tag = node.as(); - EXPECT_EQ("name1", tag.Name()); - EXPECT_TRUE(tag.IsAddition()); - EXPECT_EQ("file(\"Foo.esp\")", tag.Condition()); + node = YAML::Load("{name: name1, condition: invalid}"); + EXPECT_THROW(node.as(), YAML::RepresentationException); - node = YAML::Load("{name: name1, condition: invalid}"); - EXPECT_THROW(node.as(), YAML::RepresentationException); - - node = YAML::Load("[0, 1, 2]"); - EXPECT_THROW(node.as(), YAML::RepresentationException); + node = YAML::Load("[0, 1, 2]"); + EXPECT_THROW(node.as(), YAML::RepresentationException); + } + } } #endif diff --git a/src/tests/backend/plugin/test_plugin.h b/src/tests/backend/plugin/test_plugin.h index 710565d5..cffefa83 100644 --- a/src/tests/backend/plugin/test_plugin.h +++ b/src/tests/backend/plugin/test_plugin.h @@ -28,227 +28,231 @@ along with LOOT. If not, see #include "backend/plugin/plugin.h" #include "tests/fixtures.h" -class Plugin : public SkyrimTest { -protected: - inline virtual void SetUp() { - SkyrimTest::SetUp(); +namespace loot { + namespace test { + class PluginTest : public SkyrimTest { + protected: + inline virtual void SetUp() { + SkyrimTest::SetUp(); - game = loot::Game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); + game = Game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); + ASSERT_NO_THROW(game.Init(false, localPath)); + } + + Game game; + }; + + TEST_F(PluginTest, ConstructorsAndDataAccess) { + Plugin plugin(game, "Blank.esm", true); + EXPECT_EQ("Blank.esm", plugin.Name()); + EXPECT_TRUE(plugin.getFormIds().empty()); + EXPECT_TRUE(plugin.getMasters().empty()); + EXPECT_TRUE(plugin.isMasterFile()); + EXPECT_FALSE(plugin.IsEmpty()); + EXPECT_EQ("v5.0", plugin.getDescription()); + EXPECT_EQ(0, plugin.Crc()); + + plugin = Plugin(game, "Blank.esm", false); + EXPECT_EQ("Blank.esm", plugin.Name()); + EXPECT_EQ(std::set({ + libespm::FormId("Blank.esm", std::vector(), 0xCF0), + libespm::FormId("Blank.esm", std::vector(), 0xCF1), + libespm::FormId("Blank.esm", std::vector(), 0xCF2), + libespm::FormId("Blank.esm", std::vector(), 0xCF3), + libespm::FormId("Blank.esm", std::vector(), 0xCF4), + libespm::FormId("Blank.esm", std::vector(), 0xCF5), + libespm::FormId("Blank.esm", std::vector(), 0xCF6), + libespm::FormId("Blank.esm", std::vector(), 0xCF7), + libespm::FormId("Blank.esm", std::vector(), 0xCF8), + libespm::FormId("Blank.esm", std::vector(), 0xCF9), + }), plugin.getFormIds()); + EXPECT_TRUE(plugin.getMasters().empty()); + EXPECT_TRUE(plugin.isMasterFile()); + EXPECT_FALSE(plugin.IsEmpty()); + EXPECT_EQ("v5.0", plugin.getDescription()); + EXPECT_EQ(0x187BE342, plugin.Crc()); + + plugin = Plugin(game, "Blank - Master Dependent.esp", false); + EXPECT_EQ("Blank - Master Dependent.esp", plugin.Name()); + EXPECT_FALSE(plugin.IsEmpty()); + EXPECT_FALSE(plugin.isMasterFile()); + EXPECT_EQ(std::set({ + libespm::FormId("Blank.esm", std::vector(), 0xCF0), + libespm::FormId("Blank.esm", std::vector(), 0xCF1), + libespm::FormId("Blank - Master Dependent.esp", std::vector(), 0xCE9), + libespm::FormId("Blank - Master Dependent.esp", std::vector(), 0xCEA), + }), plugin.getFormIds()); + EXPECT_EQ(std::vector({ + "Blank.esm" + }), plugin.getMasters()); + EXPECT_EQ("", plugin.getDescription()); + EXPECT_EQ(0x832152DC, plugin.Crc()); + } + + TEST_F(PluginTest, LoadsArchive) { + EXPECT_FALSE(Plugin(game, "Blank - Different.esm", true).LoadsArchive()); + EXPECT_FALSE(Plugin(game, "Blank\\.esm", true).LoadsArchive()); + EXPECT_TRUE(Plugin(game, "Blank.esm", true).LoadsArchive()); + } + + TEST_F(PluginTest, IsValid) { + EXPECT_TRUE(Plugin::IsValid("Blank.esm", game)); + EXPECT_FALSE(Plugin::IsValid("NotAPlugin.esm", game)); + EXPECT_FALSE(Plugin::IsValid("EmptyFile.esm", game)); + } + + TEST_F(PluginTest, IsActive) { + Plugin plugin(game, "Blank.esm", true); + EXPECT_TRUE(plugin.IsActive()); + + plugin = Plugin(game, "Blank.esp", true); + EXPECT_FALSE(plugin.IsActive()); + } + + TEST_F(PluginTest, EqualityOperator) { + Plugin plugin1(game, "Blank.esm", true); + Plugin plugin2(game, "blank.esm", true); + EXPECT_TRUE(plugin1 == plugin2); + EXPECT_TRUE(plugin2 == plugin1); + + plugin2 = Plugin(game, "Blank.esp", true); + EXPECT_FALSE(plugin1 == plugin2); + EXPECT_FALSE(plugin2 == plugin1); + + plugin2 = Plugin(game, "Blan.\\.esm", true); + EXPECT_TRUE(plugin1 == plugin2); + EXPECT_TRUE(plugin2 == plugin1); + + plugin1 = Plugin(game, "Blan.esm", true); + EXPECT_FALSE(plugin1 == plugin2); + EXPECT_FALSE(plugin2 == plugin1); + + plugin1 = Plugin(game, "Blan.\\.esm", true); + EXPECT_TRUE(plugin1 == plugin2); + EXPECT_TRUE(plugin2 == plugin1); + + plugin1 = Plugin(game, "Blan(k|p).esm", true); + EXPECT_FALSE(plugin1 == plugin2); + EXPECT_FALSE(plugin2 == plugin1); + } + + TEST_F(PluginTest, InequalityOperator) { + Plugin plugin1(game, "Blank.esm", true); + Plugin plugin2(game, "blank.esm", true); + EXPECT_FALSE(plugin1 != plugin2); + EXPECT_FALSE(plugin2 != plugin1); + + plugin2 = Plugin(game, "Blank.esp", true); + EXPECT_TRUE(plugin1 != plugin2); + EXPECT_TRUE(plugin2 != plugin1); + + plugin2 = Plugin(game, "Blan.\\.esm", true); + EXPECT_FALSE(plugin1 != plugin2); + EXPECT_FALSE(plugin2 != plugin1); + + plugin1 = Plugin(game, "Blan.esm", true); + EXPECT_TRUE(plugin1 != plugin2); + EXPECT_TRUE(plugin2 != plugin1); + + plugin1 = Plugin(game, "Blan.\\.esm", true); + EXPECT_FALSE(plugin1 != plugin2); + EXPECT_FALSE(plugin2 != plugin1); + + plugin1 = Plugin(game, "Blan(k|p).esm", true); + EXPECT_TRUE(plugin1 != plugin2); + EXPECT_TRUE(plugin2 != plugin1); + } + + TEST_F(PluginTest, DoFormIDsOverlap) { + Plugin plugin1(game, "Blank.esm", true); + Plugin plugin2(game, "blank.esm", true); + EXPECT_FALSE(plugin1.DoFormIDsOverlap(plugin2)); + EXPECT_FALSE(plugin2.DoFormIDsOverlap(plugin1)); + + plugin1 = Plugin(game, "Blank.esm", true); + plugin2 = Plugin(game, "Blank - Master Dependent.esm", true); + EXPECT_FALSE(plugin1.DoFormIDsOverlap(plugin2)); + EXPECT_FALSE(plugin2.DoFormIDsOverlap(plugin1)); + + plugin1 = Plugin(game, "Blank.esm", false); + plugin2 = Plugin(game, "Blank.esp", false); + EXPECT_FALSE(plugin1.DoFormIDsOverlap(plugin2)); + EXPECT_FALSE(plugin2.DoFormIDsOverlap(plugin1)); + + plugin1 = Plugin(game, "Blank.esm", false); + plugin2 = Plugin(game, "Blank - Master Dependent.esm", false); + EXPECT_TRUE(plugin1.DoFormIDsOverlap(plugin2)); + EXPECT_TRUE(plugin2.DoFormIDsOverlap(plugin1)); + } + + TEST_F(PluginTest, OverlapFormIDs) { + Plugin plugin1(game, "Blank.esm", true); + Plugin plugin2(game, "blank.esm", true); + EXPECT_TRUE(plugin1.OverlapFormIDs(plugin2).empty()); + EXPECT_TRUE(plugin2.OverlapFormIDs(plugin1).empty()); + + plugin1 = Plugin(game, "Blank.esm", true); + plugin2 = Plugin(game, "Blank - Master Dependent.esm", true); + EXPECT_TRUE(plugin1.OverlapFormIDs(plugin2).empty()); + EXPECT_TRUE(plugin2.OverlapFormIDs(plugin1).empty()); + + plugin1 = Plugin(game, "Blank.esm", false); + plugin2 = Plugin(game, "Blank.esp", false); + EXPECT_TRUE(plugin1.OverlapFormIDs(plugin2).empty()); + EXPECT_TRUE(plugin2.OverlapFormIDs(plugin1).empty()); + + plugin1 = Plugin(game, "Blank.esm", false); + plugin2 = Plugin(game, "Blank - Master Dependent.esm", false); + EXPECT_EQ(std::set({ + libespm::FormId("Blank.esm", std::vector(), 0xCF0), + libespm::FormId("Blank.esm", std::vector(), 0xCF1), + libespm::FormId("Blank.esm", std::vector(), 0xCF2), + libespm::FormId("Blank.esm", std::vector(), 0xCF3), + }), plugin1.OverlapFormIDs(plugin2)); + EXPECT_EQ(std::set({ + libespm::FormId("Blank.esm", std::vector(), 0xCF0), + libespm::FormId("Blank.esm", std::vector(), 0xCF1), + libespm::FormId("Blank.esm", std::vector(), 0xCF2), + libespm::FormId("Blank.esm", std::vector(), 0xCF3), + }), plugin2.OverlapFormIDs(plugin1)); + } + + TEST_F(PluginTest, CheckInstallValidity) { + Plugin plugin(game, "Blank.esm", false); + plugin.Reqs({ + File("Blank.missing.esm"), + File("Blank.esp"), + File("Blank - Master Dependent.esm"), + }); + plugin.Incs({ + File("Blank - Different.esm"), + File("Skyrim.esm"), + }); + plugin.DirtyInfo({ + PluginDirtyInfo(0x187BE342, 0, 1, 2, "utility1"), + PluginDirtyInfo(0xDEADBEEF, 0, 5, 10, "utility2"), + }); + EXPECT_TRUE(plugin.CheckInstallValidity(game)); + EXPECT_EQ(std::list({ + Message(Message::error, "This plugin requires \"Blank.missing.esm\" to be installed, but it is missing."), + Message(Message::error, "This plugin is incompatible with \"Skyrim.esm\", but both are present."), + PluginDirtyInfo(0x187BE342, 0, 1, 2, "utility1").AsMessage(), + PluginDirtyInfo(0xDEADBEEF, 0, 5, 10, "utility2").AsMessage(), + }), plugin.Messages()); + + plugin = Plugin(game, "Blank - Different Master Dependent.esp", false); + EXPECT_FALSE(plugin.CheckInstallValidity(game)); + EXPECT_EQ(std::list({ + Message(Message::error, "This plugin requires \"Blank - Different.esm\" to be active, but it is inactive."), + }), plugin.Messages()); + + plugin = Plugin(game, "Blank - Different Master Dependent.esp", false); + plugin.Tags({Tag("Filter")}); + EXPECT_FALSE(plugin.CheckInstallValidity(game)); + EXPECT_TRUE(plugin.Messages().empty()); + } } - - loot::Game game; -}; - -TEST_F(Plugin, ConstructorsAndDataAccess) { - loot::Plugin plugin(game, "Blank.esm", true); - EXPECT_EQ("Blank.esm", plugin.Name()); - EXPECT_TRUE(plugin.getFormIds().empty()); - EXPECT_TRUE(plugin.getMasters().empty()); - EXPECT_TRUE(plugin.isMasterFile()); - EXPECT_FALSE(plugin.IsEmpty()); - EXPECT_EQ("v5.0", plugin.getDescription()); - EXPECT_EQ(0, plugin.Crc()); - - plugin = loot::Plugin(game, "Blank.esm", false); - EXPECT_EQ("Blank.esm", plugin.Name()); - EXPECT_EQ(std::set({ - libespm::FormId("Blank.esm", std::vector(), 0xCF0), - libespm::FormId("Blank.esm", std::vector(), 0xCF1), - libespm::FormId("Blank.esm", std::vector(), 0xCF2), - libespm::FormId("Blank.esm", std::vector(), 0xCF3), - libespm::FormId("Blank.esm", std::vector(), 0xCF4), - libespm::FormId("Blank.esm", std::vector(), 0xCF5), - libespm::FormId("Blank.esm", std::vector(), 0xCF6), - libespm::FormId("Blank.esm", std::vector(), 0xCF7), - libespm::FormId("Blank.esm", std::vector(), 0xCF8), - libespm::FormId("Blank.esm", std::vector(), 0xCF9), - }), plugin.getFormIds()); - EXPECT_TRUE(plugin.getMasters().empty()); - EXPECT_TRUE(plugin.isMasterFile()); - EXPECT_FALSE(plugin.IsEmpty()); - EXPECT_EQ("v5.0", plugin.getDescription()); - EXPECT_EQ(0x187BE342, plugin.Crc()); - - plugin = loot::Plugin(game, "Blank - Master Dependent.esp", false); - EXPECT_EQ("Blank - Master Dependent.esp", plugin.Name()); - EXPECT_FALSE(plugin.IsEmpty()); - EXPECT_FALSE(plugin.isMasterFile()); - EXPECT_EQ(std::set({ - libespm::FormId("Blank.esm", std::vector(), 0xCF0), - libespm::FormId("Blank.esm", std::vector(), 0xCF1), - libespm::FormId("Blank - Master Dependent.esp", std::vector(), 0xCE9), - libespm::FormId("Blank - Master Dependent.esp", std::vector(), 0xCEA), - }), plugin.getFormIds()); - EXPECT_EQ(std::vector({ - "Blank.esm" - }), plugin.getMasters()); - EXPECT_EQ("", plugin.getDescription()); - EXPECT_EQ(0x832152DC, plugin.Crc()); -} - -TEST_F(Plugin, LoadsArchive) { - EXPECT_FALSE(loot::Plugin(game, "Blank - Different.esm", true).LoadsArchive()); - EXPECT_FALSE(loot::Plugin(game, "Blank\\.esm", true).LoadsArchive()); - EXPECT_TRUE(loot::Plugin(game, "Blank.esm", true).LoadsArchive()); -} - -TEST_F(Plugin, IsValid) { - EXPECT_TRUE(loot::Plugin::IsValid("Blank.esm", game)); - EXPECT_FALSE(loot::Plugin::IsValid("NotAPlugin.esm", game)); - EXPECT_FALSE(loot::Plugin::IsValid("EmptyFile.esm", game)); -} - -TEST_F(Plugin, IsActive) { - loot::Plugin plugin(game, "Blank.esm", true); - EXPECT_TRUE(plugin.IsActive()); - - plugin = loot::Plugin(game, "Blank.esp", true); - EXPECT_FALSE(plugin.IsActive()); -} - -TEST_F(Plugin, EqualityOperator) { - loot::Plugin plugin1(game, "Blank.esm", true); - loot::Plugin plugin2(game, "blank.esm", true); - EXPECT_TRUE(plugin1 == plugin2); - EXPECT_TRUE(plugin2 == plugin1); - - plugin2 = loot::Plugin(game, "Blank.esp", true); - EXPECT_FALSE(plugin1 == plugin2); - EXPECT_FALSE(plugin2 == plugin1); - - plugin2 = loot::Plugin(game, "Blan.\\.esm", true); - EXPECT_TRUE(plugin1 == plugin2); - EXPECT_TRUE(plugin2 == plugin1); - - plugin1 = loot::Plugin(game, "Blan.esm", true); - EXPECT_FALSE(plugin1 == plugin2); - EXPECT_FALSE(plugin2 == plugin1); - - plugin1 = loot::Plugin(game, "Blan.\\.esm", true); - EXPECT_TRUE(plugin1 == plugin2); - EXPECT_TRUE(plugin2 == plugin1); - - plugin1 = loot::Plugin(game, "Blan(k|p).esm", true); - EXPECT_FALSE(plugin1 == plugin2); - EXPECT_FALSE(plugin2 == plugin1); -} - -TEST_F(Plugin, InequalityOperator) { - loot::Plugin plugin1(game, "Blank.esm", true); - loot::Plugin plugin2(game, "blank.esm", true); - EXPECT_FALSE(plugin1 != plugin2); - EXPECT_FALSE(plugin2 != plugin1); - - plugin2 = loot::Plugin(game, "Blank.esp", true); - EXPECT_TRUE(plugin1 != plugin2); - EXPECT_TRUE(plugin2 != plugin1); - - plugin2 = loot::Plugin(game, "Blan.\\.esm", true); - EXPECT_FALSE(plugin1 != plugin2); - EXPECT_FALSE(plugin2 != plugin1); - - plugin1 = loot::Plugin(game, "Blan.esm", true); - EXPECT_TRUE(plugin1 != plugin2); - EXPECT_TRUE(plugin2 != plugin1); - - plugin1 = loot::Plugin(game, "Blan.\\.esm", true); - EXPECT_FALSE(plugin1 != plugin2); - EXPECT_FALSE(plugin2 != plugin1); - - plugin1 = loot::Plugin(game, "Blan(k|p).esm", true); - EXPECT_TRUE(plugin1 != plugin2); - EXPECT_TRUE(plugin2 != plugin1); -} - -TEST_F(Plugin, DoFormIDsOverlap) { - loot::Plugin plugin1(game, "Blank.esm", true); - loot::Plugin plugin2(game, "blank.esm", true); - EXPECT_FALSE(plugin1.DoFormIDsOverlap(plugin2)); - EXPECT_FALSE(plugin2.DoFormIDsOverlap(plugin1)); - - plugin1 = loot::Plugin(game, "Blank.esm", true); - plugin2 = loot::Plugin(game, "Blank - Master Dependent.esm", true); - EXPECT_FALSE(plugin1.DoFormIDsOverlap(plugin2)); - EXPECT_FALSE(plugin2.DoFormIDsOverlap(plugin1)); - - plugin1 = loot::Plugin(game, "Blank.esm", false); - plugin2 = loot::Plugin(game, "Blank.esp", false); - EXPECT_FALSE(plugin1.DoFormIDsOverlap(plugin2)); - EXPECT_FALSE(plugin2.DoFormIDsOverlap(plugin1)); - - plugin1 = loot::Plugin(game, "Blank.esm", false); - plugin2 = loot::Plugin(game, "Blank - Master Dependent.esm", false); - EXPECT_TRUE(plugin1.DoFormIDsOverlap(plugin2)); - EXPECT_TRUE(plugin2.DoFormIDsOverlap(plugin1)); -} - -TEST_F(Plugin, OverlapFormIDs) { - loot::Plugin plugin1(game, "Blank.esm", true); - loot::Plugin plugin2(game, "blank.esm", true); - EXPECT_TRUE(plugin1.OverlapFormIDs(plugin2).empty()); - EXPECT_TRUE(plugin2.OverlapFormIDs(plugin1).empty()); - - plugin1 = loot::Plugin(game, "Blank.esm", true); - plugin2 = loot::Plugin(game, "Blank - Master Dependent.esm", true); - EXPECT_TRUE(plugin1.OverlapFormIDs(plugin2).empty()); - EXPECT_TRUE(plugin2.OverlapFormIDs(plugin1).empty()); - - plugin1 = loot::Plugin(game, "Blank.esm", false); - plugin2 = loot::Plugin(game, "Blank.esp", false); - EXPECT_TRUE(plugin1.OverlapFormIDs(plugin2).empty()); - EXPECT_TRUE(plugin2.OverlapFormIDs(plugin1).empty()); - - plugin1 = loot::Plugin(game, "Blank.esm", false); - plugin2 = loot::Plugin(game, "Blank - Master Dependent.esm", false); - EXPECT_EQ(std::set({ - libespm::FormId("Blank.esm", std::vector(), 0xCF0), - libespm::FormId("Blank.esm", std::vector(), 0xCF1), - libespm::FormId("Blank.esm", std::vector(), 0xCF2), - libespm::FormId("Blank.esm", std::vector(), 0xCF3), - }), plugin1.OverlapFormIDs(plugin2)); - EXPECT_EQ(std::set({ - libespm::FormId("Blank.esm", std::vector(), 0xCF0), - libespm::FormId("Blank.esm", std::vector(), 0xCF1), - libespm::FormId("Blank.esm", std::vector(), 0xCF2), - libespm::FormId("Blank.esm", std::vector(), 0xCF3), - }), plugin2.OverlapFormIDs(plugin1)); -} - -TEST_F(Plugin, CheckInstallValidity) { - loot::Plugin plugin(game, "Blank.esm", false); - plugin.Reqs({ - loot::File("Blank.missing.esm"), - loot::File("Blank.esp"), - loot::File("Blank - Master Dependent.esm"), - }); - plugin.Incs({ - loot::File("Blank - Different.esm"), - loot::File("Skyrim.esm"), - }); - plugin.DirtyInfo({ - loot::PluginDirtyInfo(0x187BE342, 0, 1, 2, "utility1"), - loot::PluginDirtyInfo(0xDEADBEEF, 0, 5, 10, "utility2"), - }); - EXPECT_TRUE(plugin.CheckInstallValidity(game)); - EXPECT_EQ(std::list({ - loot::Message(loot::Message::error, "This plugin requires \"Blank.missing.esm\" to be installed, but it is missing."), - loot::Message(loot::Message::error, "This plugin is incompatible with \"Skyrim.esm\", but both are present."), - loot::PluginDirtyInfo(0x187BE342, 0, 1, 2, "utility1").AsMessage(), - loot::PluginDirtyInfo(0xDEADBEEF, 0, 5, 10, "utility2").AsMessage(), - }), plugin.Messages()); - - plugin = loot::Plugin(game, "Blank - Different Master Dependent.esp", false); - EXPECT_FALSE(plugin.CheckInstallValidity(game)); - EXPECT_EQ(std::list({ - loot::Message(loot::Message::error, "This plugin requires \"Blank - Different.esm\" to be active, but it is inactive."), - }), plugin.Messages()); - - plugin = loot::Plugin(game, "Blank - Different Master Dependent.esp", false); - plugin.Tags({loot::Tag("Filter")}); - EXPECT_FALSE(plugin.CheckInstallValidity(game)); - EXPECT_TRUE(plugin.Messages().empty()); } #endif diff --git a/src/tests/backend/test_masterlist.h b/src/tests/backend/test_masterlist.h index c1c4fb12..b79b906d 100644 --- a/src/tests/backend/test_masterlist.h +++ b/src/tests/backend/test_masterlist.h @@ -28,125 +28,129 @@ along with LOOT. If not, see #include "backend/masterlist.h" #include "tests/fixtures.h" -class Masterlist : public SkyrimTest {}; +namespace loot { + namespace test { + class MasterlistTest : public SkyrimTest {}; -TEST_F(Masterlist, Update_Game) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - game.SetRepoURL("https://github.com/loot/testing-metadata.git"); - game.SetRepoBranch("master"); - ASSERT_NO_THROW(game.Init(false, localPath)); + TEST_F(MasterlistTest, Update_Game) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); + game.SetRepoURL("https://github.com/loot/testing-metadata.git"); + game.SetRepoBranch("master"); + ASSERT_NO_THROW(game.Init(false, localPath)); - // This may fail on Windows if a 'real' LOOT install is also present. - loot::Masterlist masterlist; - EXPECT_TRUE(masterlist.Update(game)); - EXPECT_TRUE(boost::filesystem::exists(game.MasterlistPath())); + // This may fail on Windows if a 'real' LOOT install is also present. + Masterlist masterlist; + EXPECT_TRUE(masterlist.Update(game)); + EXPECT_TRUE(boost::filesystem::exists(game.MasterlistPath())); - EXPECT_FALSE(masterlist.Update(game)); - EXPECT_TRUE(boost::filesystem::exists(game.MasterlistPath())); -} + EXPECT_FALSE(masterlist.Update(game)); + EXPECT_TRUE(boost::filesystem::exists(game.MasterlistPath())); + } -TEST_F(Masterlist, Update_NonGame_InvalidPath) { - loot::Masterlist masterlist; - EXPECT_ANY_THROW(masterlist.Update(";//\?", - "https://github.com/loot/testing-metadata.git", - "master")); -} + TEST_F(MasterlistTest, Update_NonGame_InvalidPath) { + Masterlist masterlist; + EXPECT_ANY_THROW(masterlist.Update(";//\?", + "https://github.com/loot/testing-metadata.git", + "master")); + } -TEST_F(Masterlist, Update_NonGame_EmptyPath) { - loot::Masterlist masterlist; - EXPECT_ANY_THROW(masterlist.Update("", - "https://github.com/loot/testing-metadata.git", - "master")); -} + TEST_F(MasterlistTest, Update_NonGame_EmptyPath) { + Masterlist masterlist; + EXPECT_ANY_THROW(masterlist.Update("", + "https://github.com/loot/testing-metadata.git", + "master")); + } -TEST_F(Masterlist, Update_NonGame_InvalidBranch) { - loot::Masterlist masterlist; - EXPECT_ANY_THROW(masterlist.Update(masterlistPath, - "https://github.com/loot/testing-metadata.git", - "missing-branch")); -} + TEST_F(MasterlistTest, Update_NonGame_InvalidBranch) { + Masterlist masterlist; + EXPECT_ANY_THROW(masterlist.Update(masterlistPath, + "https://github.com/loot/testing-metadata.git", + "missing-branch")); + } -TEST_F(Masterlist, Update_NonGame_EmptyBranch) { - loot::Masterlist masterlist; - EXPECT_ANY_THROW(masterlist.Update(masterlistPath, - "https://github.com/loot/testing-metadata.git", - "")); -} + TEST_F(MasterlistTest, Update_NonGame_EmptyBranch) { + Masterlist masterlist; + EXPECT_ANY_THROW(masterlist.Update(masterlistPath, + "https://github.com/loot/testing-metadata.git", + "")); + } -TEST_F(Masterlist, Update_NonGame_InvalidUrl) { - loot::Masterlist masterlist; - EXPECT_ANY_THROW(masterlist.Update(masterlistPath, - "https://github.com/loot/does-not-exist.git", - "master")); -} + TEST_F(MasterlistTest, Update_NonGame_InvalidUrl) { + Masterlist masterlist; + EXPECT_ANY_THROW(masterlist.Update(masterlistPath, + "https://github.com/loot/does-not-exist.git", + "master")); + } -TEST_F(Masterlist, Update_NonGame_EmptyUrl) { - loot::Masterlist masterlist; - EXPECT_ANY_THROW(masterlist.Update(masterlistPath, - "", - "master")); -} + TEST_F(MasterlistTest, Update_NonGame_EmptyUrl) { + Masterlist masterlist; + EXPECT_ANY_THROW(masterlist.Update(masterlistPath, + "", + "master")); + } -TEST_F(Masterlist, Update_NonGame) { - loot::Masterlist masterlist; - EXPECT_TRUE(masterlist.Update(masterlistPath, - "https://github.com/loot/testing-metadata.git", - "master")); + TEST_F(MasterlistTest, Update_NonGame) { + Masterlist masterlist; + EXPECT_TRUE(masterlist.Update(masterlistPath, + "https://github.com/loot/testing-metadata.git", + "master")); - EXPECT_FALSE(masterlist.Update(masterlistPath, - "https://github.com/loot/testing-metadata.git", - "master")); -} + EXPECT_FALSE(masterlist.Update(masterlistPath, + "https://github.com/loot/testing-metadata.git", + "master")); + } -TEST_F(Masterlist, GetInfo_NoMasterlist) { - loot::Masterlist masterlist; - EXPECT_ANY_THROW(masterlist.GetInfo(masterlistPath, false)); -} + TEST_F(MasterlistTest, GetInfo_NoMasterlist) { + Masterlist masterlist; + EXPECT_ANY_THROW(masterlist.GetInfo(masterlistPath, false)); + } -TEST_F(Masterlist, GetInfo_NoRepository) { - ASSERT_NO_THROW(boost::filesystem::copy("./testing-metadata/masterlist.yaml", masterlistPath)); + TEST_F(MasterlistTest, GetInfo_NoRepository) { + ASSERT_NO_THROW(boost::filesystem::copy("./testing-metadata/masterlist.yaml", masterlistPath)); - loot::Masterlist masterlist; - EXPECT_ANY_THROW(masterlist.GetInfo(masterlistPath, false)); -} + Masterlist masterlist; + EXPECT_ANY_THROW(masterlist.GetInfo(masterlistPath, false)); + } -TEST_F(Masterlist, GetInfo_LongID) { - loot::Masterlist masterlist; - ASSERT_TRUE(masterlist.Update(masterlistPath, - "https://github.com/loot/testing-metadata.git", - "master")); + TEST_F(MasterlistTest, GetInfo_LongID) { + Masterlist masterlist; + ASSERT_TRUE(masterlist.Update(masterlistPath, + "https://github.com/loot/testing-metadata.git", + "master")); - loot::Masterlist::Info info = masterlist.GetInfo(masterlistPath, false); - EXPECT_EQ(40, info.revision.length()); - EXPECT_EQ(10, info.date.length()); -} + Masterlist::Info info = masterlist.GetInfo(masterlistPath, false); + EXPECT_EQ(40, info.revision.length()); + EXPECT_EQ(10, info.date.length()); + } -TEST_F(Masterlist, GetInfo_ShortID) { - loot::Masterlist masterlist; - ASSERT_TRUE(masterlist.Update(masterlistPath, - "https://github.com/loot/testing-metadata.git", - "master")); + TEST_F(MasterlistTest, GetInfo_ShortID) { + Masterlist masterlist; + ASSERT_TRUE(masterlist.Update(masterlistPath, + "https://github.com/loot/testing-metadata.git", + "master")); - loot::Masterlist::Info info = masterlist.GetInfo(masterlistPath, true); - EXPECT_GE((unsigned)40, info.revision.length()); - EXPECT_LE((unsigned)7, info.revision.length()); - EXPECT_EQ(10, info.date.length()); -} + Masterlist::Info info = masterlist.GetInfo(masterlistPath, true); + EXPECT_GE((unsigned)40, info.revision.length()); + EXPECT_LE((unsigned)7, info.revision.length()); + EXPECT_EQ(10, info.date.length()); + } -TEST_F(Masterlist, GetInfo_Edited) { - loot::Masterlist masterlist; - ASSERT_TRUE(masterlist.Update(masterlistPath, - "https://github.com/loot/testing-metadata.git", - "master")); - boost::filesystem::ofstream out(masterlistPath); - out.close(); + TEST_F(MasterlistTest, GetInfo_Edited) { + Masterlist masterlist; + ASSERT_TRUE(masterlist.Update(masterlistPath, + "https://github.com/loot/testing-metadata.git", + "master")); + boost::filesystem::ofstream out(masterlistPath); + out.close(); - loot::Masterlist::Info info = masterlist.GetInfo(masterlistPath, false); - EXPECT_EQ(49, info.revision.length()); - EXPECT_EQ(" (edited)", info.revision.substr(40)); - EXPECT_EQ(19, info.date.length()); - EXPECT_EQ(" (edited)", info.date.substr(10)); + Masterlist::Info info = masterlist.GetInfo(masterlistPath, false); + EXPECT_EQ(49, info.revision.length()); + EXPECT_EQ(" (edited)", info.revision.substr(40)); + EXPECT_EQ(19, info.date.length()); + EXPECT_EQ(" (edited)", info.date.substr(10)); + } + } } #endif diff --git a/src/tests/backend/test_metadata_list.h b/src/tests/backend/test_metadata_list.h index b4bfa8d7..bcc3475b 100644 --- a/src/tests/backend/test_metadata_list.h +++ b/src/tests/backend/test_metadata_list.h @@ -28,220 +28,224 @@ along with LOOT. If not, see #include "backend/metadata_list.h" #include "tests/fixtures.h" -class MetadataList : public SkyrimTest { -protected: - MetadataList() : - metadataPath("./testing-metadata/masterlist.yaml"), - savedMetadataPath("./testing-metadata/saved.masterlist.yaml"), - invalidMetadataPaths({"./testing-metadata/invalid/non_unique.yaml"}) { - PluginMetadataToString = [](const loot::PluginMetadata& plugin) { - return plugin.Name(); +namespace loot { + namespace test { + class MetadataListTest : public SkyrimTest { + protected: + MetadataListTest() : + metadataPath("./testing-metadata/masterlist.yaml"), + savedMetadataPath("./testing-metadata/saved.masterlist.yaml"), + invalidMetadataPaths({"./testing-metadata/invalid/non_unique.yaml"}) { + PluginMetadataToString = [](const PluginMetadata& plugin) { + return plugin.Name(); + }; + } + + inline virtual void SetUp() { + SkyrimTest::SetUp(); + + ASSERT_TRUE(boost::filesystem::exists(metadataPath)); + ASSERT_FALSE(boost::filesystem::exists(savedMetadataPath)); + + for (const auto& path : invalidMetadataPaths) { + ASSERT_TRUE(boost::filesystem::exists(path)); + } + } + + inline virtual void TearDown() { + SkyrimTest::TearDown(); + + ASSERT_TRUE(boost::filesystem::exists(metadataPath)); + ASSERT_NO_THROW(boost::filesystem::remove(savedMetadataPath)); + + for (const auto& path : invalidMetadataPaths) { + ASSERT_TRUE(boost::filesystem::exists(path)); + } + } + + const boost::filesystem::path metadataPath; + const boost::filesystem::path savedMetadataPath; + const std::vector invalidMetadataPaths; + + std::function PluginMetadataToString; }; - } - inline virtual void SetUp() { - SkyrimTest::SetUp(); + TEST_F(MetadataListTest, Load) { + MetadataList ml; + EXPECT_NO_THROW(ml.Load(metadataPath)); + EXPECT_EQ(std::list({ + Message(Message::say, "A global message."), + }), ml.Messages()); - ASSERT_TRUE(boost::filesystem::exists(metadataPath)); - ASSERT_FALSE(boost::filesystem::exists(savedMetadataPath)); + // Non-regex plugins can be outputted in any order, and regex entries can + // match each other, so convert the list to a set of strings for + // comparison. + std::list result(ml.Plugins()); + std::set names; + std::transform(result.begin(), + result.end(), + std::insert_iterator>(names, names.begin()), + PluginMetadataToString); + EXPECT_EQ(std::set({ + "Blank.esm", + "Blank.esp", + "Blank.+\\.esp", + "Blank.+(Different)?.*\\.esp", + }), names); - for (const auto& path : invalidMetadataPaths) { - ASSERT_TRUE(boost::filesystem::exists(path)); + EXPECT_ANY_THROW(ml.Load("NotAPlugin.esm")); + EXPECT_TRUE(ml.Messages().empty()); + EXPECT_TRUE(ml.Plugins().empty()); + + // Fill the list again. + ASSERT_NO_THROW(ml.Load(metadataPath)); + + EXPECT_ANY_THROW(ml.Load("Blank.missing.esm")); + EXPECT_TRUE(ml.Messages().empty()); + EXPECT_TRUE(ml.Plugins().empty()); + } + + TEST_F(MetadataListTest, Load_Invalid) { + MetadataList ml; + for (const auto& path : invalidMetadataPaths) { + EXPECT_ANY_THROW(ml.Load(path)); + } + } + + TEST_F(MetadataListTest, Save) { + MetadataList ml; + ASSERT_NO_THROW(ml.Load(metadataPath)); + + EXPECT_NO_THROW(ml.Save(savedMetadataPath)); + EXPECT_TRUE(boost::filesystem::exists(savedMetadataPath)); + EXPECT_NO_THROW(ml.Load(savedMetadataPath)); + + EXPECT_EQ(std::list({ + Message(Message::say, "A global message."), + }), ml.Messages()); + + // Non-regex plugins can be outputted in any order, and regex entries can + // match each other, so convert the list to a set of strings for + // comparison. + std::list result(ml.Plugins()); + std::set names; + std::transform(result.begin(), + result.end(), + std::insert_iterator>(names, names.begin()), + PluginMetadataToString); + EXPECT_EQ(std::set({ + "Blank.esm", + "Blank.esp", + "Blank.+\\.esp", + "Blank.+(Different)?.*\\.esp", + }), names); + } + + TEST_F(MetadataListTest, clear) { + MetadataList ml; + ASSERT_NO_THROW(ml.Load(metadataPath)); + ASSERT_FALSE(ml.Messages().empty()); + ASSERT_FALSE(ml.Plugins().empty()); + + ml.clear(); + EXPECT_TRUE(ml.Messages().empty()); + EXPECT_TRUE(ml.Plugins().empty()); + } + + TEST_F(MetadataListTest, FindPlugin) { + MetadataList ml; + ASSERT_NO_THROW(ml.Load(metadataPath)); + + PluginMetadata pm = ml.FindPlugin(PluginMetadata("Blank - Different.esm")); + EXPECT_EQ("Blank - Different.esm", pm.Name()); + EXPECT_TRUE(pm.HasNameOnly()); + + pm = ml.FindPlugin(PluginMetadata("Blank - Different.esp")); + EXPECT_EQ("Blank - Different.esp", pm.Name()); + EXPECT_EQ(std::set({ + File("Blank.esm"), + }), pm.LoadAfter()); + EXPECT_EQ(std::set({ + File("Blank.esp"), + }), pm.Incs()); + } + + TEST_F(MetadataListTest, AddPlugin) { + MetadataList ml; + ASSERT_NO_THROW(ml.Load(metadataPath)); + + PluginMetadata pm = ml.FindPlugin(PluginMetadata("Blank - Different.esm")); + ASSERT_EQ("Blank - Different.esm", pm.Name()); + ASSERT_TRUE(pm.HasNameOnly()); + + pm.Priority(1000); + ml.AddPlugin(pm); + pm = ml.FindPlugin(pm); + EXPECT_EQ("Blank - Different.esm", pm.Name()); + EXPECT_EQ(1000, pm.Priority()); + + pm = PluginMetadata(".+Dependent\\.esp"); + pm.Priority(-10); + ml.AddPlugin(pm); + pm = ml.FindPlugin(PluginMetadata("Blank - Plugin Dependent.esp")); + EXPECT_EQ(-10, pm.Priority()); + } + + TEST_F(MetadataListTest, AddPlugin_NonUnique) { + MetadataList ml; + ASSERT_NO_THROW(ml.Load(metadataPath)); + + PluginMetadata pm = ml.FindPlugin(PluginMetadata("Blank.esm")); + ASSERT_EQ("Blank.esm", pm.Name()); + ASSERT_FALSE(pm.HasNameOnly()); + + ASSERT_ANY_THROW(ml.AddPlugin(PluginMetadata("Blank.esm"))); + } + + TEST_F(MetadataListTest, ErasePlugin) { + MetadataList ml; + ASSERT_NO_THROW(ml.Load(metadataPath)); + + PluginMetadata pm = ml.FindPlugin(PluginMetadata("Blank.esp")); + ASSERT_EQ("Blank.esp", pm.Name()); + ASSERT_FALSE(pm.HasNameOnly()); + + ml.ErasePlugin(pm); + pm = ml.FindPlugin(pm); + ASSERT_EQ("Blank.esp", pm.Name()); + ASSERT_TRUE(pm.HasNameOnly()); + } + + TEST_F(MetadataListTest, EvalAllConditions) { + Game game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); + ASSERT_NO_THROW(game.Init(false, localPath)); + + MetadataList ml; + ASSERT_NO_THROW(ml.Load(metadataPath)); + + PluginMetadata pm = ml.FindPlugin(PluginMetadata("Blank.esm")); + ASSERT_EQ(std::list({ + Message(Message::warn, "This is a warning."), + Message(Message::say, "This message should be removed when evaluating conditions."), + }), pm.Messages()); + + pm = ml.FindPlugin(PluginMetadata("Blank.esp")); + ASSERT_EQ("Blank.esp", pm.Name()); + ASSERT_FALSE(pm.HasNameOnly()); + + EXPECT_NO_THROW(ml.EvalAllConditions(game, Language::english)); + + pm = ml.FindPlugin(PluginMetadata("Blank.esm")); + EXPECT_EQ(std::list({ + Message(Message::warn, "This is a warning."), + }), pm.Messages()); + + pm = ml.FindPlugin(PluginMetadata("Blank.esp")); + EXPECT_EQ("Blank.esp", pm.Name()); + EXPECT_TRUE(pm.HasNameOnly()); } } - - inline virtual void TearDown() { - SkyrimTest::TearDown(); - - ASSERT_TRUE(boost::filesystem::exists(metadataPath)); - ASSERT_NO_THROW(boost::filesystem::remove(savedMetadataPath)); - - for (const auto& path : invalidMetadataPaths) { - ASSERT_TRUE(boost::filesystem::exists(path)); - } - } - - const boost::filesystem::path metadataPath; - const boost::filesystem::path savedMetadataPath; - const std::vector invalidMetadataPaths; - - std::function PluginMetadataToString; -}; - -TEST_F(MetadataList, Load) { - loot::MetadataList ml; - EXPECT_NO_THROW(ml.Load(metadataPath)); - EXPECT_EQ(std::list({ - loot::Message(loot::Message::say, "A global message."), - }), ml.Messages()); - - // Non-regex plugins can be outputted in any order, and regex entries can - // match each other, so convert the list to a set of strings for - // comparison. - std::list result(ml.Plugins()); - std::set names; - std::transform(result.begin(), - result.end(), - std::insert_iterator>(names, names.begin()), - PluginMetadataToString); - EXPECT_EQ(std::set({ - "Blank.esm", - "Blank.esp", - "Blank.+\\.esp", - "Blank.+(Different)?.*\\.esp", - }), names); - - EXPECT_ANY_THROW(ml.Load("NotAPlugin.esm")); - EXPECT_TRUE(ml.Messages().empty()); - EXPECT_TRUE(ml.Plugins().empty()); - - // Fill the list again. - ASSERT_NO_THROW(ml.Load(metadataPath)); - - EXPECT_ANY_THROW(ml.Load("Blank.missing.esm")); - EXPECT_TRUE(ml.Messages().empty()); - EXPECT_TRUE(ml.Plugins().empty()); -} - -TEST_F(MetadataList, Load_Invalid) { - loot::MetadataList ml; - for (const auto& path : invalidMetadataPaths) { - EXPECT_ANY_THROW(ml.Load(path)); - } -} - -TEST_F(MetadataList, Save) { - loot::MetadataList ml; - ASSERT_NO_THROW(ml.Load(metadataPath)); - - EXPECT_NO_THROW(ml.Save(savedMetadataPath)); - EXPECT_TRUE(boost::filesystem::exists(savedMetadataPath)); - EXPECT_NO_THROW(ml.Load(savedMetadataPath)); - - EXPECT_EQ(std::list({ - loot::Message(loot::Message::say, "A global message."), - }), ml.Messages()); - - // Non-regex plugins can be outputted in any order, and regex entries can - // match each other, so convert the list to a set of strings for - // comparison. - std::list result(ml.Plugins()); - std::set names; - std::transform(result.begin(), - result.end(), - std::insert_iterator>(names, names.begin()), - PluginMetadataToString); - EXPECT_EQ(std::set({ - "Blank.esm", - "Blank.esp", - "Blank.+\\.esp", - "Blank.+(Different)?.*\\.esp", - }), names); -} - -TEST_F(MetadataList, clear) { - loot::MetadataList ml; - ASSERT_NO_THROW(ml.Load(metadataPath)); - ASSERT_FALSE(ml.Messages().empty()); - ASSERT_FALSE(ml.Plugins().empty()); - - ml.clear(); - EXPECT_TRUE(ml.Messages().empty()); - EXPECT_TRUE(ml.Plugins().empty()); -} - -TEST_F(MetadataList, FindPlugin) { - loot::MetadataList ml; - ASSERT_NO_THROW(ml.Load(metadataPath)); - - loot::PluginMetadata pm = ml.FindPlugin(loot::PluginMetadata("Blank - Different.esm")); - EXPECT_EQ("Blank - Different.esm", pm.Name()); - EXPECT_TRUE(pm.HasNameOnly()); - - pm = ml.FindPlugin(loot::PluginMetadata("Blank - Different.esp")); - EXPECT_EQ("Blank - Different.esp", pm.Name()); - EXPECT_EQ(std::set({ - loot::File("Blank.esm"), - }), pm.LoadAfter()); - EXPECT_EQ(std::set({ - loot::File("Blank.esp"), - }), pm.Incs()); -} - -TEST_F(MetadataList, AddPlugin) { - loot::MetadataList ml; - ASSERT_NO_THROW(ml.Load(metadataPath)); - - loot::PluginMetadata pm = ml.FindPlugin(loot::PluginMetadata("Blank - Different.esm")); - ASSERT_EQ("Blank - Different.esm", pm.Name()); - ASSERT_TRUE(pm.HasNameOnly()); - - pm.Priority(1000); - ml.AddPlugin(pm); - pm = ml.FindPlugin(pm); - EXPECT_EQ("Blank - Different.esm", pm.Name()); - EXPECT_EQ(1000, pm.Priority()); - - pm = loot::PluginMetadata(".+Dependent\\.esp"); - pm.Priority(-10); - ml.AddPlugin(pm); - pm = ml.FindPlugin(loot::PluginMetadata("Blank - Plugin Dependent.esp")); - EXPECT_EQ(-10, pm.Priority()); -} - -TEST_F(MetadataList, AddPlugin_NonUnique) { - loot::MetadataList ml; - ASSERT_NO_THROW(ml.Load(metadataPath)); - - loot::PluginMetadata pm = ml.FindPlugin(loot::PluginMetadata("Blank.esm")); - ASSERT_EQ("Blank.esm", pm.Name()); - ASSERT_FALSE(pm.HasNameOnly()); - - ASSERT_ANY_THROW(ml.AddPlugin(loot::PluginMetadata("Blank.esm"))); -} - -TEST_F(MetadataList, ErasePlugin) { - loot::MetadataList ml; - ASSERT_NO_THROW(ml.Load(metadataPath)); - - loot::PluginMetadata pm = ml.FindPlugin(loot::PluginMetadata("Blank.esp")); - ASSERT_EQ("Blank.esp", pm.Name()); - ASSERT_FALSE(pm.HasNameOnly()); - - ml.ErasePlugin(pm); - pm = ml.FindPlugin(pm); - ASSERT_EQ("Blank.esp", pm.Name()); - ASSERT_TRUE(pm.HasNameOnly()); -} - -TEST_F(MetadataList, EvalAllConditions) { - loot::Game game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); - - loot::MetadataList ml; - ASSERT_NO_THROW(ml.Load(metadataPath)); - - loot::PluginMetadata pm = ml.FindPlugin(loot::PluginMetadata("Blank.esm")); - ASSERT_EQ(std::list({ - loot::Message(loot::Message::warn, "This is a warning."), - loot::Message(loot::Message::say, "This message should be removed when evaluating conditions."), - }), pm.Messages()); - - pm = ml.FindPlugin(loot::PluginMetadata("Blank.esp")); - ASSERT_EQ("Blank.esp", pm.Name()); - ASSERT_FALSE(pm.HasNameOnly()); - - EXPECT_NO_THROW(ml.EvalAllConditions(game, loot::Language::english)); - - pm = ml.FindPlugin(loot::PluginMetadata("Blank.esm")); - EXPECT_EQ(std::list({ - loot::Message(loot::Message::warn, "This is a warning."), - }), pm.Messages()); - - pm = ml.FindPlugin(loot::PluginMetadata("Blank.esp")); - EXPECT_EQ("Blank.esp", pm.Name()); - EXPECT_TRUE(pm.HasNameOnly()); } #endif diff --git a/src/tests/backend/test_plugin_sorter.h b/src/tests/backend/test_plugin_sorter.h index 06bd3be2..9f9aa847 100644 --- a/src/tests/backend/test_plugin_sorter.h +++ b/src/tests/backend/test_plugin_sorter.h @@ -28,241 +28,245 @@ along with LOOT. If not, see #include "backend/plugin_sorter.h" #include "tests/fixtures.h" -class PluginSorter : public SkyrimTest { -protected: - inline virtual void SetUp() { - SkyrimTest::SetUp(); +namespace loot { + namespace test { + class PluginSorterTest : public SkyrimTest { + protected: + inline virtual void SetUp() { + SkyrimTest::SetUp(); - game = loot::Game(loot::Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); + game = Game(Game::tes5); + game.SetGamePath(dataPath.parent_path()); + ASSERT_NO_THROW(game.Init(false, localPath)); + } + + inline std::list GetExpectedSortedOrder() const { + return std::list({ + "Skyrim.esm", + "Blank.esm", + "Blank - Different.esm", + "Blank - Master Dependent.esm", + "Blank - Different Master Dependent.esm", + "Blank.esp", + "Blank - Different.esp", + "Blank - Master Dependent.esp", + "Blank - Different Master Dependent.esp", + "Blank - Plugin Dependent.esp", + "Blank - Different Plugin Dependent.esp", + }); + } + + inline static std::list GetActualSortedOrder(const std::list& sortedPlugins) { + std::list output; + std::transform(begin(sortedPlugins), + end(sortedPlugins), + std::back_inserter(output), + [](const Plugin& plugin) { + return plugin.Name(); + }); + return output; + } + + Game game; + std::function callback; + }; + + TEST_F(PluginSorterTest, Sort_NoPlugins) { + PluginSorter ps; + std::list sorted = ps.Sort(game, Language::english); + EXPECT_TRUE(sorted.empty()); + } + + TEST_F(PluginSorterTest, Sort) { + ASSERT_NO_THROW(game.LoadPlugins(false)); + + PluginSorter ps; + std::list expectedSortedOrder = GetExpectedSortedOrder(); + + std::list sorted = ps.Sort(game, Language::english); + EXPECT_TRUE(std::equal(begin(sorted), end(sorted), begin(expectedSortedOrder))); + + // Check stability. + sorted = ps.Sort(game, Language::english); + EXPECT_TRUE(std::equal(begin(sorted), end(sorted), begin(expectedSortedOrder))); + } + + TEST_F(PluginSorterTest, sortingShouldClearExistingGameMessages) { + ASSERT_NO_THROW(game.LoadPlugins(false)); + game.AppendMessage(Message(Message::say, "1")); + ASSERT_FALSE(game.GetMessages().empty()); + + PluginSorter ps; + std::list sorted = ps.Sort(game, Language::english); + EXPECT_TRUE(game.GetMessages().empty()); + } + + TEST_F(PluginSorterTest, failedSortShouldNotClearExistingGameMessages) { + ASSERT_NO_THROW(game.LoadPlugins(false)); + PluginMetadata plugin("Blank.esm"); + plugin.LoadAfter({File("Blank - Master Dependent.esm")}); + game.GetUserlist().AddPlugin(plugin); + game.AppendMessage(Message(Message::say, "1")); + ASSERT_FALSE(game.GetMessages().empty()); + + PluginSorter ps; + EXPECT_ANY_THROW(ps.Sort(game, Language::english)); + EXPECT_FALSE(game.GetMessages().empty()); + } + + TEST_F(PluginSorterTest, Sort_HeadersOnly) { + ASSERT_NO_THROW(game.LoadPlugins(true)); + + PluginSorter ps; + std::list expectedSortedOrder = GetExpectedSortedOrder(); + + std::list sorted = ps.Sort(game, Language::english); + EXPECT_TRUE(std::equal(begin(sorted), end(sorted), begin(expectedSortedOrder))); + } + + TEST_F(PluginSorterTest, Sort_WithPriority) { + ASSERT_NO_THROW(game.LoadPlugins(false)); + PluginMetadata plugin("Blank - Different Master Dependent.esp"); + plugin.Priority(-100000); + plugin.SetPriorityGlobal(true); + game.GetUserlist().AddPlugin(plugin); + + PluginSorter ps; + std::list expectedSortedOrder({ + "Skyrim.esm", + "Blank.esm", + "Blank - Different.esm", + "Blank - Master Dependent.esm", + "Blank - Different Master Dependent.esm", + "Blank - Different Master Dependent.esp", + "Blank.esp", + "Blank - Different.esp", + "Blank - Master Dependent.esp", + "Blank - Plugin Dependent.esp", + "Blank - Different Plugin Dependent.esp", + }); + + std::list sorted = ps.Sort(game, Language::english); + EXPECT_TRUE(std::equal(begin(sorted), end(sorted), begin(expectedSortedOrder))); + } + + TEST_F(PluginSorterTest, sortingWithPrioritiesShouldInheritRecursivelyRegardlessOfEvaluationOrder) { + ASSERT_NO_THROW(game.LoadPlugins(false)); + + // Set Blank.esp's priority. + PluginMetadata plugin("Blank.esp"); + plugin.Priority(2); + game.GetUserlist().AddPlugin(plugin); + + // Load Blank - Master Dependent.esp after Blank.esp so that it + // inherits Blank.esp's priority. + plugin = PluginMetadata("Blank - Master Dependent.esp"); + plugin.LoadAfter({ + File("Blank.esp"), + }); + game.GetUserlist().AddPlugin(plugin); + + // Load Blank - Different.esp after Blank - Master Dependent.esp, so + // that it inherits its inherited priority. + plugin = PluginMetadata("Blank - Different.esp"); + plugin.LoadAfter({ + File("Blank - Master Dependent.esp"), + }); + game.GetUserlist().AddPlugin(plugin); + + // Set Blank - Different Master Dependent.esp to have a higher priority + // than 0 but lower than Blank.esp. Need to also make it a global priority + // because it doesn't otherwise conflict with the other plugins. + plugin = PluginMetadata("Blank - Different Master Dependent.esp"); + plugin.Priority(1); + plugin.SetPriorityGlobal(true); + game.GetUserlist().AddPlugin(plugin); + + PluginSorter ps; + std::list expectedSortedOrder({ + "Skyrim.esm", + "Blank.esm", + "Blank - Different.esm", + "Blank - Master Dependent.esm", + "Blank - Different Master Dependent.esm", + "Blank - Different Master Dependent.esp", + "Blank.esp", + "Blank - Master Dependent.esp", + "Blank - Different.esp", + "Blank - Plugin Dependent.esp", + "Blank - Different Plugin Dependent.esp", + }); + + std::list actualSortedOrder = GetActualSortedOrder(ps.Sort(game, Language::english)); + EXPECT_EQ(expectedSortedOrder, actualSortedOrder); + } + + TEST_F(PluginSorterTest, Sort_WithLoadAfter) { + ASSERT_NO_THROW(game.LoadPlugins(false)); + PluginMetadata plugin("Blank.esp"); + plugin.LoadAfter({ + File("Blank - Different.esp"), + File("Blank - Different Plugin Dependent.esp"), + }); + game.GetUserlist().AddPlugin(plugin); + + PluginSorter ps; + std::list expectedSortedOrder({ + "Skyrim.esm", + "Blank.esm", + "Blank - Different.esm", + "Blank - Master Dependent.esm", + "Blank - Different Master Dependent.esm", + "Blank - Different.esp", + "Blank - Master Dependent.esp", + "Blank - Different Master Dependent.esp", + "Blank - Different Plugin Dependent.esp", + "Blank.esp", + "Blank - Plugin Dependent.esp", + }); + + std::list sorted = ps.Sort(game, Language::english); + EXPECT_TRUE(std::equal(begin(sorted), end(sorted), begin(expectedSortedOrder))); + } + + TEST_F(PluginSorterTest, Sort_WithRequirements) { + ASSERT_NO_THROW(game.LoadPlugins(false)); + PluginMetadata plugin("Blank.esp"); + plugin.Reqs({ + File("Blank - Different.esp"), + File("Blank - Different Plugin Dependent.esp"), + }); + game.GetUserlist().AddPlugin(plugin); + + PluginSorter ps; + std::list expectedSortedOrder({ + "Skyrim.esm", + "Blank.esm", + "Blank - Different.esm", + "Blank - Master Dependent.esm", + "Blank - Different Master Dependent.esm", + "Blank - Different.esp", + "Blank - Master Dependent.esp", + "Blank - Different Master Dependent.esp", + "Blank - Different Plugin Dependent.esp", + "Blank.esp", + "Blank - Plugin Dependent.esp", + }); + + std::list sorted = ps.Sort(game, Language::english); + EXPECT_TRUE(std::equal(begin(sorted), end(sorted), begin(expectedSortedOrder))); + } + + TEST_F(PluginSorterTest, Sort_HasCycle) { + ASSERT_NO_THROW(game.LoadPlugins(false)); + PluginMetadata plugin("Blank.esm"); + plugin.LoadAfter({File("Blank - Master Dependent.esm")}); + game.GetUserlist().AddPlugin(plugin); + + PluginSorter ps; + EXPECT_ANY_THROW(ps.Sort(game, Language::english)); + } } - - inline std::list GetExpectedSortedOrder() const { - return std::list({ - "Skyrim.esm", - "Blank.esm", - "Blank - Different.esm", - "Blank - Master Dependent.esm", - "Blank - Different Master Dependent.esm", - "Blank.esp", - "Blank - Different.esp", - "Blank - Master Dependent.esp", - "Blank - Different Master Dependent.esp", - "Blank - Plugin Dependent.esp", - "Blank - Different Plugin Dependent.esp", - }); - } - - inline static std::list GetActualSortedOrder(const std::list& sortedPlugins) { - std::list output; - std::transform(begin(sortedPlugins), - end(sortedPlugins), - std::back_inserter(output), - [](const loot::Plugin& plugin) { - return plugin.Name(); - }); - return output; - } - - loot::Game game; - std::function callback; -}; - -TEST_F(PluginSorter, Sort_NoPlugins) { - loot::PluginSorter ps; - std::list sorted = ps.Sort(game, loot::Language::english); - EXPECT_TRUE(sorted.empty()); -} - -TEST_F(PluginSorter, Sort) { - ASSERT_NO_THROW(game.LoadPlugins(false)); - - loot::PluginSorter ps; - std::list expectedSortedOrder = GetExpectedSortedOrder(); - - std::list sorted = ps.Sort(game, loot::Language::english); - EXPECT_TRUE(std::equal(begin(sorted), end(sorted), begin(expectedSortedOrder))); - - // Check stability. - sorted = ps.Sort(game, loot::Language::english); - EXPECT_TRUE(std::equal(begin(sorted), end(sorted), begin(expectedSortedOrder))); -} - -TEST_F(PluginSorter, sortingShouldClearExistingGameMessages) { - ASSERT_NO_THROW(game.LoadPlugins(false)); - game.AppendMessage(loot::Message(loot::Message::say, "1")); - ASSERT_FALSE(game.GetMessages().empty()); - - loot::PluginSorter ps; - std::list sorted = ps.Sort(game, loot::Language::english); - EXPECT_TRUE(game.GetMessages().empty()); -} - -TEST_F(PluginSorter, failedSortShouldNotClearExistingGameMessages) { - ASSERT_NO_THROW(game.LoadPlugins(false)); - loot::PluginMetadata plugin("Blank.esm"); - plugin.LoadAfter({loot::File("Blank - Master Dependent.esm")}); - game.GetUserlist().AddPlugin(plugin); - game.AppendMessage(loot::Message(loot::Message::say, "1")); - ASSERT_FALSE(game.GetMessages().empty()); - - loot::PluginSorter ps; - EXPECT_ANY_THROW(ps.Sort(game, loot::Language::english)); - EXPECT_FALSE(game.GetMessages().empty()); -} - -TEST_F(PluginSorter, Sort_HeadersOnly) { - ASSERT_NO_THROW(game.LoadPlugins(true)); - - loot::PluginSorter ps; - std::list expectedSortedOrder = GetExpectedSortedOrder(); - - std::list sorted = ps.Sort(game, loot::Language::english); - EXPECT_TRUE(std::equal(begin(sorted), end(sorted), begin(expectedSortedOrder))); -} - -TEST_F(PluginSorter, Sort_WithPriority) { - ASSERT_NO_THROW(game.LoadPlugins(false)); - loot::PluginMetadata plugin("Blank - Different Master Dependent.esp"); - plugin.Priority(-100000); - plugin.SetPriorityGlobal(true); - game.GetUserlist().AddPlugin(plugin); - - loot::PluginSorter ps; - std::list expectedSortedOrder({ - "Skyrim.esm", - "Blank.esm", - "Blank - Different.esm", - "Blank - Master Dependent.esm", - "Blank - Different Master Dependent.esm", - "Blank - Different Master Dependent.esp", - "Blank.esp", - "Blank - Different.esp", - "Blank - Master Dependent.esp", - "Blank - Plugin Dependent.esp", - "Blank - Different Plugin Dependent.esp", - }); - - std::list sorted = ps.Sort(game, loot::Language::english); - EXPECT_TRUE(std::equal(begin(sorted), end(sorted), begin(expectedSortedOrder))); -} - -TEST_F(PluginSorter, sortingWithPrioritiesShouldInheritRecursivelyRegardlessOfEvaluationOrder) { - ASSERT_NO_THROW(game.LoadPlugins(false)); - - // Set Blank.esp's priority. - loot::PluginMetadata plugin("Blank.esp"); - plugin.Priority(2); - game.GetUserlist().AddPlugin(plugin); - - // Load Blank - Master Dependent.esp after Blank.esp so that it - // inherits Blank.esp's priority. - plugin = loot::PluginMetadata("Blank - Master Dependent.esp"); - plugin.LoadAfter({ - loot::File("Blank.esp"), - }); - game.GetUserlist().AddPlugin(plugin); - - // Load Blank - Different.esp after Blank - Master Dependent.esp, so - // that it inherits its inherited priority. - plugin = loot::PluginMetadata("Blank - Different.esp"); - plugin.LoadAfter({ - loot::File("Blank - Master Dependent.esp"), - }); - game.GetUserlist().AddPlugin(plugin); - - // Set Blank - Different Master Dependent.esp to have a higher priority - // than 0 but lower than Blank.esp. Need to also make it a global priority - // because it doesn't otherwise conflict with the other plugins. - plugin = loot::PluginMetadata("Blank - Different Master Dependent.esp"); - plugin.Priority(1); - plugin.SetPriorityGlobal(true); - game.GetUserlist().AddPlugin(plugin); - - loot::PluginSorter ps; - std::list expectedSortedOrder({ - "Skyrim.esm", - "Blank.esm", - "Blank - Different.esm", - "Blank - Master Dependent.esm", - "Blank - Different Master Dependent.esm", - "Blank - Different Master Dependent.esp", - "Blank.esp", - "Blank - Master Dependent.esp", - "Blank - Different.esp", - "Blank - Plugin Dependent.esp", - "Blank - Different Plugin Dependent.esp", - }); - - std::list actualSortedOrder = GetActualSortedOrder(ps.Sort(game, loot::Language::english)); - EXPECT_EQ(expectedSortedOrder, actualSortedOrder); -} - -TEST_F(PluginSorter, Sort_WithLoadAfter) { - ASSERT_NO_THROW(game.LoadPlugins(false)); - loot::PluginMetadata plugin("Blank.esp"); - plugin.LoadAfter({ - loot::File("Blank - Different.esp"), - loot::File("Blank - Different Plugin Dependent.esp"), - }); - game.GetUserlist().AddPlugin(plugin); - - loot::PluginSorter ps; - std::list expectedSortedOrder({ - "Skyrim.esm", - "Blank.esm", - "Blank - Different.esm", - "Blank - Master Dependent.esm", - "Blank - Different Master Dependent.esm", - "Blank - Different.esp", - "Blank - Master Dependent.esp", - "Blank - Different Master Dependent.esp", - "Blank - Different Plugin Dependent.esp", - "Blank.esp", - "Blank - Plugin Dependent.esp", - }); - - std::list sorted = ps.Sort(game, loot::Language::english); - EXPECT_TRUE(std::equal(begin(sorted), end(sorted), begin(expectedSortedOrder))); -} - -TEST_F(PluginSorter, Sort_WithRequirements) { - ASSERT_NO_THROW(game.LoadPlugins(false)); - loot::PluginMetadata plugin("Blank.esp"); - plugin.Reqs({ - loot::File("Blank - Different.esp"), - loot::File("Blank - Different Plugin Dependent.esp"), - }); - game.GetUserlist().AddPlugin(plugin); - - loot::PluginSorter ps; - std::list expectedSortedOrder({ - "Skyrim.esm", - "Blank.esm", - "Blank - Different.esm", - "Blank - Master Dependent.esm", - "Blank - Different Master Dependent.esm", - "Blank - Different.esp", - "Blank - Master Dependent.esp", - "Blank - Different Master Dependent.esp", - "Blank - Different Plugin Dependent.esp", - "Blank.esp", - "Blank - Plugin Dependent.esp", - }); - - std::list sorted = ps.Sort(game, loot::Language::english); - EXPECT_TRUE(std::equal(begin(sorted), end(sorted), begin(expectedSortedOrder))); -} - -TEST_F(PluginSorter, Sort_HasCycle) { - ASSERT_NO_THROW(game.LoadPlugins(false)); - loot::PluginMetadata plugin("Blank.esm"); - plugin.LoadAfter({loot::File("Blank - Master Dependent.esm")}); - game.GetUserlist().AddPlugin(plugin); - - loot::PluginSorter ps; - EXPECT_ANY_THROW(ps.Sort(game, loot::Language::english)); } #endif diff --git a/src/tests/fixtures.h b/src/tests/fixtures.h index 7073e608..e11038cf 100644 --- a/src/tests/fixtures.h +++ b/src/tests/fixtures.h @@ -32,286 +32,290 @@ along with LOOT. If not, see #include #include -class GameTest : public ::testing::Test { -protected: - GameTest(const boost::filesystem::path& gameDataPath, const boost::filesystem::path& gameLocalPath) - : dataPath(gameDataPath), - localPath(gameLocalPath), - missingPath("./missing"), - masterlistPath(localPath / "masterlist.yaml"), - userlistPath(localPath / "userlist.yaml"), - resourcePath(dataPath / "resource" / "detail" / "resource.txt"), - db(nullptr) {} +namespace loot { + namespace test { + class GenericGameTest : public ::testing::Test { + protected: + GenericGameTest(const boost::filesystem::path& gameDataPath, const boost::filesystem::path& gameLocalPath) + : dataPath(gameDataPath), + localPath(gameLocalPath), + missingPath("./missing"), + masterlistPath(localPath / "masterlist.yaml"), + userlistPath(localPath / "userlist.yaml"), + resourcePath(dataPath / "resource" / "detail" / "resource.txt"), + db(nullptr) {} - inline virtual void SetUp() { - ASSERT_NO_THROW(boost::filesystem::create_directories(localPath)); - ASSERT_TRUE(boost::filesystem::exists(localPath)); + inline virtual void SetUp() { + ASSERT_NO_THROW(boost::filesystem::create_directories(localPath)); + ASSERT_TRUE(boost::filesystem::exists(localPath)); - ASSERT_FALSE(boost::filesystem::exists(masterlistPath)); - ASSERT_FALSE(boost::filesystem::exists(userlistPath)); - ASSERT_FALSE(boost::filesystem::exists(localPath / ".git")); - ASSERT_FALSE(boost::filesystem::exists(missingPath)); + ASSERT_FALSE(boost::filesystem::exists(masterlistPath)); + ASSERT_FALSE(boost::filesystem::exists(userlistPath)); + ASSERT_FALSE(boost::filesystem::exists(localPath / ".git")); + ASSERT_FALSE(boost::filesystem::exists(missingPath)); - ASSERT_TRUE(boost::filesystem::exists(dataPath / "Blank.esm")); - ASSERT_TRUE(boost::filesystem::exists(dataPath / "Blank - Different.esm")); - ASSERT_TRUE(boost::filesystem::exists(dataPath / "Blank - Master Dependent.esm")); - ASSERT_TRUE(boost::filesystem::exists(dataPath / "Blank - Different Master Dependent.esm")); - ASSERT_TRUE(boost::filesystem::exists(dataPath / "Blank.esp")); - ASSERT_TRUE(boost::filesystem::exists(dataPath / "Blank - Different.esp")); - ASSERT_TRUE(boost::filesystem::exists(dataPath / "Blank - Master Dependent.esp")); - ASSERT_TRUE(boost::filesystem::exists(dataPath / "Blank - Different Master Dependent.esp")); - ASSERT_TRUE(boost::filesystem::exists(dataPath / "Blank - Plugin Dependent.esp")); - ASSERT_TRUE(boost::filesystem::exists(dataPath / "Blank - Different Plugin Dependent.esp")); + ASSERT_TRUE(boost::filesystem::exists(dataPath / "Blank.esm")); + ASSERT_TRUE(boost::filesystem::exists(dataPath / "Blank - Different.esm")); + ASSERT_TRUE(boost::filesystem::exists(dataPath / "Blank - Master Dependent.esm")); + ASSERT_TRUE(boost::filesystem::exists(dataPath / "Blank - Different Master Dependent.esm")); + ASSERT_TRUE(boost::filesystem::exists(dataPath / "Blank.esp")); + ASSERT_TRUE(boost::filesystem::exists(dataPath / "Blank - Different.esp")); + ASSERT_TRUE(boost::filesystem::exists(dataPath / "Blank - Master Dependent.esp")); + ASSERT_TRUE(boost::filesystem::exists(dataPath / "Blank - Different Master Dependent.esp")); + ASSERT_TRUE(boost::filesystem::exists(dataPath / "Blank - Plugin Dependent.esp")); + ASSERT_TRUE(boost::filesystem::exists(dataPath / "Blank - Different Plugin Dependent.esp")); - ASSERT_FALSE(boost::filesystem::exists(dataPath / "Blank.missing.esm")); - ASSERT_FALSE(boost::filesystem::exists(dataPath / "Blank.missing.esp")); + ASSERT_FALSE(boost::filesystem::exists(dataPath / "Blank.missing.esm")); + ASSERT_FALSE(boost::filesystem::exists(dataPath / "Blank.missing.esp")); - // Ghost a plugin. - ASSERT_FALSE(boost::filesystem::exists(dataPath / "Blank - Master Dependent.esm.ghost")); - ASSERT_NO_THROW(boost::filesystem::rename(dataPath / "Blank - Master Dependent.esm", dataPath / "Blank - Master Dependent.esm.ghost")); - ASSERT_TRUE(boost::filesystem::exists(dataPath / "Blank - Master Dependent.esm.ghost")); + // Ghost a plugin. + ASSERT_FALSE(boost::filesystem::exists(dataPath / "Blank - Master Dependent.esm.ghost")); + ASSERT_NO_THROW(boost::filesystem::rename(dataPath / "Blank - Master Dependent.esm", dataPath / "Blank - Master Dependent.esm.ghost")); + ASSERT_TRUE(boost::filesystem::exists(dataPath / "Blank - Master Dependent.esm.ghost")); - // Write out an empty file. - boost::filesystem::ofstream out(dataPath / "EmptyFile.esm"); - out.close(); - ASSERT_TRUE(boost::filesystem::exists(dataPath / "EmptyFile.esm")); + // Write out an empty file. + boost::filesystem::ofstream out(dataPath / "EmptyFile.esm"); + out.close(); + ASSERT_TRUE(boost::filesystem::exists(dataPath / "EmptyFile.esm")); - // Write out an empty resource file. - ASSERT_NO_THROW(boost::filesystem::create_directories(resourcePath.parent_path())); - out.open(resourcePath); - out.close(); - ASSERT_TRUE(boost::filesystem::exists(resourcePath)); + // Write out an empty resource file. + ASSERT_NO_THROW(boost::filesystem::create_directories(resourcePath.parent_path())); + out.open(resourcePath); + out.close(); + ASSERT_TRUE(boost::filesystem::exists(resourcePath)); - // Write out an non-empty, non-plugin file. - out.open(dataPath / "NotAPlugin.esm"); - out << "This isn't a valid plugin file."; - out.close(); - ASSERT_TRUE(boost::filesystem::exists(dataPath / "NotAPlugin.esm")); - } + // Write out an non-empty, non-plugin file. + out.open(dataPath / "NotAPlugin.esm"); + out << "This isn't a valid plugin file."; + out.close(); + ASSERT_TRUE(boost::filesystem::exists(dataPath / "NotAPlugin.esm")); + } - inline virtual void TearDown() { - // Unghost the ghosted plugin. - ASSERT_TRUE(boost::filesystem::exists(dataPath / "Blank - Master Dependent.esm.ghost")); - ASSERT_NO_THROW(boost::filesystem::rename(dataPath / "Blank - Master Dependent.esm.ghost", dataPath / "Blank - Master Dependent.esm")); - ASSERT_FALSE(boost::filesystem::exists(dataPath / "Blank - Master Dependent.esm.ghost")); + inline virtual void TearDown() { + // Unghost the ghosted plugin. + ASSERT_TRUE(boost::filesystem::exists(dataPath / "Blank - Master Dependent.esm.ghost")); + ASSERT_NO_THROW(boost::filesystem::rename(dataPath / "Blank - Master Dependent.esm.ghost", dataPath / "Blank - Master Dependent.esm")); + ASSERT_FALSE(boost::filesystem::exists(dataPath / "Blank - Master Dependent.esm.ghost")); - // Delete generated files. - ASSERT_NO_THROW(boost::filesystem::remove(dataPath / "EmptyFile.esm")); - ASSERT_NO_THROW(boost::filesystem::remove(resourcePath)); - ASSERT_NO_THROW(boost::filesystem::remove(dataPath / "NotAPlugin.esm")); - ASSERT_FALSE(boost::filesystem::exists(dataPath / "EmptyFile.esm")); - ASSERT_FALSE(boost::filesystem::exists(resourcePath)); - ASSERT_FALSE(boost::filesystem::exists(dataPath / "NotAPlugin.esm")); + // Delete generated files. + ASSERT_NO_THROW(boost::filesystem::remove(dataPath / "EmptyFile.esm")); + ASSERT_NO_THROW(boost::filesystem::remove(resourcePath)); + ASSERT_NO_THROW(boost::filesystem::remove(dataPath / "NotAPlugin.esm")); + ASSERT_FALSE(boost::filesystem::exists(dataPath / "EmptyFile.esm")); + ASSERT_FALSE(boost::filesystem::exists(resourcePath)); + ASSERT_FALSE(boost::filesystem::exists(dataPath / "NotAPlugin.esm")); - // Masterlist & userlist may have been created during test, so delete them. - ASSERT_NO_THROW(boost::filesystem::remove(masterlistPath)); - ASSERT_NO_THROW(boost::filesystem::remove(userlistPath)); + // Masterlist & userlist may have been created during test, so delete them. + ASSERT_NO_THROW(boost::filesystem::remove(masterlistPath)); + ASSERT_NO_THROW(boost::filesystem::remove(userlistPath)); - // Also remove the ".git" folder if it has been created. - ASSERT_NO_THROW(boost::filesystem::remove_all(localPath / ".git")); + // Also remove the ".git" folder if it has been created. + ASSERT_NO_THROW(boost::filesystem::remove_all(localPath / ".git")); - ASSERT_NO_THROW(loot_destroy_db(db)); - } + ASSERT_NO_THROW(loot_destroy_db(db)); + } - const boost::filesystem::path dataPath; - const boost::filesystem::path localPath; - const boost::filesystem::path missingPath; + const boost::filesystem::path dataPath; + const boost::filesystem::path localPath; + const boost::filesystem::path missingPath; - const boost::filesystem::path masterlistPath; - const boost::filesystem::path userlistPath; + const boost::filesystem::path masterlistPath; + const boost::filesystem::path userlistPath; - const boost::filesystem::path resourcePath; + const boost::filesystem::path resourcePath; - loot_db * db; -}; - -class OblivionTest : public GameTest { -protected: - OblivionTest() : GameTest("./Oblivion/Data", "./local/Oblivion") {} - - inline virtual void SetUp() { - GameTest::SetUp(); - - // LOOT expects the game master file to be present, so mock it. - ASSERT_FALSE(boost::filesystem::exists(dataPath / "Oblivion.esm")); - ASSERT_NO_THROW(boost::filesystem::copy_file(dataPath / "Blank.esm", dataPath / "Oblivion.esm")); - ASSERT_TRUE(boost::filesystem::exists(dataPath / "Oblivion.esm")); - - // Oblivion's load order is decided through timestamps, so reset them to a known order before each test. - std::list loadOrder = { - "Oblivion.esm", - "Blank.esm", - "Blank - Different.esm", - "Blank - Master Dependent.esm", // Ghosted - "Blank - Different Master Dependent.esm", - "Blank.esp", - "Blank - Different.esp", - "Blank - Master Dependent.esp", - "Blank - Different Master Dependent.esp", - "Blank - Plugin Dependent.esp", - "Blank - Different Plugin Dependent.esp" + loot_db * db; }; - time_t modificationTime = time(NULL); // Current time. - for (const auto &plugin : loadOrder) { - if (boost::filesystem::exists(dataPath / boost::filesystem::path(plugin + ".ghost"))) { - boost::filesystem::last_write_time(dataPath / boost::filesystem::path(plugin + ".ghost"), modificationTime); + + class OblivionTest : public GenericGameTest { + protected: + OblivionTest() : GenericGameTest("./Oblivion/Data", "./local/Oblivion") {} + + inline virtual void SetUp() { + GenericGameTest::SetUp(); + + // LOOT expects the game master file to be present, so mock it. + ASSERT_FALSE(boost::filesystem::exists(dataPath / "Oblivion.esm")); + ASSERT_NO_THROW(boost::filesystem::copy_file(dataPath / "Blank.esm", dataPath / "Oblivion.esm")); + ASSERT_TRUE(boost::filesystem::exists(dataPath / "Oblivion.esm")); + + // Oblivion's load order is decided through timestamps, so reset them to a known order before each test. + std::list loadOrder = { + "Oblivion.esm", + "Blank.esm", + "Blank - Different.esm", + "Blank - Master Dependent.esm", // Ghosted + "Blank - Different Master Dependent.esm", + "Blank.esp", + "Blank - Different.esp", + "Blank - Master Dependent.esp", + "Blank - Different Master Dependent.esp", + "Blank - Plugin Dependent.esp", + "Blank - Different Plugin Dependent.esp" + }; + time_t modificationTime = time(NULL); // Current time. + for (const auto &plugin : loadOrder) { + if (boost::filesystem::exists(dataPath / boost::filesystem::path(plugin + ".ghost"))) { + boost::filesystem::last_write_time(dataPath / boost::filesystem::path(plugin + ".ghost"), modificationTime); + } + else { + boost::filesystem::last_write_time(dataPath / plugin, modificationTime); + } + modificationTime += 60; + } + + // Set Oblivion's active plugins to a known list before running the test. + boost::filesystem::ofstream activePlugins(localPath / "plugins.txt"); + activePlugins + << "Oblivion.esm" << std::endl + << "Blank.esm" << std::endl; + activePlugins.close(); } - else { - boost::filesystem::last_write_time(dataPath / plugin, modificationTime); + + inline virtual void TearDown() { + GenericGameTest::TearDown(); + + // Delete the mock Oblivion.esm. + ASSERT_TRUE(boost::filesystem::exists(dataPath / "Oblivion.esm")); + ASSERT_NO_THROW(boost::filesystem::remove(dataPath / "Oblivion.esm")); + ASSERT_FALSE(boost::filesystem::exists(dataPath / "Oblivion.esm")); + + // Delete existing plugins.txt. + ASSERT_NO_THROW(boost::filesystem::remove(localPath / "plugins.txt")); + }; + + inline void GenerateMasterlist() { + boost::filesystem::ofstream masterlist(masterlistPath); + masterlist + << "plugins:" << std::endl + << " - name: Oblivion.esm" << std::endl + << " - name: Silgrad_Tower.esm" << std::endl + << " - name: No Lights Flicker.esm" << std::endl + << " msg:" << std::endl + << " - type: say" << std::endl + << " content: Use Wrye Bash Bashed Patch tweak instead." << std::endl + << " - name: bookplacing.esm" << std::endl + << " msg:" << std::endl + << " - type: warn" << std::endl + << " content: 'Check you are using v2+. If not, Update. v1 has a severe bug with the Mystic Emporium disappearing.'" << std::endl + << " - name: EnhancedWeatherSIOnly.esm" << std::endl + << " msg:" << std::endl + << " - type: error" << std::endl + << " content: Obsolete. Remove this and install Enhanced Weather." << std::endl + << " - name: Hammerfell.esm" << std::endl + << " dirty:" << std::endl + << " - crc: 0x7d22f9df" << std::endl + << " util: TES4Edit" << std::endl + << " udr: 4" << std::endl + << " - name: nVidia Black Screen Fix.esp" << std::endl + << " msg:" << std::endl + << " - type: say" << std::endl + << " content: Use Wrye Bash Bashed Patch tweak instead." << std::endl + << " - type: say" << std::endl + << " content: 'Alternatively, remove this and use UOP v3.0.1+ instead.'" << std::endl + << " - name: Unofficial Oblivion Patch.esp" << std::endl + << " msg:" << std::endl + << " - type: say" << std::endl + << " content: 'Do not clean ITM records, they are intentional and required for the mod to function.'" << std::endl + << " tag:" << std::endl + << " - Actors.ACBS" << std::endl + << " - Actors.AIData" << std::endl + << " - Actors.AIPackages" << std::endl + << " - Actors.CombatStyle" << std::endl + << " - Actors.DeathItem" << std::endl + << " - Actors.Stats" << std::endl + << " - C.Climate" << std::endl + << " - C.Light" << std::endl + << " - C.Music" << std::endl + << " - C.Name" << std::endl + << " - C.Owner" << std::endl + << " - Creatures.Blood" << std::endl + << " - Delev" << std::endl + << " - Factions" << std::endl + << " - Invent" << std::endl + << " - Names" << std::endl + << " - NPC.Class" << std::endl + << " - Relations" << std::endl + << " - Relev" << std::endl + << " - Scripts" << std::endl + << " - Stats" << std::endl + << " - '-C.Water'" << std::endl; + + masterlist.close(); } - modificationTime += 60; - } + }; - // Set Oblivion's active plugins to a known list before running the test. - boost::filesystem::ofstream activePlugins(localPath / "plugins.txt"); - activePlugins - << "Oblivion.esm" << std::endl - << "Blank.esm" << std::endl; - activePlugins.close(); + class OblivionAPIOperationsTest : public OblivionTest { + protected: + inline virtual void SetUp() { + OblivionTest::SetUp(); + + ASSERT_EQ(loot_ok, loot_create_db(&db, loot_game_tes4, dataPath.parent_path().string().c_str(), localPath.string().c_str())); + } + }; + + class SkyrimTest : public GenericGameTest { + protected: + SkyrimTest() : GenericGameTest("./Skyrim/Data", "./local/Skyrim") {} + + inline virtual void SetUp() { + GenericGameTest::SetUp(); + + ASSERT_TRUE(boost::filesystem::exists(dataPath / "Blank.bsa")); + ASSERT_TRUE(boost::filesystem::exists(dataPath / "Blank.bsl")); + + // Can't change Skyrim's main master file, so mock it. + ASSERT_FALSE(boost::filesystem::exists(dataPath / "Skyrim.esm")); + ASSERT_NO_THROW(boost::filesystem::copy_file(dataPath / "Blank.esm", dataPath / "Skyrim.esm")); + ASSERT_TRUE(boost::filesystem::exists(dataPath / "Skyrim.esm")); + + // Set Skyrim's load order to a known list before running the test. + boost::filesystem::ofstream loadOrder(localPath / "loadorder.txt"); + loadOrder + << "Skyrim.esm" << std::endl + << "Blank.esm" << std::endl + << "Blank - Different.esm" << std::endl + << "Blank - Master Dependent.esm" << std::endl // Ghosted + << "Blank - Different Master Dependent.esm" << std::endl + << "Blank.esp" << std::endl + << "Blank - Different.esp" << std::endl + << "Blank - Master Dependent.esp" << std::endl + << "Blank - Different Master Dependent.esp" << std::endl + << "Blank - Plugin Dependent.esp" << std::endl + << "Blank - Different Plugin Dependent.esp" << std::endl; + loadOrder.close(); + + // Set Skyrim's active plugins to a known list before running the test. + boost::filesystem::ofstream activePlugins(localPath / "plugins.txt"); + activePlugins + << "Blank.esm" << std::endl + << "Blank - Different Master Dependent.esp" << std::endl; + activePlugins.close(); + } + + inline virtual void TearDown() { + GenericGameTest::TearDown(); + + // Delete the mock Skyrim.esm. + ASSERT_TRUE(boost::filesystem::exists(dataPath / "Skyrim.esm")); + ASSERT_NO_THROW(boost::filesystem::remove(dataPath / "Skyrim.esm")); + ASSERT_FALSE(boost::filesystem::exists(dataPath / "Skyrim.esm")); + + // Delete existing plugins.txt and loadorder.txt. + ASSERT_NO_THROW(boost::filesystem::remove(localPath / "plugins.txt")); + ASSERT_NO_THROW(boost::filesystem::remove(localPath / "loadorder.txt")); + }; + }; + + class SkyrimAPIOperationsTest : public SkyrimTest { + protected: + inline virtual void SetUp() { + SkyrimTest::SetUp(); + + ASSERT_EQ(loot_ok, loot_create_db(&db, loot_game_tes5, dataPath.parent_path().string().c_str(), localPath.string().c_str())); + } + }; } - - inline virtual void TearDown() { - GameTest::TearDown(); - - // Delete the mock Oblivion.esm. - ASSERT_TRUE(boost::filesystem::exists(dataPath / "Oblivion.esm")); - ASSERT_NO_THROW(boost::filesystem::remove(dataPath / "Oblivion.esm")); - ASSERT_FALSE(boost::filesystem::exists(dataPath / "Oblivion.esm")); - - // Delete existing plugins.txt. - ASSERT_NO_THROW(boost::filesystem::remove(localPath / "plugins.txt")); - }; - - inline void GenerateMasterlist() { - boost::filesystem::ofstream masterlist(masterlistPath); - masterlist - << "plugins:" << std::endl - << " - name: Oblivion.esm" << std::endl - << " - name: Silgrad_Tower.esm" << std::endl - << " - name: No Lights Flicker.esm" << std::endl - << " msg:" << std::endl - << " - type: say" << std::endl - << " content: Use Wrye Bash Bashed Patch tweak instead." << std::endl - << " - name: bookplacing.esm" << std::endl - << " msg:" << std::endl - << " - type: warn" << std::endl - << " content: 'Check you are using v2+. If not, Update. v1 has a severe bug with the Mystic Emporium disappearing.'" << std::endl - << " - name: EnhancedWeatherSIOnly.esm" << std::endl - << " msg:" << std::endl - << " - type: error" << std::endl - << " content: Obsolete. Remove this and install Enhanced Weather." << std::endl - << " - name: Hammerfell.esm" << std::endl - << " dirty:" << std::endl - << " - crc: 0x7d22f9df" << std::endl - << " util: TES4Edit" << std::endl - << " udr: 4" << std::endl - << " - name: nVidia Black Screen Fix.esp" << std::endl - << " msg:" << std::endl - << " - type: say" << std::endl - << " content: Use Wrye Bash Bashed Patch tweak instead." << std::endl - << " - type: say" << std::endl - << " content: 'Alternatively, remove this and use UOP v3.0.1+ instead.'" << std::endl - << " - name: Unofficial Oblivion Patch.esp" << std::endl - << " msg:" << std::endl - << " - type: say" << std::endl - << " content: 'Do not clean ITM records, they are intentional and required for the mod to function.'" << std::endl - << " tag:" << std::endl - << " - Actors.ACBS" << std::endl - << " - Actors.AIData" << std::endl - << " - Actors.AIPackages" << std::endl - << " - Actors.CombatStyle" << std::endl - << " - Actors.DeathItem" << std::endl - << " - Actors.Stats" << std::endl - << " - C.Climate" << std::endl - << " - C.Light" << std::endl - << " - C.Music" << std::endl - << " - C.Name" << std::endl - << " - C.Owner" << std::endl - << " - Creatures.Blood" << std::endl - << " - Delev" << std::endl - << " - Factions" << std::endl - << " - Invent" << std::endl - << " - Names" << std::endl - << " - NPC.Class" << std::endl - << " - Relations" << std::endl - << " - Relev" << std::endl - << " - Scripts" << std::endl - << " - Stats" << std::endl - << " - '-C.Water'" << std::endl; - - masterlist.close(); - } -}; - -class OblivionAPIOperationsTest : public OblivionTest { -protected: - inline virtual void SetUp() { - OblivionTest::SetUp(); - - ASSERT_EQ(loot_ok, loot_create_db(&db, loot_game_tes4, dataPath.parent_path().string().c_str(), localPath.string().c_str())); - } -}; - -class SkyrimTest : public GameTest { -protected: - SkyrimTest() : GameTest("./Skyrim/Data", "./local/Skyrim") {} - - inline virtual void SetUp() { - GameTest::SetUp(); - - ASSERT_TRUE(boost::filesystem::exists(dataPath / "Blank.bsa")); - ASSERT_TRUE(boost::filesystem::exists(dataPath / "Blank.bsl")); - - // Can't change Skyrim's main master file, so mock it. - ASSERT_FALSE(boost::filesystem::exists(dataPath / "Skyrim.esm")); - ASSERT_NO_THROW(boost::filesystem::copy_file(dataPath / "Blank.esm", dataPath / "Skyrim.esm")); - ASSERT_TRUE(boost::filesystem::exists(dataPath / "Skyrim.esm")); - - // Set Skyrim's load order to a known list before running the test. - boost::filesystem::ofstream loadOrder(localPath / "loadorder.txt"); - loadOrder - << "Skyrim.esm" << std::endl - << "Blank.esm" << std::endl - << "Blank - Different.esm" << std::endl - << "Blank - Master Dependent.esm" << std::endl // Ghosted - << "Blank - Different Master Dependent.esm" << std::endl - << "Blank.esp" << std::endl - << "Blank - Different.esp" << std::endl - << "Blank - Master Dependent.esp" << std::endl - << "Blank - Different Master Dependent.esp" << std::endl - << "Blank - Plugin Dependent.esp" << std::endl - << "Blank - Different Plugin Dependent.esp" << std::endl; - loadOrder.close(); - - // Set Skyrim's active plugins to a known list before running the test. - boost::filesystem::ofstream activePlugins(localPath / "plugins.txt"); - activePlugins - << "Blank.esm" << std::endl - << "Blank - Different Master Dependent.esp" << std::endl; - activePlugins.close(); - } - - inline virtual void TearDown() { - GameTest::TearDown(); - - // Delete the mock Skyrim.esm. - ASSERT_TRUE(boost::filesystem::exists(dataPath / "Skyrim.esm")); - ASSERT_NO_THROW(boost::filesystem::remove(dataPath / "Skyrim.esm")); - ASSERT_FALSE(boost::filesystem::exists(dataPath / "Skyrim.esm")); - - // Delete existing plugins.txt and loadorder.txt. - ASSERT_NO_THROW(boost::filesystem::remove(localPath / "plugins.txt")); - ASSERT_NO_THROW(boost::filesystem::remove(localPath / "loadorder.txt")); - }; -}; - -class SkyrimAPIOperationsTest : public SkyrimTest { -protected: - inline virtual void SetUp() { - SkyrimTest::SetUp(); - - ASSERT_EQ(loot_ok, loot_create_db(&db, loot_game_tes5, dataPath.parent_path().string().c_str(), localPath.string().c_str())); - } -}; +} #endif diff --git a/src/tests/gui/test_loot_settings.h b/src/tests/gui/test_loot_settings.h index dfd11cb4..d9a4a44b 100644 --- a/src/tests/gui/test_loot_settings.h +++ b/src/tests/gui/test_loot_settings.h @@ -30,19 +30,19 @@ along with LOOT. If not, see namespace loot { namespace test { - class LootSettings : public ::testing::Test { + class LootSettingsTest : public ::testing::Test { protected: - LootSettings() : settingsFile("./settings.yaml") {} + LootSettingsTest() : settingsFile("./settings.yaml") {} - ~LootSettings() { + ~LootSettingsTest() { boost::filesystem::remove(settingsFile); } boost::filesystem::path settingsFile; - loot::LootSettings settings; + LootSettings settings; }; - TEST_F(LootSettings, defaultConstructorShouldSetDefaultValues) { + TEST_F(LootSettingsTest, defaultConstructorShouldSetDefaultValues) { const std::string currentVersion = std::to_string(g_version_major) + "." + std::to_string(g_version_minor) + "." + std::to_string(g_version_patch); const std::vector expectedGameSettings({ GameSettings(GameSettings::tes4), @@ -109,7 +109,7 @@ namespace loot { EXPECT_EQ(expectedGameSettings[5].RepoBranch(), actualGameSettings[5].RepoBranch()); } - TEST_F(LootSettings, loadingFromFileShouldLoadContentAsYaml) { + TEST_F(LootSettingsTest, loadingFromFileShouldLoadContentAsYaml) { boost::filesystem::ofstream out(settingsFile); out << "enableDebugLogging: true" << std::endl; out.close(); @@ -119,7 +119,7 @@ namespace loot { EXPECT_TRUE(settings.isDebugLoggingEnabled()); } - TEST_F(LootSettings, loadingFromYamlShouldStoreLoadedValues) { + TEST_F(LootSettingsTest, loadingFromYamlShouldStoreLoadedValues) { const bool enableDebugLogging = true; const bool updateMasterlist = true; const std::string game = "Oblivion"; @@ -174,12 +174,12 @@ namespace loot { EXPECT_EQ(games[0].Name(), settings.getGameSettings()[0].Name()); } - TEST_F(LootSettings, loadingFromEmptyYamlShouldNotThrow) { + TEST_F(LootSettingsTest, loadingFromEmptyYamlShouldNotThrow) { YAML::Node yaml; EXPECT_NO_THROW(settings.load(yaml)); } - TEST_F(LootSettings, loadingFromYamlShouldUpgradeFromVersion0Point6Format) { + TEST_F(LootSettingsTest, loadingFromYamlShouldUpgradeFromVersion0Point6Format) { const unsigned int DebugVerbosity = 3; const bool UpdateMasterlist = true; const std::string Game = "Oblivion"; @@ -215,7 +215,7 @@ namespace loot { EXPECT_EQ(Games[0].RepoBranch(), settings.getGameSettings()[0].RepoBranch()); } - TEST_F(LootSettings, loadingFromYamlShouldNotUpgradeVersion0Point6SettingsIfEquivalentsAlreadyExist) { + TEST_F(LootSettingsTest, loadingFromYamlShouldNotUpgradeVersion0Point6SettingsIfEquivalentsAlreadyExist) { const unsigned int DebugVerbosity = 3; const bool enableDebugLogging = false; const bool UpdateMasterlist = true; @@ -264,7 +264,7 @@ namespace loot { EXPECT_EQ(games[0].Name(), settings.getGameSettings()[0].Name()); } - TEST_F(LootSettings, loadingFromYamlShouldUpgradeOldDefaultGameRepositoryBranches) { + TEST_F(LootSettingsTest, loadingFromYamlShouldUpgradeOldDefaultGameRepositoryBranches) { const std::vector games({GameSettings(GameSettings::tes4)}); YAML::Node inputYaml; @@ -276,7 +276,7 @@ namespace loot { EXPECT_EQ(games[0].RepoBranch(), settings.getGameSettings()[0].RepoBranch()); } - TEST_F(LootSettings, loadingFromYamlShouldNotUpgradeNonDefaultGameRepositoryBranches) { + TEST_F(LootSettingsTest, loadingFromYamlShouldNotUpgradeNonDefaultGameRepositoryBranches) { const std::vector games({GameSettings(GameSettings::tes4)}); YAML::Node inputYaml; @@ -288,7 +288,7 @@ namespace loot { EXPECT_EQ("foo", settings.getGameSettings()[0].RepoBranch()); } - TEST_F(LootSettings, loadingFromYamlShouldAddMissingBaseGames) { + TEST_F(LootSettingsTest, loadingFromYamlShouldAddMissingBaseGames) { const std::vector games({GameSettings(GameSettings::tes4)}); YAML::Node inputYaml; inputYaml["games"] = games; @@ -305,7 +305,7 @@ namespace loot { EXPECT_EQ(expectedGameSettings, settings.getGameSettings()); } - TEST_F(LootSettings, loadingFromYamlShouldSkipUnrecognisedGames) { + TEST_F(LootSettingsTest, loadingFromYamlShouldSkipUnrecognisedGames) { YAML::Node inputYaml; inputYaml["games"][0] = GameSettings(GameSettings::tes4); inputYaml["games"][0]["type"] = "Foobar"; @@ -317,14 +317,14 @@ namespace loot { EXPECT_EQ("Game Name", settings.getGameSettings()[0].Name()); } - TEST_F(LootSettings, loadingFromYamlShouldRemoveTheContentFilterSetting) { + TEST_F(LootSettingsTest, loadingFromYamlShouldRemoveTheContentFilterSetting) { YAML::Node inputYaml; inputYaml["filters"]["contentFilter"] = "foo"; settings.load(inputYaml); } - TEST_F(LootSettings, saveShouldWriteSettingsAsYamlToPassedFile) { + TEST_F(LootSettingsTest, saveShouldWriteSettingsAsYamlToPassedFile) { settings.storeLastGame("Skyrim"); settings.save(settingsFile); @@ -334,7 +334,7 @@ namespace loot { EXPECT_EQ("Skyrim", settings.getLastGame()); } - TEST_F(LootSettings, getLanguageShouldReturnTheCurrentValue) { + TEST_F(LootSettingsTest, getLanguageShouldReturnTheCurrentValue) { YAML::Node inputYaml; inputYaml["language"] = "fr"; @@ -343,71 +343,71 @@ namespace loot { EXPECT_EQ("fr", settings.getLanguage().Locale()); } - TEST_F(LootSettings, isWindowPositionStoredShouldReturnFalseIfAllPositionValuesAreZero) { - loot::LootSettings::WindowPosition position; + TEST_F(LootSettingsTest, isWindowPositionStoredShouldReturnFalseIfAllPositionValuesAreZero) { + LootSettings::WindowPosition position; settings.storeWindowPosition(position); EXPECT_FALSE(settings.isWindowPositionStored()); } - TEST_F(LootSettings, isWindowPositionStoredShouldReturnTrueIfTopPositionValueIsNonZero) { - loot::LootSettings::WindowPosition position; + TEST_F(LootSettingsTest, isWindowPositionStoredShouldReturnTrueIfTopPositionValueIsNonZero) { + LootSettings::WindowPosition position; position.top = 1; settings.storeWindowPosition(position); EXPECT_TRUE(settings.isWindowPositionStored()); } - TEST_F(LootSettings, isWindowPositionStoredShouldReturnTrueIfBottomPositionValueIsNonZero) { - loot::LootSettings::WindowPosition position; + TEST_F(LootSettingsTest, isWindowPositionStoredShouldReturnTrueIfBottomPositionValueIsNonZero) { + LootSettings::WindowPosition position; position.bottom = 1; settings.storeWindowPosition(position); EXPECT_TRUE(settings.isWindowPositionStored()); } - TEST_F(LootSettings, isWindowPositionStoredShouldReturnTrueIfLeftPositionValueIsNonZero) { - loot::LootSettings::WindowPosition position; + TEST_F(LootSettingsTest, isWindowPositionStoredShouldReturnTrueIfLeftPositionValueIsNonZero) { + LootSettings::WindowPosition position; position.left = 1; settings.storeWindowPosition(position); EXPECT_TRUE(settings.isWindowPositionStored()); } - TEST_F(LootSettings, isWindowPositionStoredShouldReturnTrueIfRightPositionValueIsNonZero) { - loot::LootSettings::WindowPosition position; + TEST_F(LootSettingsTest, isWindowPositionStoredShouldReturnTrueIfRightPositionValueIsNonZero) { + LootSettings::WindowPosition position; position.right = 1; settings.storeWindowPosition(position); EXPECT_TRUE(settings.isWindowPositionStored()); } - TEST_F(LootSettings, storeGameSettingsShouldReplaceExistingGameSettings) { + TEST_F(LootSettingsTest, storeGameSettingsShouldReplaceExistingGameSettings) { const std::vector gameSettings({GameSettings(GameSettings::tes5)}); settings.storeGameSettings(gameSettings); EXPECT_EQ(gameSettings, settings.getGameSettings()); } - TEST_F(LootSettings, storeLastGameShouldReplaceExistingValue) { + TEST_F(LootSettingsTest, storeLastGameShouldReplaceExistingValue) { settings.storeLastGame("Fallout3"); EXPECT_EQ("Fallout3", settings.getLastGame()); } - TEST_F(LootSettings, storeWindowPositionShouldReplaceExistingValue) { - loot::LootSettings::WindowPosition expectedPosition; + TEST_F(LootSettingsTest, storeWindowPositionShouldReplaceExistingValue) { + LootSettings::WindowPosition expectedPosition; expectedPosition.top = 1; settings.storeWindowPosition(expectedPosition); - loot::LootSettings::WindowPosition actualPosition = settings.getWindowPosition(); + LootSettings::WindowPosition actualPosition = settings.getWindowPosition(); EXPECT_EQ(expectedPosition.top, actualPosition.top); EXPECT_EQ(expectedPosition.bottom, actualPosition.bottom); EXPECT_EQ(expectedPosition.left, actualPosition.left); EXPECT_EQ(expectedPosition.right, actualPosition.right); } - TEST_F(LootSettings, updateLastVersionShouldSetValueToCurrentLootVersion) { + TEST_F(LootSettingsTest, updateLastVersionShouldSetValueToCurrentLootVersion) { const std::string currentVersion = std::to_string(g_version_major) + "." + std::to_string(g_version_minor) + "." + std::to_string(g_version_patch); YAML::Node inputYaml; inputYaml["lastVersion"] = "v0.7.1"; @@ -418,7 +418,7 @@ namespace loot { EXPECT_EQ(currentVersion, settings.getLastVersion()); } - TEST_F(LootSettings, toYamlShouldOutputStoredSettings) { + TEST_F(LootSettingsTest, toYamlShouldOutputStoredSettings) { const bool enableDebugLogging = true; const bool updateMasterlist = true; const std::string game = "Oblivion"; diff --git a/src/tests/gui/test_loot_state.h b/src/tests/gui/test_loot_state.h index 6799cd56..e4ebc89f 100644 --- a/src/tests/gui/test_loot_state.h +++ b/src/tests/gui/test_loot_state.h @@ -31,40 +31,40 @@ along with LOOT. If not, see namespace loot { namespace test { - class LootState : public ::testing::Test { + class LootStateTest : public ::testing::Test { protected: - loot::LootState lootState; + LootState lootState; }; - TEST_F(LootState, hasUnappliedChangesShouldBeFalseByDefault) { + TEST_F(LootStateTest, hasUnappliedChangesShouldBeFalseByDefault) { EXPECT_FALSE(lootState.hasUnappliedChanges()); } - TEST_F(LootState, shouldNotHaveUnappliedChangesIfCounterIsDeccremented) { + TEST_F(LootStateTest, shouldNotHaveUnappliedChangesIfCounterIsDeccremented) { lootState.decrementUnappliedChangeCounter(); EXPECT_FALSE(lootState.hasUnappliedChanges()); } - TEST_F(LootState, shouldHaveUnappliedChangesIfCounterIsIncremented) { + TEST_F(LootStateTest, shouldHaveUnappliedChangesIfCounterIsIncremented) { lootState.incrementUnappliedChangeCounter(); EXPECT_TRUE(lootState.hasUnappliedChanges()); } - TEST_F(LootState, incrementingTheChangeCounterMoreThanItIsDecrementedShouldLeaveUnappliedChanges) { + TEST_F(LootStateTest, incrementingTheChangeCounterMoreThanItIsDecrementedShouldLeaveUnappliedChanges) { lootState.incrementUnappliedChangeCounter(); lootState.incrementUnappliedChangeCounter(); lootState.decrementUnappliedChangeCounter(); EXPECT_TRUE(lootState.hasUnappliedChanges()); } - TEST_F(LootState, incrementingTheChangeCounterLessThanItIsDecrementedShouldLeaveNoUnappliedChanges) { + TEST_F(LootStateTest, incrementingTheChangeCounterLessThanItIsDecrementedShouldLeaveNoUnappliedChanges) { lootState.incrementUnappliedChangeCounter(); lootState.decrementUnappliedChangeCounter(); lootState.decrementUnappliedChangeCounter(); EXPECT_FALSE(lootState.hasUnappliedChanges()); } - TEST_F(LootState, incrementingTheChangeCounterThenDecrementingItEquallyShouldLeaveNoUnappliedChanges) { + TEST_F(LootStateTest, incrementingTheChangeCounterThenDecrementingItEquallyShouldLeaveNoUnappliedChanges) { lootState.incrementUnappliedChangeCounter(); lootState.incrementUnappliedChangeCounter(); lootState.decrementUnappliedChangeCounter(); diff --git a/src/tests/printers.h b/src/tests/printers.h index e521eddd..a5f105a2 100644 --- a/src/tests/printers.h +++ b/src/tests/printers.h @@ -39,65 +39,67 @@ along with LOOT. If not, see #include "backend/plugin/plugin.h" namespace loot { - void PrintTo(const File& value, ::std::ostream* os) { - *os << "loot::File(\"" << value.Name() << "\", " - << "\"" << value.DisplayName() << "\", " - << "\"" << value.Condition() << "\"" - << ")"; - } + namespace test { + void PrintTo(const File& value, ::std::ostream* os) { + *os << "File(\"" << value.Name() << "\", " + << "\"" << value.DisplayName() << "\", " + << "\"" << value.Condition() << "\"" + << ")"; + } - void PrintTo(const Location& value, ::std::ostream* os) { - *os << "loot::Location(\"" << value.URL() << "\", " - << "\"" << value.Name() << "\", " - << ")"; - } + void PrintTo(const Location& value, ::std::ostream* os) { + *os << "Location(\"" << value.URL() << "\", " + << "\"" << value.Name() << "\", " + << ")"; + } - void PrintTo(const Message& value, ::std::ostream* os) { - std::string type; - if (value.Type() == Message::warn) - type = "warn"; - else if (value.Type() == Message::error) - type = "error"; - else - type = "say"; + void PrintTo(const Message& value, ::std::ostream* os) { + std::string type; + if (value.Type() == Message::warn) + type = "warn"; + else if (value.Type() == Message::error) + type = "error"; + else + type = "say"; - *os << "loot::Message(\"" << type << "\", " - << ::testing::PrintToString(value.Content()) << ", " - << "\"" << value.Condition() << "\"" - << ")"; - } + *os << "Message(\"" << type << "\", " + << ::testing::PrintToString(value.Content()) << ", " + << "\"" << value.Condition() << "\"" + << ")"; + } - void PrintTo(const MessageContent& value, ::std::ostream* os) { - *os << "loot::MessageContent(\"" << value.Str() << "\", " - << "\"" << Language(value.Language()).Name() << "\"" - << ")"; - } + void PrintTo(const MessageContent& value, ::std::ostream* os) { + *os << "MessageContent(\"" << value.Str() << "\", " + << "\"" << Language(value.Language()).Name() << "\"" + << ")"; + } - void PrintTo(const PluginDirtyInfo& value, ::std::ostream* os) { - *os << "loot::PluginDirtyInfo(0x" - << std::hex << std::uppercase - << value.CRC() - << std::nouppercase << std::dec << ", " - << value.ITMs() << ", " - << value.DeletedRefs() << ", " - << value.DeletedNavmeshes() << ", " - << "\"" << value.CleaningUtility() << "\"" - << ")"; - } + void PrintTo(const PluginDirtyInfo& value, ::std::ostream* os) { + *os << "PluginDirtyInfo(0x" + << std::hex << std::uppercase + << value.CRC() + << std::nouppercase << std::dec << ", " + << value.ITMs() << ", " + << value.DeletedRefs() << ", " + << value.DeletedNavmeshes() << ", " + << "\"" << value.CleaningUtility() << "\"" + << ")"; + } - void PrintTo(const PluginMetadata& value, ::std::ostream* os) { - *os << "loot::PluginMetadata(\"" << value.Name() << "\")"; - } + void PrintTo(const PluginMetadata& value, ::std::ostream* os) { + *os << "PluginMetadata(\"" << value.Name() << "\")"; + } - void PrintTo(const Tag& value, ::std::ostream* os) { - *os << "loot::Tag(\"" << value.Name() << "\", " - << value.IsAddition() << ", " - << "\"" << value.Condition() << "\"" - << ")"; - } + void PrintTo(const Tag& value, ::std::ostream* os) { + *os << "Tag(\"" << value.Name() << "\", " + << value.IsAddition() << ", " + << "\"" << value.Condition() << "\"" + << ")"; + } - void PrintTo(const Plugin& value, ::std::ostream* os) { - *os << "loot::Plugin(\"" << value.Name() << "\")"; + void PrintTo(const Plugin& value, ::std::ostream* os) { + *os << "Plugin(\"" << value.Name() << "\")"; + } } } From 61827fc91483531271ac3f00cd5768d452737901 Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Sat, 12 Mar 2016 09:19:28 +0000 Subject: [PATCH 02/38] Fix Git repo detection tests failing on Windows Due to an incorrect file path - because the build path can vary, --- src/tests/backend/helpers/test_git_helper.h | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/tests/backend/helpers/test_git_helper.h b/src/tests/backend/helpers/test_git_helper.h index aee0a226..ef40d144 100644 --- a/src/tests/backend/helpers/test_git_helper.h +++ b/src/tests/backend/helpers/test_git_helper.h @@ -31,11 +31,16 @@ along with LOOT. If not, see namespace loot { namespace test { -#ifdef _WIN32 - boost::filesystem::path parentRepoRoot = boost::filesystem::current_path().parent_path().parent_path(); -#else - boost::filesystem::path parentRepoRoot = boost::filesystem::current_path().parent_path(); -#endif + boost::filesystem::path getRepoRoot() { + boost::filesystem::path dir = boost::filesystem::current_path(); + while (!boost::filesystem::exists(dir / ".git")) { + dir = dir.parent_path(); + } + + return dir; + } + + boost::filesystem::path parentRepoRoot = getRepoRoot(); TEST(GitHelper, ConstructorAndDestructor) { GitHelper * git = new GitHelper(); From 4516fe7bc0f6ee8e071d4399dca1682dd3a7c972 Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Sat, 12 Mar 2016 10:16:30 +0000 Subject: [PATCH 03/38] Improve API tests * Use a named fixture for each API function * Make filenames match fixture class names * Parameterise the fixture tests * Split tests up so they only test one thing * Rename tests to be more descriptive Part of #515. --- CMakeLists.txt | 20 +- src/tests/api/api_game_operations_test.h | 118 ++++ src/tests/api/loot_apply_load_order_test.h | 77 +++ src/tests/api/loot_create_db_test.h | 97 +++ .../api/{test_loot_db.h => loot_db_test.h} | 70 ++- src/tests/api/loot_eval_lists_test.h | 87 +++ src/tests/api/loot_get_dirty_info_test.h | 81 +++ .../api/loot_get_masterlist_revision_test.h | 119 ++++ src/tests/api/loot_get_plugin_messages_test.h | 113 ++++ src/tests/api/loot_get_plugin_tags_test.h | 140 +++++ src/tests/api/loot_get_tag_map_test.h | 80 +++ src/tests/api/loot_load_lists_test.h | 82 +++ src/tests/api/loot_sort_plugins_test.h | 91 +++ src/tests/api/loot_update_masterlist_test.h | 108 ++++ src/tests/api/loot_write_minimal_list_test.h | 132 ++++ src/tests/api/test_api.h | 571 +----------------- src/tests/base_game_test.h | 125 ++++ src/tests/main.cpp | 14 +- 18 files changed, 1544 insertions(+), 581 deletions(-) create mode 100644 src/tests/api/api_game_operations_test.h create mode 100644 src/tests/api/loot_apply_load_order_test.h create mode 100644 src/tests/api/loot_create_db_test.h rename src/tests/api/{test_loot_db.h => loot_db_test.h} (77%) create mode 100644 src/tests/api/loot_eval_lists_test.h create mode 100644 src/tests/api/loot_get_dirty_info_test.h create mode 100644 src/tests/api/loot_get_masterlist_revision_test.h create mode 100644 src/tests/api/loot_get_plugin_messages_test.h create mode 100644 src/tests/api/loot_get_plugin_tags_test.h create mode 100644 src/tests/api/loot_get_tag_map_test.h create mode 100644 src/tests/api/loot_load_lists_test.h create mode 100644 src/tests/api/loot_sort_plugins_test.h create mode 100644 src/tests/api/loot_update_masterlist_test.h create mode 100644 src/tests/api/loot_write_minimal_list_test.h create mode 100644 src/tests/base_game_test.h diff --git a/CMakeLists.txt b/CMakeLists.txt index d94e2d44..f69f74cc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -215,10 +215,26 @@ set (LOOT_TESTS_SRC ${LOOT_SRC} "${CMAKE_SOURCE_DIR}/src/gui/loot_state.cpp" "${CMAKE_SOURCE_DIR}/src/tests/main.cpp") -set (LOOT_TESTS_HEADERS "${CMAKE_SOURCE_DIR}/src/tests/fixtures.h" +set (LOOT_TESTS_HEADERS "${CMAKE_SOURCE_DIR}/src/tests/base_game_test.h" + "${CMAKE_SOURCE_DIR}/src/tests/fixtures.h" "${CMAKE_SOURCE_DIR}/src/tests/printers.h" + + "${CMAKE_SOURCE_DIR}/src/tests/api/api_game_operations_test.h" + "${CMAKE_SOURCE_DIR}/src/tests/api/loot_apply_load_order_test.h" + "${CMAKE_SOURCE_DIR}/src/tests/api/loot_create_db_test.h" + "${CMAKE_SOURCE_DIR}/src/tests/api/loot_db_test.h" + "${CMAKE_SOURCE_DIR}/src/tests/api/loot_eval_lists_test.h" + "${CMAKE_SOURCE_DIR}/src/tests/api/loot_get_dirty_info_test.h" + "${CMAKE_SOURCE_DIR}/src/tests/api/loot_get_masterlist_revision_test.h" + "${CMAKE_SOURCE_DIR}/src/tests/api/loot_get_plugin_messages_test.h" + "${CMAKE_SOURCE_DIR}/src/tests/api/loot_get_plugin_tags_test.h" + "${CMAKE_SOURCE_DIR}/src/tests/api/loot_get_tag_map_test.h" + "${CMAKE_SOURCE_DIR}/src/tests/api/loot_load_lists_test.h" + "${CMAKE_SOURCE_DIR}/src/tests/api/loot_sort_plugins_test.h" + "${CMAKE_SOURCE_DIR}/src/tests/api/loot_update_masterlist_test.h" + "${CMAKE_SOURCE_DIR}/src/tests/api/loot_write_minimal_list_test.h" "${CMAKE_SOURCE_DIR}/src/tests/api/test_api.h" - "${CMAKE_SOURCE_DIR}/src/tests/api/test_loot_db.h" + "${CMAKE_SOURCE_DIR}/src/tests/backend/game/test_game.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/game/test_game_cache.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/game/test_game_settings.h" diff --git a/src/tests/api/api_game_operations_test.h b/src/tests/api/api_game_operations_test.h new file mode 100644 index 00000000..3216f91f --- /dev/null +++ b/src/tests/api/api_game_operations_test.h @@ -0,0 +1,118 @@ +/* LOOT + +A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and +Fallout: New Vegas. + +Copyright (C) 2013-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_TEST_API_GAME_OPERATIONS_TEST +#define LOOT_TEST_API_GAME_OPERATIONS_TEST + +#include "../base_game_test.h" + +namespace loot { + namespace test { + class ApiGameOperationsTest : public BaseGameTest { + protected: + ApiGameOperationsTest() : + db(nullptr), + masterlistPath(localPath / "masterlist.yaml"), + noteMessage("Do not clean ITM records, they are intentional and required for the mod to function."), + warningMessage("Check you are using v2+. If not, Update. v1 has a severe bug with the Mystic Emporium disappearing."), + errorMessage("Obsolete. Remove this and install Enhanced Weather.") {} + + inline virtual void SetUp() { + BaseGameTest::SetUp(); + + ASSERT_FALSE(boost::filesystem::exists(masterlistPath)); + + ASSERT_EQ(loot_ok, loot_create_db(&db, GetParam(), dataPath.parent_path().string().c_str(), localPath.string().c_str())); + } + + inline virtual void TearDown() { + BaseGameTest::TearDown(); + + ASSERT_NO_THROW(loot_destroy_db(db)); + + // The masterlist may have been created during the test, so delete it. + ASSERT_NO_THROW(boost::filesystem::remove(masterlistPath)); + } + + inline void generateMasterlist() { + using std::endl; + + boost::filesystem::ofstream masterlist(masterlistPath); + masterlist + << "plugins:" << endl + << " - name: " << blankEsm << endl + << " after:" << endl + << " - " << masterFile << endl + << " msg:" << endl + << " - type: say" << endl + << " content: '" << noteMessage << "'" << endl + << " tag:" << endl + << " - Actors.ACBS" << endl + << " - Actors.AIData" << endl + << " - '-C.Water'" << endl + << " - name: " << blankDifferentEsm << endl + << " after:" << endl + << " - " << blankMasterDependentEsm << endl + << " msg:" << endl + << " - type: warn" << endl + << " content: '" << warningMessage << "'" << endl + << " dirty:" << endl + << " - crc: 0x7d22f9df" << endl + << " util: TES4Edit" << endl + << " udr: 4" << endl + << " - name: " << blankDifferentEsp << endl + << " after:" << endl + << " - " << blankPluginDependentEsp << endl + << " msg:" << endl + << " - type: error" << endl + << " content: '" << errorMessage << "'" << endl + << " - name: " << blankEsp << endl + << " after:" << endl + << " - " << blankDifferentMasterDependentEsp << endl + << " - name: " << blankDifferentMasterDependentEsp << endl + << " after:" << endl + << " - " << blankMasterDependentEsp << endl + << " msg:" << endl + << " - type: say" << endl + << " content: '" << noteMessage << "'" << endl + << " - type: warn" << endl + << " content: '" << warningMessage << "'" << endl + << " - type: error" << endl + << " content: '" << errorMessage << "'" << endl; + + masterlist.close(); + } + + loot_db * db; + + const boost::filesystem::path masterlistPath; + + const std::string noteMessage; + const std::string warningMessage; + const std::string errorMessage; + }; + } +} + +#endif diff --git a/src/tests/api/loot_apply_load_order_test.h b/src/tests/api/loot_apply_load_order_test.h new file mode 100644 index 00000000..e798890f --- /dev/null +++ b/src/tests/api/loot_apply_load_order_test.h @@ -0,0 +1,77 @@ +/* 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_TEST_LOOT_APPLY_LOAD_ORDER +#define LOOT_TEST_LOOT_APPLY_LOAD_ORDER + +#include "../include/loot/api.h" +#include "api_game_operations_test.h" + +namespace loot { + namespace test { + class loot_apply_load_order_test : public ApiGameOperationsTest {}; + + // Pass an empty first argument, as it's a prefix for the test instantation, + // but we only have the one so no prefix is necessary. + INSTANTIATE_TEST_CASE_P(, + loot_apply_load_order_test, + ::testing::Values( + loot_game_tes4, + loot_game_tes5, + loot_game_fo3, + loot_game_fonv, + loot_game_fo4)); + + TEST_P(loot_apply_load_order_test, shouldReturnAnInvalidArgsIfTheDbOrLoadOrderPointersAreNull) { + const char * loadOrder[1] = { + masterFile.c_str(), + }; + size_t numPlugins = 0; + + EXPECT_EQ(loot_error_invalid_args, loot_apply_load_order(NULL, loadOrder, numPlugins)); + EXPECT_EQ(loot_error_invalid_args, loot_apply_load_order(db, NULL, numPlugins)); + } + + TEST_P(loot_apply_load_order_test, shouldReturnOkIfLoadOrderGivenIsNotEmpty) { + const char * loadOrder[11] = { + masterFile.c_str(), + blankEsm.c_str(), + blankMasterDependentEsm.c_str(), + blankDifferentEsm.c_str(), + blankDifferentMasterDependentEsm.c_str(), + blankMasterDependentEsp.c_str(), + blankDifferentMasterDependentEsp.c_str(), + blankEsp.c_str(), + blankPluginDependentEsp.c_str(), + blankDifferentEsp.c_str(), + blankDifferentPluginDependentEsp.c_str(), + }; + size_t numPlugins = 11; + + EXPECT_EQ(loot_ok, loot_apply_load_order(db, loadOrder, numPlugins)); + } + } +} + +#endif diff --git a/src/tests/api/loot_create_db_test.h b/src/tests/api/loot_create_db_test.h new file mode 100644 index 00000000..09434741 --- /dev/null +++ b/src/tests/api/loot_create_db_test.h @@ -0,0 +1,97 @@ +/* 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_TEST_LOOT_CREATE_DB +#define LOOT_TEST_LOOT_CREATE_DB + +#include "../include/loot/api.h" +#include "tests/base_game_test.h" + +#include + +namespace loot { + namespace test { + class loot_create_db_test : public BaseGameTest { + protected: + loot_create_db_test() : + db(nullptr) {} + + inline virtual void TearDown() { + BaseGameTest::TearDown(); + + ASSERT_NO_THROW(loot_destroy_db(db)); + } + + loot_db * db; + }; + + // Pass an empty first argument, as it's a prefix for the test instantation, + // but we only have the one so no prefix is necessary. + INSTANTIATE_TEST_CASE_P(, + loot_create_db_test, + ::testing::Values( + loot_game_tes4, + loot_game_tes5, + loot_game_fo3, + loot_game_fonv, + loot_game_fo4)); + + TEST_P(loot_create_db_test, shouldSucceedIfPassedValidParametersWithRelativePaths) { + EXPECT_EQ(loot_ok, loot_create_db(&db, GetParam(), dataPath.parent_path().string().c_str(), localPath.string().c_str())); + EXPECT_NE(nullptr, db); + } + + TEST_P(loot_create_db_test, shouldSucceedIfPassedValidParametersWithAbsolutePaths) { + boost::filesystem::path game = boost::filesystem::current_path() / dataPath.parent_path(); + boost::filesystem::path local = boost::filesystem::current_path() / localPath; + + EXPECT_EQ(loot_ok, loot_create_db(&db, GetParam(), game.string().c_str(), local.string().c_str())); + EXPECT_NE(nullptr, db); + } + + TEST_P(loot_create_db_test, shouldReturnAnInvalidArgsErrorIfPassedANullPointer) { + EXPECT_EQ(loot_error_invalid_args, loot_create_db(NULL, GetParam(), dataPath.parent_path().string().c_str(), localPath.string().c_str())); + } + + TEST_P(loot_create_db_test, shouldReturnAnInvalidArgsErrorIfPassedAnInvalidGameType) { + EXPECT_EQ(loot_error_invalid_args, loot_create_db(&db, UINT_MAX, dataPath.parent_path().string().c_str(), localPath.string().c_str())); + } + + TEST_P(loot_create_db_test, shouldReturnAnInvalidArgsErrorIfPassedAGamePathThatDoesNotExist) { + EXPECT_EQ(loot_error_invalid_args, loot_create_db(&db, GetParam(), missingPath.string().c_str(), localPath.string().c_str())); + } + + TEST_P(loot_create_db_test, shouldReturnAnInvalidArgsErrorIfPassedALocalPathThatDoesNotExist) { + EXPECT_EQ(loot_error_invalid_args, loot_create_db(&db, GetParam(), dataPath.parent_path().string().c_str(), missingPath.string().c_str())); + } + +#ifdef _WIN32 + TEST_P(loot_create_db_test, shouldReturnOkIfPassedANullLocalPathPointer) { + EXPECT_EQ(loot_ok, loot_create_db(&db, GetParam(), dataPath.parent_path().string().c_str(), NULL)); + } +#endif + } +} + +#endif diff --git a/src/tests/api/test_loot_db.h b/src/tests/api/loot_db_test.h similarity index 77% rename from src/tests/api/test_loot_db.h rename to src/tests/api/loot_db_test.h index 01f3bd8b..e5d5ed6c 100644 --- a/src/tests/api/test_loot_db.h +++ b/src/tests/api/loot_db_test.h @@ -27,30 +27,52 @@ along with LOOT. If not, see #include "api/loot_db.h" #include "backend/game/game_settings.h" -#include "tests/fixtures.h" +#include "tests/base_game_test.h" namespace loot { namespace test { - class loot_db_test : public SkyrimTest { + class loot_db_test : public BaseGameTest { protected: - virtual void SetUp() { - SkyrimTest::SetUp(); + loot_db_test() : + db(nullptr) {} - db = new loot_db(Game::tes5, dataPath.parent_path().string().c_str(), localPath.string().c_str()); + virtual void SetUp() { + BaseGameTest::SetUp(); + + db = new loot_db(GetParam(), dataPath.parent_path().string().c_str(), localPath.string().c_str()); } + + inline virtual void TearDown() { + BaseGameTest::TearDown(); + + delete db; + } + + loot_db * db; }; - TEST_F(loot_db_test, settingRevisionIdStringShouldCopyIt) { + // Pass an empty first argument, as it's a prefix for the test instantation, + // but we only have the one so no prefix is necessary. + INSTANTIATE_TEST_CASE_P(, + loot_db_test, + ::testing::Values( + loot_game_tes4, + loot_game_tes5, + loot_game_fo3, + loot_game_fonv, + loot_game_fo4)); + + TEST_P(loot_db_test, settingRevisionIdStringShouldCopyIt) { db->setRevisionIdString("id"); EXPECT_STREQ("id", db->getRevisionIdString()); } - TEST_F(loot_db_test, settingRevisionDateStringShouldCopyIt) { + TEST_P(loot_db_test, settingRevisionDateStringShouldCopyIt) { db->setRevisionDateString("date"); EXPECT_STREQ("date", db->getRevisionDateString()); } - TEST_F(loot_db_test, settingPluginNamesShouldCopyThem) { + TEST_P(loot_db_test, settingPluginNamesShouldCopyThem) { db->setPluginNames(std::vector({ PluginMetadata("Blank.esm"), PluginMetadata("Blank.esp"), @@ -61,7 +83,7 @@ namespace loot { EXPECT_STREQ("Blank.esp", db->getPluginNames()[1]); } - TEST_F(loot_db_test, settingPluginNamesTwiceShouldOverwriteTheFirstDataSet) { + TEST_P(loot_db_test, settingPluginNamesTwiceShouldOverwriteTheFirstDataSet) { db->setPluginNames(std::vector({ PluginMetadata("Blank.esm"), PluginMetadata("Blank.esp"), @@ -76,7 +98,7 @@ namespace loot { EXPECT_STREQ("Blank - Different.esp", db->getPluginNames()[1]); } - TEST_F(loot_db_test, addingNewBashTagsToTheMapShouldAppendThem) { + TEST_P(loot_db_test, addingNewBashTagsToTheMapShouldAppendThem) { db->addBashTagsToMap({ "C.Climate", "Relev", @@ -87,7 +109,7 @@ namespace loot { EXPECT_STREQ("Relev", db->getBashTagMap()[1]); } - TEST_F(loot_db_test, addingAnExistingBashTagToTheMapShouldNotDuplicateIt) { + TEST_P(loot_db_test, addingAnExistingBashTagToTheMapShouldNotDuplicateIt) { db->addBashTagsToMap({ "C.Climate", "Relev", @@ -99,11 +121,11 @@ namespace loot { EXPECT_STREQ("Relev", db->getBashTagMap()[1]); } - TEST_F(loot_db_test, gettingABashTagsUidForATagThatIsNotInTheMapShouldThrow) { + TEST_P(loot_db_test, gettingABashTagsUidForATagThatIsNotInTheMapShouldThrow) { EXPECT_ANY_THROW(db->getBashTagUid("Relev")); } - TEST_F(loot_db_test, gettingABashTagsUidShouldReturnItsTagMapIndex) { + TEST_P(loot_db_test, gettingABashTagsUidShouldReturnItsTagMapIndex) { db->addBashTagsToMap({ "C.Climate", "Relev", @@ -112,11 +134,11 @@ namespace loot { EXPECT_EQ(1, db->getBashTagUid("Relev")); } - TEST_F(loot_db_test, clearingAnEmptyBashTagMapShouldDoNothing) { + TEST_P(loot_db_test, clearingAnEmptyBashTagMapShouldDoNothing) { EXPECT_NO_THROW(db->clearBashTagMap()); } - TEST_F(loot_db_test, clearingABashTagMapShouldEmptyIt) { + TEST_P(loot_db_test, clearingABashTagMapShouldEmptyIt) { db->addBashTagsToMap({ "C.Climate", "Relev", @@ -126,7 +148,7 @@ namespace loot { EXPECT_TRUE(db->getBashTagMap().empty()); } - TEST_F(loot_db_test, clearingABashTagMapShouldAffectExistingReferences) { + TEST_P(loot_db_test, clearingABashTagMapShouldAffectExistingReferences) { db->addBashTagsToMap({ "C.Climate", "Relev", @@ -137,13 +159,13 @@ namespace loot { EXPECT_TRUE(bashTagMap.empty()); } - TEST_F(loot_db_test, settingAddedTagsWithNoTagMapShouldThrow) { + TEST_P(loot_db_test, settingAddedTagsWithNoTagMapShouldThrow) { EXPECT_ANY_THROW(db->setAddedTags({ "Relev", })); } - TEST_F(loot_db_test, gettingSetAddedTagsShouldReturnTheirUids) { + TEST_P(loot_db_test, gettingSetAddedTagsShouldReturnTheirUids) { db->addBashTagsToMap({ "C.Climate", "Relev", @@ -158,13 +180,13 @@ namespace loot { }), db->getAddedTagIds()); } - TEST_F(loot_db_test, settingRemovedTagsWithNoTagMapShouldThrow) { + TEST_P(loot_db_test, settingRemovedTagsWithNoTagMapShouldThrow) { EXPECT_ANY_THROW(db->setRemovedTags({ "Relev", })); } - TEST_F(loot_db_test, gettingSetRemovedTagsShouldReturnTheirUids) { + TEST_P(loot_db_test, gettingSetRemovedTagsShouldReturnTheirUids) { db->addBashTagsToMap({ "C.Climate", "Relev", @@ -179,7 +201,7 @@ namespace loot { }), db->getRemovedTagIds()); } - TEST_F(loot_db_test, settingPluginMessagesShouldCopyThem) { + TEST_P(loot_db_test, settingPluginMessagesShouldCopyThem) { db->setPluginMessages(std::list({ Message(Message::warn, "Test 1"), Message(Message::error, "Test 2"), @@ -192,7 +214,7 @@ namespace loot { EXPECT_STREQ("Test 2", db->getPluginMessages()[1].message); } - TEST_F(loot_db_test, settingPluginMessagesTwiceShouldOverwriteTheFirstDataSet) { + TEST_P(loot_db_test, settingPluginMessagesTwiceShouldOverwriteTheFirstDataSet) { db->setPluginMessages(std::list({ Message(Message::warn, "Test 1"), Message(Message::error, "Test 2"), @@ -212,7 +234,7 @@ namespace loot { EXPECT_STREQ("Test 5", db->getPluginMessages()[2].message); } - TEST_F(loot_db_test, clearingArraysShouldEmptyPluginNamesTagIdsAndMessages) { + TEST_P(loot_db_test, clearingArraysShouldEmptyPluginNamesTagIdsAndMessages) { db->setPluginMessages(std::list({ Message(Message::warn, "Test 1"), Message(Message::error, "Test 2"), @@ -247,7 +269,7 @@ namespace loot { EXPECT_TRUE(db->getRemovedTagIds().empty()); } - TEST_F(loot_db_test, clearingArraysShouldNotEmptyBashTagMap) { + TEST_P(loot_db_test, clearingArraysShouldNotEmptyBashTagMap) { db->addBashTagsToMap({ "C.Climate", "Relev", diff --git a/src/tests/api/loot_eval_lists_test.h b/src/tests/api/loot_eval_lists_test.h new file mode 100644 index 00000000..bb4f2e01 --- /dev/null +++ b/src/tests/api/loot_eval_lists_test.h @@ -0,0 +1,87 @@ +/* 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_TEST_LOOT_EVAL_LISTS +#define LOOT_TEST_LOOT_EVAL_LISTS + +#include "../include/loot/api.h" +#include "api_game_operations_test.h" + +namespace loot { + namespace test { + class loot_eval_lists_test : public ApiGameOperationsTest {}; + + // Pass an empty first argument, as it's a prefix for the test instantation, + // but we only have the one so no prefix is necessary. + INSTANTIATE_TEST_CASE_P(, + loot_eval_lists_test, + ::testing::Values( + loot_game_tes4, + loot_game_tes5, + loot_game_fo3, + loot_game_fonv, + loot_game_fo4)); + + TEST_P(loot_eval_lists_test, shouldReturnAnInvalidArgsErrorIfPassedANullPointer) { + EXPECT_EQ(loot_error_invalid_args, loot_eval_lists(NULL, loot_lang_any)); + } + + TEST_P(loot_eval_lists_test, shouldReturnAnInvalidArgsErrorIfPassedAnInvalidLanguageCode) { + EXPECT_EQ(loot_error_invalid_args, loot_eval_lists(db, UINT_MAX)); + } + + TEST_P(loot_eval_lists_test, shouldReturnOkForAllLanguagesWithNoListsLoaded) { + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_any)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_english)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_spanish)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_russian)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_french)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_chinese)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_polish)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_brazilian_portuguese)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_finnish)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_german)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_danish)); + } + + TEST_P(loot_eval_lists_test, shouldReturnOKForAllLanguagesWithAMasterlistLoaded) { + ASSERT_NO_THROW(generateMasterlist()); + ASSERT_EQ(loot_ok, loot_load_lists(db, masterlistPath.string().c_str(), NULL)); + + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_any)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_english)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_spanish)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_russian)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_french)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_chinese)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_polish)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_brazilian_portuguese)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_finnish)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_german)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_danish)); + } + } +} + +#endif diff --git a/src/tests/api/loot_get_dirty_info_test.h b/src/tests/api/loot_get_dirty_info_test.h new file mode 100644 index 00000000..286512b4 --- /dev/null +++ b/src/tests/api/loot_get_dirty_info_test.h @@ -0,0 +1,81 @@ +/* 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_TEST_LOOT_GET_DIRTY_INFO +#define LOOT_TEST_LOOT_GET_DIRTY_INFO + +#include "../include/loot/api.h" +#include "api_game_operations_test.h" + +namespace loot { + namespace test { + class loot_get_dirty_info_test : public ApiGameOperationsTest { + protected: + loot_get_dirty_info_test() : + needsCleaning(0) {} + + unsigned int needsCleaning; + }; + + // Pass an empty first argument, as it's a prefix for the test instantation, + // but we only have the one so no prefix is necessary. + INSTANTIATE_TEST_CASE_P(, + loot_get_dirty_info_test, + ::testing::Values( + loot_game_tes4, + loot_game_tes5, + loot_game_fo3, + loot_game_fonv, + loot_game_fo4)); + + TEST_P(loot_get_dirty_info_test, shouldReturnAnInvalidArgsErrorIfAnyOfTheArgumentsAreNull) { + EXPECT_EQ(loot_error_invalid_args, loot_get_dirty_info(NULL, blankEsp.c_str(), &needsCleaning)); + EXPECT_EQ(loot_error_invalid_args, loot_get_dirty_info(db, NULL, &needsCleaning)); + EXPECT_EQ(loot_error_invalid_args, loot_get_dirty_info(db, blankEsp.c_str(), NULL)); + } + + TEST_P(loot_get_dirty_info_test, shouldReturnOkAndOutputUnknownForAPluginWithNoDirtyInfo) { + EXPECT_EQ(loot_ok, loot_get_dirty_info(db, blankEsp.c_str(), &needsCleaning)); + EXPECT_EQ(loot_needs_cleaning_unknown, needsCleaning); + } + + TEST_P(loot_get_dirty_info_test, shouldReturnOkAndOutputYesForAPluginWithDirtyInfo) { + ASSERT_NO_THROW(generateMasterlist()); + ASSERT_EQ(loot_ok, loot_load_lists(db, masterlistPath.string().c_str(), NULL)); + + EXPECT_EQ(loot_ok, loot_get_dirty_info(db, blankDifferentEsm.c_str(), &needsCleaning)); + EXPECT_EQ(loot_needs_cleaning_yes, needsCleaning); + } + + TEST_P(loot_get_dirty_info_test, shouldReturnOkAndOutputNoForAPluginWithADoNotCleanMessage) { + ASSERT_NO_THROW(generateMasterlist()); + ASSERT_EQ(loot_ok, loot_load_lists(db, masterlistPath.string().c_str(), NULL)); + + EXPECT_EQ(loot_ok, loot_get_dirty_info(db, blankEsm.c_str(), &needsCleaning)); + EXPECT_EQ(loot_needs_cleaning_no, needsCleaning); + } + } +} + +#endif diff --git a/src/tests/api/loot_get_masterlist_revision_test.h b/src/tests/api/loot_get_masterlist_revision_test.h new file mode 100644 index 00000000..5894c540 --- /dev/null +++ b/src/tests/api/loot_get_masterlist_revision_test.h @@ -0,0 +1,119 @@ +/* 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_TEST_LOOT_GET_MASTERLIST_REVISION +#define LOOT_TEST_LOOT_GET_MASTERLIST_REVISION + +#include "../include/loot/api.h" +#include "api_game_operations_test.h" + +namespace loot { + namespace test { + class loot_get_masterlist_revision_test : public ApiGameOperationsTest { + protected: + loot_get_masterlist_revision_test() : + revisionId("foo"), + revisionDate("bar"), + isModified(true), + updated(false) {} + + const char * revisionId; + const char * revisionDate; + bool isModified; + bool updated; + }; + + // Pass an empty first argument, as it's a prefix for the test instantation, + // but we only have the one so no prefix is necessary. + INSTANTIATE_TEST_CASE_P(, + loot_get_masterlist_revision_test, + ::testing::Values( + loot_game_tes4, + loot_game_tes5, + loot_game_fo3, + loot_game_fonv, + loot_game_fo4)); + + TEST_P(loot_get_masterlist_revision_test, shouldReturnAnInvalidArgsErrorIfAnyOfTheArgumentsAreNull) { + EXPECT_EQ(loot_error_invalid_args, loot_get_masterlist_revision(NULL, masterlistPath.string().c_str(), false, &revisionId, &revisionDate, &isModified)); + EXPECT_EQ(loot_error_invalid_args, loot_get_masterlist_revision(db, NULL, false, &revisionId, &revisionDate, &isModified)); + EXPECT_EQ(loot_error_invalid_args, loot_get_masterlist_revision(db, masterlistPath.string().c_str(), false, NULL, &revisionDate, &isModified)); + EXPECT_EQ(loot_error_invalid_args, loot_get_masterlist_revision(db, masterlistPath.string().c_str(), false, &revisionId, NULL, &isModified)); + EXPECT_EQ(loot_error_invalid_args, loot_get_masterlist_revision(db, masterlistPath.string().c_str(), false, &revisionId, &revisionDate, NULL)); + } + + TEST_P(loot_get_masterlist_revision_test, shouldSucceedIfNoMasterlistIsPresent) { + EXPECT_EQ(loot_ok, loot_get_masterlist_revision(db, masterlistPath.string().c_str(), false, &revisionId, &revisionDate, &isModified)); + EXPECT_EQ(NULL, revisionId); + EXPECT_EQ(NULL, revisionDate); + EXPECT_FALSE(isModified); + } + + TEST_P(loot_get_masterlist_revision_test, shouldSucceedIfANonVersionControlledMasterlistIsPresent) { + ASSERT_NO_THROW(generateMasterlist()); + EXPECT_EQ(loot_ok, loot_get_masterlist_revision(db, masterlistPath.string().c_str(), false, &revisionId, &revisionDate, &isModified)); + EXPECT_EQ(NULL, revisionId); + EXPECT_EQ(NULL, revisionDate); + EXPECT_FALSE(isModified); + } + + TEST_P(loot_get_masterlist_revision_test, shouldOutputLongStringsAndBooleanFalseIfAVersionControlledMasterlistIsPresentAndGetShortIdParameterIsFalse) { + ASSERT_EQ(loot_ok, loot_update_masterlist(db, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "master", &updated)); + + EXPECT_EQ(loot_ok, loot_get_masterlist_revision(db, masterlistPath.string().c_str(), false, &revisionId, &revisionDate, &isModified)); + EXPECT_STRNE(NULL, revisionId); + EXPECT_EQ(40, strlen(revisionId)); + EXPECT_STRNE(NULL, revisionDate); + EXPECT_EQ(10, strlen(revisionDate)); + EXPECT_FALSE(isModified); + } + + TEST_P(loot_get_masterlist_revision_test, shouldOutputShortStringsAndBooleanFalseIfAVersionControlledMasterlistIsPresentAndGetShortIdParameterIsTrue) { + ASSERT_EQ(loot_ok, loot_update_masterlist(db, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "master", &updated)); + + EXPECT_EQ(loot_ok, loot_get_masterlist_revision(db, masterlistPath.string().c_str(), false, &revisionId, &revisionDate, &isModified)); + EXPECT_STRNE(NULL, revisionId); + EXPECT_GE(size_t(40), strlen(revisionId)); + EXPECT_LE(size_t(7), strlen(revisionId)); + EXPECT_STRNE(NULL, revisionDate); + EXPECT_EQ(10, strlen(revisionDate)); + EXPECT_FALSE(isModified); + } + + TEST_P(loot_get_masterlist_revision_test, shouldSucceedIfAnEditedVersionControlledMasterlistIsPresent) { + ASSERT_EQ(loot_ok, loot_update_masterlist(db, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "master", &updated)); + + ASSERT_NO_THROW(generateMasterlist()); + EXPECT_EQ(loot_ok, loot_get_masterlist_revision(db, masterlistPath.string().c_str(), false, &revisionId, &revisionDate, &isModified)); + + EXPECT_STRNE(NULL, revisionId); + EXPECT_EQ(40, strlen(revisionId)); + EXPECT_STRNE(NULL, revisionDate); + EXPECT_EQ(10, strlen(revisionDate)); + EXPECT_TRUE(isModified); + } + } +} + +#endif diff --git a/src/tests/api/loot_get_plugin_messages_test.h b/src/tests/api/loot_get_plugin_messages_test.h new file mode 100644 index 00000000..9ddd0283 --- /dev/null +++ b/src/tests/api/loot_get_plugin_messages_test.h @@ -0,0 +1,113 @@ +/* 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_TEST_LOOT_GET_PLUGIN_MESSAGES +#define LOOT_TEST_LOOT_GET_PLUGIN_MESSAGES + +#include "../include/loot/api.h" +#include "api_game_operations_test.h" + +namespace loot { + namespace test { + class loot_get_plugin_messages_test : public ApiGameOperationsTest { + protected: + loot_get_plugin_messages_test() : + messages(nullptr), + numMessages(0) {} + + const loot_message * messages; + size_t numMessages; + }; + + // Pass an empty first argument, as it's a prefix for the test instantation, + // but we only have the one so no prefix is necessary. + INSTANTIATE_TEST_CASE_P(, + loot_get_plugin_messages_test, + ::testing::Values( + loot_game_tes4, + loot_game_tes5, + loot_game_fo3, + loot_game_fonv, + loot_game_fo4)); + + TEST_P(loot_get_plugin_messages_test, shouldReturnAnInvalidArgsErrorIfAnyOfTheArgumentsAreNull) { + EXPECT_EQ(loot_error_invalid_args, loot_get_plugin_messages(NULL, blankEsp.c_str(), &messages, &numMessages)); + EXPECT_EQ(loot_error_invalid_args, loot_get_plugin_messages(db, NULL, &messages, &numMessages)); + EXPECT_EQ(loot_error_invalid_args, loot_get_plugin_messages(db, blankEsp.c_str(), NULL, &numMessages)); + EXPECT_EQ(loot_error_invalid_args, loot_get_plugin_messages(db, blankEsp.c_str(), &messages, NULL)); + } + + TEST_P(loot_get_plugin_messages_test, shouldReturnOkAndOutputANullArrayIfAPluginWithNoMessagesIsQueried) { + EXPECT_EQ(loot_ok, loot_get_plugin_messages(db, blankEsp.c_str(), &messages, &numMessages)); + EXPECT_EQ(0, numMessages); + EXPECT_EQ(NULL, messages); + } + + TEST_P(loot_get_plugin_messages_test, shouldReturnOkAndOutputANoteIfAPluginWithANoteMessageIsQueried) { + ASSERT_NO_THROW(generateMasterlist()); + ASSERT_EQ(loot_ok, loot_load_lists(db, masterlistPath.string().c_str(), NULL)); + + EXPECT_EQ(loot_ok, loot_get_plugin_messages(db, blankEsm.c_str(), &messages, &numMessages)); + ASSERT_EQ(1, numMessages); + EXPECT_EQ(loot_message_say, messages[0].type); + EXPECT_STREQ(noteMessage.c_str(), messages[0].message); + } + + TEST_P(loot_get_plugin_messages_test, shouldReturnOkAndOutputAWarningIfAPluginWithAWarningMessageIsQueried) { + ASSERT_NO_THROW(generateMasterlist()); + ASSERT_EQ(loot_ok, loot_load_lists(db, masterlistPath.string().c_str(), NULL)); + + EXPECT_EQ(loot_ok, loot_get_plugin_messages(db, blankDifferentEsm.c_str(), &messages, &numMessages)); + ASSERT_EQ(1, numMessages); + EXPECT_EQ(loot_message_warn, messages[0].type); + EXPECT_STREQ(warningMessage.c_str(), messages[0].message); + } + + TEST_P(loot_get_plugin_messages_test, shouldReturnOkAndOutputAnErrorIfAPluginWithAnErrorMessageIsQueried) { + ASSERT_NO_THROW(generateMasterlist()); + ASSERT_EQ(loot_ok, loot_load_lists(db, masterlistPath.string().c_str(), NULL)); + + EXPECT_EQ(loot_ok, loot_get_plugin_messages(db, blankDifferentEsp.c_str(), &messages, &numMessages)); + ASSERT_EQ(1, numMessages); + EXPECT_EQ(loot_message_error, messages[0].type); + EXPECT_STREQ(errorMessage.c_str(), messages[0].message); + } + + TEST_P(loot_get_plugin_messages_test, shouldReturnOkAndOutputMultipleMessagesIfAPluginWithMultipleMessagesIsQueried) { + ASSERT_NO_THROW(generateMasterlist()); + ASSERT_EQ(loot_ok, loot_load_lists(db, masterlistPath.string().c_str(), NULL)); + + EXPECT_EQ(loot_ok, loot_get_plugin_messages(db, blankDifferentMasterDependentEsp.c_str(), &messages, &numMessages)); + ASSERT_EQ(3, numMessages); + EXPECT_EQ(loot_message_say, messages[0].type); + EXPECT_STREQ(noteMessage.c_str(), messages[0].message); + EXPECT_EQ(loot_message_warn, messages[1].type); + EXPECT_STREQ(warningMessage.c_str(), messages[1].message); + EXPECT_EQ(loot_message_error, messages[2].type); + EXPECT_STREQ(errorMessage.c_str(), messages[2].message); + } + } +} + +#endif diff --git a/src/tests/api/loot_get_plugin_tags_test.h b/src/tests/api/loot_get_plugin_tags_test.h new file mode 100644 index 00000000..49026914 --- /dev/null +++ b/src/tests/api/loot_get_plugin_tags_test.h @@ -0,0 +1,140 @@ +/* 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_TEST_LOOT_GET_PLUGIN_TAGS +#define LOOT_TEST_LOOT_GET_PLUGIN_TAGS + +#include "../include/loot/api.h" +#include "api_game_operations_test.h" + +namespace loot { + namespace test { + class loot_get_plugin_tags_test : public ApiGameOperationsTest { + protected: + loot_get_plugin_tags_test() : + tagMap(nullptr), + numTags(0), + added(nullptr), + removed(nullptr), + numAdded(0), + numRemoved(0), + modified(false) {} + + const char * const * tagMap; + size_t numTags; + + const unsigned int * added; + const unsigned int * removed; + size_t numAdded; + size_t numRemoved; + bool modified; + + void getTagMap() { + ASSERT_EQ(loot_ok, loot_get_tag_map(db, &tagMap, &numTags)); + + ASSERT_EQ(3, numTags); + ASSERT_STREQ("Actors.ACBS", tagMap[0]); + ASSERT_STREQ("Actors.AIData", tagMap[1]); + ASSERT_STREQ("C.Water", tagMap[2]); + } + }; + + // Pass an empty first argument, as it's a prefix for the test instantation, + // but we only have the one so no prefix is necessary. + INSTANTIATE_TEST_CASE_P(, + loot_get_plugin_tags_test, + ::testing::Values( + loot_game_tes4, + loot_game_tes5, + loot_game_fo3, + loot_game_fonv, + loot_game_fo4)); + + TEST_P(loot_get_plugin_tags_test, shouldReturnAnInvalidArgsErrorIfAnyOfTheArgumentsAreNull) { + EXPECT_EQ(loot_error_invalid_args, loot_get_plugin_tags(NULL, blankEsm.c_str(), &added, &numAdded, &removed, &numRemoved, &modified)); + EXPECT_EQ(loot_error_invalid_args, loot_get_plugin_tags(db, NULL, &added, &numAdded, &removed, &numRemoved, &modified)); + EXPECT_EQ(loot_error_invalid_args, loot_get_plugin_tags(db, blankEsm.c_str(), NULL, &numAdded, &removed, &numRemoved, &modified)); + EXPECT_EQ(loot_error_invalid_args, loot_get_plugin_tags(db, blankEsm.c_str(), &added, NULL, &removed, &numRemoved, &modified)); + EXPECT_EQ(loot_error_invalid_args, loot_get_plugin_tags(db, blankEsm.c_str(), &added, &numAdded, NULL, &numRemoved, &modified)); + EXPECT_EQ(loot_error_invalid_args, loot_get_plugin_tags(db, blankEsm.c_str(), &added, &numAdded, &removed, NULL, &modified)); + EXPECT_EQ(loot_error_invalid_args, loot_get_plugin_tags(db, blankEsm.c_str(), &added, &numAdded, &removed, &numRemoved, NULL)); + } + + TEST_P(loot_get_plugin_tags_test, shouldReturnANoTagMapIfCalledBeforeATagMapHasBeenGotten) { + EXPECT_EQ(loot_error_no_tag_map, loot_get_plugin_tags(db, blankEsm.c_str(), &added, &numAdded, &removed, &numRemoved, &modified)); + } + + TEST_P(loot_get_plugin_tags_test, shouldReturnOkAndOutputEmptyNonModifiedArraysIfAPluginWithoutTagsIsQueried) { + ASSERT_NO_THROW(generateMasterlist()); + ASSERT_EQ(loot_ok, loot_load_lists(db, masterlistPath.string().c_str(), NULL)); + getTagMap(); + + EXPECT_EQ(loot_ok, loot_get_plugin_tags(db, blankEsp.c_str(), &added, &numAdded, &removed, &numRemoved, &modified)); + + EXPECT_EQ(0, numAdded); + EXPECT_EQ(NULL, added); + EXPECT_EQ(0, numRemoved); + EXPECT_EQ(NULL, removed); + EXPECT_FALSE(modified); + } + + TEST_P(loot_get_plugin_tags_test, shouldReturnOkAndNonEmptyNonModifiedArraysIfAPluginWithTagsIsQueried) { + ASSERT_NO_THROW(generateMasterlist()); + ASSERT_EQ(loot_ok, loot_load_lists(db, masterlistPath.string().c_str(), NULL)); + getTagMap(); + + EXPECT_EQ(loot_ok, loot_get_plugin_tags(db, blankEsm.c_str(), &added, &numAdded, &removed, &numRemoved, &modified)); + + // The values are tag map indices, check they match up as expected. + ASSERT_EQ(2, numAdded); + EXPECT_EQ(0, added[0]); + EXPECT_EQ(1, added[1]); + + ASSERT_EQ(1, numRemoved); + EXPECT_EQ(2, removed[0]); + + EXPECT_FALSE(modified); + } + + TEST_P(loot_get_plugin_tags_test, shouldReturnOkAndNonEmptyModifiedArraysIfAPluginWithTagsIsQueriedAndMetadataWasAlsoLoadedFromAUserlist) { + ASSERT_NO_THROW(generateMasterlist()); + ASSERT_EQ(loot_ok, loot_load_lists(db, masterlistPath.string().c_str(), masterlistPath.string().c_str())); + getTagMap(); + + EXPECT_EQ(loot_ok, loot_get_plugin_tags(db, blankEsm.c_str(), &added, &numAdded, &removed, &numRemoved, &modified)); + + // The values are tag map indices, check they match up as expected. + ASSERT_EQ(2, numAdded); + EXPECT_EQ(0, added[0]); + EXPECT_EQ(1, added[1]); + + ASSERT_EQ(1, numRemoved); + EXPECT_EQ(2, removed[0]); + + EXPECT_TRUE(modified); + } + } +} + +#endif diff --git a/src/tests/api/loot_get_tag_map_test.h b/src/tests/api/loot_get_tag_map_test.h new file mode 100644 index 00000000..3bf76771 --- /dev/null +++ b/src/tests/api/loot_get_tag_map_test.h @@ -0,0 +1,80 @@ +/* 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_TEST_LOOT_GET_TAG_MAP +#define LOOT_TEST_LOOT_GET_TAG_MAP + +#include "../include/loot/api.h" +#include "api_game_operations_test.h" + +namespace loot { + namespace test { + class loot_get_tag_map_test : public ApiGameOperationsTest { + protected: + loot_get_tag_map_test() : + tagMap(nullptr), + numTags(0) {} + + const char * const * tagMap; + size_t numTags; + }; + + // Pass an empty first argument, as it's a prefix for the test instantation, + // but we only have the one so no prefix is necessary. + INSTANTIATE_TEST_CASE_P(, + loot_get_tag_map_test, + ::testing::Values( + loot_game_tes4, + loot_game_tes5, + loot_game_fo3, + loot_game_fonv, + loot_game_fo4)); + + TEST_P(loot_get_tag_map_test, shouldReturnAnInvalidArgsErrorIfAnyOfTheArgumentsAreNull) { + EXPECT_EQ(loot_error_invalid_args, loot_get_tag_map(NULL, &tagMap, &numTags)); + EXPECT_EQ(loot_error_invalid_args, loot_get_tag_map(db, NULL, &numTags)); + EXPECT_EQ(loot_error_invalid_args, loot_get_tag_map(db, &tagMap, NULL)); + } + + TEST_P(loot_get_tag_map_test, shouldReturnOkAndOutputAnEmptyTagMapIfNoMetadataHasBeenLoaded) { + EXPECT_EQ(loot_ok, loot_get_tag_map(db, &tagMap, &numTags)); + EXPECT_EQ(0, numTags); + EXPECT_EQ(NULL, tagMap); + } + + TEST_P(loot_get_tag_map_test, shouldReturnOKAndOutputANonEmptyTagMapIfMetadataHasBeenLoaded) { + ASSERT_NO_THROW(generateMasterlist()); + ASSERT_EQ(loot_ok, loot_load_lists(db, masterlistPath.string().c_str(), NULL)); + + EXPECT_EQ(loot_ok, loot_get_tag_map(db, &tagMap, &numTags)); + + ASSERT_EQ(3, numTags); + EXPECT_STREQ("Actors.ACBS", tagMap[0]); + EXPECT_STREQ("Actors.AIData", tagMap[1]); + EXPECT_STREQ("C.Water", tagMap[2]); + } + } +} + +#endif diff --git a/src/tests/api/loot_load_lists_test.h b/src/tests/api/loot_load_lists_test.h new file mode 100644 index 00000000..6c29bced --- /dev/null +++ b/src/tests/api/loot_load_lists_test.h @@ -0,0 +1,82 @@ +/* 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_TEST_LOOT_LOAD_LISTS +#define LOOT_TEST_LOOT_LOAD_LISTS + +#include "../include/loot/api.h" +#include "api_game_operations_test.h" + +namespace loot { + namespace test { + class loot_load_lists_test : public ApiGameOperationsTest { + protected: + loot_load_lists_test() : + userlistPath(localPath / "userlist.yaml") {} + + inline virtual void TearDown() { + ApiGameOperationsTest::TearDown(); + + // The userlist may have been created during the test, so delete it. + ASSERT_NO_THROW(boost::filesystem::remove(userlistPath)); + } + + boost::filesystem::path userlistPath; + }; + + // Pass an empty first argument, as it's a prefix for the test instantation, + // but we only have the one so no prefix is necessary. + INSTANTIATE_TEST_CASE_P(, + loot_load_lists_test, + ::testing::Values( + loot_game_tes4, + loot_game_tes5, + loot_game_fo3, + loot_game_fonv, + loot_game_fo4)); + + TEST_P(loot_load_lists_test, shouldReturnAnInvalidArgsErrorIfTheDbOrMasterlistPathArgumentsAreNull) { + EXPECT_EQ(loot_error_invalid_args, loot_load_lists(NULL, masterlistPath.string().c_str(), NULL)); + EXPECT_EQ(loot_error_invalid_args, loot_load_lists(db, NULL, NULL)); + } + + TEST_P(loot_load_lists_test, shouldReturnAPathNotFoundErrorIfNoMasterlistIsPresent) { + EXPECT_EQ(loot_error_path_not_found, loot_load_lists(db, masterlistPath.string().c_str(), NULL)); + } + + TEST_P(loot_load_lists_test, shouldReturnAPathNotFoundErrorIfAMasterlistIsPresentButAUserlistDoesNotExistAtTheGivenPath) { + ASSERT_NO_THROW(generateMasterlist()); + EXPECT_EQ(loot_error_path_not_found, loot_load_lists(db, masterlistPath.string().c_str(), userlistPath.string().c_str())); + } + + TEST_P(loot_load_lists_test, shouldReturnOkIfTheMasterlistAndUserlistAreBothPresent) { + ASSERT_NO_THROW(generateMasterlist()); + ASSERT_NO_THROW(boost::filesystem::copy(masterlistPath, userlistPath)); + + EXPECT_EQ(loot_ok, loot_load_lists(db, masterlistPath.string().c_str(), userlistPath.string().c_str())); + } + } +} + +#endif diff --git a/src/tests/api/loot_sort_plugins_test.h b/src/tests/api/loot_sort_plugins_test.h new file mode 100644 index 00000000..0cb9a831 --- /dev/null +++ b/src/tests/api/loot_sort_plugins_test.h @@ -0,0 +1,91 @@ +/* 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_TEST_LOOT_SORT_PLUGINS +#define LOOT_TEST_LOOT_SORT_PLUGINS + +#include "../include/loot/api.h" +#include "api_game_operations_test.h" + +namespace loot { + namespace test { + class loot_sort_plugins_test : public ApiGameOperationsTest { + protected: + loot_sort_plugins_test() : + sortedPlugins(nullptr), + numPlugins(0) {} + + const char * const * sortedPlugins; + size_t numPlugins; + }; + + // Pass an empty first argument, as it's a prefix for the test instantation, + // but we only have the one so no prefix is necessary. + INSTANTIATE_TEST_CASE_P(, + loot_sort_plugins_test, + ::testing::Values( + loot_game_tes4, + loot_game_tes5, + loot_game_fo3, + loot_game_fonv, + loot_game_fo4)); + + TEST_P(loot_sort_plugins_test, shouldReturnAnInvalidArgsErrorIfAnyOfTheArgumentsAreNull) { + EXPECT_EQ(loot_error_invalid_args, loot_sort_plugins(NULL, &sortedPlugins, &numPlugins)); + EXPECT_EQ(loot_error_invalid_args, loot_sort_plugins(db, NULL, &numPlugins)); + EXPECT_EQ(loot_error_invalid_args, loot_sort_plugins(db, &sortedPlugins, NULL)); + } + + TEST_P(loot_sort_plugins_test, shouldSucceedIfPassedValidArguments) { + std::list expectedOrder = { + masterFile, + blankEsm, + blankMasterDependentEsm, + blankDifferentEsm, + blankDifferentMasterDependentEsm, + blankMasterDependentEsp, + blankDifferentMasterDependentEsp, + blankEsp, + blankPluginDependentEsp, + blankDifferentEsp, + blankDifferentPluginDependentEsp, + }; + + ASSERT_NO_THROW(generateMasterlist()); + ASSERT_EQ(loot_ok, loot_load_lists(db, masterlistPath.string().c_str(), NULL)); + + EXPECT_EQ(loot_ok, loot_sort_plugins(db, &sortedPlugins, &numPlugins)); + + ASSERT_EQ(expectedOrder.size(), numPlugins); + + size_t i = 0; + for (const auto& plugin : expectedOrder) { + EXPECT_EQ(plugin, sortedPlugins[i]); + ++i; + } + } + } +} + +#endif diff --git a/src/tests/api/loot_update_masterlist_test.h b/src/tests/api/loot_update_masterlist_test.h new file mode 100644 index 00000000..dc69f43e --- /dev/null +++ b/src/tests/api/loot_update_masterlist_test.h @@ -0,0 +1,108 @@ +/* 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_TEST_LOOT_UPDATE_MASTERLIST +#define LOOT_TEST_LOOT_UPDATE_MASTERLIST + +#include "../include/loot/api.h" +#include "api_game_operations_test.h" + +namespace loot { + namespace test { + class loot_update_masterlist_test : public ApiGameOperationsTest { + protected: + loot_update_masterlist_test() : + updated(false) {} + + inline virtual void TearDown() { + ApiGameOperationsTest::TearDown(); + + // Also remove the ".git" folder if it has been created. + ASSERT_NO_THROW(boost::filesystem::remove_all(masterlistPath.parent_path() / ".git")); + } + + bool updated; + }; + + // Pass an empty first argument, as it's a prefix for the test instantation, + // but we only have the one so no prefix is necessary. + INSTANTIATE_TEST_CASE_P(, + loot_update_masterlist_test, + ::testing::Values( + loot_game_tes4, + loot_game_tes5, + loot_game_fo3, + loot_game_fonv, + loot_game_fo4)); + + TEST_P(loot_update_masterlist_test, shouldReturnAnInvalidArgsErrorIfAnyOfTheArgumentsAreNull) { + EXPECT_EQ(loot_error_invalid_args, loot_update_masterlist(NULL, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "master", &updated)); + EXPECT_EQ(loot_error_invalid_args, loot_update_masterlist(db, NULL, "https://github.com/loot/testing-metadata.git", "master", &updated)); + EXPECT_EQ(loot_error_invalid_args, loot_update_masterlist(db, masterlistPath.string().c_str(), NULL, "master", &updated)); + EXPECT_EQ(loot_error_invalid_args, loot_update_masterlist(db, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", NULL, &updated)); + EXPECT_EQ(loot_error_invalid_args, loot_update_masterlist(db, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "master", NULL)); + } + + TEST_P(loot_update_masterlist_test, shouldReturnAnInvalidArgsErrorIfTheMasterlistPathGivenIsInvalid) { + EXPECT_EQ(loot_error_invalid_args, loot_update_masterlist(db, ";//\?", "https://github.com/loot/testing-metadata.git", "master", &updated)); + } + + TEST_P(loot_update_masterlist_test, shouldReturnAnInvalidArgsErrorIfTheMasterlistPathGivenIsEmpty) { + EXPECT_EQ(loot_error_invalid_args, loot_update_masterlist(db, "", "https://github.com/loot/testing-metadata.git", "master", &updated)); + } + + TEST_P(loot_update_masterlist_test, shouldReturnAGitErrorIfTheRepositoryUrlGivenCannotBeFound) { + EXPECT_EQ(loot_error_git_error, loot_update_masterlist(db, masterlistPath.string().c_str(), "https://github.com/loot/oblivion-does-not-exist.git", "master", &updated)); + } + + TEST_P(loot_update_masterlist_test, shouldReturnAnInvalidArgsErrorIfTheRepositoryUrlGivenIsEmpty) { + EXPECT_EQ(loot_error_invalid_args, loot_update_masterlist(db, masterlistPath.string().c_str(), "", "master", &updated)); + } + + TEST_P(loot_update_masterlist_test, shouldReturnAGitErrorIfTheRepositoryBranchGivenCannotBeFound) { + EXPECT_EQ(loot_error_git_error, loot_update_masterlist(db, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "missing-branch", &updated)); + } + + TEST_P(loot_update_masterlist_test, shouldReturnAnInvalidArgsErrorIfTheRepositoryBranchGivenIsEmpty) { + EXPECT_EQ(loot_error_invalid_args, loot_update_masterlist(db, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "", &updated)); + } + + TEST_P(loot_update_masterlist_test, shouldSucceedIfPassedValidParametersAndOutputTrueIfTheMasterlistWasUpdated) { + EXPECT_EQ(loot_ok, loot_update_masterlist(db, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "master", &updated)); + EXPECT_TRUE(updated); + EXPECT_TRUE(boost::filesystem::exists(masterlistPath)); + } + + TEST_P(loot_update_masterlist_test, shouldSucceedIfCalledRepeatedlyButOnlyOutputTrueForTheFirstCall) { + EXPECT_EQ(loot_ok, loot_update_masterlist(db, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "master", &updated)); + EXPECT_TRUE(updated); + + EXPECT_EQ(loot_ok, loot_update_masterlist(db, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "master", &updated)); + EXPECT_FALSE(updated); + EXPECT_TRUE(boost::filesystem::exists(masterlistPath)); + } + } +} + +#endif diff --git a/src/tests/api/loot_write_minimal_list_test.h b/src/tests/api/loot_write_minimal_list_test.h new file mode 100644 index 00000000..9c7061d3 --- /dev/null +++ b/src/tests/api/loot_write_minimal_list_test.h @@ -0,0 +1,132 @@ +/* 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_TEST_LOOT_WRITE_MINIMAL_LIST +#define LOOT_TEST_LOOT_WRITE_MINIMAL_LIST + +#include "../include/loot/api.h" +#include "api_game_operations_test.h" + +namespace loot { + namespace test { + class loot_write_minimal_list_test : public ApiGameOperationsTest { + protected: + loot_write_minimal_list_test() : + outputPath(localPath / "minimal.yml") {} + + void SetUp() { + ApiGameOperationsTest::SetUp(); + + ASSERT_FALSE(boost::filesystem::exists(outputPath)); + } + + void TearDown() { + ApiGameOperationsTest::TearDown(); + + ASSERT_NO_THROW(boost::filesystem::remove(outputPath)); + } + + std::string getExpectedContent() const { + using std::endl; + + std::stringstream expectedContent; + expectedContent + << "plugins:" << endl + << " - name: '" << blankEsm << "'" << endl + << " tag:" << endl + << " - Actors.ACBS" << endl + << " - Actors.AIData" << endl + << " - -C.Water" << endl + << " - name: '" << blankDifferentEsm << "'" << endl + << " dirty:" << endl + << " - crc: 0x7d22f9df" << endl + << " util: 'TES4Edit'" << endl + << " udr: 4"; + + return expectedContent.str(); + } + + const boost::filesystem::path outputPath; + }; + + // Pass an empty first argument, as it's a prefix for the test instantation, + // but we only have the one so no prefix is necessary. + INSTANTIATE_TEST_CASE_P(, + loot_write_minimal_list_test, + ::testing::Values( + loot_game_tes4, + loot_game_tes5, + loot_game_fo3, + loot_game_fonv, + loot_game_fo4)); + + TEST_P(loot_write_minimal_list_test, shouldReturnAnInvalidArgsErrorIfAPointerArgumentIsNull) { + EXPECT_EQ(loot_error_invalid_args, loot_write_minimal_list(NULL, outputPath.string().c_str(), false)); + EXPECT_EQ(loot_error_invalid_args, loot_write_minimal_list(db, NULL, false)); + } + + TEST_P(loot_write_minimal_list_test, shouldReturnAFileWriteErrorIfThePathGivenIsInvalid) { + EXPECT_EQ(loot_error_file_write_fail, loot_write_minimal_list(db, "/:?*", false)); + } + + TEST_P(loot_write_minimal_list_test, shouldReturnOkAndWriteToFileIfArgumentsGivenAreValid) { + EXPECT_EQ(loot_ok, loot_write_minimal_list(db, outputPath.string().c_str(), false)); + EXPECT_TRUE(boost::filesystem::exists(outputPath)); + } + + TEST_P(loot_write_minimal_list_test, shouldReturnAFileWriteErrorIfTheFileAlreadyExistsAndTheOverwriteArgumentIsFalse) { + ASSERT_EQ(loot_ok, loot_write_minimal_list(db, outputPath.string().c_str(), false)); + ASSERT_TRUE(boost::filesystem::exists(outputPath)); + + EXPECT_EQ(loot_error_file_write_fail, loot_write_minimal_list(db, outputPath.string().c_str(), false)); + } + + TEST_P(loot_write_minimal_list_test, shouldReturnOkAndWriteToFileIfTheArgumentsAreValidAndTheOverwriteArgumentIsTrue) { + EXPECT_EQ(loot_ok, loot_write_minimal_list(db, outputPath.string().c_str(), true)); + EXPECT_TRUE(boost::filesystem::exists(outputPath)); + } + + TEST_P(loot_write_minimal_list_test, shouldReturnOkIfTheFileAlreadyExistsAndTheOverwriteArgumentIsTrue) { + ASSERT_EQ(loot_ok, loot_write_minimal_list(db, outputPath.string().c_str(), false)); + ASSERT_TRUE(boost::filesystem::exists(outputPath)); + + EXPECT_EQ(loot_ok, loot_write_minimal_list(db, outputPath.string().c_str(), true)); + } + + TEST_P(loot_write_minimal_list_test, shouldWriteOnlyBashTagsAndDirtyInfo) { + ASSERT_NO_THROW(generateMasterlist()); + ASSERT_EQ(loot_ok, loot_load_lists(db, masterlistPath.string().c_str(), NULL)); + + EXPECT_EQ(loot_ok, loot_write_minimal_list(db, outputPath.string().c_str(), true)); + + boost::filesystem::ifstream in(outputPath); + std::stringstream content; + content << in.rdbuf(); + + EXPECT_EQ(getExpectedContent(), content.str()); + } + } +} + +#endif diff --git a/src/tests/api/test_api.h b/src/tests/api/test_api.h index 2c464f76..94f6a4b0 100644 --- a/src/tests/api/test_api.h +++ b/src/tests/api/test_api.h @@ -26,13 +26,10 @@ along with LOOT. If not, see #define LOOT_TEST_API #include "../include/loot/api.h" -#include "tests/fixtures.h" - -#include namespace loot { namespace test { - TEST(GetVersion, HandlesNullInput) { + TEST(loot_get_version, shouldReturnAnInvalidArgsErrorIfPassedNullPointers) { unsigned int vMajor, vMinor, vPatch; EXPECT_EQ(loot_error_invalid_args, loot_get_version(&vMajor, NULL, NULL)); EXPECT_EQ(loot_error_invalid_args, loot_get_version(NULL, &vMinor, NULL)); @@ -40,37 +37,37 @@ namespace loot { EXPECT_EQ(loot_error_invalid_args, loot_get_version(NULL, NULL, NULL)); } - TEST(GetVersion, HandlesValidInput) { + TEST(loot_get_version, shouldReturnOkIfPassedNonNullPointers) { unsigned int vMajor, vMinor, vPatch; EXPECT_EQ(loot_ok, loot_get_version(&vMajor, &vMinor, &vPatch)); } - TEST(GetBuildID, HandlesNullInput) { + TEST(loot_get_build_id, shouldReturnAnInvalidArgsErrorIfPassedANullPointer) { EXPECT_EQ(loot_error_invalid_args, loot_get_build_id(NULL)); } - TEST(GetBuildID, HandlesValidInput) { + TEST(loot_get_build_id, shouldReturnOkAndOutputANonNullNonPlaceholderRevisionString) { const char * revision; EXPECT_EQ(loot_ok, loot_get_build_id(&revision)); EXPECT_STRNE(NULL, revision); EXPECT_STRNE("@GIT_COMMIT_STRING@", revision); // The CMake placeholder. } - TEST(IsCompatible, shouldReturnTrueWithEqualMajorAndMinorVersionsAndUnequalPatchVersion) { + TEST(loot_is_compatible, shouldReturnTrueWithEqualMajorAndMinorVersionsAndUnequalPatchVersion) { unsigned int vMajor, vMinor, vPatch; EXPECT_EQ(loot_ok, loot_get_version(&vMajor, &vMinor, &vPatch)); EXPECT_TRUE(loot_is_compatible(vMajor, vMinor, vPatch + 1)); } - TEST(IsCompatible, shouldReturnFalseWithEqualMajorVersionAndUnequalMinorAndPatchVersions) { + TEST(loot_is_compatible, shouldReturnFalseWithEqualMajorVersionAndUnequalMinorAndPatchVersions) { unsigned int vMajor, vMinor, vPatch; EXPECT_EQ(loot_ok, loot_get_version(&vMajor, &vMinor, &vPatch)); EXPECT_FALSE(loot_is_compatible(vMajor, vMinor + 1, vPatch + 1)); } - TEST(GetErrorMessage, HandlesInputCorrectly) { + TEST(loot_get_error_message, shouldReturnAnInvalidArgsErrorIfPassedANullPointer) { EXPECT_EQ(loot_error_invalid_args, loot_get_error_message(NULL)); const char * error; @@ -78,556 +75,22 @@ namespace loot { ASSERT_STREQ("Null message pointer passed.", error); } - TEST_F(OblivionTest, CreateDbHandlesValidInputs) { - EXPECT_EQ(loot_ok, loot_create_db(&db, loot_game_tes4, dataPath.parent_path().string().c_str(), localPath.string().c_str())); - ASSERT_NO_THROW(loot_destroy_db(db)); - db = nullptr; - - // Also test absolute paths. - boost::filesystem::path game = boost::filesystem::current_path() / dataPath.parent_path(); - boost::filesystem::path local = boost::filesystem::current_path() / localPath; - EXPECT_EQ(loot_ok, loot_create_db(&db, loot_game_tes4, game.string().c_str(), local.string().c_str())); + TEST(loot_get_error_message, shouldReturnOkIfPassedANonNullPointer) { + const char * error; + EXPECT_EQ(loot_ok, loot_get_error_message(&error)); } - TEST_F(OblivionTest, CreateDbHandlesInvalidHandleInput) { - EXPECT_EQ(loot_error_invalid_args, loot_create_db(NULL, loot_game_tes4, dataPath.parent_path().string().c_str(), localPath.string().c_str())); + TEST(loot_get_error_message, shouldOutputAnErrorMessageDetailingTheLastErrorIfAnErrorHasOccurred) { + EXPECT_EQ(loot_error_invalid_args, loot_get_error_message(NULL)); + + const char * error; + EXPECT_EQ(loot_ok, loot_get_error_message(&error)); + ASSERT_STREQ("Null message pointer passed.", error); } - TEST_F(OblivionTest, CreateDbHandlesInvalidGameType) { - EXPECT_EQ(loot_error_invalid_args, loot_create_db(&db, UINT_MAX, dataPath.parent_path().string().c_str(), localPath.string().c_str())); - } - - TEST_F(OblivionTest, CreateDbHandlesInvalidGamePathInput) { - EXPECT_EQ(loot_error_invalid_args, loot_create_db(&db, loot_game_tes4, missingPath.string().c_str(), localPath.string().c_str())); - } - - TEST_F(OblivionTest, CreateDbHandlesInvalidLocalPathInput) { - EXPECT_EQ(loot_error_invalid_args, loot_create_db(&db, loot_game_tes4, dataPath.parent_path().string().c_str(), missingPath.string().c_str())); - } - -#ifdef _WIN32 - TEST_F(OblivionTest, CreateDbHandlesNullLocalPath) { - EXPECT_EQ(loot_ok, loot_create_db(&db, loot_game_tes4, dataPath.parent_path().string().c_str(), NULL)); - } -#endif - - TEST_F(SkyrimTest, CreateDbHandlesValidInputs) { - EXPECT_EQ(loot_ok, loot_create_db(&db, loot_game_tes5, dataPath.parent_path().string().c_str(), localPath.string().c_str())); - ASSERT_NO_THROW(loot_destroy_db(db)); - db = nullptr; - - // Also test absolute paths. - boost::filesystem::path game = boost::filesystem::current_path() / dataPath.parent_path(); - boost::filesystem::path local = boost::filesystem::current_path() / localPath; - EXPECT_EQ(loot_ok, loot_create_db(&db, loot_game_tes5, game.string().c_str(), local.string().c_str())); - } - - TEST_F(SkyrimTest, CreateDbHandlesInvalidHandleInput) { - EXPECT_EQ(loot_error_invalid_args, loot_create_db(NULL, loot_game_tes5, dataPath.parent_path().string().c_str(), localPath.string().c_str())); - } - - TEST_F(SkyrimTest, CreateDbHandlesInvalidGameType) { - EXPECT_EQ(loot_error_invalid_args, loot_create_db(&db, UINT_MAX, dataPath.parent_path().string().c_str(), localPath.string().c_str())); - } - - TEST_F(SkyrimTest, CreateDbHandlesInvalidGamePathInput) { - EXPECT_EQ(loot_error_invalid_args, loot_create_db(&db, loot_game_tes5, missingPath.string().c_str(), localPath.string().c_str())); - } - - TEST_F(SkyrimTest, CreateDbHandlesInvalidLocalPathInput) { - EXPECT_EQ(loot_error_invalid_args, loot_create_db(&db, loot_game_tes5, dataPath.parent_path().string().c_str(), missingPath.string().c_str())); - } - -#ifdef _WIN32 - TEST_F(SkyrimTest, CreateDbHandlesNullLocalPath) { - EXPECT_EQ(loot_ok, loot_create_db(&db, loot_game_tes5, dataPath.parent_path().string().c_str(), NULL)); - } -#endif - - TEST(GameHandleDestroyTest, HandledNullInput) { + TEST(loot_destroy_db, shouldNotThrowIfPassedANullPointer) { ASSERT_NO_THROW(loot_destroy_db(NULL)); } - - TEST_F(OblivionAPIOperationsTest, UpdateMasterlist) { - bool updated; - EXPECT_EQ(loot_error_invalid_args, loot_update_masterlist(NULL, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "master", &updated)); - EXPECT_EQ(loot_error_invalid_args, loot_update_masterlist(db, NULL, "https://github.com/loot/testing-metadata.git", "master", &updated)); - EXPECT_EQ(loot_error_invalid_args, loot_update_masterlist(db, masterlistPath.string().c_str(), NULL, "master", &updated)); - EXPECT_EQ(loot_error_invalid_args, loot_update_masterlist(db, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", NULL, &updated)); - EXPECT_EQ(loot_error_invalid_args, loot_update_masterlist(db, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "master", NULL)); - - EXPECT_EQ(loot_error_invalid_args, loot_update_masterlist(db, ";//\?", "https://github.com/loot/testing-metadata.git", "master", &updated)); - EXPECT_EQ(loot_error_invalid_args, loot_update_masterlist(db, "", "https://github.com/loot/testing-metadata.git", "master", &updated)); - EXPECT_EQ(loot_error_git_error, loot_update_masterlist(db, masterlistPath.string().c_str(), "https://github.com/loot/oblivion-does-not-exist.git", "master", &updated)); - EXPECT_EQ(loot_error_invalid_args, loot_update_masterlist(db, masterlistPath.string().c_str(), "", "master", &updated)); - EXPECT_EQ(loot_error_git_error, loot_update_masterlist(db, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "missing-branch", &updated)); - EXPECT_EQ(loot_error_invalid_args, loot_update_masterlist(db, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "", &updated)); - - // Test actual masterlist update. - EXPECT_EQ(loot_ok, loot_update_masterlist(db, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "master", &updated)); - EXPECT_TRUE(updated); - - // Test with an up-to-date masterlist. - EXPECT_EQ(loot_ok, loot_update_masterlist(db, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "master", &updated)); - EXPECT_FALSE(updated); - } - - TEST_F(OblivionAPIOperationsTest, GetMasterlistRevision) { - const char * revisionID; - const char * revisionDate; - bool isModified; - EXPECT_EQ(loot_error_invalid_args, loot_get_masterlist_revision(NULL, masterlistPath.string().c_str(), false, &revisionID, &revisionDate, &isModified)); - EXPECT_EQ(loot_error_invalid_args, loot_get_masterlist_revision(db, NULL, false, &revisionID, &revisionDate, &isModified)); - EXPECT_EQ(loot_error_invalid_args, loot_get_masterlist_revision(db, masterlistPath.string().c_str(), false, NULL, &revisionDate, &isModified)); - EXPECT_EQ(loot_error_invalid_args, loot_get_masterlist_revision(db, masterlistPath.string().c_str(), false, &revisionID, NULL, &isModified)); - EXPECT_EQ(loot_error_invalid_args, loot_get_masterlist_revision(db, masterlistPath.string().c_str(), false, &revisionID, &revisionDate, NULL)); - - // Test with no masterlist. - EXPECT_EQ(loot_ok, loot_get_masterlist_revision(db, masterlistPath.string().c_str(), false, &revisionID, &revisionDate, &isModified)); - EXPECT_EQ(NULL, revisionID); - EXPECT_EQ(NULL, revisionDate); - EXPECT_FALSE(isModified); - - // Test with a generated (non-revision-control) masterlist. - ASSERT_NO_THROW(GenerateMasterlist()); - EXPECT_EQ(loot_ok, loot_get_masterlist_revision(db, masterlistPath.string().c_str(), false, &revisionID, &revisionDate, &isModified)); - EXPECT_EQ(NULL, revisionID); - EXPECT_EQ(NULL, revisionDate); - EXPECT_FALSE(isModified); - - // Update the masterlist and test. - bool updated; - ASSERT_EQ(loot_ok, loot_update_masterlist(db, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "master", &updated)); - ASSERT_TRUE(updated); - EXPECT_EQ(loot_ok, loot_get_masterlist_revision(db, masterlistPath.string().c_str(), false, &revisionID, &revisionDate, &isModified)); - EXPECT_STRNE(NULL, revisionID); - EXPECT_EQ(40, strlen(revisionID)); - EXPECT_STRNE(NULL, revisionDate); - EXPECT_EQ(10, strlen(revisionDate)); - EXPECT_FALSE(isModified); - - // Test with a short revision string. - EXPECT_EQ(loot_ok, loot_get_masterlist_revision(db, masterlistPath.string().c_str(), true, &revisionID, &revisionDate, &isModified)); - EXPECT_STRNE(NULL, revisionID); - EXPECT_GE(size_t(40), strlen(revisionID)); - EXPECT_LE(size_t(7), strlen(revisionID)); - EXPECT_STRNE(NULL, revisionDate); - EXPECT_EQ(10, strlen(revisionDate)); - EXPECT_FALSE(isModified); - - // Overwrite the masterlist with a generated one. - ASSERT_NO_THROW(GenerateMasterlist()); - EXPECT_EQ(loot_ok, loot_get_masterlist_revision(db, masterlistPath.string().c_str(), false, &revisionID, &revisionDate, &isModified)); - EXPECT_STRNE(NULL, revisionID); - EXPECT_EQ(40, strlen(revisionID)); - EXPECT_STRNE(NULL, revisionDate); - EXPECT_EQ(10, strlen(revisionDate)); - EXPECT_TRUE(isModified); - } - - TEST_F(OblivionAPIOperationsTest, LoadLists) { - EXPECT_EQ(loot_error_invalid_args, loot_load_lists(NULL, masterlistPath.string().c_str(), NULL)); - EXPECT_EQ(loot_error_invalid_args, loot_load_lists(db, NULL, NULL)); - - EXPECT_EQ(loot_error_path_not_found, loot_load_lists(db, masterlistPath.string().c_str(), NULL)); - bool updated; - ASSERT_EQ(loot_ok, loot_update_masterlist(db, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "master", &updated)); - EXPECT_EQ(loot_error_path_not_found, loot_load_lists(db, masterlistPath.string().c_str(), userlistPath.string().c_str())); - - ASSERT_NO_THROW(boost::filesystem::copy(masterlistPath, userlistPath)); - EXPECT_EQ(loot_ok, loot_load_lists(db, masterlistPath.string().c_str(), userlistPath.string().c_str())); - } - - TEST_F(SkyrimAPIOperationsTest, LoadLists) { - EXPECT_EQ(loot_error_invalid_args, loot_load_lists(NULL, masterlistPath.string().c_str(), NULL)); - EXPECT_EQ(loot_error_invalid_args, loot_load_lists(db, NULL, NULL)); - - EXPECT_EQ(loot_error_path_not_found, loot_load_lists(db, masterlistPath.string().c_str(), NULL)); - bool updated; - ASSERT_EQ(loot_ok, loot_update_masterlist(db, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "master", &updated)); - EXPECT_EQ(loot_error_path_not_found, loot_load_lists(db, masterlistPath.string().c_str(), userlistPath.string().c_str())); - - ASSERT_NO_THROW(boost::filesystem::copy(masterlistPath, userlistPath)); - EXPECT_EQ(loot_ok, loot_load_lists(db, masterlistPath.string().c_str(), userlistPath.string().c_str())); - } - - TEST_F(OblivionAPIOperationsTest, EvalLists) { - // No lists loaded. - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_any)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_english)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_spanish)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_russian)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_french)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_chinese)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_polish)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_brazilian_portuguese)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_finnish)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_german)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_danish)); - - // Invalid args. - EXPECT_EQ(loot_error_invalid_args, loot_eval_lists(NULL, loot_lang_any)); - EXPECT_EQ(loot_error_invalid_args, loot_eval_lists(db, UINT_MAX)); - - // Now test different languages with a list loaded. - bool updated; - ASSERT_EQ(loot_ok, loot_update_masterlist(db, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "master", &updated)); - ASSERT_EQ(loot_ok, loot_load_lists(db, masterlistPath.string().c_str(), NULL)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_any)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_english)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_spanish)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_russian)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_french)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_chinese)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_polish)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_brazilian_portuguese)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_finnish)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_german)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_danish)); - } - - TEST_F(SkyrimAPIOperationsTest, EvalLists) { - // No lists loaded. - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_any)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_english)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_spanish)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_russian)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_french)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_chinese)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_polish)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_brazilian_portuguese)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_finnish)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_german)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_danish)); - - // Invalid args. - EXPECT_EQ(loot_error_invalid_args, loot_eval_lists(NULL, loot_lang_any)); - EXPECT_EQ(loot_error_invalid_args, loot_eval_lists(db, UINT_MAX)); - - // Now test different languages with a list loaded. - bool updated; - ASSERT_EQ(loot_ok, loot_update_masterlist(db, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "master", &updated)); - ASSERT_EQ(loot_ok, loot_load_lists(db, masterlistPath.string().c_str(), NULL)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_any)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_english)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_spanish)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_russian)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_french)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_chinese)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_polish)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_brazilian_portuguese)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_finnish)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_german)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_danish)); - } - - TEST_F(OblivionAPIOperationsTest, SortPlugins) { - const char * const * sortedPlugins; - size_t numPlugins; - EXPECT_EQ(loot_error_invalid_args, loot_sort_plugins(NULL, &sortedPlugins, &numPlugins)); - EXPECT_EQ(loot_error_invalid_args, loot_sort_plugins(db, NULL, &numPlugins)); - EXPECT_EQ(loot_error_invalid_args, loot_sort_plugins(db, &sortedPlugins, NULL)); - - EXPECT_EQ(loot_ok, loot_sort_plugins(db, &sortedPlugins, &numPlugins)); - - // Expected order was obtained from running the API function once. - std::list expectedOrder = { - "Oblivion.esm", - "Blank.esm", - "Blank - Different.esm", - "Blank - Master Dependent.esm", - "Blank - Different Master Dependent.esm", - "Blank.esp", - "Blank - Different.esp", - "Blank - Master Dependent.esp", - "Blank - Different Master Dependent.esp", - "Blank - Plugin Dependent.esp", - "Blank - Different Plugin Dependent.esp", - }; - std::list actualOrder; - for (size_t i = 0; i < numPlugins; ++i) { - actualOrder.push_back(sortedPlugins[i]); - } - EXPECT_EQ(11, numPlugins); - EXPECT_EQ(expectedOrder, actualOrder); - } - - TEST_F(SkyrimAPIOperationsTest, SortPlugins) { - const char * const * sortedPlugins; - size_t numPlugins; - EXPECT_EQ(loot_error_invalid_args, loot_sort_plugins(NULL, &sortedPlugins, &numPlugins)); - EXPECT_EQ(loot_error_invalid_args, loot_sort_plugins(db, NULL, &numPlugins)); - EXPECT_EQ(loot_error_invalid_args, loot_sort_plugins(db, &sortedPlugins, NULL)); - - EXPECT_EQ(loot_ok, loot_sort_plugins(db, &sortedPlugins, &numPlugins)); - - // Expected order was obtained from running the API function once. - std::list expectedOrder = { - "Skyrim.esm", - "Blank.esm", - "Blank - Different.esm", - "Blank - Master Dependent.esm", - "Blank - Different Master Dependent.esm", - "Blank.esp", - "Blank - Different.esp", - "Blank - Master Dependent.esp", - "Blank - Different Master Dependent.esp", - "Blank - Plugin Dependent.esp", - "Blank - Different Plugin Dependent.esp", - }; - std::list actualOrder; - for (size_t i = 0; i < numPlugins; ++i) { - actualOrder.push_back(sortedPlugins[i]); - } - EXPECT_EQ(11, numPlugins); - EXPECT_EQ(expectedOrder, actualOrder); - } - - TEST_F(OblivionAPIOperationsTest, ApplyLoadOrder) { - const char * loadOrder[11] = { - "Oblivion.esm", - "Blank.esm", - "Blank - Different.esm", - "Blank - Different Master Dependent.esm", - "Blank - Master Dependent.esm", - "Blank.esp", - "Blank - Different.esp", - "Blank - Different Master Dependent.esp", - "Blank - Different Plugin Dependent.esp", - "Blank - Master Dependent.esp", - "Blank - Plugin Dependent.esp", - }; - size_t numPlugins = 11; - EXPECT_EQ(loot_error_invalid_args, loot_apply_load_order(NULL, loadOrder, numPlugins)); - EXPECT_EQ(loot_error_invalid_args, loot_apply_load_order(db, NULL, numPlugins)); - - EXPECT_EQ(loot_ok, loot_apply_load_order(db, loadOrder, numPlugins)); - } - - TEST_F(SkyrimAPIOperationsTest, ApplyLoadOrder) { - const char * loadOrder[11] = { - "Skyrim.esm", - "Blank.esm", - "Blank - Different.esm", - "Blank - Different Master Dependent.esm", - "Blank - Master Dependent.esm", - "Blank.esp", - "Blank - Different.esp", - "Blank - Different Master Dependent.esp", - "Blank - Different Plugin Dependent.esp", - "Blank - Master Dependent.esp", - "Blank - Plugin Dependent.esp", - }; - size_t numPlugins = 11; - EXPECT_EQ(loot_error_invalid_args, loot_apply_load_order(NULL, loadOrder, numPlugins)); - EXPECT_EQ(loot_error_invalid_args, loot_apply_load_order(db, NULL, numPlugins)); - - EXPECT_EQ(loot_ok, loot_apply_load_order(db, loadOrder, numPlugins)); - } - - TEST_F(OblivionAPIOperationsTest, GetTagMap) { - const char * const * tagMap; - size_t numTags; - EXPECT_EQ(loot_error_invalid_args, loot_get_tag_map(NULL, &tagMap, &numTags)); - EXPECT_EQ(loot_error_invalid_args, loot_get_tag_map(db, NULL, &numTags)); - EXPECT_EQ(loot_error_invalid_args, loot_get_tag_map(db, &tagMap, NULL)); - - // Get tag map with no masterlist loaded: should have no tags. - EXPECT_EQ(loot_ok, loot_get_tag_map(db, &tagMap, &numTags)); - EXPECT_EQ(0, numTags); - EXPECT_EQ(NULL, tagMap); - - // Get a masterlist, then get tags from it. - ASSERT_NO_THROW(GenerateMasterlist()); - ASSERT_EQ(loot_ok, loot_load_lists(db, masterlistPath.string().c_str(), NULL)); - EXPECT_EQ(loot_ok, loot_get_tag_map(db, &tagMap, &numTags)); - ASSERT_EQ(22, numTags); - EXPECT_STREQ("Actors.ACBS", tagMap[0]); - EXPECT_STREQ("Actors.AIData", tagMap[1]); - EXPECT_STREQ("Actors.AIPackages", tagMap[2]); - EXPECT_STREQ("Actors.CombatStyle", tagMap[3]); - EXPECT_STREQ("Actors.DeathItem", tagMap[4]); - EXPECT_STREQ("Actors.Stats", tagMap[5]); - EXPECT_STREQ("C.Climate", tagMap[6]); - EXPECT_STREQ("C.Light", tagMap[7]); - EXPECT_STREQ("C.Music", tagMap[8]); - EXPECT_STREQ("C.Name", tagMap[9]); - EXPECT_STREQ("C.Owner", tagMap[10]); - EXPECT_STREQ("C.Water", tagMap[11]); - EXPECT_STREQ("Creatures.Blood", tagMap[12]); - EXPECT_STREQ("Delev", tagMap[13]); - EXPECT_STREQ("Factions", tagMap[14]); - EXPECT_STREQ("Invent", tagMap[15]); - EXPECT_STREQ("NPC.Class", tagMap[16]); - EXPECT_STREQ("Names", tagMap[17]); - EXPECT_STREQ("Relations", tagMap[18]); - EXPECT_STREQ("Relev", tagMap[19]); - EXPECT_STREQ("Scripts", tagMap[20]); - EXPECT_STREQ("Stats", tagMap[21]); - } - - TEST_F(OblivionAPIOperationsTest, GetPluginTags) { - const unsigned int * added; - const unsigned int * removed; - size_t numAdded, numRemoved; - bool modified; - EXPECT_EQ(loot_error_invalid_args, loot_get_plugin_tags(NULL, "Unofficial Oblivion Patch.esp", &added, &numAdded, &removed, &numRemoved, &modified)); - EXPECT_EQ(loot_error_invalid_args, loot_get_plugin_tags(db, NULL, &added, &numAdded, &removed, &numRemoved, &modified)); - EXPECT_EQ(loot_error_invalid_args, loot_get_plugin_tags(db, "Unofficial Oblivion Patch.esp", NULL, &numAdded, &removed, &numRemoved, &modified)); - EXPECT_EQ(loot_error_invalid_args, loot_get_plugin_tags(db, "Unofficial Oblivion Patch.esp", &added, NULL, &removed, &numRemoved, &modified)); - EXPECT_EQ(loot_error_invalid_args, loot_get_plugin_tags(db, "Unofficial Oblivion Patch.esp", &added, &numAdded, NULL, &numRemoved, &modified)); - EXPECT_EQ(loot_error_invalid_args, loot_get_plugin_tags(db, "Unofficial Oblivion Patch.esp", &added, &numAdded, &removed, NULL, &modified)); - EXPECT_EQ(loot_error_invalid_args, loot_get_plugin_tags(db, "Unofficial Oblivion Patch.esp", &added, &numAdded, &removed, &numRemoved, NULL)); - - // Get tags before getting a tag map. - EXPECT_EQ(loot_error_no_tag_map, loot_get_plugin_tags(db, "Unofficial Oblivion Patch.esp", &added, &numAdded, &removed, &numRemoved, &modified)); - - // Load tag map. - const char * const * tagMap; - size_t numTags; - ASSERT_NO_THROW(GenerateMasterlist()); - ASSERT_EQ(loot_ok, loot_load_lists(db, masterlistPath.string().c_str(), NULL)); - ASSERT_EQ(loot_ok, loot_get_tag_map(db, &tagMap, &numTags)); - - // Get tags for a plugin without any. - EXPECT_EQ(loot_ok, loot_get_plugin_tags(db, "Blank.esp", &added, &numAdded, &removed, &numRemoved, &modified)); - EXPECT_EQ(0, numAdded); - EXPECT_EQ(NULL, added); - EXPECT_EQ(0, numRemoved); - EXPECT_EQ(NULL, removed); - EXPECT_FALSE(modified); - - // Get tags for a plugin with some. - EXPECT_EQ(loot_ok, loot_get_plugin_tags(db, "Unofficial Oblivion Patch.esp", &added, &numAdded, &removed, &numRemoved, &modified)); - ASSERT_EQ(21, numAdded); - for (size_t i = 0; i < 11; ++i) { - EXPECT_EQ(i, added[i]); - } - for (size_t i = 11; i < 21; ++i) { - EXPECT_EQ(i + 1, added[i]); - } - - ASSERT_EQ(1, numRemoved); - EXPECT_EQ(11, removed[0]); - EXPECT_FALSE(modified); - - // Now load the masterlist as the userlist too, and check the modified flag. - ASSERT_NO_THROW(boost::filesystem::copy_file(masterlistPath, userlistPath)); - ASSERT_EQ(loot_ok, loot_load_lists(db, masterlistPath.string().c_str(), userlistPath.string().c_str())); - ASSERT_EQ(loot_ok, loot_get_tag_map(db, &tagMap, &numTags)); - - EXPECT_EQ(loot_ok, loot_get_plugin_tags(db, "Unofficial Oblivion Patch.esp", &added, &numAdded, &removed, &numRemoved, &modified)); - ASSERT_EQ(21, numAdded); - for (size_t i = 0; i < 11; ++i) { - EXPECT_EQ(i, added[i]); - } - for (size_t i = 11; i < 21; ++i) { - EXPECT_EQ(i + 1, added[i]); - } - EXPECT_EQ(0, added[0]); - ASSERT_EQ(1, numRemoved); - EXPECT_EQ(11, removed[0]); - EXPECT_TRUE(modified); - } - - TEST_F(OblivionAPIOperationsTest, GetPluginMessages) { - const loot_message * messages; - size_t numMessages; - EXPECT_EQ(loot_error_invalid_args, loot_get_plugin_messages(NULL, "EnhancedWeatherSIOnly.esm", &messages, &numMessages)); - EXPECT_EQ(loot_error_invalid_args, loot_get_plugin_messages(db, NULL, &messages, &numMessages)); - EXPECT_EQ(loot_error_invalid_args, loot_get_plugin_messages(db, "EnhancedWeatherSIOnly.esm", NULL, &numMessages)); - EXPECT_EQ(loot_error_invalid_args, loot_get_plugin_messages(db, "EnhancedWeatherSIOnly.esm", &messages, NULL)); - - // Fetch and load the metadata. - ASSERT_NO_THROW(GenerateMasterlist()); - ASSERT_EQ(loot_ok, loot_load_lists(db, masterlistPath.string().c_str(), NULL)); - - // Test for plugin with no messages. - EXPECT_EQ(loot_ok, loot_get_plugin_messages(db, "Silgrad_Tower.esm", &messages, &numMessages)); - EXPECT_EQ(0, numMessages); - EXPECT_EQ(NULL, messages); - - // Test for plugin with one note. - EXPECT_EQ(loot_ok, loot_get_plugin_messages(db, "No Lights Flicker.esm", &messages, &numMessages)); - EXPECT_EQ(1, numMessages); - EXPECT_EQ(loot_message_say, messages[0].type); - EXPECT_STREQ("Use Wrye Bash Bashed Patch tweak instead.", messages[0].message); - - // Test for plugin with one warning. - EXPECT_EQ(loot_ok, loot_get_plugin_messages(db, "bookplacing.esm", &messages, &numMessages)); - EXPECT_EQ(1, numMessages); - EXPECT_EQ(loot_message_warn, messages[0].type); - EXPECT_STREQ("Check you are using v2+. If not, Update. v1 has a severe bug with the Mystic Emporium disappearing.", messages[0].message); - - // Test for plugin with one error. - EXPECT_EQ(loot_ok, loot_get_plugin_messages(db, "EnhancedWeatherSIOnly.esm", &messages, &numMessages)); - EXPECT_EQ(1, numMessages); - EXPECT_EQ(loot_message_error, messages[0].type); - EXPECT_STREQ("Obsolete. Remove this and install Enhanced Weather.", messages[0].message); - - // Test for plugin with more than one message. - EXPECT_EQ(loot_ok, loot_get_plugin_messages(db, "nVidia Black Screen Fix.esp", &messages, &numMessages)); - EXPECT_EQ(2, numMessages); - EXPECT_EQ(loot_message_say, messages[0].type); - EXPECT_STREQ("Use Wrye Bash Bashed Patch tweak instead.", messages[0].message); - EXPECT_EQ(loot_message_say, messages[1].type); - EXPECT_STREQ("Alternatively, remove this and use UOP v3.0.1+ instead.", messages[1].message); - } - - TEST_F(OblivionAPIOperationsTest, GetDirtyInfo) { - unsigned int needsCleaning; - EXPECT_EQ(loot_error_invalid_args, loot_get_dirty_info(NULL, "Oblivion.esm", &needsCleaning)); - EXPECT_EQ(loot_error_invalid_args, loot_get_dirty_info(db, NULL, &needsCleaning)); - EXPECT_EQ(loot_error_invalid_args, loot_get_dirty_info(db, "Oblivion.esm", NULL)); - - // Fetch and load the metadata. - ASSERT_NO_THROW(GenerateMasterlist()); - ASSERT_EQ(loot_ok, loot_load_lists(db, masterlistPath.string().c_str(), NULL)); - - // A plugin with no metadata. - EXPECT_EQ(loot_ok, loot_get_dirty_info(db, "Oblivion.esm", &needsCleaning)); - EXPECT_EQ(loot_needs_cleaning_unknown, needsCleaning); - - // A plugin with dirty metadata. - EXPECT_EQ(loot_ok, loot_get_dirty_info(db, "Hammerfell.esm", &needsCleaning)); - EXPECT_EQ(loot_needs_cleaning_yes, needsCleaning); - - // A plugin with a standard "Do not clean" message. - EXPECT_EQ(loot_ok, loot_get_dirty_info(db, "Unofficial Oblivion Patch.esp", &needsCleaning)); - EXPECT_EQ(loot_needs_cleaning_no, needsCleaning); - } - - TEST_F(OblivionAPIOperationsTest, WriteMinimalList) { - std::string outputFile = (localPath / "minimal.yml").string(); - EXPECT_EQ(loot_error_invalid_args, loot_write_minimal_list(NULL, outputFile.c_str(), false)); - EXPECT_EQ(loot_error_invalid_args, loot_write_minimal_list(db, NULL, false)); - EXPECT_EQ(loot_error_file_write_fail, loot_write_minimal_list(db, "/:?*", false)); - - ASSERT_FALSE(boost::filesystem::exists(outputFile)); - EXPECT_EQ(loot_ok, loot_write_minimal_list(db, outputFile.c_str(), false)); - EXPECT_TRUE(boost::filesystem::exists(outputFile)); - EXPECT_EQ(loot_error_file_write_fail, loot_write_minimal_list(db, outputFile.c_str(), false)); - - EXPECT_EQ(loot_ok, loot_write_minimal_list(db, outputFile.c_str(), true)); - ASSERT_NO_THROW(boost::filesystem::remove(outputFile)); - EXPECT_EQ(loot_ok, loot_write_minimal_list(db, outputFile.c_str(), true)); - EXPECT_TRUE(boost::filesystem::exists(outputFile)); - ASSERT_NO_THROW(boost::filesystem::remove(outputFile)); - - // Check that Bash Tag removals get outputted correctly. - bool updated; - ASSERT_EQ(loot_ok, loot_update_masterlist(db, masterlistPath.string().c_str(), "https://github.com/loot/testing-metadata.git", "master", &updated)); - EXPECT_EQ(loot_ok, loot_load_lists(db, masterlistPath.string().c_str(), NULL)); - EXPECT_EQ(loot_ok, loot_write_minimal_list(db, outputFile.c_str(), false)); - - boost::filesystem::ifstream in(outputFile); - std::string line; - while (std::getline(in, line)) { - EXPECT_FALSE(boost::contains(line, "- \"-\"")); - } - in.close(); - ASSERT_NO_THROW(boost::filesystem::remove(outputFile)); - } } } diff --git a/src/tests/base_game_test.h b/src/tests/base_game_test.h new file mode 100644 index 00000000..105db2c4 --- /dev/null +++ b/src/tests/base_game_test.h @@ -0,0 +1,125 @@ +/* LOOT + +A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and +Fallout: New Vegas. + +Copyright (C) 2013-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_TEST_BASE_GAME_TEST +#define LOOT_TEST_BASE_GAME_TEST + +#include +#include + +namespace loot { + namespace test { + class BaseGameTest : public ::testing::TestWithParam { + protected: + BaseGameTest() : + missingPath("./missing"), + dataPath(getPluginsPath()), + localPath(getLocalPath()), + masterFile(getMasterFile()), + blankEsm("Blank.esm"), + blankDifferentEsm("Blank - Different.esm"), + blankMasterDependentEsm("Blank - Master Dependent.esm"), + blankDifferentMasterDependentEsm("Blank - Different Master Dependent.esm"), + blankEsp("Blank.esp"), + blankDifferentEsp("Blank - Different.esp"), + blankMasterDependentEsp("Blank - Master Dependent.esp"), + blankDifferentMasterDependentEsp("Blank - Different Master Dependent.esp"), + blankPluginDependentEsp("Blank - Plugin Dependent.esp"), + blankDifferentPluginDependentEsp("Blank - Different Plugin Dependent.esp") {} + + inline virtual void SetUp() { + ASSERT_NO_THROW(boost::filesystem::create_directories(localPath)); + ASSERT_TRUE(boost::filesystem::exists(localPath)); + + ASSERT_FALSE(boost::filesystem::exists(missingPath)); + + ASSERT_TRUE(boost::filesystem::exists(dataPath / blankEsm)); + ASSERT_TRUE(boost::filesystem::exists(dataPath / blankDifferentEsm)); + ASSERT_TRUE(boost::filesystem::exists(dataPath / blankMasterDependentEsm)); + ASSERT_TRUE(boost::filesystem::exists(dataPath / blankDifferentMasterDependentEsm)); + ASSERT_TRUE(boost::filesystem::exists(dataPath / blankEsp)); + ASSERT_TRUE(boost::filesystem::exists(dataPath / blankDifferentEsp)); + ASSERT_TRUE(boost::filesystem::exists(dataPath / blankMasterDependentEsp)); + ASSERT_TRUE(boost::filesystem::exists(dataPath / blankDifferentMasterDependentEsp)); + ASSERT_TRUE(boost::filesystem::exists(dataPath / blankPluginDependentEsp)); + ASSERT_TRUE(boost::filesystem::exists(dataPath / blankDifferentPluginDependentEsp)); + + // Make sure the game master file exists. + ASSERT_FALSE(boost::filesystem::exists(dataPath / masterFile)); + ASSERT_NO_THROW(boost::filesystem::copy_file(dataPath / blankEsm, dataPath / masterFile)); + ASSERT_TRUE(boost::filesystem::exists(dataPath / masterFile)); + } + + inline virtual void TearDown() { + ASSERT_NO_THROW(boost::filesystem::remove(dataPath / masterFile)); + } + + const boost::filesystem::path missingPath; + const boost::filesystem::path dataPath; + const boost::filesystem::path localPath; + + const std::string masterFile; + const std::string blankEsm; + const std::string blankDifferentEsm; + const std::string blankMasterDependentEsm; + const std::string blankDifferentMasterDependentEsm; + const std::string blankEsp; + const std::string blankDifferentEsp; + const std::string blankMasterDependentEsp; + const std::string blankDifferentMasterDependentEsp; + const std::string blankPluginDependentEsp; + const std::string blankDifferentPluginDependentEsp; + + private: + inline boost::filesystem::path getLocalPath() const { + if (GetParam() == loot_game_tes4) + return "./local/Oblivion"; + else + return "./local/Skyrim"; + } + + inline boost::filesystem::path getPluginsPath() const { + if (GetParam() == loot_game_tes4) + return "./Oblivion/Data"; + else + return "./Skyrim/Data"; + } + + inline std::string getMasterFile() const { + if (GetParam() == loot_game_tes4) + return "Oblivion.esm"; + else if (GetParam() == loot_game_tes5) + return "Skyrim.esm"; + else if (GetParam() == loot_game_fo3) + return "Fallout3.esm"; + else if (GetParam() == loot_game_fonv) + return "FalloutNV.esm"; + else + return "Fallout4.esm"; + } + }; + } +} + +#endif diff --git a/src/tests/main.cpp b/src/tests/main.cpp index 0eaabece..53358127 100644 --- a/src/tests/main.cpp +++ b/src/tests/main.cpp @@ -27,8 +27,20 @@ #define BOOST_NO_CXX11_SCOPED_ENUMS #endif +#include "api/loot_apply_load_order_test.h" +#include "api/loot_create_db_test.h" +#include "api/loot_db_test.h" +#include "api/loot_eval_lists_test.h" +#include "api/loot_get_dirty_info_test.h" +#include "api/loot_get_masterlist_revision_test.h" +#include "api/loot_get_plugin_messages_test.h" +#include "api/loot_get_plugin_tags_test.h" +#include "api/loot_get_tag_map_test.h" +#include "api/loot_load_lists_test.h" +#include "api/loot_sort_plugins_test.h" +#include "api/loot_update_masterlist_test.h" +#include "api/loot_write_minimal_list_test.h" #include "api/test_api.h" -#include "api/test_loot_db.h" #include "backend/game/test_game.h" #include "backend/game/test_game_cache.h" #include "backend/game/test_game_settings.h" From 23e60b4f52aee475a349e4a51d9b7d2d42a18c72 Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Sun, 13 Mar 2016 22:08:55 +0000 Subject: [PATCH 04/38] Refactor non-parameterised fixture code --- src/tests/backend/test_masterlist.h | 17 +- src/tests/fixtures.h | 231 ++++++++-------------------- 2 files changed, 78 insertions(+), 170 deletions(-) diff --git a/src/tests/backend/test_masterlist.h b/src/tests/backend/test_masterlist.h index b79b906d..5a97d60b 100644 --- a/src/tests/backend/test_masterlist.h +++ b/src/tests/backend/test_masterlist.h @@ -30,7 +30,22 @@ along with LOOT. If not, see namespace loot { namespace test { - class MasterlistTest : public SkyrimTest {}; + class MasterlistTest : public SkyrimTest { + protected: +#ifndef _WIN32 + void SetUp() { + SkyrimTest::SetUp(); + + ASSERT_NO_THROW(boost::filesystem::create_directories(g_path_local / "Skyrim")); + } + + void TearDown() { + SkyrimTest::TearDown(); + + ASSERT_NO_THROW(boost::filesystem::remove_all(g_path_local)); + } +#endif + }; TEST_F(MasterlistTest, Update_Game) { Game game(Game::tes5); diff --git a/src/tests/fixtures.h b/src/tests/fixtures.h index e11038cf..3ce5db0f 100644 --- a/src/tests/fixtures.h +++ b/src/tests/fixtures.h @@ -36,14 +36,14 @@ namespace loot { namespace test { class GenericGameTest : public ::testing::Test { protected: - GenericGameTest(const boost::filesystem::path& gameDataPath, const boost::filesystem::path& gameLocalPath) - : dataPath(gameDataPath), - localPath(gameLocalPath), + GenericGameTest(const std::string& gameName) + : dataPath("./" + gameName + "/Data"), + localPath("./local/" + gameName), missingPath("./missing"), + masterFile(gameName + ".esm"), masterlistPath(localPath / "masterlist.yaml"), userlistPath(localPath / "userlist.yaml"), - resourcePath(dataPath / "resource" / "detail" / "resource.txt"), - db(nullptr) {} + resourcePath(dataPath / "resource" / "detail" / "resource.txt") {} inline virtual void SetUp() { ASSERT_NO_THROW(boost::filesystem::create_directories(localPath)); @@ -89,6 +89,21 @@ namespace loot { out << "This isn't a valid plugin file."; out.close(); ASSERT_TRUE(boost::filesystem::exists(dataPath / "NotAPlugin.esm")); + + // LOOT expects the game master file to be present, so mock it. + ASSERT_FALSE(boost::filesystem::exists(dataPath / masterFile)); + ASSERT_NO_THROW(boost::filesystem::copy_file(dataPath / "Blank.esm", dataPath / masterFile)); + ASSERT_TRUE(boost::filesystem::exists(dataPath / masterFile)); + + setLoadOrder(); + + // Set Oblivion's active plugins to a known list before running the test. + boost::filesystem::ofstream activePlugins(localPath / "plugins.txt"); + activePlugins + << masterFile << std::endl + << "Blank.esm" << std::endl + << "Blank - Different Master Dependent.esp" << std::endl; + activePlugins.close(); } inline virtual void TearDown() { @@ -112,36 +127,32 @@ namespace loot { // Also remove the ".git" folder if it has been created. ASSERT_NO_THROW(boost::filesystem::remove_all(localPath / ".git")); - ASSERT_NO_THROW(loot_destroy_db(db)); + // Delete the mock Oblivion.esm. + ASSERT_TRUE(boost::filesystem::exists(dataPath / masterFile)); + ASSERT_NO_THROW(boost::filesystem::remove(dataPath / masterFile)); + ASSERT_FALSE(boost::filesystem::exists(dataPath / masterFile)); + + // Delete existing plugins.txt. + ASSERT_NO_THROW(boost::filesystem::remove(localPath / "plugins.txt")); + + // Delete loadorder.txt if it exists. + ASSERT_NO_THROW(boost::filesystem::remove(localPath / "loadorder.txt")); } const boost::filesystem::path dataPath; const boost::filesystem::path localPath; const boost::filesystem::path missingPath; + const std::string masterFile; + const boost::filesystem::path masterlistPath; const boost::filesystem::path userlistPath; const boost::filesystem::path resourcePath; - - loot_db * db; - }; - - class OblivionTest : public GenericGameTest { - protected: - OblivionTest() : GenericGameTest("./Oblivion/Data", "./local/Oblivion") {} - - inline virtual void SetUp() { - GenericGameTest::SetUp(); - - // LOOT expects the game master file to be present, so mock it. - ASSERT_FALSE(boost::filesystem::exists(dataPath / "Oblivion.esm")); - ASSERT_NO_THROW(boost::filesystem::copy_file(dataPath / "Blank.esm", dataPath / "Oblivion.esm")); - ASSERT_TRUE(boost::filesystem::exists(dataPath / "Oblivion.esm")); - - // Oblivion's load order is decided through timestamps, so reset them to a known order before each test. - std::list loadOrder = { - "Oblivion.esm", + private: + inline std::list GetExpectedSortedOrder() const { + return std::list({ + masterFile, "Blank.esm", "Blank - Different.esm", "Blank - Master Dependent.esm", // Ghosted @@ -152,167 +163,49 @@ namespace loot { "Blank - Different Master Dependent.esp", "Blank - Plugin Dependent.esp", "Blank - Different Plugin Dependent.esp" - }; - time_t modificationTime = time(NULL); // Current time. - for (const auto &plugin : loadOrder) { - if (boost::filesystem::exists(dataPath / boost::filesystem::path(plugin + ".ghost"))) { - boost::filesystem::last_write_time(dataPath / boost::filesystem::path(plugin + ".ghost"), modificationTime); - } - else { - boost::filesystem::last_write_time(dataPath / plugin, modificationTime); - } - modificationTime += 60; - } - - // Set Oblivion's active plugins to a known list before running the test. - boost::filesystem::ofstream activePlugins(localPath / "plugins.txt"); - activePlugins - << "Oblivion.esm" << std::endl - << "Blank.esm" << std::endl; - activePlugins.close(); + }); } - inline virtual void TearDown() { - GenericGameTest::TearDown(); + inline void setLoadOrder() { + if (isTimestampLoadOrderMethod()) { + time_t modificationTime = time(NULL); // Current time. + for (const auto &plugin : GetExpectedSortedOrder()) { + if (boost::filesystem::exists(dataPath / boost::filesystem::path(plugin + ".ghost"))) { + boost::filesystem::last_write_time(dataPath / boost::filesystem::path(plugin + ".ghost"), modificationTime); + } + else { + boost::filesystem::last_write_time(dataPath / plugin, modificationTime); + } + modificationTime += 60; + } + } + else { + boost::filesystem::ofstream loadOrder(localPath / "loadorder.txt"); + for (const auto &plugin : GetExpectedSortedOrder()) + loadOrder << plugin << std::endl; + loadOrder.close(); + } + } - // Delete the mock Oblivion.esm. - ASSERT_TRUE(boost::filesystem::exists(dataPath / "Oblivion.esm")); - ASSERT_NO_THROW(boost::filesystem::remove(dataPath / "Oblivion.esm")); - ASSERT_FALSE(boost::filesystem::exists(dataPath / "Oblivion.esm")); - - // Delete existing plugins.txt. - ASSERT_NO_THROW(boost::filesystem::remove(localPath / "plugins.txt")); - }; - - inline void GenerateMasterlist() { - boost::filesystem::ofstream masterlist(masterlistPath); - masterlist - << "plugins:" << std::endl - << " - name: Oblivion.esm" << std::endl - << " - name: Silgrad_Tower.esm" << std::endl - << " - name: No Lights Flicker.esm" << std::endl - << " msg:" << std::endl - << " - type: say" << std::endl - << " content: Use Wrye Bash Bashed Patch tweak instead." << std::endl - << " - name: bookplacing.esm" << std::endl - << " msg:" << std::endl - << " - type: warn" << std::endl - << " content: 'Check you are using v2+. If not, Update. v1 has a severe bug with the Mystic Emporium disappearing.'" << std::endl - << " - name: EnhancedWeatherSIOnly.esm" << std::endl - << " msg:" << std::endl - << " - type: error" << std::endl - << " content: Obsolete. Remove this and install Enhanced Weather." << std::endl - << " - name: Hammerfell.esm" << std::endl - << " dirty:" << std::endl - << " - crc: 0x7d22f9df" << std::endl - << " util: TES4Edit" << std::endl - << " udr: 4" << std::endl - << " - name: nVidia Black Screen Fix.esp" << std::endl - << " msg:" << std::endl - << " - type: say" << std::endl - << " content: Use Wrye Bash Bashed Patch tweak instead." << std::endl - << " - type: say" << std::endl - << " content: 'Alternatively, remove this and use UOP v3.0.1+ instead.'" << std::endl - << " - name: Unofficial Oblivion Patch.esp" << std::endl - << " msg:" << std::endl - << " - type: say" << std::endl - << " content: 'Do not clean ITM records, they are intentional and required for the mod to function.'" << std::endl - << " tag:" << std::endl - << " - Actors.ACBS" << std::endl - << " - Actors.AIData" << std::endl - << " - Actors.AIPackages" << std::endl - << " - Actors.CombatStyle" << std::endl - << " - Actors.DeathItem" << std::endl - << " - Actors.Stats" << std::endl - << " - C.Climate" << std::endl - << " - C.Light" << std::endl - << " - C.Music" << std::endl - << " - C.Name" << std::endl - << " - C.Owner" << std::endl - << " - Creatures.Blood" << std::endl - << " - Delev" << std::endl - << " - Factions" << std::endl - << " - Invent" << std::endl - << " - Names" << std::endl - << " - NPC.Class" << std::endl - << " - Relations" << std::endl - << " - Relev" << std::endl - << " - Scripts" << std::endl - << " - Stats" << std::endl - << " - '-C.Water'" << std::endl; - - masterlist.close(); + inline bool isTimestampLoadOrderMethod() { + return masterFile == "Oblivion.esm"; } }; - class OblivionAPIOperationsTest : public OblivionTest { + class OblivionTest : public GenericGameTest { protected: - inline virtual void SetUp() { - OblivionTest::SetUp(); - - ASSERT_EQ(loot_ok, loot_create_db(&db, loot_game_tes4, dataPath.parent_path().string().c_str(), localPath.string().c_str())); - } + OblivionTest() : GenericGameTest("Oblivion") {} }; class SkyrimTest : public GenericGameTest { protected: - SkyrimTest() : GenericGameTest("./Skyrim/Data", "./local/Skyrim") {} + SkyrimTest() : GenericGameTest("Skyrim") {} inline virtual void SetUp() { GenericGameTest::SetUp(); ASSERT_TRUE(boost::filesystem::exists(dataPath / "Blank.bsa")); ASSERT_TRUE(boost::filesystem::exists(dataPath / "Blank.bsl")); - - // Can't change Skyrim's main master file, so mock it. - ASSERT_FALSE(boost::filesystem::exists(dataPath / "Skyrim.esm")); - ASSERT_NO_THROW(boost::filesystem::copy_file(dataPath / "Blank.esm", dataPath / "Skyrim.esm")); - ASSERT_TRUE(boost::filesystem::exists(dataPath / "Skyrim.esm")); - - // Set Skyrim's load order to a known list before running the test. - boost::filesystem::ofstream loadOrder(localPath / "loadorder.txt"); - loadOrder - << "Skyrim.esm" << std::endl - << "Blank.esm" << std::endl - << "Blank - Different.esm" << std::endl - << "Blank - Master Dependent.esm" << std::endl // Ghosted - << "Blank - Different Master Dependent.esm" << std::endl - << "Blank.esp" << std::endl - << "Blank - Different.esp" << std::endl - << "Blank - Master Dependent.esp" << std::endl - << "Blank - Different Master Dependent.esp" << std::endl - << "Blank - Plugin Dependent.esp" << std::endl - << "Blank - Different Plugin Dependent.esp" << std::endl; - loadOrder.close(); - - // Set Skyrim's active plugins to a known list before running the test. - boost::filesystem::ofstream activePlugins(localPath / "plugins.txt"); - activePlugins - << "Blank.esm" << std::endl - << "Blank - Different Master Dependent.esp" << std::endl; - activePlugins.close(); - } - - inline virtual void TearDown() { - GenericGameTest::TearDown(); - - // Delete the mock Skyrim.esm. - ASSERT_TRUE(boost::filesystem::exists(dataPath / "Skyrim.esm")); - ASSERT_NO_THROW(boost::filesystem::remove(dataPath / "Skyrim.esm")); - ASSERT_FALSE(boost::filesystem::exists(dataPath / "Skyrim.esm")); - - // Delete existing plugins.txt and loadorder.txt. - ASSERT_NO_THROW(boost::filesystem::remove(localPath / "plugins.txt")); - ASSERT_NO_THROW(boost::filesystem::remove(localPath / "loadorder.txt")); - }; - }; - - class SkyrimAPIOperationsTest : public SkyrimTest { - protected: - inline virtual void SetUp() { - SkyrimTest::SetUp(); - - ASSERT_EQ(loot_ok, loot_create_db(&db, loot_game_tes5, dataPath.parent_path().string().c_str(), localPath.string().c_str())); } }; } From 96ca64acb7fb4695820cc26c221423e70fc65132 Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Sun, 13 Mar 2016 22:14:18 +0000 Subject: [PATCH 05/38] Improve modulo operator test --- src/tests/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/main.cpp b/src/tests/main.cpp index 53358127..953c9cf6 100644 --- a/src/tests/main.cpp +++ b/src/tests/main.cpp @@ -68,7 +68,7 @@ #include -TEST(ModuloOperator, Cpp11Conformance) { +TEST(ModuloOperator, shouldConformToTheCpp11Standard) { // C++11 defines the modulo operator more strongly // (only x % 0 is left undefined), whereas C++03 // only defined the operator for positive first operand. From 3dd140bb4407bd701a2fb9a629556b0ae40b2f62 Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Tue, 15 Mar 2016 18:25:05 +0000 Subject: [PATCH 06/38] Rename GUI tests --- CMakeLists.txt | 4 ++-- src/tests/gui/{test_loot_settings.h => loot_settings_test.h} | 0 src/tests/gui/{test_loot_state.h => loot_state_test.h} | 2 +- src/tests/main.cpp | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) rename src/tests/gui/{test_loot_settings.h => loot_settings_test.h} (100%) rename src/tests/gui/{test_loot_state.h => loot_state_test.h} (98%) diff --git a/CMakeLists.txt b/CMakeLists.txt index f69f74cc..2a4465ff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -257,8 +257,8 @@ set (LOOT_TESTS_HEADERS "${CMAKE_SOURCE_DIR}/src/tests/base_game_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/test_metadata_list.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/test_masterlist.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/test_plugin_sorter.h" - "${CMAKE_SOURCE_DIR}/src/tests/gui/test_loot_settings.h" - "${CMAKE_SOURCE_DIR}/src/tests/gui/test_loot_state.h") + "${CMAKE_SOURCE_DIR}/src/tests/gui/loot_settings_test.h" + "${CMAKE_SOURCE_DIR}/src/tests/gui/loot_state_test.h") source_group("Header Files\\backend" FILES ${LOOT_HEADERS}) source_group("Header Files\\gui" FILES ${LOOT_GUI_HEADERS}) diff --git a/src/tests/gui/test_loot_settings.h b/src/tests/gui/loot_settings_test.h similarity index 100% rename from src/tests/gui/test_loot_settings.h rename to src/tests/gui/loot_settings_test.h diff --git a/src/tests/gui/test_loot_state.h b/src/tests/gui/loot_state_test.h similarity index 98% rename from src/tests/gui/test_loot_state.h rename to src/tests/gui/loot_state_test.h index e4ebc89f..8601c436 100644 --- a/src/tests/gui/test_loot_state.h +++ b/src/tests/gui/loot_state_test.h @@ -27,7 +27,7 @@ along with LOOT. If not, see #include "gui/loot_state.h" -#include "tests/fixtures.h" +#include namespace loot { namespace test { diff --git a/src/tests/main.cpp b/src/tests/main.cpp index 953c9cf6..45f5a154 100644 --- a/src/tests/main.cpp +++ b/src/tests/main.cpp @@ -63,8 +63,8 @@ #include "backend/test_metadata_list.h" #include "backend/test_masterlist.h" #include "backend/test_plugin_sorter.h" -#include "gui/test_loot_settings.h" -#include "gui/test_loot_state.h" +#include "gui/loot_settings_test.h" +#include "gui/loot_state_test.h" #include From a6545e7600cc5895ad473c134f78ec82083961e5 Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Tue, 15 Mar 2016 20:46:30 +0000 Subject: [PATCH 07/38] Improve Game tests --- CMakeLists.txt | 2 +- src/tests/backend/game/game_test.h | 379 +++++++++++++++++ src/tests/backend/game/test_game.h | 662 ----------------------------- src/tests/base_game_test.h | 12 +- src/tests/main.cpp | 2 +- 5 files changed, 392 insertions(+), 665 deletions(-) create mode 100644 src/tests/backend/game/game_test.h delete mode 100644 src/tests/backend/game/test_game.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 2a4465ff..e63f2525 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -235,7 +235,7 @@ set (LOOT_TESTS_HEADERS "${CMAKE_SOURCE_DIR}/src/tests/base_game_test.h" "${CMAKE_SOURCE_DIR}/src/tests/api/loot_write_minimal_list_test.h" "${CMAKE_SOURCE_DIR}/src/tests/api/test_api.h" - "${CMAKE_SOURCE_DIR}/src/tests/backend/game/test_game.h" + "${CMAKE_SOURCE_DIR}/src/tests/backend/game/game_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/game/test_game_cache.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/game/test_game_settings.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/game/test_load_order_handler.h" diff --git a/src/tests/backend/game/game_test.h b/src/tests/backend/game/game_test.h new file mode 100644 index 00000000..bef5ab03 --- /dev/null +++ b/src/tests/backend/game/game_test.h @@ -0,0 +1,379 @@ +/* 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_TEST_BACKEND_GAME +#define LOOT_TEST_BACKEND_GAME + +#include "backend/error.h" +#include "backend/globals.h" +#include "backend/game/game.h" + +#include "tests/base_game_test.h" + +namespace loot { + namespace test { + class GameTest : public BaseGameTest { + protected: + + void SetUp() { + BaseGameTest::SetUp(); + + setLoadOrder(); + setActivePlugins(); + } +#ifndef _WIN32 + void TearDown() { + BaseGameTest::TearDown(); + + ASSERT_NO_THROW(boost::filesystem::remove_all(g_path_local)); + } +#endif + + inline std::vector getExpectedLoadOrder() const { + return std::vector({ + masterFile, + blankEsm, + blankDifferentEsm, + blankMasterDependentEsm, + blankDifferentMasterDependentEsm, + blankEsp, + blankDifferentEsp, + blankMasterDependentEsp, + blankDifferentMasterDependentEsp, + blankPluginDependentEsp, + blankDifferentPluginDependentEsp, + }); + } + + inline void setLoadOrder() { + if (isTimestampLoadOrderMethod()) { + time_t modificationTime = time(NULL); // Current time. + for (const auto &plugin : getExpectedLoadOrder()) { + if (boost::filesystem::exists(dataPath / boost::filesystem::path(plugin + ".ghost"))) { + boost::filesystem::last_write_time(dataPath / boost::filesystem::path(plugin + ".ghost"), modificationTime); + } + else { + boost::filesystem::last_write_time(dataPath / plugin, modificationTime); + } + modificationTime += 60; + } + } + else { + boost::filesystem::ofstream loadOrder(localPath / "loadorder.txt"); + for (const auto &plugin : getExpectedLoadOrder()) + loadOrder << plugin << std::endl; + loadOrder.close(); + } + } + + inline void setActivePlugins() { + boost::filesystem::ofstream activePlugins(localPath / "plugins.txt"); + activePlugins + << blankEsm << std::endl; + activePlugins.close(); + } + + inline bool isTimestampLoadOrderMethod() { + return GetParam() == Game::tes4 || GetParam() == Game::fo3 || GetParam() == Game::fonv; + } + }; + + // Pass an empty first argument, as it's a prefix for the test instantation, + // but we only have the one so no prefix is necessary. + INSTANTIATE_TEST_CASE_P(, + GameTest, + ::testing::Values( + GameSettings::tes4, + GameSettings::tes5, + GameSettings::fo3, + GameSettings::fonv, + GameSettings::fo4)); + + TEST_P(GameTest, defaultConstructorShouldConstructWithDefaultGameSettings) { + GameSettings settings; + Game game; + + EXPECT_EQ(settings.Id(), game.Id()); + EXPECT_EQ(settings.FolderName(), game.FolderName()); + } + + TEST_P(GameTest, constructingFromGameSettingsShouldUseTheirValues) { + GameSettings settings = GameSettings(GetParam(), "folder"); + settings.SetName("foo"); + settings.SetMaster(blankEsm); + settings.SetRegistryKey("foo"); + settings.SetRepoURL("foo"); + settings.SetRepoBranch("foo"); + settings.SetGamePath(localPath); + Game game = Game(settings); + + EXPECT_EQ(GetParam(), game.Id()); + EXPECT_EQ(settings.Name(), game.Name()); + EXPECT_EQ(settings.FolderName(), game.FolderName()); + EXPECT_EQ(settings.Master(), game.Master()); + EXPECT_EQ(settings.RegistryKey(), game.RegistryKey()); + EXPECT_EQ(settings.RepoURL(), game.RepoURL()); + EXPECT_EQ(settings.RepoBranch(), game.RepoBranch()); + + EXPECT_EQ(settings.GamePath(), game.GamePath()); + } + + TEST_P(GameTest, constructingFromIdAndFolderShouldPassThemToGameSettingsConstructor) { + GameSettings settings = GameSettings(GetParam(), "folder"); + Game game = Game(GetParam(), "folder"); + + EXPECT_EQ(settings.Id(), game.Id()); + EXPECT_EQ(settings.FolderName(), game.FolderName()); + } + + TEST_P(GameTest, initShouldThrowIfGameHasAnInvalidId) { + Game game; + EXPECT_THROW(game.Init(false), error); + EXPECT_THROW(game.Init(true), error); + EXPECT_THROW(game.Init(false, localPath), error); + EXPECT_THROW(game.Init(true, localPath), error); + } + +#ifndef _WIN32 + // Testing on Windows will find real game installs in the Registry, so cannot + // test autodetection fully unless on Linux. + TEST_P(GameTest, initShouldThrowOnLinuxIfGamePathIsNotGiven) { + Game game = Game(GetParam()); + EXPECT_THROW(game.Init(false), error); + EXPECT_THROW(game.Init(true), error); + EXPECT_THROW(game.Init(false, localPath), error); + EXPECT_THROW(game.Init(true, localPath), error); + } + + TEST_P(GameTest, initShouldThrowOnLinuxIfLocalPathIsNotGiven) { + Game game = Game(GetParam()).SetGamePath(dataPath.parent_path()); + ASSERT_FALSE(boost::filesystem::exists(g_path_local / game.FolderName())); + EXPECT_THROW(game.Init(false), error); + } + + // Testing on Windows will find real LOOT installs, and they shouldn't be + // interfered with. + TEST_P(GameTest, initShouldNotCreateAGameFolderIfTheCreateFolderArgumentIsFalse) { + Game game = Game(GetParam()).SetGamePath(dataPath.parent_path()); + + ASSERT_FALSE(boost::filesystem::exists(g_path_local / game.FolderName())); + EXPECT_NO_THROW(game.Init(false, localPath)); + + EXPECT_FALSE(boost::filesystem::exists(g_path_local / game.FolderName())); + } + + TEST_P(GameTest, initShouldCreateAGameFolderIfTheCreateFolderArgumentIsTrue) { + Game game = Game(GetParam()).SetGamePath(dataPath.parent_path()); + + ASSERT_FALSE(boost::filesystem::exists(g_path_local / game.FolderName())); + EXPECT_NO_THROW(game.Init(true, localPath)); + + EXPECT_TRUE(boost::filesystem::exists(g_path_local / game.FolderName())); + } +#else + TEST_P(GameTest, initShouldNotThrowOnWindowsIfLocalPathIsNotGiven) { + Game game = Game(GetParam()).SetGamePath(dataPath.parent_path()); + + EXPECT_NO_THROW(game.Init(false)); + } +#endif + + TEST_P(GameTest, initShouldNotThrowIfGameAndLocalPathsAreGiven) { + Game game = Game(GetParam()).SetGamePath(dataPath.parent_path()); + + EXPECT_NO_THROW(game.Init(false, localPath)); + } + + TEST_P(GameTest, redatePluginsShouldThrowIfTheGameHasNotYetBeenInitialisedForSkyrimAndNotForOtherGames) { + Game game(GetParam()); + game.SetGamePath(dataPath.parent_path()); + + if (GetParam() == Game::tes5) + EXPECT_THROW(game.RedatePlugins(), error); + else + EXPECT_NO_THROW(game.RedatePlugins()); + } + + TEST_P(GameTest, redatePluginsShouldRedatePluginsForSkyrimAndDoNothingForOtherGames) { + Game game(GetParam()); + game.SetGamePath(dataPath.parent_path()); + game.Init(false, localPath); + + std::vector loadOrder = getExpectedLoadOrder(); + + // First set reverse timestamps to be sure. + time_t time = boost::filesystem::last_write_time(dataPath / masterFile); + for (size_t i = 1; i < loadOrder.size(); ++i) { + boost::filesystem::last_write_time(dataPath / loadOrder[i], time - i * 60); + ASSERT_EQ(time - i * 60, boost::filesystem::last_write_time(dataPath / loadOrder[i])); + } + + EXPECT_NO_THROW(game.RedatePlugins()); + + if (GetParam() == Game::tes5) { + for (size_t i = 0; i < loadOrder.size(); ++i) { + ASSERT_EQ(time + i * 60, boost::filesystem::last_write_time(dataPath / loadOrder[i])); + } + } + else { + for (size_t i = 0; i < loadOrder.size(); ++i) { + ASSERT_EQ(time - i * 60, boost::filesystem::last_write_time(dataPath / loadOrder[i])); + } + } + } + + TEST_P(GameTest, loadPluginsWithHeadersOnlyTrueShouldLoadTheHeadersOfAllInstalledPlugins) { + Game game(GetParam()); + game.SetGamePath(dataPath.parent_path()); + + EXPECT_NO_THROW(game.LoadPlugins(true)); + EXPECT_EQ(11, game.GetPlugins().size()); + + // Check that one plugin's header has been read. + ASSERT_NO_THROW(game.GetPlugin(masterFile)); + Plugin plugin = game.GetPlugin(masterFile); + EXPECT_EQ("v5.0", plugin.getDescription()); + + // Check that only the header has been read. + EXPECT_EQ(0, plugin.Crc()); + } + + TEST_P(GameTest, loadPluginsWithHeadersOnlyFalseShouldFullyLoadAllInstalledPlugins) { + Game game(GetParam()); + game.SetGamePath(dataPath.parent_path()); + + EXPECT_NO_THROW(game.LoadPlugins(false)); + EXPECT_EQ(11, game.GetPlugins().size()); + + // Check that one plugin's header has been read. + ASSERT_NO_THROW(game.GetPlugin(blankEsm)); + Plugin plugin = game.GetPlugin(blankEsm); + EXPECT_EQ("v5.0", plugin.getDescription()); + + // Check that not only the header has been read. + EXPECT_EQ(blankEsmCrc, plugin.Crc()); + } + + TEST_P(GameTest, pluginsShouldNotBeFullyLoadedByDefault) { + EXPECT_FALSE(Game().ArePluginsFullyLoaded()); + EXPECT_FALSE(Game(GameSettings()).ArePluginsFullyLoaded()); + EXPECT_FALSE(Game(GetParam(), "folder").ArePluginsFullyLoaded()); + } + + TEST_P(GameTest, pluginsShouldNotBeFullyLoadedAfterLoadingHeadersOnly) { + Game game(GetParam()); + game.SetGamePath(dataPath.parent_path()); + + ASSERT_NO_THROW(game.LoadPlugins(true)); + + EXPECT_FALSE(game.ArePluginsFullyLoaded()); + } + + TEST_P(GameTest, pluginsShouldBeFullyLoadedAfterFullyLoadingThem) { + Game game(GetParam()); + game.SetGamePath(dataPath.parent_path()); + + ASSERT_NO_THROW(game.LoadPlugins(false)); + + EXPECT_TRUE(game.ArePluginsFullyLoaded()); + } + + TEST_P(GameTest, shouldThrowIfCheckingIfPluginThatIsntLoadedIsActiveAndGameHasNotBeenInitialised) { + Game game(GetParam()); + game.SetGamePath(dataPath.parent_path()); + + EXPECT_ANY_THROW(game.IsPluginActive(blankEsm)); + } + + TEST_P(GameTest, shouldShowBlankEsmAsActiveIfItHasNotBeenLoadedAndTheGameHasBeenInitialised) { + Game game(GetParam()); + game.SetGamePath(dataPath.parent_path()); + ASSERT_NO_THROW(game.Init(false, localPath)); + + EXPECT_TRUE(game.IsPluginActive(blankEsm)); + } + + TEST_P(GameTest, shouldShowBlankEspAsInactiveIfItHasNotBeenLoadedAndTheGameHasBeenInitialised) { + Game game(GetParam()); + game.SetGamePath(dataPath.parent_path()); + ASSERT_NO_THROW(game.Init(false, localPath)); + + EXPECT_FALSE(game.IsPluginActive(blankEsp)); + } + + TEST_P(GameTest, shouldShowBlankEsmAsInactiveIfItsHeaderHasBeenLoadedAndGameHasNotBeenInitialised) { + Game game(GetParam()); + game.SetGamePath(dataPath.parent_path()); + ASSERT_NO_THROW(game.LoadPlugins(true)); + + EXPECT_FALSE(game.IsPluginActive(blankEsm)); + } + + TEST_P(GameTest, shouldShowBlankEspAsInactiveIfItsHeaderHasBeenLoadedAndGameHasNotBeenInitialised) { + Game game(GetParam()); + game.SetGamePath(dataPath.parent_path()); + ASSERT_NO_THROW(game.LoadPlugins(true)); + + EXPECT_FALSE(game.IsPluginActive(blankEsp)); + } + + TEST_P(GameTest, shouldShowBlankEsmAsActiveIfItsHeaderHasBeenLoadedAndTheGameHasBeenInitialised) { + Game game(GetParam()); + game.SetGamePath(dataPath.parent_path()); + ASSERT_NO_THROW(game.Init(false, localPath)); + ASSERT_NO_THROW(game.LoadPlugins(true)); + + EXPECT_TRUE(game.IsPluginActive(blankEsm)); + } + + TEST_P(GameTest, shouldShowBlankEspAsInactiveIfItsHeaderHasBeenLoadedAndTheGameHasBeenInitialised) { + Game game(GetParam()); + game.SetGamePath(dataPath.parent_path()); + ASSERT_NO_THROW(game.Init(false, localPath)); + ASSERT_NO_THROW(game.LoadPlugins(true)); + + EXPECT_FALSE(game.IsPluginActive(blankEsp)); + } + + TEST_P(GameTest, shouldShowBlankEsmAsActiveIfItHasBeenFullyLoadedAndTheGameHasBeenInitialised) { + Game game(GetParam()); + game.SetGamePath(dataPath.parent_path()); + ASSERT_NO_THROW(game.Init(false, localPath)); + ASSERT_NO_THROW(game.LoadPlugins(false)); + + EXPECT_TRUE(game.IsPluginActive(blankEsm)); + } + + TEST_P(GameTest, shouldShowBlankEspAsInactiveIfItHasBeenFullyLoadedAndTheGameHasBeenInitialised) { + Game game(GetParam()); + game.SetGamePath(dataPath.parent_path()); + ASSERT_NO_THROW(game.Init(false, localPath)); + ASSERT_NO_THROW(game.LoadPlugins(false)); + + EXPECT_FALSE(game.IsPluginActive(blankEsp)); + } +} +} + +#endif diff --git a/src/tests/backend/game/test_game.h b/src/tests/backend/game/test_game.h deleted file mode 100644 index 23d41620..00000000 --- a/src/tests/backend/game/test_game.h +++ /dev/null @@ -1,662 +0,0 @@ -/* 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_TEST_BACKEND_GAME -#define LOOT_TEST_BACKEND_GAME - -#include "backend/error.h" -#include "backend/globals.h" -#include "backend/game/game.h" - -#include "tests/fixtures.h" - -namespace loot { - namespace test { - class GameTest : public SkyrimTest {}; - - TEST_F(GameTest, Constructors) { - // The constructors should just passthrough to the GameSettings - // members, so just check that is happening. - Game game; - GameSettings settings; - - EXPECT_EQ(Game::autodetect, game.Id()); - EXPECT_EQ(settings.Name(), game.Name()); - EXPECT_EQ(settings.FolderName(), game.FolderName()); - EXPECT_EQ(settings.Master(), game.Master()); - EXPECT_EQ(settings.RegistryKey(), game.RegistryKey()); - EXPECT_EQ(settings.RepoURL(), game.RepoURL()); - EXPECT_EQ(settings.RepoBranch(), game.RepoBranch()); - - EXPECT_EQ(settings.GamePath(), game.GamePath()); - EXPECT_EQ(settings.DataPath(), game.DataPath()); - EXPECT_EQ(settings.MasterlistPath(), game.MasterlistPath()); - EXPECT_EQ(settings.UserlistPath(), game.UserlistPath()); - - EXPECT_FALSE(game.ArePluginsFullyLoaded()); - - game = Game(Game::tes5); - settings = GameSettings(GameSettings::tes5); - - EXPECT_EQ(Game::tes5, game.Id()); - EXPECT_EQ(settings.Name(), game.Name()); - EXPECT_EQ(settings.FolderName(), game.FolderName()); - EXPECT_EQ(settings.Master(), game.Master()); - EXPECT_EQ(settings.RegistryKey(), game.RegistryKey()); - EXPECT_EQ(settings.RepoURL(), game.RepoURL()); - EXPECT_EQ(settings.RepoBranch(), game.RepoBranch()); - - EXPECT_EQ(settings.GamePath(), game.GamePath()); - EXPECT_EQ(settings.DataPath(), game.DataPath()); - EXPECT_EQ(settings.MasterlistPath(), game.MasterlistPath()); - EXPECT_EQ(settings.UserlistPath(), game.UserlistPath()); - - EXPECT_FALSE(game.ArePluginsFullyLoaded()); - - game = Game(Game::tes5, "folder"); - settings = GameSettings(GameSettings::tes5, "folder"); - - EXPECT_EQ(Game::tes5, game.Id()); - EXPECT_EQ(settings.Name(), game.Name()); - EXPECT_EQ(settings.FolderName(), game.FolderName()); - EXPECT_EQ(settings.Master(), game.Master()); - EXPECT_EQ(settings.RegistryKey(), game.RegistryKey()); - EXPECT_EQ(settings.RepoURL(), game.RepoURL()); - EXPECT_EQ(settings.RepoBranch(), game.RepoBranch()); - - EXPECT_EQ(settings.GamePath(), game.GamePath()); - EXPECT_EQ(settings.DataPath(), game.DataPath()); - EXPECT_EQ(settings.MasterlistPath(), game.MasterlistPath()); - EXPECT_EQ(settings.UserlistPath(), game.UserlistPath()); - - EXPECT_FALSE(game.ArePluginsFullyLoaded()); - - game = Game(settings); - - EXPECT_EQ(Game::tes5, game.Id()); - EXPECT_EQ(settings.Name(), game.Name()); - EXPECT_EQ(settings.FolderName(), game.FolderName()); - EXPECT_EQ(settings.Master(), game.Master()); - EXPECT_EQ(settings.RegistryKey(), game.RegistryKey()); - EXPECT_EQ(settings.RepoURL(), game.RepoURL()); - EXPECT_EQ(settings.RepoBranch(), game.RepoBranch()); - - EXPECT_EQ(settings.GamePath(), game.GamePath()); - EXPECT_EQ(settings.DataPath(), game.DataPath()); - EXPECT_EQ(settings.MasterlistPath(), game.MasterlistPath()); - EXPECT_EQ(settings.UserlistPath(), game.UserlistPath()); - - EXPECT_FALSE(game.ArePluginsFullyLoaded()); - } - - TEST_F(GameTest, Init) { - // Should throw for invalid ID. - Game game; - EXPECT_THROW(game.Init(false), error); - EXPECT_THROW(game.Init(true), error); - EXPECT_THROW(game.Init(false, localPath), error); - EXPECT_THROW(game.Init(true, localPath), error); - -#ifndef _WIN32 - // No point testing installation detection on Windows, because it will - // find real installs, and the multi-game fixtures are set up so that they - // won't get auto-detected. Test for failure on Linux though. - game = Game(Game::tes5); - EXPECT_THROW(game.Init(false), error); - EXPECT_THROW(game.Init(true), error); - EXPECT_THROW(game.Init(false, localPath), error); - EXPECT_THROW(game.Init(true, localPath), error); - - // No point testing LOOT folder creation on Windows, because there may be - // a real LOOT install. - // Not supplying a game local path on Linux should throw an exception. - game = Game(Game::tes5).SetGamePath(dataPath.parent_path()); - ASSERT_FALSE(boost::filesystem::exists(g_path_local / game.FolderName())); - EXPECT_THROW(game.Init(false), error); - EXPECT_FALSE(boost::filesystem::exists(g_path_local / game.FolderName())); - - game = Game(Game::tes5).SetGamePath(dataPath.parent_path()); - EXPECT_NO_THROW(game.Init(false, localPath)); - EXPECT_FALSE(boost::filesystem::exists(g_path_local / game.FolderName())); - EXPECT_TRUE(game.IsPluginActive("Skyrim.esm")); - EXPECT_TRUE(game.IsPluginActive("skyrim.esm")); - EXPECT_TRUE(game.IsPluginActive("Blank.esm")); - EXPECT_FALSE(game.IsPluginActive("Blank - Different.esm")); - EXPECT_FALSE(game.IsPluginActive("Blank - Master Dependent.esm")); - EXPECT_FALSE(game.IsPluginActive("Blank - Different Master Dependent.esm")); - EXPECT_FALSE(game.IsPluginActive("Blank.esp")); - EXPECT_FALSE(game.IsPluginActive("Blank - Different.esp")); - EXPECT_FALSE(game.IsPluginActive("Blank - Master Dependent.esp")); - EXPECT_TRUE(game.IsPluginActive("Blank - Different Master Dependent.esp")); - EXPECT_FALSE(game.IsPluginActive("Blank - Plugin Dependent.esp")); - EXPECT_FALSE(game.IsPluginActive("Blank - Different Plugin Dependent.esp")); - - game = Game(Game::tes5).SetGamePath(dataPath.parent_path()); - EXPECT_NO_THROW(game.Init(true, localPath)); - EXPECT_TRUE(boost::filesystem::exists(g_path_local / game.FolderName())); - EXPECT_TRUE(game.IsPluginActive("Skyrim.esm")); - EXPECT_TRUE(game.IsPluginActive("skyrim.esm")); - EXPECT_TRUE(game.IsPluginActive("Blank.esm")); - EXPECT_FALSE(game.IsPluginActive("Blank - Different.esm")); - EXPECT_FALSE(game.IsPluginActive("Blank - Master Dependent.esm")); - EXPECT_FALSE(game.IsPluginActive("Blank - Different Master Dependent.esm")); - EXPECT_FALSE(game.IsPluginActive("Blank.esp")); - EXPECT_FALSE(game.IsPluginActive("Blank - Different.esp")); - EXPECT_FALSE(game.IsPluginActive("Blank - Master Dependent.esp")); - EXPECT_TRUE(game.IsPluginActive("Blank - Different Master Dependent.esp")); - EXPECT_FALSE(game.IsPluginActive("Blank - Plugin Dependent.esp")); - EXPECT_FALSE(game.IsPluginActive("Blank - Different Plugin Dependent.esp")); -#else - game = Game(Game::tes5).SetGamePath(dataPath.parent_path()); - EXPECT_NO_THROW(game.Init(false)); - - game = Game(Game::tes5).SetGamePath(dataPath.parent_path()); - EXPECT_NO_THROW(game.Init(false, localPath)); - -#endif - } - - TEST_F(GameTest, RedatePlugins) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - - // Throw because game hasn't been initialised yet. - EXPECT_THROW(game.RedatePlugins(), error); - - game.Init(false, localPath); - - std::vector loadOrder({ - "Skyrim.esm", - "Blank.esm", - "Blank - Different.esm", - "Blank - Master Dependent.esm.ghost", - "Blank - Different Master Dependent.esm", - "Blank.esp", - "Blank - Different.esp", - "Blank - Master Dependent.esp", - "Blank - Different Master Dependent.esp", - "Blank - Plugin Dependent.esp", - "Blank - Different Plugin Dependent.esp", - }); - - time_t time = boost::filesystem::last_write_time(dataPath / "Skyrim.esm"); - // First set reverse timestamps to be sure. - for (size_t i = 1; i < loadOrder.size(); ++i) { - boost::filesystem::last_write_time(dataPath / loadOrder[i], time - i * 60); - ASSERT_EQ(time - i * 60, boost::filesystem::last_write_time(dataPath / loadOrder[i])); - } - EXPECT_NO_THROW(game.RedatePlugins()); - EXPECT_EQ(time, boost::filesystem::last_write_time(dataPath / "Skyrim.esm")); - for (size_t i = 1; i < loadOrder.size(); ++i) { - ASSERT_EQ(time + i * 60, boost::filesystem::last_write_time(dataPath / loadOrder[i])); - } - } - - TEST_F(GameTest, LoadPlugins) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - - EXPECT_NO_THROW(game.LoadPlugins(false)); - EXPECT_EQ(11, game.GetPlugins().size()); - - // Check that all the plugins' data have loaded correctly. - ASSERT_NO_THROW(game.GetPlugin("Skyrim.esm")); - Plugin plugin = game.GetPlugin("Skyrim.esm"); - EXPECT_EQ("Skyrim.esm", plugin.Name()); - EXPECT_FALSE(plugin.IsEmpty()); - EXPECT_TRUE(plugin.isMasterFile()); - EXPECT_EQ(std::set({ - libespm::FormId("Skyrim.esm", std::vector(), 0xCF0), - libespm::FormId("Skyrim.esm", std::vector(), 0xCF1), - libespm::FormId("Skyrim.esm", std::vector(), 0xCF2), - libespm::FormId("Skyrim.esm", std::vector(), 0xCF3), - libespm::FormId("Skyrim.esm", std::vector(), 0xCF4), - libespm::FormId("Skyrim.esm", std::vector(), 0xCF5), - libespm::FormId("Skyrim.esm", std::vector(), 0xCF6), - libespm::FormId("Skyrim.esm", std::vector(), 0xCF7), - libespm::FormId("Skyrim.esm", std::vector(), 0xCF8), - libespm::FormId("Skyrim.esm", std::vector(), 0xCF9), - }), plugin.getFormIds()); - EXPECT_TRUE(plugin.getMasters().empty()); - EXPECT_EQ("v5.0", plugin.getDescription()); - EXPECT_EQ(0x187BE342, plugin.Crc()); - EXPECT_EQ(0, plugin.NumOverrideFormIDs()); - - ASSERT_NO_THROW(game.GetPlugin("blank.esm")); - plugin = game.GetPlugin("blank.esm"); - EXPECT_EQ("Blank.esm", plugin.Name()); - EXPECT_FALSE(plugin.IsEmpty()); - EXPECT_TRUE(plugin.isMasterFile()); - EXPECT_EQ(std::set({ - libespm::FormId("Blank.esm", std::vector(), 0xCF0), - libespm::FormId("Blank.esm", std::vector(), 0xCF1), - libespm::FormId("Blank.esm", std::vector(), 0xCF2), - libespm::FormId("Blank.esm", std::vector(), 0xCF3), - libespm::FormId("Blank.esm", std::vector(), 0xCF4), - libespm::FormId("Blank.esm", std::vector(), 0xCF5), - libespm::FormId("Blank.esm", std::vector(), 0xCF6), - libespm::FormId("Blank.esm", std::vector(), 0xCF7), - libespm::FormId("Blank.esm", std::vector(), 0xCF8), - libespm::FormId("Blank.esm", std::vector(), 0xCF9), - }), plugin.getFormIds()); - EXPECT_TRUE(plugin.getMasters().empty()); - EXPECT_EQ("v5.0", plugin.getDescription()); - EXPECT_EQ(0x187BE342, plugin.Crc()); - EXPECT_EQ(0, plugin.NumOverrideFormIDs()); - - ASSERT_NO_THROW(game.GetPlugin("Blank - Different.esm")); - plugin = game.GetPlugin("Blank - Different.esm"); - EXPECT_EQ("Blank - Different.esm", plugin.Name()); - EXPECT_FALSE(plugin.IsEmpty()); - EXPECT_TRUE(plugin.isMasterFile()); - EXPECT_EQ(std::set({ - libespm::FormId("Blank - Different.esm", std::vector(), 0xCEF), - libespm::FormId("Blank - Different.esm", std::vector(), 0xCF0), - libespm::FormId("Blank - Different.esm", std::vector(), 0xCF1), - libespm::FormId("Blank - Different.esm", std::vector(), 0xCF2), - libespm::FormId("Blank - Different.esm", std::vector(), 0xCF3), - libespm::FormId("Blank - Different.esm", std::vector(), 0xCF4), - libespm::FormId("Blank - Different.esm", std::vector(), 0xCF5), - libespm::FormId("Blank - Different.esm", std::vector(), 0xCF6), - libespm::FormId("Blank - Different.esm", std::vector(), 0xCF7), - }), plugin.getFormIds()); - EXPECT_TRUE(plugin.getMasters().empty()); - EXPECT_EQ("", plugin.getDescription()); - EXPECT_EQ(0x64B9F757, plugin.Crc()); - EXPECT_EQ(0, plugin.NumOverrideFormIDs()); - - ASSERT_NO_THROW(game.GetPlugin("blank - master dependent.esm")); - plugin = game.GetPlugin("blank - master dependent.esm"); - EXPECT_EQ("Blank - Master Dependent.esm", plugin.Name()); - EXPECT_FALSE(plugin.IsEmpty()); - EXPECT_TRUE(plugin.isMasterFile()); - EXPECT_EQ(std::set({ - libespm::FormId("Blank.esm", std::vector(), 0xCF0), - libespm::FormId("Blank.esm", std::vector(), 0xCF1), - libespm::FormId("Blank.esm", std::vector(), 0xCF2), - libespm::FormId("Blank.esm", std::vector(), 0xCF3), - libespm::FormId("Blank - Master Dependent.esm", std::vector(), 0xCEA), - libespm::FormId("Blank - Master Dependent.esm", std::vector(), 0xCEB), - libespm::FormId("Blank - Master Dependent.esm", std::vector(), 0xCEC), - libespm::FormId("Blank - Master Dependent.esm", std::vector(), 0xCED), - }), plugin.getFormIds()); - EXPECT_EQ(std::vector({ - "Blank.esm" - }), plugin.getMasters()); - EXPECT_EQ("", plugin.getDescription()); - EXPECT_EQ(0xB2D4119E, plugin.Crc()); - EXPECT_EQ(4, plugin.NumOverrideFormIDs()); - - ASSERT_NO_THROW(game.GetPlugin("blank - different master dependent.esm")); - plugin = game.GetPlugin("blank - different master dependent.esm"); - EXPECT_EQ("Blank - Different Master Dependent.esm", plugin.Name()); - EXPECT_FALSE(plugin.IsEmpty()); - EXPECT_TRUE(plugin.isMasterFile()); - EXPECT_EQ(std::set({ - libespm::FormId("Blank - Different.esm", std::vector(), 0xCEF), - libespm::FormId("Blank - Different.esm", std::vector(), 0xCF0), - libespm::FormId("Blank - Different.esm", std::vector(), 0xCF1), - libespm::FormId("Blank - Different.esm", std::vector(), 0xCF2), - libespm::FormId("Blank - Different Master Dependent.esm", std::vector(), 0xCE9), - libespm::FormId("Blank - Different Master Dependent.esm", std::vector(), 0xCEA), - libespm::FormId("Blank - Different Master Dependent.esm", std::vector(), 0xCEB), - }), plugin.getFormIds()); - EXPECT_EQ(std::vector({ - "Blank - Different.esm" - }), plugin.getMasters()); - EXPECT_EQ("", plugin.getDescription()); - EXPECT_EQ(0xAADF6710, plugin.Crc()); - EXPECT_EQ(4, plugin.NumOverrideFormIDs()); - - ASSERT_NO_THROW(game.GetPlugin("blank.esp")); - plugin = game.GetPlugin("blank.esp"); - EXPECT_EQ("Blank.esp", plugin.Name()); - EXPECT_FALSE(plugin.IsEmpty()); - EXPECT_FALSE(plugin.isMasterFile()); - EXPECT_EQ(std::set({ - libespm::FormId("Blank.esp", std::vector(), 0xCEC), - libespm::FormId("Blank.esp", std::vector(), 0xCED), - libespm::FormId("Blank.esp", std::vector(), 0xCEE), - libespm::FormId("Blank.esp", std::vector(), 0xCEF), - libespm::FormId("Blank.esp", std::vector(), 0xCF0), - libespm::FormId("Blank.esp", std::vector(), 0xCF1), - }), plugin.getFormIds()); - EXPECT_TRUE(plugin.getMasters().empty()); - EXPECT_EQ("\xE2\x82\xAC\xC6\x92\xC5\xA0", plugin.getDescription()); - EXPECT_EQ(0x24F0E2A1, plugin.Crc()); - EXPECT_EQ(0, plugin.NumOverrideFormIDs()); - - ASSERT_NO_THROW(game.GetPlugin("blank - different.esp")); - plugin = game.GetPlugin("blank - different.esp"); - EXPECT_EQ("Blank - Different.esp", plugin.Name()); - EXPECT_FALSE(plugin.IsEmpty()); - EXPECT_FALSE(plugin.isMasterFile()); - EXPECT_EQ(std::set({ - libespm::FormId("Blank - Different.esp", std::vector(), 0xCEB), - libespm::FormId("Blank - Different.esp", std::vector(), 0xCEC), - libespm::FormId("Blank - Different.esp", std::vector(), 0xCED), - libespm::FormId("Blank - Different.esp", std::vector(), 0xCEE), - libespm::FormId("Blank - Different.esp", std::vector(), 0xCEF), - }), plugin.getFormIds()); - EXPECT_TRUE(plugin.getMasters().empty()); - EXPECT_EQ("", plugin.getDescription()); - EXPECT_EQ(0xD4C9B7AE, plugin.Crc()); - EXPECT_EQ(0, plugin.NumOverrideFormIDs()); - - ASSERT_NO_THROW(game.GetPlugin("blank - master dependent.esp")); - plugin = game.GetPlugin("blank - master dependent.esp"); - EXPECT_EQ("Blank - Master Dependent.esp", plugin.Name()); - EXPECT_FALSE(plugin.IsEmpty()); - EXPECT_FALSE(plugin.isMasterFile()); - EXPECT_EQ(std::set({ - libespm::FormId("Blank.esm", std::vector(), 0xCF0), - libespm::FormId("Blank.esm", std::vector(), 0xCF1), - libespm::FormId("Blank - Master Dependent.esp", std::vector(), 0xCE9), - libespm::FormId("Blank - Master Dependent.esp", std::vector(), 0xCEA), - }), plugin.getFormIds()); - EXPECT_EQ(std::vector({ - "Blank.esm" - }), plugin.getMasters()); - EXPECT_EQ("", plugin.getDescription()); - EXPECT_EQ(0x832152DC, plugin.Crc()); - EXPECT_EQ(2, plugin.NumOverrideFormIDs()); - - ASSERT_NO_THROW(game.GetPlugin("blank - different master dependent.esp")); - plugin = game.GetPlugin("blank - different master dependent.esp"); - EXPECT_EQ("Blank - Different Master Dependent.esp", plugin.Name()); - EXPECT_FALSE(plugin.IsEmpty()); - EXPECT_FALSE(plugin.isMasterFile()); - EXPECT_EQ(std::set({ - libespm::FormId("Blank - Different.esm", std::vector(), 0xCEF), - libespm::FormId("Blank - Different.esm", std::vector(), 0xCF0), - libespm::FormId("Blank - Different Master Dependent.esp", std::vector(), 0xCE7), - }), plugin.getFormIds()); - EXPECT_EQ(std::vector({ - "Blank - Different.esm" - }), plugin.getMasters()); - EXPECT_EQ("", plugin.getDescription()); - EXPECT_EQ(0x3AD17683, plugin.Crc()); - EXPECT_EQ(2, plugin.NumOverrideFormIDs()); - - ASSERT_NO_THROW(game.GetPlugin("blank - plugin dependent.esp")); - plugin = game.GetPlugin("blank - plugin dependent.esp"); - EXPECT_EQ("Blank - Plugin Dependent.esp", plugin.Name()); - EXPECT_FALSE(plugin.IsEmpty()); - EXPECT_FALSE(plugin.isMasterFile()); - EXPECT_EQ(std::set({ - libespm::FormId("Blank.esp", std::vector(), 0xCEC), - libespm::FormId("Blank - Plugin Dependent.esp", std::vector(), 0xCE7), - }), plugin.getFormIds()); - EXPECT_EQ(std::vector({ - "Blank.esp" - }), plugin.getMasters()); - EXPECT_EQ("", plugin.getDescription()); - EXPECT_EQ(0x28EF26DB, plugin.Crc()); - EXPECT_EQ(1, plugin.NumOverrideFormIDs()); - - ASSERT_NO_THROW(game.GetPlugin("blank - different plugin dependent.esp")); - plugin = game.GetPlugin("blank - different plugin dependent.esp"); - EXPECT_EQ("Blank - Different Plugin Dependent.esp", plugin.Name()); - EXPECT_FALSE(plugin.IsEmpty()); - EXPECT_FALSE(plugin.isMasterFile()); - EXPECT_EQ(std::set({ - libespm::FormId("Blank - Different.esp", std::vector(), 0xCEB), - }), plugin.getFormIds()); - EXPECT_EQ(std::vector({ - "Blank - Different.esp" - }), plugin.getMasters()); - EXPECT_EQ("", plugin.getDescription()); - EXPECT_EQ(0xEB47BE63, plugin.Crc()); - EXPECT_EQ(1, plugin.NumOverrideFormIDs()); - } - - TEST_F(GameTest, LoadPlugins_HeadersOnly) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - - EXPECT_NO_THROW(game.LoadPlugins(true)); - EXPECT_EQ(11, game.GetPlugins().size()); - - // Check that all the plugins' data have loaded correctly. - ASSERT_NO_THROW(game.GetPlugin("Skyrim.esm")); - Plugin plugin = game.GetPlugin("Skyrim.esm"); - EXPECT_EQ("Skyrim.esm", plugin.Name()); - EXPECT_FALSE(plugin.IsEmpty()); - EXPECT_TRUE(plugin.isMasterFile()); - EXPECT_TRUE(plugin.getFormIds().empty()); - EXPECT_TRUE(plugin.getMasters().empty()); - EXPECT_EQ("v5.0", plugin.getDescription()); - EXPECT_EQ(0, plugin.Crc()); - EXPECT_EQ(0, plugin.NumOverrideFormIDs()); - - ASSERT_NO_THROW(game.GetPlugin("blank.esm")); - plugin = game.GetPlugin("blank.esm"); - EXPECT_EQ("Blank.esm", plugin.Name()); - EXPECT_FALSE(plugin.IsEmpty()); - EXPECT_TRUE(plugin.isMasterFile()); - EXPECT_TRUE(plugin.getFormIds().empty()); - EXPECT_TRUE(plugin.getMasters().empty()); - EXPECT_EQ("v5.0", plugin.getDescription()); - EXPECT_EQ(0, plugin.Crc()); - EXPECT_EQ(0, plugin.NumOverrideFormIDs()); - - ASSERT_NO_THROW(game.GetPlugin("Blank - Different.esm")); - plugin = game.GetPlugin("Blank - Different.esm"); - EXPECT_EQ("Blank - Different.esm", plugin.Name()); - EXPECT_FALSE(plugin.IsEmpty()); - EXPECT_TRUE(plugin.isMasterFile()); - EXPECT_TRUE(plugin.getFormIds().empty()); - EXPECT_TRUE(plugin.getMasters().empty()); - EXPECT_EQ("", plugin.getDescription()); - EXPECT_EQ(0, plugin.Crc()); - EXPECT_EQ(0, plugin.NumOverrideFormIDs()); - - ASSERT_NO_THROW(game.GetPlugin("blank - master dependent.esm")); - plugin = game.GetPlugin("blank - master dependent.esm"); - EXPECT_EQ("Blank - Master Dependent.esm", plugin.Name()); - EXPECT_FALSE(plugin.IsEmpty()); - EXPECT_TRUE(plugin.isMasterFile()); - EXPECT_TRUE(plugin.getFormIds().empty()); - EXPECT_EQ(std::vector({ - "Blank.esm" - }), plugin.getMasters()); - EXPECT_EQ("", plugin.getDescription()); - EXPECT_EQ(0, plugin.Crc()); - EXPECT_EQ(0, plugin.NumOverrideFormIDs()); - - ASSERT_NO_THROW(game.GetPlugin("blank - different master dependent.esm")); - plugin = game.GetPlugin("blank - different master dependent.esm"); - EXPECT_EQ("Blank - Different Master Dependent.esm", plugin.Name()); - EXPECT_FALSE(plugin.IsEmpty()); - EXPECT_TRUE(plugin.isMasterFile()); - EXPECT_TRUE(plugin.getFormIds().empty()); - EXPECT_EQ(std::vector({ - "Blank - Different.esm" - }), plugin.getMasters()); - EXPECT_EQ("", plugin.getDescription()); - EXPECT_EQ(0, plugin.Crc()); - EXPECT_EQ(0, plugin.NumOverrideFormIDs()); - - ASSERT_NO_THROW(game.GetPlugin("blank.esp")); - plugin = game.GetPlugin("blank.esp"); - EXPECT_EQ("Blank.esp", plugin.Name()); - EXPECT_FALSE(plugin.IsEmpty()); - EXPECT_FALSE(plugin.isMasterFile()); - EXPECT_TRUE(plugin.getFormIds().empty()); - EXPECT_TRUE(plugin.getMasters().empty()); - EXPECT_EQ("\xE2\x82\xAC\xC6\x92\xC5\xA0", plugin.getDescription()); - EXPECT_EQ(0, plugin.Crc()); - EXPECT_EQ(0, plugin.NumOverrideFormIDs()); - - ASSERT_NO_THROW(game.GetPlugin("blank - different.esp")); - plugin = game.GetPlugin("blank - different.esp"); - EXPECT_EQ("Blank - Different.esp", plugin.Name()); - EXPECT_FALSE(plugin.IsEmpty()); - EXPECT_FALSE(plugin.isMasterFile()); - EXPECT_TRUE(plugin.getFormIds().empty()); - EXPECT_TRUE(plugin.getMasters().empty()); - EXPECT_EQ("", plugin.getDescription()); - EXPECT_EQ(0, plugin.Crc()); - EXPECT_EQ(0, plugin.NumOverrideFormIDs()); - - ASSERT_NO_THROW(game.GetPlugin("blank - master dependent.esp")); - plugin = game.GetPlugin("blank - master dependent.esp"); - EXPECT_EQ("Blank - Master Dependent.esp", plugin.Name()); - EXPECT_FALSE(plugin.IsEmpty()); - EXPECT_FALSE(plugin.isMasterFile()); - EXPECT_TRUE(plugin.getFormIds().empty()); - EXPECT_EQ(std::vector({ - "Blank.esm" - }), plugin.getMasters()); - EXPECT_EQ("", plugin.getDescription()); - EXPECT_EQ(0, plugin.Crc()); - EXPECT_EQ(0, plugin.NumOverrideFormIDs()); - - ASSERT_NO_THROW(game.GetPlugin("blank - different master dependent.esp")); - plugin = game.GetPlugin("blank - different master dependent.esp"); - EXPECT_EQ("Blank - Different Master Dependent.esp", plugin.Name()); - EXPECT_FALSE(plugin.IsEmpty()); - EXPECT_FALSE(plugin.isMasterFile()); - EXPECT_TRUE(plugin.getFormIds().empty()); - EXPECT_EQ(std::vector({ - "Blank - Different.esm" - }), plugin.getMasters()); - EXPECT_EQ("", plugin.getDescription()); - EXPECT_EQ(0, plugin.Crc()); - EXPECT_EQ(0, plugin.NumOverrideFormIDs()); - - ASSERT_NO_THROW(game.GetPlugin("blank - plugin dependent.esp")); - plugin = game.GetPlugin("blank - plugin dependent.esp"); - EXPECT_EQ("Blank - Plugin Dependent.esp", plugin.Name()); - EXPECT_FALSE(plugin.IsEmpty()); - EXPECT_FALSE(plugin.isMasterFile()); - EXPECT_TRUE(plugin.getFormIds().empty()); - EXPECT_EQ(std::vector({ - "Blank.esp" - }), plugin.getMasters()); - EXPECT_EQ("", plugin.getDescription()); - EXPECT_EQ(0, plugin.Crc()); - EXPECT_EQ(0, plugin.NumOverrideFormIDs()); - - ASSERT_NO_THROW(game.GetPlugin("blank - different plugin dependent.esp")); - plugin = game.GetPlugin("blank - different plugin dependent.esp"); - EXPECT_EQ("Blank - Different Plugin Dependent.esp", plugin.Name()); - EXPECT_FALSE(plugin.IsEmpty()); - EXPECT_FALSE(plugin.isMasterFile()); - EXPECT_TRUE(plugin.getFormIds().empty()); - EXPECT_EQ(std::vector({ - "Blank - Different.esp" - }), plugin.getMasters()); - EXPECT_EQ("", plugin.getDescription()); - EXPECT_EQ(0, plugin.Crc()); - EXPECT_EQ(0, plugin.NumOverrideFormIDs()); - } - - TEST_F(GameTest, ArePluginsFullyLoaded) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - EXPECT_FALSE(game.ArePluginsFullyLoaded()); - - ASSERT_NO_THROW(game.LoadPlugins(false)); - EXPECT_TRUE(game.ArePluginsFullyLoaded()); - } - - TEST_F(GameTest, shouldThrowIfCheckingIfPluginThatIsntLoadedIsActiveAndGameHasNotBeenInitialised) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - - EXPECT_ANY_THROW(game.IsPluginActive("Blank.esm")); - } - - TEST_F(GameTest, shouldShowBlankEsmAsActiveIfItHasNotBeenLoadedAndTheGameHasBeenInitialised) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); - - EXPECT_TRUE(game.IsPluginActive("Blank.esm")); - } - - TEST_F(GameTest, shouldShowBlankEspAsInctiveIfItHasNotBeenLoadedAndTheGameHasBeenInitialised) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); - - EXPECT_FALSE(game.IsPluginActive("Blank.esp")); - } - - TEST_F(GameTest, shouldShowBlankEsmAsInactiveIfItsHeaderHasBeenLoadedAndGameHasNotBeenInitialised) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.LoadPlugins(true)); - - EXPECT_FALSE(game.IsPluginActive("Blank.esm")); - } - - TEST_F(GameTest, shouldShowBlankEspAsActiveIfItsHeaderHasBeenLoadedAndGameHasNotBeenInitialised) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.LoadPlugins(true)); - - EXPECT_FALSE(game.IsPluginActive("Blank.esp")); - } - - TEST_F(GameTest, shouldShowBlankEsmAsActiveIfItsHeaderHasBeenLoadedAndTheGameHasBeenInitialised) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); - ASSERT_NO_THROW(game.LoadPlugins(true)); - - EXPECT_TRUE(game.IsPluginActive("Blank.esm")); - } - - TEST_F(GameTest, shouldShowBlankEspAsActiveIfItsHeaderHasBeenLoadedAndTheGameHasBeenInitialised) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); - ASSERT_NO_THROW(game.LoadPlugins(true)); - - EXPECT_FALSE(game.IsPluginActive("Blank.esp")); - } - - TEST_F(GameTest, shouldShowBlankEsmAsActiveIfItHasBeenFullyLoadedAndTheGameHasBeenInitialised) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); - ASSERT_NO_THROW(game.LoadPlugins(false)); - - EXPECT_TRUE(game.IsPluginActive("Blank.esm")); - } - - TEST_F(GameTest, shouldShowBlankEspAsActiveIfItHasBeenFullyLoadedAndTheGameHasBeenInitialised) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); - ASSERT_NO_THROW(game.LoadPlugins(false)); - - EXPECT_FALSE(game.IsPluginActive("Blank.esp")); - } - } -} - -#endif diff --git a/src/tests/base_game_test.h b/src/tests/base_game_test.h index 105db2c4..c38507ec 100644 --- a/src/tests/base_game_test.h +++ b/src/tests/base_game_test.h @@ -46,7 +46,8 @@ namespace loot { blankMasterDependentEsp("Blank - Master Dependent.esp"), blankDifferentMasterDependentEsp("Blank - Different Master Dependent.esp"), blankPluginDependentEsp("Blank - Plugin Dependent.esp"), - blankDifferentPluginDependentEsp("Blank - Different Plugin Dependent.esp") {} + blankDifferentPluginDependentEsp("Blank - Different Plugin Dependent.esp"), + blankEsmCrc(getBlankEsmCrc()) {} inline virtual void SetUp() { ASSERT_NO_THROW(boost::filesystem::create_directories(localPath)); @@ -91,6 +92,8 @@ namespace loot { const std::string blankPluginDependentEsp; const std::string blankDifferentPluginDependentEsp; + const uint32_t blankEsmCrc; + private: inline boost::filesystem::path getLocalPath() const { if (GetParam() == loot_game_tes4) @@ -118,6 +121,13 @@ namespace loot { else return "Fallout4.esm"; } + + inline uint32_t getBlankEsmCrc() const { + if (GetParam() == loot_game_tes4) + return 0x374E2A6F; + else + return 0x187BE342; + } }; } } diff --git a/src/tests/main.cpp b/src/tests/main.cpp index 45f5a154..c56c909c 100644 --- a/src/tests/main.cpp +++ b/src/tests/main.cpp @@ -41,7 +41,7 @@ #include "api/loot_update_masterlist_test.h" #include "api/loot_write_minimal_list_test.h" #include "api/test_api.h" -#include "backend/game/test_game.h" +#include "backend/game/game_test.h" #include "backend/game/test_game_cache.h" #include "backend/game/test_game_settings.h" #include "backend/game/test_load_order_handler.h" From 48df37ab3cf29fd43c370f608f6eec199f08be68 Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Sat, 19 Mar 2016 22:51:08 +0000 Subject: [PATCH 08/38] Improve GameCache tests --- CMakeLists.txt | 2 +- .../{test_game_cache.h => game_cache_test.h} | 152 +++++++++--------- src/tests/main.cpp | 2 +- 3 files changed, 82 insertions(+), 74 deletions(-) rename src/tests/backend/game/{test_game_cache.h => game_cache_test.h} (50%) diff --git a/CMakeLists.txt b/CMakeLists.txt index e63f2525..5e110902 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -236,7 +236,7 @@ set (LOOT_TESTS_HEADERS "${CMAKE_SOURCE_DIR}/src/tests/base_game_test.h" "${CMAKE_SOURCE_DIR}/src/tests/api/test_api.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/game/game_test.h" - "${CMAKE_SOURCE_DIR}/src/tests/backend/game/test_game_cache.h" + "${CMAKE_SOURCE_DIR}/src/tests/backend/game/game_cache_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/game/test_game_settings.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/game/test_load_order_handler.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/helpers/test_git_helper.h" diff --git a/src/tests/backend/game/test_game_cache.h b/src/tests/backend/game/game_cache_test.h similarity index 50% rename from src/tests/backend/game/test_game_cache.h rename to src/tests/backend/game/game_cache_test.h index aa718c68..5b8445a0 100644 --- a/src/tests/backend/game/test_game_cache.h +++ b/src/tests/backend/game/game_cache_test.h @@ -27,157 +27,165 @@ along with LOOT. If not, see #include "backend/game/game_cache.h" -#include "tests/fixtures.h" +#include "tests/base_game_test.h" namespace loot { namespace test { - class GameCacheTest : public SkyrimTest { + class GameCacheTest : public BaseGameTest { protected: + GameCacheTest() : + condition("Condition"), + conditionLowercase("condition") {} + + void initialiseGame() { + game = Game(GetParam()); + game.SetGamePath(dataPath.parent_path()); + } + + Game game; GameCache cache; + + const std::string condition; + const std::string conditionLowercase; }; - TEST_F(GameCacheTest, copyConstructorShouldCopyCachedData) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); + // Pass an empty first argument, as it's a prefix for the test instantation, + // but we only have the one so no prefix is necessary. + // Just test with one game because if it works for one it will work for them + // all. + INSTANTIATE_TEST_CASE_P(, + GameCacheTest, + ::testing::Values( + Game::tes5)); - cache.CacheCondition("True Condition", true); - cache.AddPlugin(Plugin(game, "Blank.esm", true)); + TEST_P(GameCacheTest, copyConstructorShouldCopyCachedData) { + initialiseGame(); + + cache.CacheCondition(condition, true); + cache.AddPlugin(Plugin(game, blankEsm, true)); Message expectedMessage(Message::say, "1"); cache.AppendMessage(expectedMessage); cache.SetLoadOrderSorted(true); GameCache otherCache(cache); - EXPECT_EQ(std::make_pair(true, true), otherCache.GetCachedCondition("true Condition")); - EXPECT_EQ("Blank.esm", otherCache.GetPlugin("Blank.esm").Name()); + EXPECT_EQ(std::make_pair(true, true), otherCache.GetCachedCondition(conditionLowercase)); + EXPECT_EQ(blankEsm, otherCache.GetPlugin(blankEsm).Name()); ASSERT_EQ(1, otherCache.GetMessages().size()); EXPECT_EQ(expectedMessage, otherCache.GetMessages()[0]); } - TEST_F(GameCacheTest, assignmentOperatorShouldCopyCachedData) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); + TEST_P(GameCacheTest, assignmentOperatorShouldCopyCachedData) { + initialiseGame(); - cache.CacheCondition("True Condition", true); - cache.AddPlugin(Plugin(game, "Blank.esm", true)); + cache.CacheCondition(condition, true); + cache.AddPlugin(Plugin(game, blankEsm, true)); Message expectedMessage(Message::say, "1"); cache.AppendMessage(expectedMessage); cache.SetLoadOrderSorted(true); GameCache otherCache = cache; - EXPECT_EQ(std::make_pair(true, true), otherCache.GetCachedCondition("true Condition")); - EXPECT_EQ("Blank.esm", otherCache.GetPlugin("Blank.esm").Name()); + EXPECT_EQ(std::make_pair(true, true), otherCache.GetCachedCondition(conditionLowercase)); + EXPECT_EQ(blankEsm, otherCache.GetPlugin(blankEsm).Name()); ASSERT_EQ(1, otherCache.GetMessages().size()); EXPECT_EQ(expectedMessage, otherCache.GetMessages()[0]); } - TEST_F(GameCacheTest, gettingATrueConditionShouldReturnATrueTruePair) { - EXPECT_NO_THROW(cache.CacheCondition("True Condition", true)); + TEST_P(GameCacheTest, gettingATrueConditionShouldReturnATrueTruePair) { + EXPECT_NO_THROW(cache.CacheCondition(condition, true)); - EXPECT_EQ(std::make_pair(true, true), cache.GetCachedCondition("true Condition")); + EXPECT_EQ(std::make_pair(true, true), cache.GetCachedCondition(conditionLowercase)); } - TEST_F(GameCacheTest, gettingAFalseConditionShouldReturnAFalseTruePair) { - EXPECT_NO_THROW(cache.CacheCondition("False Condition", false)); + TEST_P(GameCacheTest, gettingAFalseConditionShouldReturnAFalseTruePair) { + EXPECT_NO_THROW(cache.CacheCondition(condition, false)); - EXPECT_EQ(std::make_pair(false, true), cache.GetCachedCondition("false Condition")); + EXPECT_EQ(std::make_pair(false, true), cache.GetCachedCondition(conditionLowercase)); } - TEST_F(GameCacheTest, gettingANonCachedConditionShouldReturnAFalseFalsePair) { - EXPECT_EQ(std::make_pair(false, false), cache.GetCachedCondition("true missing Condition")); + TEST_P(GameCacheTest, gettingANonCachedConditionShouldReturnAFalseFalsePair) { + EXPECT_EQ(std::make_pair(false, false), cache.GetCachedCondition(condition)); } - TEST_F(GameCacheTest, addingAPluginThatDoesNotExistShouldSucceed) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); + TEST_P(GameCacheTest, addingAPluginThatDoesNotExistShouldSucceed) { + initialiseGame(); - cache.AddPlugin(Plugin(game, "Blank.esm", true)); - EXPECT_EQ("Blank.esm", cache.GetPlugin("Blank.esm").Name()); + cache.AddPlugin(Plugin(game, blankEsm, true)); + EXPECT_EQ(blankEsm, cache.GetPlugin(blankEsm).Name()); } - TEST_F(GameCacheTest, addingAPluginThatIsAlreadyCachedShouldOverwriteExistingEntry) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); + TEST_P(GameCacheTest, addingAPluginThatIsAlreadyCachedShouldOverwriteExistingEntry) { + initialiseGame(); - cache.AddPlugin(Plugin(game, "Blank.esm", true)); - EXPECT_EQ(0, cache.GetPlugin("Blank.esm").Crc()); + cache.AddPlugin(Plugin(game, blankEsm, true)); + EXPECT_EQ(0, cache.GetPlugin(blankEsm).Crc()); - cache.AddPlugin(Plugin(game, "Blank.esm", false)); - EXPECT_EQ(0x187BE342, cache.GetPlugin("Blank.esm").Crc()); + cache.AddPlugin(Plugin(game, blankEsm, false)); + EXPECT_EQ(blankEsmCrc, cache.GetPlugin(blankEsm).Crc()); } - TEST_F(GameCacheTest, gettingAPluginThatIsNotCachedShouldThrow) { - EXPECT_ANY_THROW(cache.GetPlugin("Blank.esm")); + TEST_P(GameCacheTest, gettingAPluginThatIsNotCachedShouldThrow) { + EXPECT_ANY_THROW(cache.GetPlugin(blankEsm)); } - TEST_F(GameCacheTest, gettingAPluginShouldBeCaseInsensitive) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); + TEST_P(GameCacheTest, gettingAPluginShouldBeCaseInsensitive) { + initialiseGame(); - cache.AddPlugin(Plugin(game, "Blank.esm", true)); - EXPECT_EQ("Blank.esm", cache.GetPlugin("blanK.esm").Name()); + cache.AddPlugin(Plugin(game, blankEsm, true)); + EXPECT_EQ(blankEsm, cache.GetPlugin(blankEsm).Name()); } - TEST_F(GameCacheTest, gettingPluginsShouldReturnAnEmptySetIfNoPluginsHaveBeenCached) { + TEST_P(GameCacheTest, gettingPluginsShouldReturnAnEmptySetIfNoPluginsHaveBeenCached) { EXPECT_TRUE(cache.GetPlugins().empty()); } - TEST_F(GameCacheTest, gettingPluginsShouldReturnASetOfCachedPluginsIfPluginsHaveBeenCached) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); + TEST_P(GameCacheTest, gettingPluginsShouldReturnASetOfCachedPluginsIfPluginsHaveBeenCached) { + initialiseGame(); - cache.AddPlugin(Plugin(game, "Blank.esm", true)); - cache.AddPlugin(Plugin(game, "Blank - Master Dependent.esp", true)); + cache.AddPlugin(Plugin(game, blankEsm, true)); + cache.AddPlugin(Plugin(game, blankMasterDependentEsm, true)); EXPECT_EQ(std::set({ - Plugin(game, "Blank.esm", true), - Plugin(game, "Blank - Master Dependent.esp", true), + Plugin(game, blankEsm, true), + Plugin(game, blankMasterDependentEsm, true), }), cache.GetPlugins()); } - TEST_F(GameCacheTest, clearingCachedConditionsShouldNotThrowIfNoConditionsAreCached) { + TEST_P(GameCacheTest, clearingCachedConditionsShouldNotThrowIfNoConditionsAreCached) { EXPECT_NO_THROW(cache.ClearCachedConditions()); } - TEST_F(GameCacheTest, clearingCachedConditionsShouldClearAnyCachedConditions) { - EXPECT_NO_THROW(cache.CacheCondition("True Condition", true)); + TEST_P(GameCacheTest, clearingCachedConditionsShouldClearAnyCachedConditions) { + EXPECT_NO_THROW(cache.CacheCondition(condition, true)); EXPECT_NO_THROW(cache.ClearCachedConditions()); - EXPECT_EQ(std::make_pair(false, false), cache.GetCachedCondition("true Condition")); + EXPECT_EQ(std::make_pair(false, false), cache.GetCachedCondition(conditionLowercase)); } - TEST_F(GameCacheTest, clearingCachedPluginsShouldNotThrowIfNoPluginsAreCached) { + TEST_P(GameCacheTest, clearingCachedPluginsShouldNotThrowIfNoPluginsAreCached) { EXPECT_NO_THROW(cache.ClearCachedPlugins()); } - TEST_F(GameCacheTest, clearingCachedPluginsShouldClearAnyCachedPlugins) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); + TEST_P(GameCacheTest, clearingCachedPluginsShouldClearAnyCachedPlugins) { + initialiseGame(); - cache.AddPlugin(Plugin(game, "Blank.esm", true)); + cache.AddPlugin(Plugin(game, blankEsm, true)); cache.ClearCachedPlugins(); EXPECT_TRUE(cache.GetPlugins().empty()); } - TEST_F(GameCacheTest, aMessageShouldBeCachedByDefault) { + TEST_P(GameCacheTest, aMessageShouldBeCachedByDefault) { ASSERT_EQ(1, cache.GetMessages().size()); } - TEST_F(GameCacheTest, settingLoadOrderSortedToTrueShouldSupressDefaultCachedMessage) { + TEST_P(GameCacheTest, settingLoadOrderSortedToTrueShouldSupressDefaultCachedMessage) { cache.SetLoadOrderSorted(true); ASSERT_TRUE(cache.GetMessages().empty()); } - TEST_F(GameCacheTest, settingLoadOrderSortedToFalseShouldReverseTheDefaultCachedMessageSuppression) { + TEST_P(GameCacheTest, settingLoadOrderSortedToFalseShouldReverseTheDefaultCachedMessageSuppression) { auto expectedMessages = cache.GetMessages(); cache.SetLoadOrderSorted(true); cache.SetLoadOrderSorted(false); @@ -185,7 +193,7 @@ namespace loot { ASSERT_EQ(expectedMessages, cache.GetMessages()); } - TEST_F(GameCacheTest, appendingMessagesShouldStoreThemInTheGivenOrder) { + TEST_P(GameCacheTest, appendingMessagesShouldStoreThemInTheGivenOrder) { std::vector messages({ Message(Message::say, "1"), Message(Message::error, "2"), @@ -198,7 +206,7 @@ namespace loot { EXPECT_EQ(messages[1], cache.GetMessages()[1]); } - TEST_F(GameCacheTest, clearingMessagesShouldRemoveAllAppendedMessages) { + TEST_P(GameCacheTest, clearingMessagesShouldRemoveAllAppendedMessages) { std::vector messages({ Message(Message::say, "1"), Message(Message::error, "2"), diff --git a/src/tests/main.cpp b/src/tests/main.cpp index c56c909c..4103c27e 100644 --- a/src/tests/main.cpp +++ b/src/tests/main.cpp @@ -42,7 +42,7 @@ #include "api/loot_write_minimal_list_test.h" #include "api/test_api.h" #include "backend/game/game_test.h" -#include "backend/game/test_game_cache.h" +#include "backend/game/game_cache_test.h" #include "backend/game/test_game_settings.h" #include "backend/game/test_load_order_handler.h" #include "backend/helpers/test_git_helper.h" From 1aeaf9a0e686611b802b99317ce886ca8cb2d7e3 Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Mon, 21 Mar 2016 09:10:26 +0000 Subject: [PATCH 09/38] Improve GameSettings tests --- CMakeLists.txt | 2 +- ...t_game_settings.h => game_settings_test.h} | 135 ++++++++++-------- src/tests/main.cpp | 2 +- 3 files changed, 74 insertions(+), 65 deletions(-) rename src/tests/backend/game/{test_game_settings.h => game_settings_test.h} (67%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5e110902..1aae04e7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -237,7 +237,7 @@ set (LOOT_TESTS_HEADERS "${CMAKE_SOURCE_DIR}/src/tests/base_game_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/game/game_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/game/game_cache_test.h" - "${CMAKE_SOURCE_DIR}/src/tests/backend/game/test_game_settings.h" + "${CMAKE_SOURCE_DIR}/src/tests/backend/game/game_settings_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/game/test_load_order_handler.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/helpers/test_git_helper.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/helpers/test_helpers.h" diff --git a/src/tests/backend/game/test_game_settings.h b/src/tests/backend/game/game_settings_test.h similarity index 67% rename from src/tests/backend/game/test_game_settings.h rename to src/tests/backend/game/game_settings_test.h index 6b90b3bc..c56adcf9 100644 --- a/src/tests/backend/game/test_game_settings.h +++ b/src/tests/backend/game/game_settings_test.h @@ -27,15 +27,26 @@ along with LOOT. If not, see #include "backend/globals.h" #include "backend/game/game_settings.h" -#include "tests/fixtures.h" + +#include "tests/base_game_test.h" namespace loot { namespace test { - class GameSettingsTest : public SkyrimTest {}; - - TEST_F(GameSettingsTest, ConstructorsAndDataAccess) { + class GameSettingsTest : public BaseGameTest { + protected: GameSettings game; + }; + // Pass an empty first argument, as it's a prefix for the test instantation, + // but we only have the one so no prefix is necessary. + // Just test with one game because if it works for one it will work for them + // all. + INSTANTIATE_TEST_CASE_P(, + GameSettingsTest, + ::testing::Values( + GameSettings::tes5)); + + TEST_P(GameSettingsTest, defaultConstructorShouldInitialiseIdToAutodetectAndAllOtherSettingsToEmptyStrings) { EXPECT_EQ(GameSettings::autodetect, game.Id()); EXPECT_EQ("", game.Name()); EXPECT_EQ("", game.FolderName()); @@ -48,7 +59,9 @@ namespace loot { EXPECT_EQ("", game.DataPath()); EXPECT_EQ("", game.MasterlistPath()); EXPECT_EQ("", game.UserlistPath()); + } + TEST_P(GameSettingsTest, idConstructorShouldInitialiseSettingsToDefaultsForThatGame) { game = GameSettings(GameSettings::tes5); EXPECT_EQ(GameSettings::tes5, game.Id()); @@ -64,108 +77,100 @@ namespace loot { EXPECT_EQ("", game.DataPath()); EXPECT_EQ(g_path_local / "Skyrim" / "masterlist.yaml", game.MasterlistPath()); EXPECT_EQ(g_path_local / "Skyrim" / "userlist.yaml", game.UserlistPath()); + } + TEST_P(GameSettingsTest, idConstructorShouldSetGameFolderIfGiven) { game = GameSettings(GameSettings::tes5, "folder"); - EXPECT_EQ(GameSettings::tes5, game.Id()); - EXPECT_EQ("TES V: Skyrim", game.Name()); EXPECT_EQ("folder", game.FolderName()); - EXPECT_EQ("Skyrim.esm", game.Master()); - EXPECT_EQ("Software\\Bethesda Softworks\\Skyrim\\Installed Path", game.RegistryKey()); - EXPECT_EQ("https://github.com/loot/skyrim.git", game.RepoURL()); - // Repo branch changes between LOOT versions, so don't check an exact value. - EXPECT_NE("", game.RepoBranch()); - - EXPECT_EQ("", game.GamePath()); - EXPECT_EQ("", game.DataPath()); EXPECT_EQ(g_path_local / "folder" / "masterlist.yaml", game.MasterlistPath()); EXPECT_EQ(g_path_local / "folder" / "userlist.yaml", game.UserlistPath()); } - TEST_F(GameSettingsTest, IsInstalled) { + TEST_P(GameSettingsTest, isInstalledShouldBeFalseIfGamePathIsNotSet) { GameSettings game; EXPECT_FALSE(game.IsInstalled()); - - game = GameSettings(GameSettings::tes5); - game.SetGamePath(dataPath.parent_path()); - EXPECT_TRUE(game.IsInstalled()); - EXPECT_EQ(dataPath.parent_path(), game.GamePath()); - - game = GameSettings(GameSettings::fo3); - EXPECT_FALSE(game.IsInstalled()); } - TEST_F(GameSettingsTest, EqualityOperators) { - GameSettings game1, game2; - EXPECT_TRUE(game1 == game2); + TEST_P(GameSettingsTest, isInstalledShouldBeTrueIfGamePathIsValid) { + game = GameSettings(GameSettings::tes5); + game.SetGamePath(dataPath.parent_path()); + EXPECT_TRUE(game.IsInstalled()); + } - game1 = GameSettings(GameSettings::tes5); - game2 = GameSettings(GameSettings::tes5); - EXPECT_TRUE(game1 == game2); - - game1 = GameSettings(GameSettings::tes5, "game1") + TEST_P(GameSettingsTest, gameSettingsWithTheSameIdsShouldBeEqual) { + GameSettings game1 = GameSettings(GameSettings::tes5, "game1") .SetMaster("master1") .SetRegistryKey("key1") .SetRepoURL("url1") .SetRepoBranch("branch1") .SetGamePath("path1"); - game2 = GameSettings(GameSettings::tes5, "game2") + GameSettings game2 = GameSettings(GameSettings::tes5, "game2") .SetMaster("master2") .SetRegistryKey("key2") .SetRepoURL("url2") .SetRepoBranch("branch2") .SetGamePath("path2"); - EXPECT_TRUE(game1 == game2); - game1 = GameSettings(GameSettings::tes4) - .SetName("name"); - game2 = GameSettings(GameSettings::tes5) - .SetName("name"); EXPECT_TRUE(game1 == game2); + } + + TEST_P(GameSettingsTest, gameSettingsWithTheSameNameShouldBeEqual) { + GameSettings game1 = GameSettings(GameSettings::tes4) + .SetName("name"); + GameSettings game2 = GameSettings(GameSettings::tes5) + .SetName("name"); + + EXPECT_TRUE(game1 == game2); + } + + TEST_P(GameSettingsTest, gameSettingsWithDifferentIdsAndNamesShouldNotBeEqual) { + GameSettings game1 = GameSettings(GameSettings::tes4); + GameSettings game2 = GameSettings(GameSettings::tes5); - game1 = GameSettings(GameSettings::tes4); - game2 = GameSettings(GameSettings::tes5); EXPECT_FALSE(game1 == game2); } - TEST_F(GameSettingsTest, SetName) { + TEST_P(GameSettingsTest, setNameShouldStoreGivenValue) { GameSettings game; game.SetName("name"); EXPECT_EQ("name", game.Name()); } - TEST_F(GameSettingsTest, SetMaster) { + TEST_P(GameSettingsTest, setMasterShouldStoreGivenValue) { GameSettings game; game.SetMaster("master"); EXPECT_EQ("master", game.Master()); } - TEST_F(GameSettingsTest, SetRegistryKey) { + TEST_P(GameSettingsTest, setRegistryKeyShouldStoreGivenValue) { GameSettings game; game.SetRegistryKey("key"); EXPECT_EQ("key", game.RegistryKey()); } - TEST_F(GameSettingsTest, SetRepoURL) { + TEST_P(GameSettingsTest, setRepoUrlShouldStoreGivenValue) { GameSettings game; game.SetRepoURL("url"); EXPECT_EQ("url", game.RepoURL()); } - TEST_F(GameSettingsTest, SetRepoBranch) { + TEST_P(GameSettingsTest, setRepoBranchShouldStoreGivenValue) { GameSettings game; game.SetRepoBranch("branch"); EXPECT_EQ("branch", game.RepoBranch()); } - TEST_F(GameSettingsTest, SetGamePath) { + TEST_P(GameSettingsTest, setGamePathShouldStoreGivenValue) { + std::string pathValue = "path"; GameSettings game; - game.SetGamePath("path"); - EXPECT_EQ("path", game.GamePath().string()); - EXPECT_EQ(boost::filesystem::path("path") / "Data", game.DataPath()); + + game.SetGamePath(pathValue); + EXPECT_EQ(pathValue, game.GamePath().string()); + EXPECT_EQ(boost::filesystem::path(pathValue) / "Data", game.DataPath()); } - TEST_F(GameSettingsTest, YamlEmitter) { + TEST_P(GameSettingsTest, emittingYamlShouldSerialiseDataCorrectly) { GameSettings game(GameSettings::tes5, "folder1"); game.SetName("name1") .SetMaster("master1") @@ -186,7 +191,7 @@ namespace loot { "registry: 'key1'", e.c_str()); } - TEST_F(GameSettingsTest, YamlEncode) { + TEST_P(GameSettingsTest, encodingAsYamlShouldConvertDataCorrectly) { GameSettings game(GameSettings::tes5, "folder1"); game.SetName("name1") .SetMaster("master1") @@ -207,7 +212,7 @@ namespace loot { EXPECT_EQ("key1", node["registry"].as()); } - TEST_F(GameSettingsTest, YamlDecode) { + TEST_P(GameSettingsTest, decodingFromYamlShouldInterpretTheYamlCorrectly) { YAML::Node node = YAML::Load("type: 'Skyrim'\n" "folder: 'folder1'\n" "name: 'name1'\n" @@ -226,31 +231,35 @@ namespace loot { EXPECT_EQ("url1", game.RepoURL()); EXPECT_EQ("branch1", game.RepoBranch()); EXPECT_EQ("path1", game.GamePath()); + } - node = YAML::Load("type: 'Invalid'\n"); + TEST_P(GameSettingsTest, decodingFromAnInvalidYamlMapShouldThrowAnException) { + YAML::Node node = YAML::Load("type: 'Invalid'\n"); EXPECT_ANY_THROW(node.as()); + } - node = YAML::Load("scalar"); + TEST_P(GameSettingsTest, decodingFromAYamlScalarShouldThrowAnException) { + YAML::Node node = YAML::Load("scalar"); EXPECT_ANY_THROW(node.as()); + } - node = YAML::Load("[0, 1, 2]"); + TEST_P(GameSettingsTest, decodingFromAYamlListShouldThrowAnException) { + YAML::Node node = YAML::Load("[0, 1, 2]"); EXPECT_ANY_THROW(node.as()); + } + TEST_P(GameSettingsTest, decodingFromAnIncompleteYamlMapShouldUseDefaultValuesForMissingSettings) { // Test inheritance of unspecified settings. - node = YAML::Load("type: 'Skyrim'\n" - "folder: 'folder1'\n" - "master: 'master1'\n" - "repo: 'url1'\n" - "branch: 'branch1'\n"); + YAML::Node node = YAML::Load("type: 'Skyrim'\n" + "folder: 'folder1'\n" + "master: 'master1'\n" + "repo: 'url1'\n" + "branch: 'branch1'\n"); game = node.as(); EXPECT_EQ(GameSettings::tes5, game.Id()); EXPECT_EQ("TES V: Skyrim", game.Name()); - EXPECT_EQ("folder1", game.FolderName()); - EXPECT_EQ("master1", game.Master()); EXPECT_EQ("Software\\Bethesda Softworks\\Skyrim\\Installed Path", game.RegistryKey()); - EXPECT_EQ("url1", game.RepoURL()); - EXPECT_EQ("branch1", game.RepoBranch()); EXPECT_EQ("", game.GamePath()); } } diff --git a/src/tests/main.cpp b/src/tests/main.cpp index 4103c27e..2ad2173d 100644 --- a/src/tests/main.cpp +++ b/src/tests/main.cpp @@ -43,7 +43,7 @@ #include "api/test_api.h" #include "backend/game/game_test.h" #include "backend/game/game_cache_test.h" -#include "backend/game/test_game_settings.h" +#include "backend/game/game_settings_test.h" #include "backend/game/test_load_order_handler.h" #include "backend/helpers/test_git_helper.h" #include "backend/helpers/test_helpers.h" From ad44c25d5a74403019d7a65253f32d1f8455d980 Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Mon, 21 Mar 2016 10:36:37 +0000 Subject: [PATCH 10/38] Improve LoadOrderHandler tests and refactor fixtures --- CMakeLists.txt | 2 +- src/tests/backend/game/game_test.h | 61 +------ .../backend/game/load_order_handler_test.h | 155 ++++++++++++++++++ .../backend/game/test_load_order_handler.h | 146 ----------------- src/tests/base_game_test.h | 88 ++++++++++ src/tests/main.cpp | 2 +- 6 files changed, 248 insertions(+), 206 deletions(-) create mode 100644 src/tests/backend/game/load_order_handler_test.h delete mode 100644 src/tests/backend/game/test_load_order_handler.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 1aae04e7..767fd2cf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -238,7 +238,7 @@ set (LOOT_TESTS_HEADERS "${CMAKE_SOURCE_DIR}/src/tests/base_game_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/game/game_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/game/game_cache_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/game/game_settings_test.h" - "${CMAKE_SOURCE_DIR}/src/tests/backend/game/test_load_order_handler.h" + "${CMAKE_SOURCE_DIR}/src/tests/backend/game/load_order_handler_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/helpers/test_git_helper.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/helpers/test_helpers.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/helpers/test_language.h" diff --git a/src/tests/backend/game/game_test.h b/src/tests/backend/game/game_test.h index bef5ab03..077af4b6 100644 --- a/src/tests/backend/game/game_test.h +++ b/src/tests/backend/game/game_test.h @@ -29,19 +29,12 @@ along with LOOT. If not, see #include "backend/globals.h" #include "backend/game/game.h" -#include "tests/base_game_test.h" +#include "load_order_handler_test.h" namespace loot { namespace test { class GameTest : public BaseGameTest { protected: - - void SetUp() { - BaseGameTest::SetUp(); - - setLoadOrder(); - setActivePlugins(); - } #ifndef _WIN32 void TearDown() { BaseGameTest::TearDown(); @@ -49,54 +42,6 @@ namespace loot { ASSERT_NO_THROW(boost::filesystem::remove_all(g_path_local)); } #endif - - inline std::vector getExpectedLoadOrder() const { - return std::vector({ - masterFile, - blankEsm, - blankDifferentEsm, - blankMasterDependentEsm, - blankDifferentMasterDependentEsm, - blankEsp, - blankDifferentEsp, - blankMasterDependentEsp, - blankDifferentMasterDependentEsp, - blankPluginDependentEsp, - blankDifferentPluginDependentEsp, - }); - } - - inline void setLoadOrder() { - if (isTimestampLoadOrderMethod()) { - time_t modificationTime = time(NULL); // Current time. - for (const auto &plugin : getExpectedLoadOrder()) { - if (boost::filesystem::exists(dataPath / boost::filesystem::path(plugin + ".ghost"))) { - boost::filesystem::last_write_time(dataPath / boost::filesystem::path(plugin + ".ghost"), modificationTime); - } - else { - boost::filesystem::last_write_time(dataPath / plugin, modificationTime); - } - modificationTime += 60; - } - } - else { - boost::filesystem::ofstream loadOrder(localPath / "loadorder.txt"); - for (const auto &plugin : getExpectedLoadOrder()) - loadOrder << plugin << std::endl; - loadOrder.close(); - } - } - - inline void setActivePlugins() { - boost::filesystem::ofstream activePlugins(localPath / "plugins.txt"); - activePlugins - << blankEsm << std::endl; - activePlugins.close(); - } - - inline bool isTimestampLoadOrderMethod() { - return GetParam() == Game::tes4 || GetParam() == Game::fo3 || GetParam() == Game::fonv; - } }; // Pass an empty first argument, as it's a prefix for the test instantation, @@ -220,7 +165,7 @@ namespace loot { game.SetGamePath(dataPath.parent_path()); game.Init(false, localPath); - std::vector loadOrder = getExpectedLoadOrder(); + std::vector loadOrder = getInitialLoadOrder(); // First set reverse timestamps to be sure. time_t time = boost::filesystem::last_write_time(dataPath / masterFile); @@ -373,7 +318,7 @@ namespace loot { EXPECT_FALSE(game.IsPluginActive(blankEsp)); } -} + } } #endif diff --git a/src/tests/backend/game/load_order_handler_test.h b/src/tests/backend/game/load_order_handler_test.h new file mode 100644 index 00000000..5832e168 --- /dev/null +++ b/src/tests/backend/game/load_order_handler_test.h @@ -0,0 +1,155 @@ +/* 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_TEST_BACKEND_LOAD_ORDER_HANDLER +#define LOOT_TEST_BACKEND_LOAD_ORDER_HANDLER + +#include "backend/error.h" +#include "backend/game/load_order_handler.h" + +#include "tests/base_game_test.h" + +namespace loot { + namespace test { + class LoadOrderHandlerTest : public BaseGameTest { + protected: + LoadOrderHandler loh; + }; + + // Pass an empty first argument, as it's a prefix for the test instantation, + // but we only have the one so no prefix is necessary. + INSTANTIATE_TEST_CASE_P(, + LoadOrderHandlerTest, + ::testing::Values( + GameSettings::tes4, + GameSettings::tes5, + GameSettings::fo3, + GameSettings::fonv, + GameSettings::fo4)); + + TEST_P(LoadOrderHandlerTest, initShouldThrowForAnInvalidGameId) { + GameSettings game(GameSettings::autodetect); + game.SetGamePath(dataPath.parent_path()); + + EXPECT_THROW(loh.Init(game), error); + EXPECT_THROW(loh.Init(game), error); + EXPECT_THROW(loh.Init(game, localPath), error); + EXPECT_THROW(loh.Init(game, localPath), error); + } + + TEST_P(LoadOrderHandlerTest, initShouldThrowIfNoGamePathIsSet) { + GameSettings game(GetParam()); + + EXPECT_THROW(loh.Init(game), error); + EXPECT_THROW(loh.Init(game), error); + EXPECT_THROW(loh.Init(game, localPath), error); + EXPECT_THROW(loh.Init(game, localPath), error); + } + +#ifndef _WIN32 + TEST_P(LoadOrderHandlerTest, initShouldThrowOnLinuxIfNoLocalPathIsSet) { + GameSettings game(GetParam()); + game.SetGamePath(dataPath.parent_path()); + + EXPECT_THROW(loh.Init(game), error); + } +#endif + + TEST_P(LoadOrderHandlerTest, initShouldNotThrowIfAValidGameIdAndGamePathAndLocalPathAreSet) { + GameSettings game(GetParam()); + game.SetGamePath(dataPath.parent_path()); + + EXPECT_NO_THROW(loh.Init(game, localPath)); + } + + TEST_P(LoadOrderHandlerTest, isPluginActiveShouldThrowIfTheHandlerHasNotBeenInitialised) { + EXPECT_THROW(loh.IsPluginActive(masterFile), error); + } + + TEST_P(LoadOrderHandlerTest, isPluginActiveShouldReturnCorrectPluginStatesAfterInitialisation) { + GameSettings game(GetParam()); + game.SetGamePath(dataPath.parent_path()); + ASSERT_NO_THROW(loh.Init(game, localPath)); + + EXPECT_TRUE(loh.IsPluginActive(masterFile)); + EXPECT_TRUE(loh.IsPluginActive(blankEsm)); + EXPECT_FALSE(loh.IsPluginActive(blankEsp)); + } + + TEST_P(LoadOrderHandlerTest, getLoadOrderShouldThrowIfTheHandlerHasNotBeenInitialised) { + EXPECT_THROW(loh.GetLoadOrder(), error); + } + + TEST_P(LoadOrderHandlerTest, getLoadOrderShouldReturnTheCurrentLoadOrder) { + GameSettings game(GetParam()); + game.SetGamePath(dataPath.parent_path()); + ASSERT_NO_THROW(loh.Init(game, localPath)); + + ASSERT_EQ(getLoadOrder(), loh.GetLoadOrder()); + } + + TEST_P(LoadOrderHandlerTest, setLoadOrderShouldThrowIfTheHandlerHasNotBeenInitialised) { + std::list loadOrder({ + masterFile, + blankEsm, + blankMasterDependentEsm, + blankDifferentEsm, + blankDifferentMasterDependentEsm, + blankDifferentEsp, + blankDifferentPluginDependentEsp, + blankEsp, + blankMasterDependentEsp, + blankDifferentMasterDependentEsp, + blankPluginDependentEsp, + }); + + EXPECT_THROW(loh.SetLoadOrder(std::list()), error); + } + + TEST_P(LoadOrderHandlerTest, setLoadOrderShouldSetTheLoadOrder) { + GameSettings game(GetParam()); + game.SetGamePath(dataPath.parent_path()); + ASSERT_NO_THROW(loh.Init(game, localPath)); + + std::list loadOrder({ + masterFile, + blankEsm, + blankMasterDependentEsm, + blankDifferentEsm, + blankDifferentMasterDependentEsm, + blankDifferentEsp, + blankDifferentPluginDependentEsp, + blankEsp, + blankMasterDependentEsp, + blankDifferentMasterDependentEsp, + blankPluginDependentEsp, + }); + + EXPECT_NO_THROW(loh.SetLoadOrder(loadOrder)); + EXPECT_EQ(loadOrder, getLoadOrder()); + } + } +} + +#endif diff --git a/src/tests/backend/game/test_load_order_handler.h b/src/tests/backend/game/test_load_order_handler.h deleted file mode 100644 index 41f07aaf..00000000 --- a/src/tests/backend/game/test_load_order_handler.h +++ /dev/null @@ -1,146 +0,0 @@ -/* 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_TEST_BACKEND_LOAD_ORDER_HANDLER -#define LOOT_TEST_BACKEND_LOAD_ORDER_HANDLER - -#include "backend/error.h" -#include "backend/game/load_order_handler.h" - -#include "tests/fixtures.h" - -namespace loot { - namespace test { - class LoadOrderHandlerTest : public SkyrimTest {}; - - TEST_F(LoadOrderHandlerTest, Constructors) { - LoadOrderHandler * loh = nullptr; - EXPECT_NO_THROW(loh = new LoadOrderHandler); - EXPECT_NO_THROW(delete loh); - } - - TEST_F(LoadOrderHandlerTest, Init) { - // Should throw for invalid game settings ID. - LoadOrderHandler loh; - GameSettings game(GameSettings::autodetect); - EXPECT_THROW(loh.Init(game), error); - EXPECT_THROW(loh.Init(game), error); - EXPECT_THROW(loh.Init(game, localPath), error); - EXPECT_THROW(loh.Init(game, localPath), error); - - // Should throw an exception if no game path has been set. - game = GameSettings(GameSettings::tes5); - EXPECT_THROW(loh.Init(game), error); - EXPECT_THROW(loh.Init(game), error); - EXPECT_THROW(loh.Init(game, localPath), error); - EXPECT_THROW(loh.Init(game, localPath), error); - -#ifndef _WIN32 - // Should throw on Linux if no game local app data path is given. - game = GameSettings(GameSettings::tes5) - .SetGamePath(dataPath.parent_path()); - EXPECT_THROW(loh.Init(game), error); -#endif - - game = GameSettings(GameSettings::tes5) - .SetGamePath(dataPath.parent_path()); - EXPECT_NO_THROW(loh.Init(game, localPath)); - } - - TEST_F(LoadOrderHandlerTest, IsPluginActive) { - LoadOrderHandler loh; - GameSettings game(GameSettings::tes5); - game.SetGamePath(dataPath.parent_path()); - - EXPECT_THROW(loh.IsPluginActive("Skyrim.esm"), error); - - ASSERT_NO_THROW(loh.Init(game, localPath)); - - EXPECT_TRUE(loh.IsPluginActive("Skyrim.esm")); - EXPECT_TRUE(loh.IsPluginActive("Blank.esm")); - EXPECT_TRUE(loh.IsPluginActive("Blank - Different Master Dependent.esp")); - EXPECT_FALSE(loh.IsPluginActive("Blank.esp")); - } - - TEST_F(LoadOrderHandlerTest, GetLoadOrder) { - LoadOrderHandler loh; - GameSettings game(GameSettings::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(loh.Init(game, localPath)); - - std::list expected({ - "Skyrim.esm", - "Blank.esm", - "Blank - Different.esm", - "Blank - Master Dependent.esm", - "Blank - Different Master Dependent.esm", - "Blank.esp", - "Blank - Different.esp", - "Blank - Master Dependent.esp", - "Blank - Different Master Dependent.esp", - "Blank - Plugin Dependent.esp", - "Blank - Different Plugin Dependent.esp" - }); - - EXPECT_EQ(expected, loh.GetLoadOrder()); - } - - TEST_F(LoadOrderHandlerTest, SetLoadOrder) { - LoadOrderHandler loh; - GameSettings game(GameSettings::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(loh.Init(game, localPath)); - - std::list loadOrder({ - "Skyrim.esm", - "Blank.esm", - "Blank - Master Dependent.esm", - "Blank - Different.esm", - "Blank - Different Master Dependent.esm", - "Blank - Different.esp", - "Blank - Different Plugin Dependent.esp", - "Blank.esp", - "Blank - Master Dependent.esp", - "Blank - Different Master Dependent.esp", - "Blank - Plugin Dependent.esp", - }); - - EXPECT_NO_THROW(loh.SetLoadOrder(loadOrder)); - - std::list actual; - boost::filesystem::ifstream in(localPath / "loadorder.txt"); - while (in) { - std::string line; - std::getline(in, line); - - if (!line.empty()) - actual.push_back(line); - } - - EXPECT_EQ(loadOrder, actual); - } - } -} - -#endif diff --git a/src/tests/base_game_test.h b/src/tests/base_game_test.h index c38507ec..73bfbd68 100644 --- a/src/tests/base_game_test.h +++ b/src/tests/base_game_test.h @@ -27,6 +27,10 @@ along with LOOT. If not, see #include #include +#include +#include + +#include namespace loot { namespace test { @@ -70,12 +74,66 @@ namespace loot { ASSERT_FALSE(boost::filesystem::exists(dataPath / masterFile)); ASSERT_NO_THROW(boost::filesystem::copy_file(dataPath / blankEsm, dataPath / masterFile)); ASSERT_TRUE(boost::filesystem::exists(dataPath / masterFile)); + + // Set initial load order and active plugins. + setLoadOrder(getInitialLoadOrder()); + setActivePlugins(getInitialActivePlugins()); } inline virtual void TearDown() { ASSERT_NO_THROW(boost::filesystem::remove(dataPath / masterFile)); } + inline std::list getLoadOrder() { + std::list actual; + if (isLoadOrderTimestampBased(GetParam())) { + std::map loadOrder; + for (boost::filesystem::directory_iterator it(dataPath); it != boost::filesystem::directory_iterator(); ++it) { + if (boost::filesystem::is_regular_file(it->status()) && + (boost::ends_with(it->path().filename().string(), ".esp") || boost::ends_with(it->path().filename().string(), ".esm"))) { + loadOrder.emplace(boost::filesystem::last_write_time(it->path()), it->path().filename().string()); + } + } + for (const auto& plugin : loadOrder) + actual.push_back(plugin.second); + } + else { + boost::filesystem::ifstream in(localPath / "loadorder.txt"); + while (in) { + std::string line; + std::getline(in, line); + + if (!line.empty()) + actual.push_back(line); + } + } + + return actual; + } + + inline std::vector getInitialLoadOrder() const { + return std::vector({ + masterFile, + blankEsm, + blankDifferentEsm, + blankMasterDependentEsm, + blankDifferentMasterDependentEsm, + blankEsp, + blankDifferentEsp, + blankMasterDependentEsp, + blankDifferentMasterDependentEsp, + blankPluginDependentEsp, + blankDifferentPluginDependentEsp, + }); + } + + inline std::unordered_set getInitialActivePlugins() const { + return std::unordered_set({ + masterFile, + blankEsm, + }); + } + const boost::filesystem::path missingPath; const boost::filesystem::path dataPath; const boost::filesystem::path localPath; @@ -128,6 +186,36 @@ namespace loot { else return 0x187BE342; } + + inline void setLoadOrder(const std::vector& loadOrder) { + if (isLoadOrderTimestampBased(GetParam())) { + time_t modificationTime = time(NULL); // Current time. + for (const auto &plugin : loadOrder) { + if (boost::filesystem::exists(dataPath / boost::filesystem::path(plugin + ".ghost"))) { + boost::filesystem::last_write_time(dataPath / boost::filesystem::path(plugin + ".ghost"), modificationTime); + } + else { + boost::filesystem::last_write_time(dataPath / plugin, modificationTime); + } + modificationTime += 60; + } + } + else { + boost::filesystem::ofstream out(localPath / "loadorder.txt"); + for (const auto &plugin : loadOrder) + out << plugin << std::endl; + } + } + + inline void setActivePlugins(const std::unordered_set& activePlugins) { + boost::filesystem::ofstream out(localPath / "plugins.txt"); + for (const auto &plugin : activePlugins) + out << plugin << std::endl; + } + + inline static bool isLoadOrderTimestampBased(unsigned int gameId) { + return gameId == GameSettings::tes4 || gameId == GameSettings::fo3 || gameId == GameSettings::fonv; + } }; } } diff --git a/src/tests/main.cpp b/src/tests/main.cpp index 2ad2173d..63a8c294 100644 --- a/src/tests/main.cpp +++ b/src/tests/main.cpp @@ -44,7 +44,7 @@ #include "backend/game/game_test.h" #include "backend/game/game_cache_test.h" #include "backend/game/game_settings_test.h" -#include "backend/game/test_load_order_handler.h" +#include "backend/game/load_order_handler_test.h" #include "backend/helpers/test_git_helper.h" #include "backend/helpers/test_helpers.h" #include "backend/helpers/test_language.h" From 8f170b8a69ced242cd5ff9bae8c3edfb39aa2357 Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Thu, 24 Mar 2016 11:52:35 +0000 Subject: [PATCH 11/38] Improve GitHelper tests and refactor IsFileDifferent() --- CMakeLists.txt | 2 +- src/backend/helpers/git_helper.cpp | 7 +- src/backend/helpers/git_helper.h | 4 +- src/backend/masterlist.cpp | 4 +- .../{test_git_helper.h => git_helper_test.h} | 161 ++++++++++-------- src/tests/main.cpp | 2 +- 6 files changed, 95 insertions(+), 85 deletions(-) rename src/tests/backend/helpers/{test_git_helper.h => git_helper_test.h} (53%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 767fd2cf..19af5db1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -239,7 +239,7 @@ set (LOOT_TESTS_HEADERS "${CMAKE_SOURCE_DIR}/src/tests/base_game_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/game/game_cache_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/game/game_settings_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/game/load_order_handler_test.h" - "${CMAKE_SOURCE_DIR}/src/tests/backend/helpers/test_git_helper.h" + "${CMAKE_SOURCE_DIR}/src/tests/backend/helpers/git_helper_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/helpers/test_helpers.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/helpers/test_language.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/helpers/test_version.h" diff --git a/src/backend/helpers/git_helper.cpp b/src/backend/helpers/git_helper.cpp index 88608072..53e9baa0 100644 --- a/src/backend/helpers/git_helper.cpp +++ b/src/backend/helpers/git_helper.cpp @@ -316,15 +316,14 @@ namespace loot { return revision; } - bool IsFileDifferent(const boost::filesystem::path& repoRoot, const std::string& filename) { - GitHelper git; - - if (!git.IsRepository(repoRoot)) { + bool GitHelper::IsFileDifferent(const boost::filesystem::path& repoRoot, const std::string& filename) { + if (!IsRepository(repoRoot)) { BOOST_LOG_TRIVIAL(info) << "Unknown masterlist revision: Git repository missing."; throw error(error::ok, lc::translate("Unknown: Git repository missing")); } BOOST_LOG_TRIVIAL(debug) << "Existing repository found, attempting to open it."; + GitHelper git; git.Call(git_repository_open(&git.repo, repoRoot.string().c_str())); // Perform a git diff, then iterate the deltas to see if one exists for the masterlist. diff --git a/src/backend/helpers/git_helper.h b/src/backend/helpers/git_helper.h index 4250f42e..0e115f77 100644 --- a/src/backend/helpers/git_helper.h +++ b/src/backend/helpers/git_helper.h @@ -43,6 +43,8 @@ namespace loot { static bool IsRepository(const boost::filesystem::path& path); + static bool IsFileDifferent(const boost::filesystem::path& repoRoot, const std::string& filename); + // Clones a repository and opens it. Sets 'repo'. void Clone(const boost::filesystem::path& path, const std::string& url); @@ -85,7 +87,5 @@ namespace loot { // created by libgit2. static void FixRepoPermissions(const boost::filesystem::path& path); }; - - bool IsFileDifferent(const boost::filesystem::path& repoRoot, const std::string& filename); } #endif diff --git a/src/backend/masterlist.cpp b/src/backend/masterlist.cpp index 621f1bc1..e1303b58 100644 --- a/src/backend/masterlist.cpp +++ b/src/backend/masterlist.cpp @@ -77,7 +77,7 @@ namespace loot { info.date = out.str(); BOOST_LOG_TRIVIAL(trace) << "Diffing masterlist HEAD and working copy."; - if (IsFileDifferent(path.parent_path(), path.filename().string())) { + if (GitHelper::IsFileDifferent(path.parent_path(), path.filename().string())) { info.revision += string(" ") + lc::translate("(edited)").str(); info.date += string(" ") + lc::translate("(edited)").str(); } @@ -203,7 +203,7 @@ namespace loot { // must be performed and the checked-out file parsed. if (!updateBranchHead) { BOOST_LOG_TRIVIAL(trace) << "Local and remote branch heads are equal."; - if (!IsFileDifferent(repoPath, filename)) { + if (!GitHelper::IsFileDifferent(repoPath, filename)) { BOOST_LOG_TRIVIAL(info) << "Local branch and masterlist file are already up to date."; return false; } diff --git a/src/tests/backend/helpers/test_git_helper.h b/src/tests/backend/helpers/git_helper_test.h similarity index 53% rename from src/tests/backend/helpers/test_git_helper.h rename to src/tests/backend/helpers/git_helper_test.h index ef40d144..23a7469f 100644 --- a/src/tests/backend/helpers/test_git_helper.h +++ b/src/tests/backend/helpers/git_helper_test.h @@ -22,81 +22,22 @@ along with LOOT. If not, see . */ -#ifndef LOOT_TEST_BACKEND_HELPERS_LANGUAGE -#define LOOT_TEST_BACKEND_HELPERS_LANGUAGE +#ifndef LOOT_TEST_BACKEND_HELPERS_GIT_HELPER +#define LOOT_TEST_BACKEND_HELPERS_GIT_HELPER #include "backend/error.h" #include "backend/helpers/git_helper.h" -#include "tests/fixtures.h" + +#include namespace loot { namespace test { - boost::filesystem::path getRepoRoot() { - boost::filesystem::path dir = boost::filesystem::current_path(); - while (!boost::filesystem::exists(dir / ".git")) { - dir = dir.parent_path(); - } + class GitHelperTest : public ::testing::Test { + protected: + GitHelperTest() : + parentRepoRoot(getRepoRoot()) {} - return dir; - } - - boost::filesystem::path parentRepoRoot = getRepoRoot(); - - TEST(GitHelper, ConstructorAndDestructor) { - GitHelper * git = new GitHelper(); - EXPECT_EQ(nullptr, git->repo); - - EXPECT_EQ(2, git_libgit2_init()); - delete git; - EXPECT_EQ(0, git_libgit2_shutdown()); - } - - TEST(GitHelper, Call) { - GitHelper git; - EXPECT_NO_THROW(git.Call(0)); - EXPECT_THROW(git.Call(1), error); - EXPECT_THROW(git.Call(-1), error); - } - - TEST(GitHelper, SetErrorMessage) { - GitHelper git; - git.SetErrorMessage("test message"); - - try { - git.Call(1); - ADD_FAILURE() << "An exception should have been thrown."; - } - catch (error& e) { - EXPECT_NE(nullptr, strstr(e.what(), "test message")); - } - } - - TEST(GitHelper, Free) { - // Initialise buffer member, it's simplest to test with. - GitHelper git; - git_buf_set(&git.buf, "foo", 4); - EXPECT_NE(nullptr, git.buf.ptr); - EXPECT_EQ(4, git.buf.size); - - git.Free(); - EXPECT_EQ(nullptr, git.buf.ptr); - EXPECT_EQ(0, git.buf.size); - } - - TEST(GitHelper, IsRepository) { - GitHelper git; - - ASSERT_TRUE(boost::filesystem::exists(parentRepoRoot)); - EXPECT_TRUE(git.IsRepository(parentRepoRoot)); - EXPECT_FALSE(git.IsRepository(boost::filesystem::current_path())); - } - - class IsFileDifferentTest : public ::testing::Test { inline virtual void SetUp() { - GitHelper git; - ASSERT_TRUE(git.IsRepository(parentRepoRoot)); - ASSERT_FALSE(git.IsRepository(boost::filesystem::current_path())); - ASSERT_TRUE(boost::filesystem::exists(parentRepoRoot / "README.md")); // Create a backup of CONTRIBUTING.md. @@ -117,24 +58,94 @@ namespace loot { ASSERT_TRUE(boost::filesystem::exists(parentRepoRoot / "CONTRIBUTING.md")); ASSERT_FALSE(boost::filesystem::exists(parentRepoRoot / "CONTRIBUTING.md.copy")); } + + GitHelper git; + + const boost::filesystem::path parentRepoRoot; + + private: + inline static boost::filesystem::path getRepoRoot() { + boost::filesystem::path dir = boost::filesystem::current_path(); + while (!boost::filesystem::exists(dir / ".git")) { + dir = dir.parent_path(); + } + + return dir; + } }; - TEST_F(IsFileDifferentTest, InvalidRepository) { - EXPECT_THROW(IsFileDifferent(boost::filesystem::current_path(), "README.md"), error); + TEST_F(GitHelperTest, repoShouldInitialiseAsANullPointer) { + EXPECT_EQ(nullptr, git.repo); } - TEST_F(IsFileDifferentTest, SameFile) { - EXPECT_FALSE(IsFileDifferent(parentRepoRoot, "README.md")); + TEST_F(GitHelperTest, destructorShouldCallLibgit2CleanupFunction) { + ASSERT_EQ(2, git_libgit2_init()); + + GitHelper * gitPointer = new GitHelper(); + ASSERT_EQ(4, git_libgit2_init()); + + delete gitPointer; + EXPECT_EQ(2, git_libgit2_shutdown()); } - TEST_F(IsFileDifferentTest, NewFile) { + TEST_F(GitHelperTest, callShouldNotThrowIfPassedAZeroValue) { + EXPECT_NO_THROW(git.Call(0)); + } + + TEST_F(GitHelperTest, callShouldThrowIfPassedANonZeroValue) { + EXPECT_THROW(git.Call(1), error); + EXPECT_THROW(git.Call(-1), error); + } + + TEST_F(GitHelperTest, setErrorMessageShouldSetTheMessageForThrownExceptions) { + const char * errorMessage = "test message"; + git.SetErrorMessage(errorMessage); + + try { + git.Call(1); + ADD_FAILURE() << "An exception should have been thrown."; + } + catch (error& e) { + EXPECT_NE(nullptr, strstr(e.what(), errorMessage)); + } + } + + TEST_F(GitHelperTest, freeShouldFreeMemoryAllocatedToMembers) { + // Initialise buffer member, it's simplest to test with. + GitHelper git; + git_buf_set(&git.buf, "foo", 4); + ASSERT_NE(nullptr, git.buf.ptr); + ASSERT_EQ(4, git.buf.size); + + git.Free(); + EXPECT_EQ(nullptr, git.buf.ptr); + EXPECT_EQ(0, git.buf.size); + } + + TEST_F(GitHelperTest, isRepositoryShouldReturnTrueForARepositoryRoot) { + EXPECT_TRUE(GitHelper::IsRepository(parentRepoRoot)); + } + + TEST_F(GitHelperTest, isRepositoryShouldReturnFalseForRepositorySubdirectory) { + EXPECT_FALSE(GitHelper::IsRepository(boost::filesystem::current_path())); + } + + TEST_F(GitHelperTest, isFileDifferentShouldThrowIfGivenANonRepositoryPath) { + EXPECT_THROW(GitHelper::IsFileDifferent(boost::filesystem::current_path(), "README.md"), error); + } + + TEST_F(GitHelperTest, isFileDifferentShouldReturnFalseForAnUntrackedFile) { // New files not in the index are not tracked by Git, so aren't considered // different. - EXPECT_FALSE(IsFileDifferent(parentRepoRoot, "CONTRIBUTING.md.copy")); + EXPECT_FALSE(GitHelper::IsFileDifferent(parentRepoRoot, "CONTRIBUTING.md.copy")); } - TEST_F(IsFileDifferentTest, DifferentFile) { - EXPECT_TRUE(IsFileDifferent(parentRepoRoot, "CONTRIBUTING.md")); + TEST_F(GitHelperTest, isFileDifferentShouldReturnFalseForAnUnchangedTrackedFile) { + EXPECT_FALSE(GitHelper::IsFileDifferent(parentRepoRoot, "README.md")); + } + + TEST_F(GitHelperTest, isFileDifferentShouldReturnTrueForAChangedTrackedFile) { + EXPECT_TRUE(GitHelper::IsFileDifferent(parentRepoRoot, "CONTRIBUTING.md")); } } } diff --git a/src/tests/main.cpp b/src/tests/main.cpp index 63a8c294..bf8c7199 100644 --- a/src/tests/main.cpp +++ b/src/tests/main.cpp @@ -45,7 +45,7 @@ #include "backend/game/game_cache_test.h" #include "backend/game/game_settings_test.h" #include "backend/game/load_order_handler_test.h" -#include "backend/helpers/test_git_helper.h" +#include "backend/helpers/git_helper_test.h" #include "backend/helpers/test_helpers.h" #include "backend/helpers/test_language.h" #include "backend/helpers/test_version.h" From 714f9640cc90d875e28b537ab9a0942e5aae1029 Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Thu, 24 Mar 2016 11:52:54 +0000 Subject: [PATCH 12/38] Improve free function helpers tests --- CMakeLists.txt | 2 +- .../{test_helpers.h => helpers_test.h} | 27 ++++++++++++++----- src/tests/base_game_test.h | 19 ++++++++----- src/tests/main.cpp | 2 +- 4 files changed, 34 insertions(+), 16 deletions(-) rename src/tests/backend/helpers/{test_helpers.h => helpers_test.h} (52%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 19af5db1..951cbf92 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -240,7 +240,7 @@ set (LOOT_TESTS_HEADERS "${CMAKE_SOURCE_DIR}/src/tests/base_game_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/game/game_settings_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/game/load_order_handler_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/helpers/git_helper_test.h" - "${CMAKE_SOURCE_DIR}/src/tests/backend/helpers/test_helpers.h" + "${CMAKE_SOURCE_DIR}/src/tests/backend/helpers/helpers_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/helpers/test_language.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/helpers/test_version.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/helpers/test_yaml_set_helpers.h" diff --git a/src/tests/backend/helpers/test_helpers.h b/src/tests/backend/helpers/helpers_test.h similarity index 52% rename from src/tests/backend/helpers/test_helpers.h rename to src/tests/backend/helpers/helpers_test.h index cceea1cc..d8b6b80f 100644 --- a/src/tests/backend/helpers/test_helpers.h +++ b/src/tests/backend/helpers/helpers_test.h @@ -27,22 +27,35 @@ along with LOOT. If not, see #include "backend/helpers/helpers.h" #include "backend/error.h" -#include "tests/fixtures.h" + +#include "tests/base_game_test.h" namespace loot { namespace test { - class GetCrc32Test : public SkyrimTest {}; + class GetCrc32Test : public BaseGameTest {}; - TEST_F(GetCrc32Test, MissingFile) { - EXPECT_THROW(GetCrc32(dataPath / "Blank.missing.esp"), error); + // Pass an empty first argument, as it's a prefix for the test instantation, + // but we only have the one so no prefix is necessary. + // Just test with one game because if it works for one it will work for them + // all. + INSTANTIATE_TEST_CASE_P(, + GetCrc32Test, + ::testing::Values( + GameSettings::tes5)); + + TEST_P(GetCrc32Test, gettingTheCrcOfAMissingFileShouldThrow) { + EXPECT_THROW(GetCrc32(dataPath / missingEsp), error); } - TEST_F(GetCrc32Test, ValidFile) { - EXPECT_EQ(0x24F0E2A1, GetCrc32(dataPath / "Blank.esp")); + TEST_P(GetCrc32Test, gettingTheCrcOfAFileShouldReturnTheCorrectValue) { + EXPECT_EQ(blankEsmCrc, GetCrc32(dataPath / blankEsm)); } - TEST(IntToHexString, PositiveAndZeroValues) { + TEST(IntToHexString, intToHexStringShouldOutputANonZeroPositiveIntegerCorrectly) { EXPECT_EQ("14", IntToHexString(20)); + } + + TEST(IntToHexString, intToHexStringShouldOutputZeroCorrectly) { EXPECT_EQ("0", IntToHexString(0)); } } diff --git a/src/tests/base_game_test.h b/src/tests/base_game_test.h index 73bfbd68..d5a683c5 100644 --- a/src/tests/base_game_test.h +++ b/src/tests/base_game_test.h @@ -25,6 +25,8 @@ along with LOOT. If not, see #ifndef LOOT_TEST_BASE_GAME_TEST #define LOOT_TEST_BASE_GAME_TEST +#include "backend/game/game_settings.h" + #include #include #include @@ -41,6 +43,7 @@ namespace loot { dataPath(getPluginsPath()), localPath(getLocalPath()), masterFile(getMasterFile()), + missingEsp("Blank.missing.esp"), blankEsm("Blank.esm"), blankDifferentEsm("Blank - Different.esm"), blankMasterDependentEsm("Blank - Master Dependent.esm"), @@ -58,6 +61,7 @@ namespace loot { ASSERT_TRUE(boost::filesystem::exists(localPath)); ASSERT_FALSE(boost::filesystem::exists(missingPath)); + ASSERT_FALSE(boost::filesystem::exists(dataPath / missingEsp)); ASSERT_TRUE(boost::filesystem::exists(dataPath / blankEsm)); ASSERT_TRUE(boost::filesystem::exists(dataPath / blankDifferentEsm)); @@ -139,6 +143,7 @@ namespace loot { const boost::filesystem::path localPath; const std::string masterFile; + const std::string missingEsp; const std::string blankEsm; const std::string blankDifferentEsm; const std::string blankMasterDependentEsm; @@ -154,34 +159,34 @@ namespace loot { private: inline boost::filesystem::path getLocalPath() const { - if (GetParam() == loot_game_tes4) + if (GetParam() == GameSettings::tes4) return "./local/Oblivion"; else return "./local/Skyrim"; } inline boost::filesystem::path getPluginsPath() const { - if (GetParam() == loot_game_tes4) + if (GetParam() == GameSettings::tes4) return "./Oblivion/Data"; else return "./Skyrim/Data"; } inline std::string getMasterFile() const { - if (GetParam() == loot_game_tes4) + if (GetParam() == GameSettings::tes4) return "Oblivion.esm"; - else if (GetParam() == loot_game_tes5) + else if (GetParam() == GameSettings::tes5) return "Skyrim.esm"; - else if (GetParam() == loot_game_fo3) + else if (GetParam() == GameSettings::fo3) return "Fallout3.esm"; - else if (GetParam() == loot_game_fonv) + else if (GetParam() == GameSettings::fonv) return "FalloutNV.esm"; else return "Fallout4.esm"; } inline uint32_t getBlankEsmCrc() const { - if (GetParam() == loot_game_tes4) + if (GetParam() == GameSettings::tes4) return 0x374E2A6F; else return 0x187BE342; diff --git a/src/tests/main.cpp b/src/tests/main.cpp index bf8c7199..267e06a2 100644 --- a/src/tests/main.cpp +++ b/src/tests/main.cpp @@ -46,7 +46,7 @@ #include "backend/game/game_settings_test.h" #include "backend/game/load_order_handler_test.h" #include "backend/helpers/git_helper_test.h" -#include "backend/helpers/test_helpers.h" +#include "backend/helpers/helpers_test.h" #include "backend/helpers/test_language.h" #include "backend/helpers/test_version.h" #include "backend/helpers/test_yaml_set_helpers.h" From b03f0e493c447f2e565bd5d5c5faebd28c62e5fb Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Tue, 22 Mar 2016 21:55:49 +0000 Subject: [PATCH 13/38] Improve Language tests --- CMakeLists.txt | 2 +- .../{test_language.h => language_test.h} | 44 ++++++++++--------- src/tests/main.cpp | 2 +- 3 files changed, 25 insertions(+), 23 deletions(-) rename src/tests/backend/helpers/{test_language.h => language_test.h} (78%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 951cbf92..6f92c891 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -241,7 +241,7 @@ set (LOOT_TESTS_HEADERS "${CMAKE_SOURCE_DIR}/src/tests/base_game_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/game/load_order_handler_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/helpers/git_helper_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/helpers/helpers_test.h" - "${CMAKE_SOURCE_DIR}/src/tests/backend/helpers/test_language.h" + "${CMAKE_SOURCE_DIR}/src/tests/backend/helpers/language_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/helpers/test_version.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/helpers/test_yaml_set_helpers.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/test_condition_grammar.h" diff --git a/src/tests/backend/helpers/test_language.h b/src/tests/backend/helpers/language_test.h similarity index 78% rename from src/tests/backend/helpers/test_language.h rename to src/tests/backend/helpers/language_test.h index 3a2f2f49..d8208cf2 100644 --- a/src/tests/backend/helpers/test_language.h +++ b/src/tests/backend/helpers/language_test.h @@ -26,49 +26,50 @@ along with LOOT. If not, see #define LOOT_TEST_BACKEND_HELPERS_LANGUAGE #include "backend/helpers/language.h" -#include "tests/fixtures.h" + +#include namespace loot { namespace test { - TEST(Language, ConstructorsAndDataAccess) { - // Test English code and locale. + TEST(Language, codeConstructorShouldSetTheCorrectData) { Language lang(Language::english); EXPECT_EQ(Language::english, lang.Code()); EXPECT_EQ("English", lang.Name()); EXPECT_EQ("en", lang.Locale()); - lang = Language("en"); - EXPECT_EQ(Language::english, lang.Code()); - EXPECT_EQ("English", lang.Name()); - EXPECT_EQ("en", lang.Locale()); - - // Test code and locale for a couple of other languages, in case English - // is wrongly being used for everything. No point testing all languages, - // because that would just be copying the class code. lang = Language(Language::polish); EXPECT_EQ(Language::polish, lang.Code()); EXPECT_EQ("Polski", lang.Name()); EXPECT_EQ("pl", lang.Locale()); + } + + TEST(Language, localeConstructorShouldSetTheCorrectData) { + Language lang("en"); + EXPECT_EQ(Language::english, lang.Code()); + EXPECT_EQ("English", lang.Name()); + EXPECT_EQ("en", lang.Locale()); lang = Language("de"); EXPECT_EQ(Language::german, lang.Code()); EXPECT_EQ("Deutsch", lang.Name()); EXPECT_EQ("de", lang.Locale()); + } - // Test that invalid values get treated as English. - lang = Language(1000); - EXPECT_EQ(Language::english, lang.Code()); - EXPECT_EQ("English", lang.Name()); - EXPECT_EQ("en", lang.Locale()); - - lang = Language("foo"); + TEST(Language, codeConstructorShouldTreatAnInvalidCodeAsEnglish) { + Language lang(1000); EXPECT_EQ(Language::english, lang.Code()); EXPECT_EQ("English", lang.Name()); EXPECT_EQ("en", lang.Locale()); } - TEST(Language, Codes) { - // Check that all the expected codes are given. + TEST(Language, localeConstructorShouldTreatAnInvalidLocaleAsEnglish) { + Language lang("foo"); + EXPECT_EQ(Language::english, lang.Code()); + EXPECT_EQ("English", lang.Name()); + EXPECT_EQ("en", lang.Locale()); + } + + TEST(Language, codesShouldContainAllExpectedLanguageCodes) { std::vector codes = { Language::english, Language::spanish, @@ -82,7 +83,8 @@ namespace loot { Language::danish, Language::korean }; - EXPECT_EQ(Language::Codes, codes); + + EXPECT_EQ(codes, Language::Codes); } } } diff --git a/src/tests/main.cpp b/src/tests/main.cpp index 267e06a2..baf09f0d 100644 --- a/src/tests/main.cpp +++ b/src/tests/main.cpp @@ -47,7 +47,7 @@ #include "backend/game/load_order_handler_test.h" #include "backend/helpers/git_helper_test.h" #include "backend/helpers/helpers_test.h" -#include "backend/helpers/test_language.h" +#include "backend/helpers/language_test.h" #include "backend/helpers/test_version.h" #include "backend/helpers/test_yaml_set_helpers.h" #include "backend/metadata/test_condition_grammar.h" From 5db35de96759a49a9caac08f59c2a49169659499 Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Tue, 22 Mar 2016 22:03:08 +0000 Subject: [PATCH 14/38] Improve Version tests This also updates the DLL version extraction test to use the new API DLL name introduced in 939ca1f1ddbe9813e2ba9f73e98eaaef4068d6b9. --- CMakeLists.txt | 2 +- src/tests/backend/helpers/{test_version.h => version_test.h} | 5 +++-- src/tests/main.cpp | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) rename src/tests/backend/helpers/{test_version.h => version_test.h} (99%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6f92c891..dfa9192a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -242,7 +242,7 @@ set (LOOT_TESTS_HEADERS "${CMAKE_SOURCE_DIR}/src/tests/base_game_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/helpers/git_helper_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/helpers/helpers_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/helpers/language_test.h" - "${CMAKE_SOURCE_DIR}/src/tests/backend/helpers/test_version.h" + "${CMAKE_SOURCE_DIR}/src/tests/backend/helpers/version_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/helpers/test_yaml_set_helpers.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/test_condition_grammar.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/test_conditional_metadata.h" diff --git a/src/tests/backend/helpers/test_version.h b/src/tests/backend/helpers/version_test.h similarity index 99% rename from src/tests/backend/helpers/test_version.h rename to src/tests/backend/helpers/version_test.h index 3e8deeab..6f540899 100644 --- a/src/tests/backend/helpers/test_version.h +++ b/src/tests/backend/helpers/version_test.h @@ -27,14 +27,15 @@ along with LOOT. If not, see #include "backend/globals.h" #include "backend/helpers/version.h" -#include "tests/fixtures.h" + +#include namespace loot { namespace test { #ifdef _WIN32 TEST(Version, shouldExtractVersionFromApiDll) { // Use the API DLL built. - Version version(boost::filesystem::path("loot32.dll")); + Version version(boost::filesystem::path("loot_api.dll")); std::string expected( std::to_string(g_version_major) + "." + std::to_string(g_version_minor) + "." + diff --git a/src/tests/main.cpp b/src/tests/main.cpp index baf09f0d..cd471d52 100644 --- a/src/tests/main.cpp +++ b/src/tests/main.cpp @@ -48,7 +48,7 @@ #include "backend/helpers/git_helper_test.h" #include "backend/helpers/helpers_test.h" #include "backend/helpers/language_test.h" -#include "backend/helpers/test_version.h" +#include "backend/helpers/version_test.h" #include "backend/helpers/test_yaml_set_helpers.h" #include "backend/metadata/test_condition_grammar.h" #include "backend/metadata/test_conditional_metadata.h" From 3d5b5677e65e50f29c5a7323e5a9cc2e120da3e7 Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Tue, 22 Mar 2016 23:13:43 +0000 Subject: [PATCH 15/38] Improve YAML set helpers tests --- CMakeLists.txt | 2 +- .../backend/helpers/test_yaml_set_helpers.h | 123 ---------------- .../backend/helpers/yaml_set_helpers_test.h | 138 ++++++++++++++++++ src/tests/main.cpp | 2 +- 4 files changed, 140 insertions(+), 125 deletions(-) delete mode 100644 src/tests/backend/helpers/test_yaml_set_helpers.h create mode 100644 src/tests/backend/helpers/yaml_set_helpers_test.h diff --git a/CMakeLists.txt b/CMakeLists.txt index dfa9192a..c730d9b5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -243,7 +243,7 @@ set (LOOT_TESTS_HEADERS "${CMAKE_SOURCE_DIR}/src/tests/base_game_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/helpers/helpers_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/helpers/language_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/helpers/version_test.h" - "${CMAKE_SOURCE_DIR}/src/tests/backend/helpers/test_yaml_set_helpers.h" + "${CMAKE_SOURCE_DIR}/src/tests/backend/helpers/yaml_set_helpers_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/test_condition_grammar.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/test_conditional_metadata.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/test_file.h" diff --git a/src/tests/backend/helpers/test_yaml_set_helpers.h b/src/tests/backend/helpers/test_yaml_set_helpers.h deleted file mode 100644 index 296b3577..00000000 --- a/src/tests/backend/helpers/test_yaml_set_helpers.h +++ /dev/null @@ -1,123 +0,0 @@ -/* 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_TEST_BACKEND_HELPERS_YAML_SET_HELPERS -#define LOOT_TEST_BACKEND_HELPERS_YAML_SET_HELPERS - -#include "backend/helpers/yaml_set_helpers.h" -#include "tests/fixtures.h" - -namespace loot { - namespace test { - TEST(set, YamlEncode) { - YAML::Node node; - std::set stringSet({"a", "b", "c"}); - node = stringSet; - EXPECT_EQ("a", node[0].as()); - EXPECT_EQ("b", node[1].as()); - EXPECT_EQ("c", node[2].as()); - } - - TEST(set, YamlDecode) { - YAML::Node node; - std::set stringSet; - - node = YAML::Load("[a, b, c]"); - stringSet = node.as>(); - EXPECT_EQ(stringSet.begin(), stringSet.find("a")); - EXPECT_EQ(++stringSet.begin(), stringSet.find("b")); - EXPECT_EQ(--stringSet.end(), stringSet.find("c")); - - node = YAML::Load("[a, b, c, c]"); - EXPECT_ANY_THROW(node.as>()); - } - - TEST(set, YamlEmitter) { - std::set stringSet({"a", "b", "c"}); - YAML::Emitter e1; - e1 << stringSet; - EXPECT_STREQ("- a\n- b\n- c", e1.c_str()); - } - - bool nodeContains(const std::string& value, const YAML::Node& node) { - for (const auto& element : node) { - if (element.as() == value) - return true; - } - return false; - } - - TEST(unordered_set, YamlEncode) { - YAML::Node node; - std::unordered_set stringSet({"a", "b", "c"}); - node = stringSet; - // Check that the values are all present in the node. - EXPECT_PRED2(nodeContains, "a", node); - EXPECT_PRED2(nodeContains, "b", node); - EXPECT_PRED2(nodeContains, "c", node); - } - - TEST(unordered_set, YAMLDecode) { - YAML::Node node; - std::unordered_set stringSet; - - node = YAML::Load("[a, b, c]"); - stringSet = node.as>(); - EXPECT_EQ(1, stringSet.count("a")); - EXPECT_EQ(1, stringSet.count("b")); - EXPECT_EQ(1, stringSet.count("c")); - - node = YAML::Load("[a, b, c, c]"); - EXPECT_ANY_THROW(node.as>()); - } - - bool sequenceOf(const char val1, - const char val2, - const char val3, - const std::string& seq) { - if (seq.substr(0, 2) != "- " - || seq.substr(3, 3) != "\n- " - || seq.substr(7, 3) != "\n- ") - return false; - - std::list values({val1, val2, val3}); - std::list found({seq[2], seq[6], seq[10]}); - - values.sort(); - found.sort(); - - return values == found; - } - - TEST(unordered_set, YamlEmitter) { - std::unordered_set stringSet({"a", "b", "c"}); - YAML::Emitter e1; - e1 << stringSet; - ASSERT_EQ(11, e1.size()); - EXPECT_PRED4(sequenceOf, 'a', 'b', 'c', e1.c_str()); - } - } -} - -#endif diff --git a/src/tests/backend/helpers/yaml_set_helpers_test.h b/src/tests/backend/helpers/yaml_set_helpers_test.h new file mode 100644 index 00000000..86361865 --- /dev/null +++ b/src/tests/backend/helpers/yaml_set_helpers_test.h @@ -0,0 +1,138 @@ +/* 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_TEST_BACKEND_HELPERS_YAML_SET_HELPERS +#define LOOT_TEST_BACKEND_HELPERS_YAML_SET_HELPERS + +#include "backend/helpers/yaml_set_helpers.h" + +#include + +namespace loot { + namespace test { + TEST(set, encodingAsYamlShouldStoreAllValuesInSetOrder) { + std::set stringSet({"a", "b", "c"}); + YAML::Node node; + node = stringSet; + + EXPECT_TRUE(node.IsSequence()); + ASSERT_EQ(3, node.size()); + EXPECT_EQ("a", node[0].as()); + EXPECT_EQ("b", node[1].as()); + EXPECT_EQ("c", node[2].as()); + } + + TEST(set, decodingFromAYamlListShouldStoreValuesCorrectly) { + YAML::Node node = YAML::Load("[a, b, c]"); + std::set stringSet = node.as>(); + std::set expectedStringSet({"a", "b", "c"}); + + EXPECT_EQ(expectedStringSet, stringSet); + } + + TEST(set, decodingFromAYamlListThatContainsDuplicateElementsShouldThrow) { + YAML::Node node = YAML::Load("[a, b, c, c]"); + EXPECT_ANY_THROW(node.as>()); + } + + TEST(set, emittingAsYamlShouldOutputAYamlListContainingAllValues) { + std::set stringSet({"a", "b", "c"}); + YAML::Emitter e1; + e1 << stringSet; + + YAML::Node node = YAML::Load(e1.c_str()); + EXPECT_TRUE(node.IsSequence()); + ASSERT_EQ(3, node.size()); + EXPECT_EQ("a", node[0].as()); + EXPECT_EQ("b", node[1].as()); + EXPECT_EQ("c", node[2].as()); + } + + class unordered_set : public ::testing::Test { + protected: + static bool nodeContains(const YAML::Node& node, const std::string& value) { + for (const auto& element : node) { + if (element.as() == value) + return true; + } + return false; + } + + static bool isSequenceOf(const std::string& sequence, const std::vector& values) { + std::set sortedValues(std::begin(values), std::end(values)); + + std::set found; + size_t i = 2; + while (i < sequence.length()) { + size_t separatorPos = sequence.find("\n- ", i); + found.insert(sequence.substr(i, separatorPos)); + } + + return sortedValues == found; + } + }; + + TEST_F(unordered_set, encodingAsYamlShouldStoreAllValuesInUndefinedOrder) { + std::unordered_set stringSet({"a", "b", "c"}); + YAML::Node node; + node = stringSet; + + EXPECT_TRUE(node.IsSequence()); + ASSERT_EQ(3, node.size()); + EXPECT_PRED2(&nodeContains, node, "a"); + EXPECT_PRED2(&nodeContains, node, "b"); + EXPECT_PRED2(&nodeContains, node, "c"); + } + + TEST_F(unordered_set, decodingFromAYamlListShouldStoreValuesCorrectly) { + YAML::Node node = YAML::Load("[a, b, c]"); + std::unordered_set stringSet = node.as>(); + + EXPECT_EQ(1, stringSet.count("a")); + EXPECT_EQ(1, stringSet.count("b")); + EXPECT_EQ(1, stringSet.count("c")); + } + + TEST_F(unordered_set, decodingFromAYamlListThatContainsDuplicateElementsShouldThrow) { + YAML::Node node = YAML::Load("[a, b, c, c]"); + + EXPECT_ANY_THROW(node.as>()); + } + + TEST_F(unordered_set, emittingAsYamlShouldOutputAYamlListContainingAllValues) { + std::unordered_set stringSet({"a", "b", "c"}); + YAML::Emitter e1; + e1 << stringSet; + + YAML::Node node = YAML::Load(e1.c_str()); + EXPECT_TRUE(node.IsSequence()); + ASSERT_EQ(3, node.size()); + EXPECT_PRED2(&nodeContains, node, "a"); + EXPECT_PRED2(&nodeContains, node, "b"); + EXPECT_PRED2(&nodeContains, node, "c"); + } + } +} + +#endif diff --git a/src/tests/main.cpp b/src/tests/main.cpp index cd471d52..0ce51e9c 100644 --- a/src/tests/main.cpp +++ b/src/tests/main.cpp @@ -49,7 +49,7 @@ #include "backend/helpers/helpers_test.h" #include "backend/helpers/language_test.h" #include "backend/helpers/version_test.h" -#include "backend/helpers/test_yaml_set_helpers.h" +#include "backend/helpers/yaml_set_helpers_test.h" #include "backend/metadata/test_condition_grammar.h" #include "backend/metadata/test_conditional_metadata.h" #include "backend/metadata/test_file.h" From 817f24fdaa06f987589fb755cb6449106af7e9fa Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Thu, 24 Mar 2016 13:59:38 +0000 Subject: [PATCH 16/38] Improve ConditionGrammar tests --- CMakeLists.txt | 2 +- .../backend/metadata/condition_grammar_test.h | 585 +++++++++++++++ .../backend/metadata/test_condition_grammar.h | 664 ------------------ src/tests/main.cpp | 2 +- 4 files changed, 587 insertions(+), 666 deletions(-) create mode 100644 src/tests/backend/metadata/condition_grammar_test.h delete mode 100644 src/tests/backend/metadata/test_condition_grammar.h diff --git a/CMakeLists.txt b/CMakeLists.txt index c730d9b5..c6d60e2b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -244,7 +244,7 @@ set (LOOT_TESTS_HEADERS "${CMAKE_SOURCE_DIR}/src/tests/base_game_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/helpers/language_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/helpers/version_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/helpers/yaml_set_helpers_test.h" - "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/test_condition_grammar.h" + "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/condition_grammar_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/test_conditional_metadata.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/test_file.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/test_location.h" diff --git a/src/tests/backend/metadata/condition_grammar_test.h b/src/tests/backend/metadata/condition_grammar_test.h new file mode 100644 index 00000000..bb0def0b --- /dev/null +++ b/src/tests/backend/metadata/condition_grammar_test.h @@ -0,0 +1,585 @@ +/* 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_TEST_BACKEND_METADATA_CONDITION_GRAMMAR +#define LOOT_TEST_BACKEND_METADATA_CONDITION_GRAMMAR + +#include "backend/error.h" +#include "backend/metadata/condition_grammar.h" +#include "tests/base_game_test.h" + +namespace loot { + namespace test { + class ConditionGrammarTest : public BaseGameTest { + protected: + ConditionGrammarTest() : + resourcePath(dataPath / "resource" / "detail" / "resource.txt"), + game(Game(GetParam()).SetGamePath(dataPath.parent_path())), + result(false), + success(false) {} + + inline void SetUp() { + BaseGameTest::SetUp(); + + // Write out an empty resource file. + ASSERT_NO_THROW(boost::filesystem::create_directories(resourcePath.parent_path())); + boost::filesystem::ofstream out(resourcePath); + out.close(); + ASSERT_TRUE(boost::filesystem::exists(resourcePath)); + } + + inline void TearDown() { + BaseGameTest::TearDown(); + + ASSERT_NO_THROW(boost::filesystem::remove(resourcePath)); + } + + typedef ConditionGrammar Grammar; + + const boost::filesystem::path resourcePath; + + Game game; + boost::spirit::qi::space_type skipper; + bool result; + bool success; + }; + + // Pass an empty first argument, as it's a prefix for the test instantation, + // but we only have the one so no prefix is necessary. + INSTANTIATE_TEST_CASE_P(, + ConditionGrammarTest, + ::testing::Values( + GameSettings::tes4, + GameSettings::tes5, + GameSettings::fo3, + GameSettings::fonv, + GameSettings::fo4)); + + TEST_P(ConditionGrammarTest, parsingInvalidSyntaxShouldThrow) { + Grammar grammar(nullptr); + std::string condition("file(foo)"); + + EXPECT_THROW(boost::spirit::qi::phrase_parse(std::begin(condition), + std::end(condition), + grammar, + skipper, + result), error); + } + + TEST_P(ConditionGrammarTest, evaluatingInvalidSyntaxShouldThrow) { + Grammar grammar(&game); + std::string condition("file(foo)"); + + EXPECT_THROW(boost::spirit::qi::phrase_parse(std::begin(condition), + std::end(condition), + grammar, + skipper, + result), error); + } + + TEST_P(ConditionGrammarTest, parsingAnEmptyConditionShouldThrow) { + Grammar grammar(nullptr); + std::string condition(""); + + EXPECT_THROW(boost::spirit::qi::phrase_parse(std::begin(condition), + std::end(condition), + grammar, + skipper, + result), error); + } + + TEST_P(ConditionGrammarTest, evaluatingAnEmptyConditionShouldThrow) { + Grammar grammar(&game); + std::string condition(""); + + EXPECT_THROW(boost::spirit::qi::phrase_parse(std::begin(condition), + std::end(condition), + grammar, + skipper, + result), error); + } + + TEST_P(ConditionGrammarTest, aFileConditionWithAPluginThatExistsShouldEvaluateToTrue) { + Grammar grammar(&game); + std::string condition("file(\"" + blankEsm + "\")"); + + success = boost::spirit::qi::phrase_parse(std::begin(condition), + std::end(condition), + grammar, + skipper, + result); + EXPECT_TRUE(success); + EXPECT_TRUE(result); + } + + TEST_P(ConditionGrammarTest, aFileConditionWithAPluginThatDoesNotExistShouldEvaluateToFalse) { + Grammar grammar(&game); + std::string condition("file(\"" + missingEsp + "\")"); + + success = boost::spirit::qi::phrase_parse(std::begin(condition), + std::end(condition), + grammar, + skipper, + result); + EXPECT_TRUE(success); + EXPECT_FALSE(result); + } + + TEST_P(ConditionGrammarTest, evaluatingAFileConditionForAnUnsafePathShouldThrow) { + Grammar grammar(&game); + std::string condition("file(\"../../" + blankEsm + "\")"); + + EXPECT_THROW(boost::spirit::qi::phrase_parse(std::begin(condition), + std::end(condition), + grammar, + skipper, + result), error); + } + + TEST_P(ConditionGrammarTest, aRegexConditionWithAnInvalidRegexShouldThrow) { + Grammar grammar(&game); + std::string condition("regex(\"RagnvaldBook(Farengar(+Ragnvald)?)?\\.esp\")"); + + EXPECT_THROW(boost::spirit::qi::phrase_parse(std::begin(condition), + std::end(condition), + grammar, + skipper, + result), error); + } + + TEST_P(ConditionGrammarTest, aRegexConditionWithARegexMatchingAPluginThatExistsShouldEvaluateToTrue) { + Grammar grammar(&game); + std::string condition("regex(\"Blank.+\\.esm\")"); + + success = boost::spirit::qi::phrase_parse(std::begin(condition), + std::end(condition), + grammar, + skipper, + result); + EXPECT_TRUE(success); + EXPECT_TRUE(result); + } + + TEST_P(ConditionGrammarTest, aRegexConditionWithARegexMatchingAPluginThatDoesNotExistShouldEvaluateToFalse) { + Grammar grammar(&game); + std::string condition("regex(\"Blank\\.m.+\\.esm\")"); + + success = boost::spirit::qi::phrase_parse(std::begin(condition), + std::end(condition), + grammar, + skipper, + result); + EXPECT_TRUE(success); + EXPECT_FALSE(result); + } + + TEST_P(ConditionGrammarTest, aRegexConditionWithARegexMatchingAFileInASubfolderThatExistsShouldEvaluateToTrue) { + Grammar grammar(&game); + std::string condition("regex(\"resource\\\\detail\\\\resource\\.txt\")"); + + success = boost::spirit::qi::phrase_parse(std::begin(condition), + std::end(condition), + grammar, + skipper, + result); + EXPECT_TRUE(success); + EXPECT_TRUE(result); + } + + TEST_P(ConditionGrammarTest, aManyConditionWithARegexMatchingMoreThanOnePluginShouldEvaluateToTrue) { + Grammar grammar(&game); + std::string condition("many(\"Blank.+\\.esm\")"); + + success = boost::spirit::qi::phrase_parse(std::begin(condition), + std::end(condition), + grammar, + skipper, + result); + EXPECT_TRUE(success); + EXPECT_TRUE(result); + } + + TEST_P(ConditionGrammarTest, aManyConditionWithARegexMatchingOnlyOnePluginShouldEvaluateToFalse) { + Grammar grammar(&game); + std::string condition("many(\"Blank\\.esm\")"); + + success = boost::spirit::qi::phrase_parse(std::begin(condition), + std::end(condition), + grammar, + skipper, + result); + EXPECT_TRUE(success); + EXPECT_FALSE(result); + } + + TEST_P(ConditionGrammarTest, aChecksumConditionWithACrcThatMatchesTheActualPluginCrcShouldEvaluateToTrue) { + Grammar grammar(&game); + std::string condition("checksum(\"" + blankEsm + "\", " + IntToHexString(blankEsmCrc) + ")"); + + success = boost::spirit::qi::phrase_parse(std::begin(condition), + std::end(condition), + grammar, + skipper, + result); + EXPECT_TRUE(success); + EXPECT_TRUE(result); + } + + TEST_P(ConditionGrammarTest, aChecksumConditionWithACrcThatDoesNotMatchTheActualPluginCrcShouldEvaluateToFalse) { + Grammar grammar(&game); + std::string condition("checksum(\"" + blankEsm + "\", DEADBEEF)"); + + success = boost::spirit::qi::phrase_parse(std::begin(condition), + std::end(condition), + grammar, + skipper, + result); + EXPECT_TRUE(success); + EXPECT_FALSE(result); + } + + TEST_P(ConditionGrammarTest, aVersionEqualityConditionWithAVersionThatEqualsTheActualPluginVersionShouldEvaluateToTrue) { + ASSERT_NO_THROW(game.LoadPlugins(true)); + + Grammar grammar(&game); + std::string condition("version(\"" + blankEsm + "\", \"5.0\", ==)"); + + success = boost::spirit::qi::phrase_parse(std::begin(condition), + std::end(condition), + grammar, + skipper, + result); + EXPECT_TRUE(success); + EXPECT_TRUE(result); + } + + TEST_P(ConditionGrammarTest, aVersionEqualityConditionWithAVersionThatDoesNotEqualTheActualPluginVersionShouldEvaluateToFalse) { + ASSERT_NO_THROW(game.LoadPlugins(true)); + + Grammar grammar(&game); + std::string condition("version(\"" + blankEsm + "\", \"6.0\", ==)"); + + success = boost::spirit::qi::phrase_parse(std::begin(condition), + std::end(condition), + grammar, + skipper, + result); + EXPECT_TRUE(success); + EXPECT_FALSE(result); + } + + TEST_P(ConditionGrammarTest, aVersionInequalityConditionWithAVersionThatDoesNotEqualTheActualPluginVersionShouldEvaluateToTrue) { + ASSERT_NO_THROW(game.LoadPlugins(true)); + + Grammar grammar(&game); + std::string condition("version(\"" + blankEsm + "\", \"6.0\", !=)"); + + success = boost::spirit::qi::phrase_parse(std::begin(condition), + std::end(condition), + grammar, + skipper, + result); + EXPECT_TRUE(success); + EXPECT_TRUE(result); + } + + TEST_P(ConditionGrammarTest, aVersionInequalityConditionWithAVersionThatEqualsTheActualPluginVersionShouldEvaluateToFalse) { + ASSERT_NO_THROW(game.LoadPlugins(true)); + + Grammar grammar(&game); + std::string condition("version(\"" + blankEsm + "\", \"5.0\", !=)"); + + success = boost::spirit::qi::phrase_parse(std::begin(condition), + std::end(condition), + grammar, + skipper, + result); + EXPECT_TRUE(success); + EXPECT_FALSE(result); + } + + TEST_P(ConditionGrammarTest, aVersionLessThanConditionWithAnActualPluginVersionLessThanTheGivenVersionShouldEvaluateToTrue) { + ASSERT_NO_THROW(game.LoadPlugins(true)); + + Grammar grammar(&game); + std::string condition("version(\"" + blankEsm + "\", \"6.0\", <)"); + + success = boost::spirit::qi::phrase_parse(std::begin(condition), + std::end(condition), + grammar, + skipper, + result); + EXPECT_TRUE(success); + EXPECT_TRUE(result); + } + + TEST_P(ConditionGrammarTest, aVersionLessThanConditionWithAnActualPluginVersionEqualToTheGivenVersionShouldEvaluateToFalse) { + ASSERT_NO_THROW(game.LoadPlugins(true)); + + Grammar grammar(&game); + std::string condition("version(\"" + blankEsm + "\", \"5.0\", <)"); + + success = boost::spirit::qi::phrase_parse(std::begin(condition), + std::end(condition), + grammar, + skipper, + result); + EXPECT_TRUE(success); + EXPECT_FALSE(result); + } + + TEST_P(ConditionGrammarTest, aVersionGreaterThanConditionWithAnActualPluginVersionGreaterThanTheGivenVersionShouldEvaluateToTrue) { + ASSERT_NO_THROW(game.LoadPlugins(true)); + + Grammar grammar(&game); + std::string condition("version(\"" + blankEsm + "\", \"4.0\", >)"); + + success = boost::spirit::qi::phrase_parse(std::begin(condition), + std::end(condition), + grammar, + skipper, + result); + EXPECT_TRUE(success); + EXPECT_TRUE(result); + } + + TEST_P(ConditionGrammarTest, aVersionGreaterThanConditionWithAnActualPluginVersionEqualToTheGivenVersionShouldEvaluateToFalse) { + ASSERT_NO_THROW(game.LoadPlugins(true)); + + Grammar grammar(&game); + std::string condition("version(\"" + blankEsm + "\", \"5.0\", >)"); + + success = boost::spirit::qi::phrase_parse(std::begin(condition), + std::end(condition), + grammar, + skipper, + result); + EXPECT_TRUE(success); + EXPECT_FALSE(result); + } + + TEST_P(ConditionGrammarTest, aVersionLessThanOrEqualToConditionWithAnActualPluginVersionEqualToTheGivenVersionShouldEvaluateToTrue) { + ASSERT_NO_THROW(game.LoadPlugins(true)); + + Grammar grammar(&game); + std::string condition("version(\"" + blankEsm + "\", \"5.0\", <=)"); + + success = boost::spirit::qi::phrase_parse(std::begin(condition), + std::end(condition), + grammar, + skipper, + result); + EXPECT_TRUE(success); + EXPECT_TRUE(result); + } + + TEST_P(ConditionGrammarTest, aVersionLessThanOrEqualToConditionWithAnActualPluginVersionGreaterThanTheGivenVersionShouldEvaluateToFalse) { + ASSERT_NO_THROW(game.LoadPlugins(true)); + + Grammar grammar(&game); + std::string condition("version(\"" + blankEsm + "\", \"4.0\", <=)"); + + success = boost::spirit::qi::phrase_parse(std::begin(condition), + std::end(condition), + grammar, + skipper, + result); + EXPECT_TRUE(success); + EXPECT_FALSE(result); + } + + TEST_P(ConditionGrammarTest, aVersionGreaterThanOrEqualToConditionWithAnActualPluginVersionEqualToTheGivenVersionShouldEvaluateToTrue) { + ASSERT_NO_THROW(game.Init(false, localPath)); + ASSERT_NO_THROW(game.LoadPlugins(true)); + + Grammar grammar(&game); + std::string condition("version(\"" + blankEsm + "\", \"5.0\", >=)"); + + success = boost::spirit::qi::phrase_parse(std::begin(condition), + std::end(condition), + grammar, + skipper, + result); + EXPECT_TRUE(success); + EXPECT_TRUE(result); + } + + TEST_P(ConditionGrammarTest, aVersionGreaterThanOrEqualToConditionWithAnActualPluginVersionLessThanTheGivenVersionShouldEvaluateToFalse) { + ASSERT_NO_THROW(game.LoadPlugins(true)); + + Grammar grammar(&game); + std::string condition("version(\"" + blankEsm + "\", \"6.0\", >=)"); + + success = boost::spirit::qi::phrase_parse(std::begin(condition), + std::end(condition), + grammar, + skipper, + result); + EXPECT_TRUE(success); + EXPECT_FALSE(result); + } + + TEST_P(ConditionGrammarTest, anActiveConditionWithAPluginThatIsActiveShouldEvaluateToTrue) { + ASSERT_NO_THROW(game.Init(false, localPath)); + + Grammar grammar(&game); + std::string condition("active(\"" + blankEsm + "\")"); + + success = boost::spirit::qi::phrase_parse(std::begin(condition), + std::end(condition), + grammar, + skipper, + result); + EXPECT_TRUE(success); + EXPECT_TRUE(result); + } + + TEST_P(ConditionGrammarTest, anActiveConditionWithAPluginThatIsNotActiveShouldEvaluateToFalse) { + ASSERT_NO_THROW(game.Init(false, localPath)); + + Grammar grammar(&game); + std::string condition("active(\"" + blankEsp + "\")"); + + success = boost::spirit::qi::phrase_parse(std::begin(condition), + std::end(condition), + grammar, + skipper, + result); + EXPECT_TRUE(success); + EXPECT_FALSE(result); + } + + TEST_P(ConditionGrammarTest, aFalseConditionPrecededByANegatorShouldEvaluateToTrue) { + Grammar grammar(&game); + std::string condition("not file(\"" + missingEsp + "\")"); + + success = boost::spirit::qi::phrase_parse(std::begin(condition), + std::end(condition), + grammar, + skipper, + result); + EXPECT_TRUE(success); + EXPECT_TRUE(result); + } + + TEST_P(ConditionGrammarTest, aTrueConditionPrecededByANegatorShouldEvaluateToFalse) { + Grammar grammar(&game); + std::string condition("not file(\"" + blankEsm + "\")"); + + success = boost::spirit::qi::phrase_parse(std::begin(condition), + std::end(condition), + grammar, + skipper, + result); + EXPECT_TRUE(success); + EXPECT_FALSE(result); + } + + TEST_P(ConditionGrammarTest, twoTrueConditionsJoinedByAnAndShouldEvaluateToTrue) { + Grammar grammar(&game); + std::string condition("file(\"" + blankEsm + "\")"); + std::string compound(condition + " and " + condition); + + success = boost::spirit::qi::phrase_parse(std::begin(compound), + std::end(compound), + grammar, + skipper, + result); + EXPECT_TRUE(success); + EXPECT_TRUE(result); + } + + TEST_P(ConditionGrammarTest, aTrueAndAFalseConditionJoinedByAnAndShouldEvaluateToFalse) { + Grammar grammar(&game); + std::string condition("file(\"" + blankEsm + "\")"); + std::string compound(condition + " and not " + condition); + + success = boost::spirit::qi::phrase_parse(std::begin(compound), + std::end(compound), + grammar, + skipper, + result); + EXPECT_TRUE(success); + EXPECT_FALSE(result); + } + + TEST_P(ConditionGrammarTest, aFalseAndATrueConditionJoinedByAnOrShouldEvaluateToTrue) { + Grammar grammar(&game); + std::string condition("file(\"" + blankEsm + "\")"); + std::string compound("not " + condition + " or " + condition); + + success = boost::spirit::qi::phrase_parse(std::begin(compound), + std::end(compound), + grammar, + skipper, + result); + EXPECT_TRUE(success); + EXPECT_TRUE(result); + } + + TEST_P(ConditionGrammarTest, twoFalseConditionsJoinedByAnOrShouldEvaluateToFalse) { + Grammar grammar(&game); + std::string condition("file(\"" + blankEsm + "\")"); + std::string compound("not " + condition + " or not " + condition); + + success = boost::spirit::qi::phrase_parse(std::begin(compound), + std::end(compound), + grammar, + skipper, + result); + EXPECT_TRUE(success); + EXPECT_FALSE(result); + } + + TEST_P(ConditionGrammarTest, andOperatorsShouldTakePrecedenceOverOrOperators) { + Grammar grammar(&game); + std::string condition("file(\"" + blankEsm + "\")"); + std::string compound("not " + condition + " and " + condition + " or " + condition); + + success = boost::spirit::qi::phrase_parse(std::begin(compound), + std::end(compound), + grammar, + skipper, + result); + EXPECT_TRUE(success); + EXPECT_TRUE(result); + } + + TEST_P(ConditionGrammarTest, parenthesesShouldTakePrecedenceOverAndOperators) { + Grammar grammar(&game); + std::string condition("file(\"" + blankEsm + "\")"); + std::string compound("not " + condition + " and ( " + condition + " or " + condition + " )"); + + success = boost::spirit::qi::phrase_parse(std::begin(compound), + std::end(compound), + grammar, + skipper, + result); + EXPECT_TRUE(success); + EXPECT_FALSE(result); + } + } +} + +#endif diff --git a/src/tests/backend/metadata/test_condition_grammar.h b/src/tests/backend/metadata/test_condition_grammar.h deleted file mode 100644 index 61031f61..00000000 --- a/src/tests/backend/metadata/test_condition_grammar.h +++ /dev/null @@ -1,664 +0,0 @@ -/* 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_TEST_BACKEND_METADATA_CONDITION_GRAMMAR -#define LOOT_TEST_BACKEND_METADATA_CONDITION_GRAMMAR - -#include "backend/error.h" -#include "backend/metadata/condition_grammar.h" -#include "tests/fixtures.h" - -namespace loot { - namespace test { - class ConditionGrammarTest : public SkyrimTest {}; - - typedef ConditionGrammar Grammar; - - TEST_F(ConditionGrammarTest, Constructor) { - EXPECT_NO_THROW(Grammar cg(nullptr)); - - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - - EXPECT_NO_THROW(Grammar cg(&game)); - } - - TEST_F(ConditionGrammarTest, InvalidSyntax) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - - boost::spirit::qi::space_type skipper; - bool eval = false; - bool r = false; - Grammar cg(&game); - - std::string condition("file(foo)"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval), error); - } - - TEST_F(ConditionGrammarTest, EmptyCondition) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - - boost::spirit::qi::space_type skipper; - bool eval = false; - bool r = false; - Grammar cg(&game); - - std::string condition(""); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval), error); - } - - TEST_F(ConditionGrammarTest, FileConditionTrue) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - - boost::spirit::qi::space_type skipper; - bool eval = false; - bool r = false; - Grammar cg(&game); - - std::string condition("file(\"Blank.esm\")"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval); - EXPECT_TRUE(r); - EXPECT_TRUE(eval); - } - - TEST_F(ConditionGrammarTest, FileConditionFalse) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - - boost::spirit::qi::space_type skipper; - bool eval = true; - bool r = false; - Grammar cg(&game); - - std::string condition("file(\"Blank.missing.esm\")"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_FALSE(eval); - } - - TEST_F(ConditionGrammarTest, UnsafePath) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - - boost::spirit::qi::space_type skipper; - bool eval = false; - bool r = false; - Grammar cg(&game); - - std::string condition("file(\"../../Blank.esm\")"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval), error); - } - - TEST_F(ConditionGrammarTest, RegexConditionTrue) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - - boost::spirit::qi::space_type skipper; - bool eval = false; - bool r = false; - Grammar cg(&game); - - std::string condition("regex(\"Blank.+\\.esm\")"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_TRUE(eval); - } - - TEST_F(ConditionGrammarTest, RegexConditionFalse) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - - boost::spirit::qi::space_type skipper; - bool eval = true; - bool r = false; - Grammar cg(&game); - - std::string condition("regex(\"Blank\\.m.+\\.esm\")"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_FALSE(eval); - } - - TEST_F(ConditionGrammarTest, RegexCondition_Subfolder) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - - boost::spirit::qi::space_type skipper; - bool eval = true; - bool r = false; - Grammar cg(&game); - - std::string condition("regex(\"resource\\\\detail\\\\resource\\.txt\")"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_TRUE(eval); - } - - TEST_F(ConditionGrammarTest, ManyConditionTrue) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - - boost::spirit::qi::space_type skipper; - bool eval = false; - bool r = false; - Grammar cg(&game); - - std::string condition("many(\"Blank.+\\.esm\")"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_TRUE(eval); - } - - TEST_F(ConditionGrammarTest, ManyConditionFalse) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - - boost::spirit::qi::space_type skipper; - bool eval = true; - bool r = false; - Grammar cg(&game); - - std::string condition("many(\"Blank\\.esm\")"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_FALSE(eval); - } - - TEST_F(ConditionGrammarTest, ChecksumConditionTrue) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); - - boost::spirit::qi::space_type skipper; - bool eval = false; - bool r = false; - Grammar cg(&game); - - std::string condition("checksum(\"Blank.esp\", 24F0E2A1)"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_TRUE(eval); - } - - TEST_F(ConditionGrammarTest, ChecksumConditionFalse) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); - - boost::spirit::qi::space_type skipper; - bool eval = true; - bool r = false; - Grammar cg(&game); - - std::string condition("checksum(\"Blank.esp\", DEADBEEF)"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_FALSE(eval); - } - - TEST_F(ConditionGrammarTest, VersionConditionEqualTrue) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); - ASSERT_NO_THROW(game.LoadPlugins(true)); - - boost::spirit::qi::space_type skipper; - bool eval = false; - bool r = false; - Grammar cg(&game); - - std::string condition("version(\"Blank.esm\", \"5.0\", ==)"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_TRUE(eval); - } - - TEST_F(ConditionGrammarTest, VersionConditionEqualFalse) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); - ASSERT_NO_THROW(game.LoadPlugins(true)); - - boost::spirit::qi::space_type skipper; - bool eval = true; - bool r = false; - Grammar cg(&game); - - std::string condition("version(\"Blank.esm\", \"6.0\", ==)"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_FALSE(eval); - } - - TEST_F(ConditionGrammarTest, VersionConditionNotEqualTrue) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); - ASSERT_NO_THROW(game.LoadPlugins(true)); - - boost::spirit::qi::space_type skipper; - bool eval = false; - bool r = false; - Grammar cg(&game); - - std::string condition("version(\"Blank.esm\", \"6.0\", !=)"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_TRUE(eval); - } - - TEST_F(ConditionGrammarTest, VersionConditionNotEqualFalse) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); - ASSERT_NO_THROW(game.LoadPlugins(true)); - - boost::spirit::qi::space_type skipper; - bool eval = true; - bool r = false; - Grammar cg(&game); - - std::string condition("version(\"Blank.esm\", \"5.0\", !=)"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_FALSE(eval); - } - - TEST_F(ConditionGrammarTest, VersionConditionLessThanTrue) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); - ASSERT_NO_THROW(game.LoadPlugins(true)); - - boost::spirit::qi::space_type skipper; - bool eval = false; - bool r = false; - Grammar cg(&game); - - std::string condition("version(\"Blank.esm\", \"6.0\", <)"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_TRUE(eval); - } - - TEST_F(ConditionGrammarTest, VersionConditionLessThanFalse) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); - ASSERT_NO_THROW(game.LoadPlugins(true)); - - boost::spirit::qi::space_type skipper; - bool eval = true; - bool r = false; - Grammar cg(&game); - - std::string condition("version(\"Blank.esm\", \"5.0\", <)"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_FALSE(eval); - } - - TEST_F(ConditionGrammarTest, VersionConditionGreaterThanTrue) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); - ASSERT_NO_THROW(game.LoadPlugins(true)); - - boost::spirit::qi::space_type skipper; - bool eval = false; - bool r = false; - Grammar cg(&game); - - std::string condition("version(\"Blank.esm\", \"4.0\", >)"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_TRUE(eval); - } - - TEST_F(ConditionGrammarTest, VersionConditionGreaterThanFalse) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); - ASSERT_NO_THROW(game.LoadPlugins(true)); - - boost::spirit::qi::space_type skipper; - bool eval = true; - bool r = false; - Grammar cg(&game); - - std::string condition("version(\"Blank.esm\", \"5.0\", >)"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_FALSE(eval); - } - - TEST_F(ConditionGrammarTest, VersionConditionLETrue) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); - ASSERT_NO_THROW(game.LoadPlugins(true)); - - boost::spirit::qi::space_type skipper; - bool eval = false; - bool r = false; - Grammar cg(&game); - - std::string condition("version(\"Blank.esm\", \"5.0\", <=)"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_TRUE(eval); - } - - TEST_F(ConditionGrammarTest, VersionConditionLEFalse) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); - ASSERT_NO_THROW(game.LoadPlugins(true)); - - boost::spirit::qi::space_type skipper; - bool eval = true; - bool r = false; - Grammar cg(&game); - - std::string condition("version(\"Blank.esm\", \"4.0\", <=)"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_FALSE(eval); - } - - TEST_F(ConditionGrammarTest, VersionConditionGETrue) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); - ASSERT_NO_THROW(game.LoadPlugins(true)); - - boost::spirit::qi::space_type skipper; - bool eval = false; - bool r = false; - Grammar cg(&game); - - std::string condition("version(\"Blank.esm\", \"5.0\", >=)"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_TRUE(eval); - } - - TEST_F(ConditionGrammarTest, VersionConditionGEFalse) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.LoadPlugins(true)); - - boost::spirit::qi::space_type skipper; - bool eval = true; - bool r = false; - Grammar cg(&game); - - std::string condition("version(\"Blank.esm\", \"6.0\", >=)"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_FALSE(eval); - } - - TEST_F(ConditionGrammarTest, ActiveConditionTrue) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); - - boost::spirit::qi::space_type skipper; - bool eval = false; - bool r = false; - Grammar cg(&game); - - std::string condition("active(\"Blank.esm\")"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_TRUE(eval); - } - - TEST_F(ConditionGrammarTest, ActiveConditionFalse) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); - - boost::spirit::qi::space_type skipper; - bool eval = true; - bool r = false; - Grammar cg(&game); - - std::string condition("active(\"Blank.esp\")"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_FALSE(eval); - } - - TEST_F(ConditionGrammarTest, NegatorTrue) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - - boost::spirit::qi::space_type skipper; - bool eval = false; - bool r = false; - Grammar cg(&game); - - std::string condition("not file(\"Blank.missing.esm\")"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_TRUE(eval); - } - - TEST_F(ConditionGrammarTest, NegatorFalse) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - - boost::spirit::qi::space_type skipper; - bool eval = true; - bool r = false; - Grammar cg(&game); - - std::string condition("not file(\"Blank.esm\")"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_FALSE(eval); - } - - TEST_F(ConditionGrammarTest, CompoundAndTrue) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - - boost::spirit::qi::space_type skipper; - bool eval = true; - bool r = false; - Grammar cg(&game); - - std::string condition("file(\"Blank.esm\") and file(\"Blank.esp\")"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_TRUE(eval); - } - - TEST_F(ConditionGrammarTest, CompoundAndFalse) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - - boost::spirit::qi::space_type skipper; - bool eval = true; - bool r = false; - Grammar cg(&game); - - std::string condition("file(\"Blank.esm\") and file(\"Blank.missing.esp\")"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_FALSE(eval); - } - - TEST_F(ConditionGrammarTest, CompoundOrTrue) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - - boost::spirit::qi::space_type skipper; - bool eval = true; - bool r = false; - Grammar cg(&game); - - std::string condition("file(\"Blank.missing.esm\") or file(\"Blank.esp\")"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_TRUE(eval); - } - - TEST_F(ConditionGrammarTest, CompoundOrFalse) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - - boost::spirit::qi::space_type skipper; - bool eval = true; - bool r = false; - Grammar cg(&game); - - std::string condition("file(\"Blank.missing.esm\") or file(\"Blank.missing.esp\")"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_FALSE(eval); - } - - TEST_F(ConditionGrammarTest, OrderOfEvaluation) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - - boost::spirit::qi::space_type skipper; - bool eval = true; - bool r = false; - Grammar cg(&game); - - std::string condition("file(\"Blank.esm\") and ( not file(\"Blank.esm\") or file(\"Blank.esp\") ) or file(\"Blank.missing.esp\")"); - std::string::const_iterator begin = condition.begin(); - std::string::const_iterator end = condition.end(); - - EXPECT_NO_THROW(r = boost::spirit::qi::phrase_parse(begin, end, cg, skipper, eval)); - EXPECT_TRUE(r); - EXPECT_TRUE(eval); - } - } -} - -#endif diff --git a/src/tests/main.cpp b/src/tests/main.cpp index 0ce51e9c..21e5e72f 100644 --- a/src/tests/main.cpp +++ b/src/tests/main.cpp @@ -50,7 +50,7 @@ #include "backend/helpers/language_test.h" #include "backend/helpers/version_test.h" #include "backend/helpers/yaml_set_helpers_test.h" -#include "backend/metadata/test_condition_grammar.h" +#include "backend/metadata/condition_grammar_test.h" #include "backend/metadata/test_conditional_metadata.h" #include "backend/metadata/test_file.h" #include "backend/metadata/test_location.h" From 86f17a275176bd21e63f7351192cfc36074f6575 Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Thu, 24 Mar 2016 17:48:00 +0000 Subject: [PATCH 17/38] Improve ConditionalMetadata tests --- CMakeLists.txt | 2 +- .../metadata/conditional_metadata_test.h | 122 ++++++++++++++++++ .../metadata/test_conditional_metadata.h | 90 ------------- src/tests/main.cpp | 2 +- 4 files changed, 124 insertions(+), 92 deletions(-) create mode 100644 src/tests/backend/metadata/conditional_metadata_test.h delete mode 100644 src/tests/backend/metadata/test_conditional_metadata.h diff --git a/CMakeLists.txt b/CMakeLists.txt index c6d60e2b..2efc94d4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -245,7 +245,7 @@ set (LOOT_TESTS_HEADERS "${CMAKE_SOURCE_DIR}/src/tests/base_game_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/helpers/version_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/helpers/yaml_set_helpers_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/condition_grammar_test.h" - "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/test_conditional_metadata.h" + "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/conditional_metadata_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/test_file.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/test_location.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/test_message.h" diff --git a/src/tests/backend/metadata/conditional_metadata_test.h b/src/tests/backend/metadata/conditional_metadata_test.h new file mode 100644 index 00000000..d718934c --- /dev/null +++ b/src/tests/backend/metadata/conditional_metadata_test.h @@ -0,0 +1,122 @@ +/* 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_TEST_BACKEND_METADATA_CONDITIONAL_METADATA +#define LOOT_TEST_BACKEND_METADATA_CONDITIONAL_METADATA + +#include "backend/error.h" +#include "backend/metadata/conditional_metadata.h" +#include "tests/base_game_test.h" + +namespace loot { + namespace test { + class ConditionalMetadataTest : public BaseGameTest { + protected: + ConditionalMetadata conditionalMetadata; + }; + + // Pass an empty first argument, as it's a prefix for the test instantation, + // but we only have the one so no prefix is necessary. + INSTANTIATE_TEST_CASE_P(, + ConditionalMetadataTest, + ::testing::Values( + GameSettings::tes4, + GameSettings::tes5, + GameSettings::fo3, + GameSettings::fonv, + GameSettings::fo4)); + + TEST_P(ConditionalMetadataTest, defaultConstructorShouldSetEmptyConditionString) { + EXPECT_TRUE(conditionalMetadata.Condition().empty()); + } + + TEST_P(ConditionalMetadataTest, stringConstructorShouldSetConditionToGivenString) { + std::string condition("condition"); + conditionalMetadata = ConditionalMetadata(condition); + + EXPECT_EQ(condition, conditionalMetadata.Condition()); + } + + TEST_P(ConditionalMetadataTest, isConditionalShouldBeFalseForAnEmptyConditionString) { + EXPECT_FALSE(conditionalMetadata.IsConditional()); + } + + TEST_P(ConditionalMetadataTest, isConditionalShouldBeTrueForANonEmptyConditionString) { + conditionalMetadata = ConditionalMetadata("condition"); + EXPECT_TRUE(conditionalMetadata.IsConditional()); + } + + TEST_P(ConditionalMetadataTest, evalConditionShouldReturnTrueForAnEmptyCondition) { + Game game(GetParam()); + game.SetGamePath(dataPath.parent_path()); + + EXPECT_TRUE(conditionalMetadata.EvalCondition(game)); + } + + TEST_P(ConditionalMetadataTest, evalConditionShouldThrowForAnInvalidCondition) { + Game game(GetParam()); + game.SetGamePath(dataPath.parent_path()); + + conditionalMetadata = ConditionalMetadata("condition"); + EXPECT_THROW(conditionalMetadata.EvalCondition(game), error); + } + + TEST_P(ConditionalMetadataTest, evalConditionShouldReturnTrueForAConditionThatIsTrue) { + Game game(GetParam()); + game.SetGamePath(dataPath.parent_path()); + + conditionalMetadata = ConditionalMetadata("file(\"" + blankEsm + "\")"); + EXPECT_TRUE(conditionalMetadata.EvalCondition(game)); + } + + TEST_P(ConditionalMetadataTest, evalConditionShouldReturnFalseForAConditionThatIsFalse) { + Game game(GetParam()); + game.SetGamePath(dataPath.parent_path()); + + conditionalMetadata = ConditionalMetadata("file(\"" + missingEsp + "\")"); + EXPECT_FALSE(conditionalMetadata.EvalCondition(game)); + } + + TEST_P(ConditionalMetadataTest, parseConditionShouldNotThrowForAnEmptyCondition) { + EXPECT_NO_THROW(conditionalMetadata.ParseCondition()); + } + + TEST_P(ConditionalMetadataTest, parseConditionShouldThrowForAnInvalidCondition) { + conditionalMetadata = ConditionalMetadata("condition"); + EXPECT_THROW(conditionalMetadata.ParseCondition(), error); + } + + TEST_P(ConditionalMetadataTest, parseConditionShouldNotThrowForATrueCondition) { + conditionalMetadata = ConditionalMetadata("file(\"" + blankEsm + "\")"); + EXPECT_NO_THROW(conditionalMetadata.ParseCondition()); + } + + TEST_P(ConditionalMetadataTest, parseConditionShouldNotThrowForAFalseCondition) { + conditionalMetadata = ConditionalMetadata("file(\"" + missingEsp + "\")"); + EXPECT_NO_THROW(conditionalMetadata.ParseCondition()); + } + } +} + +#endif diff --git a/src/tests/backend/metadata/test_conditional_metadata.h b/src/tests/backend/metadata/test_conditional_metadata.h deleted file mode 100644 index e3c9b317..00000000 --- a/src/tests/backend/metadata/test_conditional_metadata.h +++ /dev/null @@ -1,90 +0,0 @@ -/* 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_TEST_BACKEND_METADATA_CONDITIONAL_METADATA -#define LOOT_TEST_BACKEND_METADATA_CONDITION_GRAMMAR - -#include "backend/error.h" -#include "backend/metadata/conditional_metadata.h" -#include "tests/fixtures.h" - -namespace loot { - namespace test { - class ConditionalMetadataTest : public SkyrimTest {}; - - TEST_F(ConditionalMetadataTest, ConstructorAndDataAccess) { - ConditionalMetadata cm; - EXPECT_EQ("", cm.Condition()); - - cm = ConditionalMetadata("condition"); - EXPECT_EQ("condition", cm.Condition()); - } - - TEST_F(ConditionalMetadataTest, IsConditional) { - ConditionalMetadata cm; - EXPECT_FALSE(cm.IsConditional()); - - cm = ConditionalMetadata("condition"); - EXPECT_TRUE(cm.IsConditional()); - } - - TEST_F(ConditionalMetadataTest, EvalCondition) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); - - ConditionalMetadata cm; - EXPECT_TRUE(cm.EvalCondition(game)); - - cm = ConditionalMetadata("condition"); - EXPECT_THROW(cm.EvalCondition(game), error); - - cm = ConditionalMetadata("file(\"Blank.esm\")"); - EXPECT_TRUE(cm.EvalCondition(game)); - - cm = ConditionalMetadata("file(\"Blank.missing.esm\")"); - EXPECT_FALSE(cm.EvalCondition(game)); - } - - TEST_F(ConditionalMetadataTest, ParseCondition) { - ConditionalMetadata cm; - EXPECT_NO_THROW(cm.ParseCondition()); - - cm = ConditionalMetadata("condition"); - EXPECT_THROW(cm.ParseCondition(), error); - - // Check that invalid regex also throws. - cm = ConditionalMetadata("regex(\"RagnvaldBook(Farengar(+Ragnvald)?)?\\.esp\")"); - EXPECT_THROW(cm.ParseCondition(), error); - - cm = ConditionalMetadata("file(\"Blank.esm\")"); - EXPECT_NO_THROW(cm.ParseCondition()); - - cm = ConditionalMetadata("file(\"Blank.missing.esm\")"); - EXPECT_NO_THROW(cm.ParseCondition()); - } - } -} - -#endif diff --git a/src/tests/main.cpp b/src/tests/main.cpp index 21e5e72f..2b6621b1 100644 --- a/src/tests/main.cpp +++ b/src/tests/main.cpp @@ -51,7 +51,7 @@ #include "backend/helpers/version_test.h" #include "backend/helpers/yaml_set_helpers_test.h" #include "backend/metadata/condition_grammar_test.h" -#include "backend/metadata/test_conditional_metadata.h" +#include "backend/metadata/conditional_metadata_test.h" #include "backend/metadata/test_file.h" #include "backend/metadata/test_location.h" #include "backend/metadata/test_message.h" From 06d7a4b31bd3804a4cafc2f395f72d19895167e8 Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Thu, 24 Mar 2016 19:05:21 +0000 Subject: [PATCH 18/38] Improve File tests --- CMakeLists.txt | 2 +- src/tests/backend/metadata/file_test.h | 186 +++++++++++++++++++++++++ src/tests/backend/metadata/test_file.h | 180 ------------------------ src/tests/main.cpp | 2 +- 4 files changed, 188 insertions(+), 182 deletions(-) create mode 100644 src/tests/backend/metadata/file_test.h delete mode 100644 src/tests/backend/metadata/test_file.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 2efc94d4..3bcf781b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -246,7 +246,7 @@ set (LOOT_TESTS_HEADERS "${CMAKE_SOURCE_DIR}/src/tests/base_game_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/helpers/yaml_set_helpers_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/condition_grammar_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/conditional_metadata_test.h" - "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/test_file.h" + "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/file_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/test_location.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/test_message.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/test_message_content.h" diff --git a/src/tests/backend/metadata/file_test.h b/src/tests/backend/metadata/file_test.h new file mode 100644 index 00000000..0b54013e --- /dev/null +++ b/src/tests/backend/metadata/file_test.h @@ -0,0 +1,186 @@ +/* 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_TEST_BACKEND_METADATA_FILE +#define LOOT_TEST_BACKEND_METADATA_FILE + +#include "backend/metadata/file.h" + +#include + +namespace loot { + namespace test { + TEST(File, defaultConstructorShouldInitialiseEmptyStrings) { + File file; + + EXPECT_EQ("", file.Name()); + EXPECT_EQ("", file.DisplayName()); + EXPECT_EQ("", file.Condition()); + } + + TEST(File, stringsConstructorShouldStoreGivenStrings) { + File file("name", "display", "condition"); + + EXPECT_EQ("name", file.Name()); + EXPECT_EQ("display", file.DisplayName()); + EXPECT_EQ("condition", file.Condition()); + } + + TEST(File, filesWithCaseInsensitiveEqualNameStringsShouldBeEqual) { + File file1("name", "display1", "condition1"); + File file2("Name", "display2", "condition2"); + + EXPECT_TRUE(file1 == file2); + } + + TEST(File, filesWithDifferentNamesShouldBeUnequal) { + File file1("name1"); + File file2("name2"); + + EXPECT_FALSE(file1 == file2); + } + + TEST(File, lessThanOperatorShouldUseCaseInsensitiveLexicographicalNameComparison) { + File file1("name", "display1", "condition1"); + File file2("Name", "display2", "condition2"); + + EXPECT_FALSE(file1 < file2); + EXPECT_FALSE(file2 < file1); + + file1 = File("name1"); + file2 = File("name2"); + + EXPECT_TRUE(file1 < file2); + EXPECT_FALSE(file2 < file1); + } + + TEST(File, emittingAsYamlShouldSingleQuoteValues) { + File file("name1", "display1", "condition1"); + YAML::Emitter emitter; + emitter << file; + std::string expected = "name: '" + file.Name() + + "'\ncondition: '" + file.Condition() + + "'\ndisplay: '" + file.DisplayName() + "'"; + + EXPECT_EQ(expected, emitter.c_str()); + } + + TEST(File, emittingAsYamlShouldOutputAsAScalarIfOnlyTheNameStringIsNotEmpty) { + File file("name1"); + YAML::Emitter emitter; + emitter << file; + + EXPECT_EQ("'" + file.Name() + "'", emitter.c_str()); + } + + TEST(File, emittingAsYamlShouldOmitDisplayFieldIfItMatchesTheNameField) { + File file("name1", "name1"); + YAML::Emitter emitter; + emitter << file; + + EXPECT_EQ("'" + file.Name() + "'", emitter.c_str()); + } + + TEST(File, emittingAsYamlShouldOmitAnEmptyConditionString) { + File file("name1", "display1"); + YAML::Emitter emitter; + emitter << file; + std::string expected = "name: '" + file.Name() + + "'\ndisplay: '" + file.DisplayName() + "'"; + + EXPECT_EQ(expected, emitter.c_str()); + } + + TEST(File, encodingAsYamlShouldStoreDataCorrectly) { + File file("name1", "display1", "condition1"); + YAML::Node node; + node = file; + + EXPECT_EQ(file.Name(), node["name"].as()); + EXPECT_EQ(file.DisplayName(), node["display"].as()); + EXPECT_EQ(file.Condition(), node["condition"].as()); + } + + TEST(File, encodingAsYamlShouldOmitEmptyFields) { + File file("name1"); + YAML::Node node; + node = file; + + EXPECT_EQ(file.Name(), node["name"].as()); + EXPECT_FALSE(node["display"]); + EXPECT_FALSE(node["condition"]); + } + + TEST(File, encodingAsYamlShouldOmitDisplayFieldIfItMatchesTheNameField) { + File file("name1", "name1"); + YAML::Node node; + node = file; + + EXPECT_EQ(file.Name(), node["name"].as()); + EXPECT_FALSE(node["display"]); + EXPECT_FALSE(node["condition"]); + } + + TEST(File, decodingFromYamlShouldSetDataCorrectly) { + YAML::Node node = YAML::Load("{name: name1, display: display1, condition: 'file(\"Foo.esp\")'}"); + File file = node.as(); + + EXPECT_EQ(node["name"].as(), file.Name()); + EXPECT_EQ(node["display"].as(), file.DisplayName()); + EXPECT_EQ(node["condition"].as(), file.Condition()); + } + + TEST(File, decodingFromYamlWithMissingConditionFieldShouldLeaveConditionStringEmpty) { + YAML::Node node = YAML::Load("{name: name1, display: display1}"); + File file = node.as(); + + EXPECT_EQ(node["name"].as(), file.Name()); + EXPECT_EQ(node["display"].as(), file.DisplayName()); + EXPECT_TRUE(file.Condition().empty()); + } + + TEST(File, decodingFromYamlScalarShouldUseNameValueForDisplayNameAndLeaveConditionEmpty) { + YAML::Node node = YAML::Load("name1"); + File file = node.as(); + + EXPECT_EQ(node.as(), file.Name()); + EXPECT_EQ(node.as(), file.DisplayName()); + EXPECT_TRUE(file.Condition().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_ANY_THROW(node.as()); + } + } +} + +#endif diff --git a/src/tests/backend/metadata/test_file.h b/src/tests/backend/metadata/test_file.h deleted file mode 100644 index d9addd36..00000000 --- a/src/tests/backend/metadata/test_file.h +++ /dev/null @@ -1,180 +0,0 @@ -/* 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_TEST_BACKEND_METADATA_FILE -#define LOOT_TEST_BACKEND_METADATA_FILE - -#include "backend/metadata/file.h" -#include "tests/fixtures.h" - -namespace loot { - namespace test { - TEST(File, ConstructorsAndDataAccess) { - File file; - EXPECT_EQ("", file.Name()); - EXPECT_EQ("", file.DisplayName()); - EXPECT_EQ("", file.Condition()); - - file = File("name"); - EXPECT_EQ("name", file.Name()); - EXPECT_EQ("name", file.DisplayName()); - EXPECT_EQ("", file.Condition()); - - file = File("name", "display"); - EXPECT_EQ("name", file.Name()); - EXPECT_EQ("display", file.DisplayName()); - EXPECT_EQ("", file.Condition()); - - // Not a valid condition, but not evaluating it in this test. - file = File("name", "display", "condition"); - EXPECT_EQ("name", file.Name()); - EXPECT_EQ("display", file.DisplayName()); - EXPECT_EQ("condition", file.Condition()); - } - - TEST(File, EqualityOperator) { - File file1, file2; - EXPECT_TRUE(file1 == file2); - - // Not valid conditions, but not evaluating them in this test. - file1 = File("name", "display1", "condition1"); - file2 = File("name", "display2", "condition2"); - EXPECT_TRUE(file1 == file2); - - file1 = File("name1"); - file2 = File("name2"); - EXPECT_FALSE(file1 == file2); - } - - TEST(File, LessThanOperator) { - File file1, file2; - EXPECT_FALSE(file1 < file2); - EXPECT_FALSE(file2 < file1); - - file1 = File("name", "display1", "condition1"); - file2 = File("name", "display2", "condition2"); - EXPECT_FALSE(file1 < file2); - EXPECT_FALSE(file2 < file1); - - file1 = File("name1"); - file2 = File("name2"); - EXPECT_TRUE(file1 < file2); - EXPECT_FALSE(file2 < file1); - } - - TEST(File, YamlEmitter) { - File file("name1", "display1", "condition1"); - - YAML::Emitter e1; - e1 << file; - EXPECT_STREQ("name: 'name1'\ncondition: 'condition1'\ndisplay: 'display1'", e1.c_str()); - - file = File("name1"); - YAML::Emitter e2; - e2 << file; - EXPECT_STREQ("'name1'", e2.c_str()); - - file = File("name1", "", "condition1"); - YAML::Emitter e3; - e3 << file; - EXPECT_STREQ("name: 'name1'\ncondition: 'condition1'", e3.c_str()); - - file = File("name1", "display1"); - YAML::Emitter e4; - e4 << file; - EXPECT_STREQ("name: 'name1'\ndisplay: 'display1'", e4.c_str()); - - file = File("name1", "name1"); - YAML::Emitter e5; - e5 << file; - EXPECT_STREQ("'name1'", e5.c_str()); - - file = File("name1", "name1", "condition1"); - YAML::Emitter e6; - e6 << file; - EXPECT_STREQ("name: 'name1'\ncondition: 'condition1'", e6.c_str()); - } - - TEST(File, YamlEncode) { - File file("name1", "display1", "condition1"); - YAML::Node node; - node = file; - EXPECT_EQ("name1", node["name"].as()); - EXPECT_EQ("display1", node["display"].as()); - EXPECT_EQ("condition1", node["condition"].as()); - - file = File("name1"); - node = file; - EXPECT_EQ("name1", node["name"].as()); - EXPECT_FALSE(node["display"]); - EXPECT_FALSE(node["condition"]); - - file = File("name1", "name1"); - node = file; - EXPECT_EQ("name1", node["name"].as()); - EXPECT_FALSE(node["display"]); - EXPECT_FALSE(node["condition"]); - - file = File("name1", "display1"); - node = file; - EXPECT_EQ("name1", node["name"].as()); - EXPECT_EQ("display1", node["display"].as()); - EXPECT_FALSE(node["condition"]); - } - - TEST(File, YamlDecode) { - YAML::Node node = YAML::Load("{name: name1, display: display1, condition: 'file(\"Foo.esp\")'}"); - File file = node.as(); - EXPECT_EQ("name1", file.Name()); - EXPECT_EQ("display1", file.DisplayName()); - EXPECT_EQ("file(\"Foo.esp\")", file.Condition()); - - node = YAML::Load("name1"); - file = node.as(); - EXPECT_EQ("name1", file.Name()); - EXPECT_EQ("name1", file.DisplayName()); - EXPECT_EQ("", file.Condition()); - - node = YAML::Load("{name: name1, display: display1}"); - file = node.as(); - EXPECT_EQ("name1", file.Name()); - EXPECT_EQ("display1", file.DisplayName()); - EXPECT_EQ("", file.Condition()); - - node = YAML::Load("{name: name1, condition: 'file(\"Foo.esp\")'}"); - file = node.as(); - EXPECT_EQ("name1", file.Name()); - EXPECT_EQ("name1", file.DisplayName()); - EXPECT_EQ("file(\"Foo.esp\")", file.Condition()); - - node = YAML::Load("{name: name1, condition: invalid}"); - EXPECT_THROW(node.as(), YAML::RepresentationException); - - node = YAML::Load("[0, 1, 2]"); - EXPECT_ANY_THROW(node.as()); - } - } -} - -#endif diff --git a/src/tests/main.cpp b/src/tests/main.cpp index 2b6621b1..9c03dfdf 100644 --- a/src/tests/main.cpp +++ b/src/tests/main.cpp @@ -52,7 +52,7 @@ #include "backend/helpers/yaml_set_helpers_test.h" #include "backend/metadata/condition_grammar_test.h" #include "backend/metadata/conditional_metadata_test.h" -#include "backend/metadata/test_file.h" +#include "backend/metadata/file_test.h" #include "backend/metadata/test_location.h" #include "backend/metadata/test_message.h" #include "backend/metadata/test_message_content.h" From fc12632b55e659b7dcbf8f91a3da2a50495117bd Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Thu, 24 Mar 2016 19:14:49 +0000 Subject: [PATCH 19/38] Remove unnecessary Location constructor --- src/backend/metadata/location.cpp | 2 -- src/backend/metadata/location.h | 3 +-- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/backend/metadata/location.cpp b/src/backend/metadata/location.cpp index 16f97619..ce68a6d3 100644 --- a/src/backend/metadata/location.cpp +++ b/src/backend/metadata/location.cpp @@ -31,8 +31,6 @@ using namespace std; namespace loot { Location::Location() {} - Location::Location(const std::string& url) : _url(url) {} - Location::Location(const std::string& url, const std::string& name) : _url(url), _name(name) {} bool Location::operator < (const Location& rhs) const { diff --git a/src/backend/metadata/location.h b/src/backend/metadata/location.h index 7a2adb91..080d2880 100644 --- a/src/backend/metadata/location.h +++ b/src/backend/metadata/location.h @@ -33,8 +33,7 @@ namespace loot { class Location { public: Location(); - Location(const std::string& url); - Location(const std::string& url, const std::string& name); + Location(const std::string& url, const std::string& name = ""); bool operator < (const Location& rhs) const; bool operator == (const Location& rhs) const; From 7c61d1221083fe745f9e872bb300d185e2d9982f Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Thu, 24 Mar 2016 20:23:55 +0000 Subject: [PATCH 20/38] Improve Location tests --- CMakeLists.txt | 2 +- src/tests/backend/metadata/location_test.h | 134 +++++++++++++++++++++ src/tests/backend/metadata/test_location.h | 129 -------------------- src/tests/main.cpp | 2 +- 4 files changed, 136 insertions(+), 131 deletions(-) create mode 100644 src/tests/backend/metadata/location_test.h delete mode 100644 src/tests/backend/metadata/test_location.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 3bcf781b..5d822b72 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -247,7 +247,7 @@ set (LOOT_TESTS_HEADERS "${CMAKE_SOURCE_DIR}/src/tests/base_game_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/condition_grammar_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/conditional_metadata_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/file_test.h" - "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/test_location.h" + "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/location_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/test_message.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/test_message_content.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/test_plugin_dirty_info.h" diff --git a/src/tests/backend/metadata/location_test.h b/src/tests/backend/metadata/location_test.h new file mode 100644 index 00000000..7fc6d6e9 --- /dev/null +++ b/src/tests/backend/metadata/location_test.h @@ -0,0 +1,134 @@ +/* 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_TEST_BACKEND_METADATA_LOCATION +#define LOOT_TEST_BACKEND_METADATA_LOCATION + +#include "backend/metadata/location.h" + +#include + +namespace loot { + namespace test { + TEST(Location, defaultConstructorShouldInitialiseEmptyStrings) { + Location location; + + EXPECT_EQ("", location.URL()); + EXPECT_EQ("", location.Name()); + } + + TEST(Location, stringsConstructorShouldStoreGivenStrings) { + Location location("http://www.example.com", "example"); + + EXPECT_EQ("http://www.example.com", location.URL()); + EXPECT_EQ("example", location.Name()); + } + + TEST(Location, locationsWithCaseInsensitiveEqualUrlsShouldBeEqual) { + Location location1("http://www.example.com", "example1"); + Location location2("HTTP://WWW.EXAMPLE.COM", "example2"); + + EXPECT_TRUE(location1 == location2); + } + + TEST(Location, locationsWithDifferentUrlsShouldBeUnequal) { + Location location1("http://www.example1.com"); + Location location2("http://www.example2.com"); + + EXPECT_FALSE(location1 == location2); + } + + TEST(Location, lessThanOperatorShouldUseCaseInsensitiveLexicographicalUrlComparison) { + Location location1("http://www.example.com", "example1"); + Location location2("HTTP://WWW.EXAMPLE.COM", "example2"); + + EXPECT_FALSE(location1 < location2); + EXPECT_FALSE(location2 < location1); + + location1 = Location("http://www.example1.com"); + location2 = Location("http://www.example2.com"); + + EXPECT_TRUE(location1 < location2); + EXPECT_FALSE(location2 < location1); + } + + TEST(Location, emittingAsYamlShouldOutputAScalarIfTheNameStringIsEmpty) { + Location location("http://www.example.com"); + YAML::Emitter emitter; + emitter << location; + + EXPECT_EQ("'" + location.URL() + "'", emitter.c_str()); + } + + TEST(Location, emittingAsYamlShouldOutputAMapIfTheNameStringIsNotEmpty) { + Location location("http://www.example.com", "example"); + YAML::Emitter emitter; + emitter << location; + + EXPECT_EQ("link: '" + location.URL() + "'\nname: '" + location.Name() + "'", emitter.c_str()); + } + + TEST(Location, encodingAsYamlShouldStoreDataCorrectly) { + Location location("http://www.example.com", "example"); + YAML::Node node; + node = location; + + EXPECT_EQ(location.URL(), node["link"].as()); + EXPECT_EQ(location.Name(), node["name"].as()); + } + + TEST(Location, encodingAsYamlShouldOmitEmptyFields) { + Location location("http://www.example.com"); + YAML::Node node; + node = location; + + EXPECT_EQ(location.URL(), 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.URL()); + EXPECT_EQ(node["name"].as(), location.Name()); + } + + TEST(Location, decodingFromYamlScalarShouldSetUrlToScalarValueAndLeaveNameEmpty) { + YAML::Node node = YAML::Load("http://www.example.com"); + Location location = node.as(); + + EXPECT_EQ(node.as(), location.URL()); + EXPECT_TRUE(location.Name().empty()); + } + + TEST(Location, decodingFromYamlShouldThrowIfAListIsGiven) { + YAML::Node node = YAML::Load("[0, 1, 2]"); + + EXPECT_ANY_THROW(node.as()); + } + } +} + +#endif diff --git a/src/tests/backend/metadata/test_location.h b/src/tests/backend/metadata/test_location.h deleted file mode 100644 index f822f51e..00000000 --- a/src/tests/backend/metadata/test_location.h +++ /dev/null @@ -1,129 +0,0 @@ -/* 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_TEST_BACKEND_METADATA_LOCATION -#define LOOT_TEST_BACKEND_METADATA_LOCATION - -#include "backend/metadata/location.h" -#include "tests/fixtures.h" - -namespace loot { - namespace test { - TEST(Location, ConstructorsAndDataAccess) { - Location loc; - EXPECT_EQ("", loc.URL()); - - loc = Location("http://www.example.com"); - EXPECT_EQ("http://www.example.com", loc.URL()); - - loc = Location("http://www.example.com", "example"); - EXPECT_EQ("http://www.example.com", loc.URL()); - EXPECT_EQ("example", loc.Name()); - } - - TEST(Location, EqualityOperator) { - Location loc1, loc2; - EXPECT_TRUE(loc1 == loc2); - - loc1 = Location("http://www.example.com"); - loc2 = Location("HTTP://WWW.EXAMPLE.COM"); - EXPECT_TRUE(loc1 == loc2); - - loc1 = Location("http://www.example.com", "example1"); - loc2 = Location("http://www.example.com", "example2"); - EXPECT_TRUE(loc1 == loc2); - - loc1 = Location("http://www.example1.com"); - loc2 = Location("http://www.example2.com"); - EXPECT_FALSE(loc1 == loc2); - } - - TEST(Location, LessThanOperator) { - Location loc1, loc2; - EXPECT_FALSE(loc1 < loc2); - EXPECT_FALSE(loc2 < loc1); - - loc1 = Location("http://www.example.com"); - loc2 = Location("HTTP://WWW.EXAMPLE.COM"); - EXPECT_FALSE(loc1 < loc2); - EXPECT_FALSE(loc2 < loc1); - - loc1 = Location("http://www.example.com", "example1"); - loc2 = Location("http://www.example.com", "example2"); - EXPECT_FALSE(loc1 < loc2); - EXPECT_FALSE(loc2 < loc1); - - loc1 = Location("http://www.example1.com"); - loc2 = Location("http://www.example2.com"); - EXPECT_TRUE(loc1 < loc2); - EXPECT_FALSE(loc2 < loc1); - } - - TEST(Location, YamlEmitter) { - Location loc("http://www.example.com"); - YAML::Emitter e1; - e1 << loc; - EXPECT_STREQ("'http://www.example.com'", e1.c_str()); - - loc = Location("http://www.example.com", "example"); - YAML::Emitter e2; - e2 << loc; - EXPECT_STREQ("link: 'http://www.example.com'\nname: 'example'", e2.c_str()); - } - - TEST(Location, YamlEncode) { - YAML::Node node; - - Location loc("http://www.example.com"); - node = loc; - EXPECT_EQ("http://www.example.com", node["link"].as()); - EXPECT_FALSE(node["name"]); - - loc = Location("http://www.example.com", "example"); - node = loc; - EXPECT_EQ("http://www.example.com", node["link"].as()); - EXPECT_EQ("example", node["name"].as()); - } - - TEST(Location, YamlDecode) { - YAML::Node node; - Location loc; - - node = YAML::Load("http://www.example.com"); - loc = node.as(); - EXPECT_EQ("http://www.example.com", loc.URL()); - EXPECT_EQ("", loc.Name()); - - node = YAML::Load("{link: http://www.example.com, name: example}"); - loc = node.as(); - EXPECT_EQ("http://www.example.com", loc.URL()); - EXPECT_EQ("example", loc.Name()); - - node = YAML::Load("[0, 1, 2]"); - EXPECT_ANY_THROW(node.as()); - } - } -} - -#endif diff --git a/src/tests/main.cpp b/src/tests/main.cpp index 9c03dfdf..7d4aab65 100644 --- a/src/tests/main.cpp +++ b/src/tests/main.cpp @@ -53,7 +53,7 @@ #include "backend/metadata/condition_grammar_test.h" #include "backend/metadata/conditional_metadata_test.h" #include "backend/metadata/file_test.h" -#include "backend/metadata/test_location.h" +#include "backend/metadata/location_test.h" #include "backend/metadata/test_message.h" #include "backend/metadata/test_message_content.h" #include "backend/metadata/test_plugin_dirty_info.h" From 3402e84a406a0301f581d81306265ba4ab3b56e5 Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Thu, 24 Mar 2016 23:49:21 +0000 Subject: [PATCH 21/38] Explicitly bump to C++14 to fix GCC error --- CMakeLists.txt | 4 +- .../backend/metadata/condition_grammar_test.h | 148 +++++++++--------- 2 files changed, 76 insertions(+), 76 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5d822b72..1152fc1b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -305,8 +305,8 @@ ENDIF () # GCC and MinGW settings. IF (CMAKE_COMPILER_IS_GNUCXX) - set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3 -std=c++11") - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -std=c++11") + set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3 -std=c++14") + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -std=c++14") IF (PROJECT_STATIC_RUNTIME) set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libstdc++ -static-libgcc") set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -static-libstdc++ -static-libgcc") diff --git a/src/tests/backend/metadata/condition_grammar_test.h b/src/tests/backend/metadata/condition_grammar_test.h index bb0def0b..c2ae7398 100644 --- a/src/tests/backend/metadata/condition_grammar_test.h +++ b/src/tests/backend/metadata/condition_grammar_test.h @@ -80,8 +80,8 @@ namespace loot { Grammar grammar(nullptr); std::string condition("file(foo)"); - EXPECT_THROW(boost::spirit::qi::phrase_parse(std::begin(condition), - std::end(condition), + EXPECT_THROW(boost::spirit::qi::phrase_parse(std::cbegin(condition), + std::cend(condition), grammar, skipper, result), error); @@ -91,8 +91,8 @@ namespace loot { Grammar grammar(&game); std::string condition("file(foo)"); - EXPECT_THROW(boost::spirit::qi::phrase_parse(std::begin(condition), - std::end(condition), + EXPECT_THROW(boost::spirit::qi::phrase_parse(std::cbegin(condition), + std::cend(condition), grammar, skipper, result), error); @@ -102,8 +102,8 @@ namespace loot { Grammar grammar(nullptr); std::string condition(""); - EXPECT_THROW(boost::spirit::qi::phrase_parse(std::begin(condition), - std::end(condition), + EXPECT_THROW(boost::spirit::qi::phrase_parse(std::cbegin(condition), + std::cend(condition), grammar, skipper, result), error); @@ -113,8 +113,8 @@ namespace loot { Grammar grammar(&game); std::string condition(""); - EXPECT_THROW(boost::spirit::qi::phrase_parse(std::begin(condition), - std::end(condition), + EXPECT_THROW(boost::spirit::qi::phrase_parse(std::cbegin(condition), + std::cend(condition), grammar, skipper, result), error); @@ -124,8 +124,8 @@ namespace loot { Grammar grammar(&game); std::string condition("file(\"" + blankEsm + "\")"); - success = boost::spirit::qi::phrase_parse(std::begin(condition), - std::end(condition), + success = boost::spirit::qi::phrase_parse(std::cbegin(condition), + std::cend(condition), grammar, skipper, result); @@ -137,8 +137,8 @@ namespace loot { Grammar grammar(&game); std::string condition("file(\"" + missingEsp + "\")"); - success = boost::spirit::qi::phrase_parse(std::begin(condition), - std::end(condition), + success = boost::spirit::qi::phrase_parse(std::cbegin(condition), + std::cend(condition), grammar, skipper, result); @@ -150,8 +150,8 @@ namespace loot { Grammar grammar(&game); std::string condition("file(\"../../" + blankEsm + "\")"); - EXPECT_THROW(boost::spirit::qi::phrase_parse(std::begin(condition), - std::end(condition), + EXPECT_THROW(boost::spirit::qi::phrase_parse(std::cbegin(condition), + std::cend(condition), grammar, skipper, result), error); @@ -161,8 +161,8 @@ namespace loot { Grammar grammar(&game); std::string condition("regex(\"RagnvaldBook(Farengar(+Ragnvald)?)?\\.esp\")"); - EXPECT_THROW(boost::spirit::qi::phrase_parse(std::begin(condition), - std::end(condition), + EXPECT_THROW(boost::spirit::qi::phrase_parse(std::cbegin(condition), + std::cend(condition), grammar, skipper, result), error); @@ -172,8 +172,8 @@ namespace loot { Grammar grammar(&game); std::string condition("regex(\"Blank.+\\.esm\")"); - success = boost::spirit::qi::phrase_parse(std::begin(condition), - std::end(condition), + success = boost::spirit::qi::phrase_parse(std::cbegin(condition), + std::cend(condition), grammar, skipper, result); @@ -185,8 +185,8 @@ namespace loot { Grammar grammar(&game); std::string condition("regex(\"Blank\\.m.+\\.esm\")"); - success = boost::spirit::qi::phrase_parse(std::begin(condition), - std::end(condition), + success = boost::spirit::qi::phrase_parse(std::cbegin(condition), + std::cend(condition), grammar, skipper, result); @@ -198,8 +198,8 @@ namespace loot { Grammar grammar(&game); std::string condition("regex(\"resource\\\\detail\\\\resource\\.txt\")"); - success = boost::spirit::qi::phrase_parse(std::begin(condition), - std::end(condition), + success = boost::spirit::qi::phrase_parse(std::cbegin(condition), + std::cend(condition), grammar, skipper, result); @@ -211,8 +211,8 @@ namespace loot { Grammar grammar(&game); std::string condition("many(\"Blank.+\\.esm\")"); - success = boost::spirit::qi::phrase_parse(std::begin(condition), - std::end(condition), + success = boost::spirit::qi::phrase_parse(std::cbegin(condition), + std::cend(condition), grammar, skipper, result); @@ -224,8 +224,8 @@ namespace loot { Grammar grammar(&game); std::string condition("many(\"Blank\\.esm\")"); - success = boost::spirit::qi::phrase_parse(std::begin(condition), - std::end(condition), + success = boost::spirit::qi::phrase_parse(std::cbegin(condition), + std::cend(condition), grammar, skipper, result); @@ -237,8 +237,8 @@ namespace loot { Grammar grammar(&game); std::string condition("checksum(\"" + blankEsm + "\", " + IntToHexString(blankEsmCrc) + ")"); - success = boost::spirit::qi::phrase_parse(std::begin(condition), - std::end(condition), + success = boost::spirit::qi::phrase_parse(std::cbegin(condition), + std::cend(condition), grammar, skipper, result); @@ -250,8 +250,8 @@ namespace loot { Grammar grammar(&game); std::string condition("checksum(\"" + blankEsm + "\", DEADBEEF)"); - success = boost::spirit::qi::phrase_parse(std::begin(condition), - std::end(condition), + success = boost::spirit::qi::phrase_parse(std::cbegin(condition), + std::cend(condition), grammar, skipper, result); @@ -265,8 +265,8 @@ namespace loot { Grammar grammar(&game); std::string condition("version(\"" + blankEsm + "\", \"5.0\", ==)"); - success = boost::spirit::qi::phrase_parse(std::begin(condition), - std::end(condition), + success = boost::spirit::qi::phrase_parse(std::cbegin(condition), + std::cend(condition), grammar, skipper, result); @@ -280,8 +280,8 @@ namespace loot { Grammar grammar(&game); std::string condition("version(\"" + blankEsm + "\", \"6.0\", ==)"); - success = boost::spirit::qi::phrase_parse(std::begin(condition), - std::end(condition), + success = boost::spirit::qi::phrase_parse(std::cbegin(condition), + std::cend(condition), grammar, skipper, result); @@ -295,8 +295,8 @@ namespace loot { Grammar grammar(&game); std::string condition("version(\"" + blankEsm + "\", \"6.0\", !=)"); - success = boost::spirit::qi::phrase_parse(std::begin(condition), - std::end(condition), + success = boost::spirit::qi::phrase_parse(std::cbegin(condition), + std::cend(condition), grammar, skipper, result); @@ -310,8 +310,8 @@ namespace loot { Grammar grammar(&game); std::string condition("version(\"" + blankEsm + "\", \"5.0\", !=)"); - success = boost::spirit::qi::phrase_parse(std::begin(condition), - std::end(condition), + success = boost::spirit::qi::phrase_parse(std::cbegin(condition), + std::cend(condition), grammar, skipper, result); @@ -325,8 +325,8 @@ namespace loot { Grammar grammar(&game); std::string condition("version(\"" + blankEsm + "\", \"6.0\", <)"); - success = boost::spirit::qi::phrase_parse(std::begin(condition), - std::end(condition), + success = boost::spirit::qi::phrase_parse(std::cbegin(condition), + std::cend(condition), grammar, skipper, result); @@ -340,8 +340,8 @@ namespace loot { Grammar grammar(&game); std::string condition("version(\"" + blankEsm + "\", \"5.0\", <)"); - success = boost::spirit::qi::phrase_parse(std::begin(condition), - std::end(condition), + success = boost::spirit::qi::phrase_parse(std::cbegin(condition), + std::cend(condition), grammar, skipper, result); @@ -355,8 +355,8 @@ namespace loot { Grammar grammar(&game); std::string condition("version(\"" + blankEsm + "\", \"4.0\", >)"); - success = boost::spirit::qi::phrase_parse(std::begin(condition), - std::end(condition), + success = boost::spirit::qi::phrase_parse(std::cbegin(condition), + std::cend(condition), grammar, skipper, result); @@ -370,8 +370,8 @@ namespace loot { Grammar grammar(&game); std::string condition("version(\"" + blankEsm + "\", \"5.0\", >)"); - success = boost::spirit::qi::phrase_parse(std::begin(condition), - std::end(condition), + success = boost::spirit::qi::phrase_parse(std::cbegin(condition), + std::cend(condition), grammar, skipper, result); @@ -385,8 +385,8 @@ namespace loot { Grammar grammar(&game); std::string condition("version(\"" + blankEsm + "\", \"5.0\", <=)"); - success = boost::spirit::qi::phrase_parse(std::begin(condition), - std::end(condition), + success = boost::spirit::qi::phrase_parse(std::cbegin(condition), + std::cend(condition), grammar, skipper, result); @@ -400,8 +400,8 @@ namespace loot { Grammar grammar(&game); std::string condition("version(\"" + blankEsm + "\", \"4.0\", <=)"); - success = boost::spirit::qi::phrase_parse(std::begin(condition), - std::end(condition), + success = boost::spirit::qi::phrase_parse(std::cbegin(condition), + std::cend(condition), grammar, skipper, result); @@ -416,8 +416,8 @@ namespace loot { Grammar grammar(&game); std::string condition("version(\"" + blankEsm + "\", \"5.0\", >=)"); - success = boost::spirit::qi::phrase_parse(std::begin(condition), - std::end(condition), + success = boost::spirit::qi::phrase_parse(std::cbegin(condition), + std::cend(condition), grammar, skipper, result); @@ -431,8 +431,8 @@ namespace loot { Grammar grammar(&game); std::string condition("version(\"" + blankEsm + "\", \"6.0\", >=)"); - success = boost::spirit::qi::phrase_parse(std::begin(condition), - std::end(condition), + success = boost::spirit::qi::phrase_parse(std::cbegin(condition), + std::cend(condition), grammar, skipper, result); @@ -446,8 +446,8 @@ namespace loot { Grammar grammar(&game); std::string condition("active(\"" + blankEsm + "\")"); - success = boost::spirit::qi::phrase_parse(std::begin(condition), - std::end(condition), + success = boost::spirit::qi::phrase_parse(std::cbegin(condition), + std::cend(condition), grammar, skipper, result); @@ -461,8 +461,8 @@ namespace loot { Grammar grammar(&game); std::string condition("active(\"" + blankEsp + "\")"); - success = boost::spirit::qi::phrase_parse(std::begin(condition), - std::end(condition), + success = boost::spirit::qi::phrase_parse(std::cbegin(condition), + std::cend(condition), grammar, skipper, result); @@ -474,8 +474,8 @@ namespace loot { Grammar grammar(&game); std::string condition("not file(\"" + missingEsp + "\")"); - success = boost::spirit::qi::phrase_parse(std::begin(condition), - std::end(condition), + success = boost::spirit::qi::phrase_parse(std::cbegin(condition), + std::cend(condition), grammar, skipper, result); @@ -487,8 +487,8 @@ namespace loot { Grammar grammar(&game); std::string condition("not file(\"" + blankEsm + "\")"); - success = boost::spirit::qi::phrase_parse(std::begin(condition), - std::end(condition), + success = boost::spirit::qi::phrase_parse(std::cbegin(condition), + std::cend(condition), grammar, skipper, result); @@ -501,8 +501,8 @@ namespace loot { std::string condition("file(\"" + blankEsm + "\")"); std::string compound(condition + " and " + condition); - success = boost::spirit::qi::phrase_parse(std::begin(compound), - std::end(compound), + success = boost::spirit::qi::phrase_parse(std::cbegin(compound), + std::cend(compound), grammar, skipper, result); @@ -515,8 +515,8 @@ namespace loot { std::string condition("file(\"" + blankEsm + "\")"); std::string compound(condition + " and not " + condition); - success = boost::spirit::qi::phrase_parse(std::begin(compound), - std::end(compound), + success = boost::spirit::qi::phrase_parse(std::cbegin(compound), + std::cend(compound), grammar, skipper, result); @@ -529,8 +529,8 @@ namespace loot { std::string condition("file(\"" + blankEsm + "\")"); std::string compound("not " + condition + " or " + condition); - success = boost::spirit::qi::phrase_parse(std::begin(compound), - std::end(compound), + success = boost::spirit::qi::phrase_parse(std::cbegin(compound), + std::cend(compound), grammar, skipper, result); @@ -543,8 +543,8 @@ namespace loot { std::string condition("file(\"" + blankEsm + "\")"); std::string compound("not " + condition + " or not " + condition); - success = boost::spirit::qi::phrase_parse(std::begin(compound), - std::end(compound), + success = boost::spirit::qi::phrase_parse(std::cbegin(compound), + std::cend(compound), grammar, skipper, result); @@ -557,8 +557,8 @@ namespace loot { std::string condition("file(\"" + blankEsm + "\")"); std::string compound("not " + condition + " and " + condition + " or " + condition); - success = boost::spirit::qi::phrase_parse(std::begin(compound), - std::end(compound), + success = boost::spirit::qi::phrase_parse(std::cbegin(compound), + std::cend(compound), grammar, skipper, result); @@ -571,8 +571,8 @@ namespace loot { std::string condition("file(\"" + blankEsm + "\")"); std::string compound("not " + condition + " and ( " + condition + " or " + condition + " )"); - success = boost::spirit::qi::phrase_parse(std::begin(compound), - std::end(compound), + success = boost::spirit::qi::phrase_parse(std::cbegin(compound), + std::cend(compound), grammar, skipper, result); From 7940864ae06431249b869f2952c9035538258c6f Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Fri, 25 Mar 2016 18:23:39 +0000 Subject: [PATCH 22/38] Remove Language::any This breaks the API (again), but Language::any is a throwback from before English-language strings were required for messages, and is not useful now that they are. Language::any picked the first message string, ignoring language, making it unpredictable compared to any of the other language options, which will provide the requested string or fall back to English if one is not available. --- include/loot/api.h | 1 - src/api/api.cpp | 6 ++---- src/api/loot_db.cpp | 2 +- src/backend/helpers/language.cpp | 1 - src/backend/helpers/language.h | 1 - src/backend/metadata/message.cpp | 2 +- src/tests/api/loot_eval_lists_test.h | 6 +++--- src/tests/backend/metadata/test_message.h | 14 +++++++------- .../backend/metadata/test_plugin_dirty_info.h | 16 ++++++++-------- 9 files changed, 22 insertions(+), 27 deletions(-) diff --git a/include/loot/api.h b/include/loot/api.h index dbb599bf..13ecf8fe 100644 --- a/include/loot/api.h +++ b/include/loot/api.h @@ -277,7 +277,6 @@ extern "C" *************************************************************************/ /**@{*/ - LOOT_API extern const unsigned int loot_lang_any; /**< Tells the API to select messages of any language. */ LOOT_API extern const unsigned int loot_lang_english; /**< Tells the API to preferentially select English messages. */ LOOT_API extern const unsigned int loot_lang_spanish; /**< Tells the API to preferentially select Spanish messages */ LOOT_API extern const unsigned int loot_lang_russian; /**< Tells the API to preferentially select Russian messages. */ diff --git a/src/api/api.cpp b/src/api/api.cpp index 5fc92793..dd7eacaf 100644 --- a/src/api/api.cpp +++ b/src/api/api.cpp @@ -69,7 +69,6 @@ const unsigned int loot_message_warn = loot::Message::warn; const unsigned int loot_message_error = loot::Message::error; // LOOT message languages. -const unsigned int loot_lang_any = loot::Language::any; const unsigned int loot_lang_english = loot::Language::english; const unsigned int loot_lang_spanish = loot::Language::spanish; const unsigned int loot_lang_russian = loot::Language::russian; @@ -283,8 +282,7 @@ LOOT_API unsigned int loot_load_lists(loot_db * const db, const char * const mas LOOT_API unsigned int loot_eval_lists(loot_db * const db, const unsigned int language) { if (db == nullptr) return c_error(loot_error_invalid_args, "Null pointer passed."); - if (language != loot_lang_any - && language != loot_lang_english + if (language != loot_lang_english && language != loot_lang_spanish && language != loot_lang_russian && language != loot_lang_french @@ -336,7 +334,7 @@ LOOT_API unsigned int loot_sort_plugins(loot_db * const db, //Sort plugins into their load order. loot::PluginSorter sorter; - db->setPluginNames(sorter.Sort(*db, loot_lang_any)); + db->setPluginNames(sorter.Sort(*db, loot::Language::english)); } catch (loot::error &e) { return c_error(e); diff --git a/src/api/loot_db.cpp b/src/api/loot_db.cpp index 411abb6d..97f3f84a 100644 --- a/src/api/loot_db.cpp +++ b/src/api/loot_db.cpp @@ -92,7 +92,7 @@ void loot_db::setPluginMessages(const std::list& pluginMessages) size_t i = 0; for (const auto& message : pluginMessages) { - pluginMessageStrings[i] = message.ChooseContent(loot::Language::any).Str(); + pluginMessageStrings[i] = message.ChooseContent(loot::Language::english).Str(); cPluginMessages[i].type = message.Type(); cPluginMessages[i].message = pluginMessageStrings[i].c_str(); diff --git a/src/backend/helpers/language.cpp b/src/backend/helpers/language.cpp index f0c094b5..270162de 100644 --- a/src/backend/helpers/language.cpp +++ b/src/backend/helpers/language.cpp @@ -25,7 +25,6 @@ #include "language.h" namespace loot { - const unsigned int Language::any = 0; const unsigned int Language::english = 1; const unsigned int Language::spanish = 2; const unsigned int Language::russian = 3; diff --git a/src/backend/helpers/language.h b/src/backend/helpers/language.h index c651fb3e..d656a96b 100644 --- a/src/backend/helpers/language.h +++ b/src/backend/helpers/language.h @@ -39,7 +39,6 @@ namespace loot { std::string Name() const; std::string Locale() const; - static const unsigned int any; // This shouldn't be used as a selectable language, just for when picking any string in a message. static const unsigned int english; static const unsigned int spanish; static const unsigned int russian; diff --git a/src/backend/metadata/message.cpp b/src/backend/metadata/message.cpp index cbb89eea..92f6fb8f 100644 --- a/src/backend/metadata/message.cpp +++ b/src/backend/metadata/message.cpp @@ -68,7 +68,7 @@ namespace loot { BOOST_LOG_TRIVIAL(trace) << "Choosing message content."; if (_content.empty()) return MessageContent(); - else if (_content.size() == 1 || language == Language::any) + else if (_content.size() == 1) return _content[0]; else { MessageContent english; diff --git a/src/tests/api/loot_eval_lists_test.h b/src/tests/api/loot_eval_lists_test.h index bb4f2e01..bca329fc 100644 --- a/src/tests/api/loot_eval_lists_test.h +++ b/src/tests/api/loot_eval_lists_test.h @@ -44,7 +44,7 @@ namespace loot { loot_game_fo4)); TEST_P(loot_eval_lists_test, shouldReturnAnInvalidArgsErrorIfPassedANullPointer) { - EXPECT_EQ(loot_error_invalid_args, loot_eval_lists(NULL, loot_lang_any)); + EXPECT_EQ(loot_error_invalid_args, loot_eval_lists(NULL, loot_lang_english)); } TEST_P(loot_eval_lists_test, shouldReturnAnInvalidArgsErrorIfPassedAnInvalidLanguageCode) { @@ -52,7 +52,7 @@ namespace loot { } TEST_P(loot_eval_lists_test, shouldReturnOkForAllLanguagesWithNoListsLoaded) { - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_any)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_english)); EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_english)); EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_spanish)); EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_russian)); @@ -69,7 +69,7 @@ namespace loot { ASSERT_NO_THROW(generateMasterlist()); ASSERT_EQ(loot_ok, loot_load_lists(db, masterlistPath.string().c_str(), NULL)); - EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_any)); + EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_english)); EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_english)); EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_spanish)); EXPECT_EQ(loot_ok, loot_eval_lists(db, loot_lang_russian)); diff --git a/src/tests/backend/metadata/test_message.h b/src/tests/backend/metadata/test_message.h index 666e5880..b561e223 100644 --- a/src/tests/backend/metadata/test_message.h +++ b/src/tests/backend/metadata/test_message.h @@ -152,7 +152,7 @@ namespace loot { ASSERT_NO_THROW(game.Init(false, localPath)); Message message; - EXPECT_TRUE(message.EvalCondition(game, Language::any)); + EXPECT_TRUE(message.EvalCondition(game, Language::english)); EXPECT_EQ(1, message.Content().size()); message = Message(Message::say, MessageContents({ @@ -167,19 +167,19 @@ namespace loot { TEST_F(MessageTest, ChooseContent) { MessageContent mc; Message message; - EXPECT_EQ(mc, message.ChooseContent(Language::any)); + EXPECT_EQ(mc, message.ChooseContent(Language::english)); EXPECT_EQ(mc, message.ChooseContent(Language::french)); EXPECT_EQ(mc, message.ChooseContent(Language::english)); mc = MessageContent("content1", Language::english); message = Message(Message::say, "content1"); - EXPECT_EQ(mc, message.ChooseContent(Language::any)); + EXPECT_EQ(mc, message.ChooseContent(Language::english)); EXPECT_EQ(mc, message.ChooseContent(Language::french)); EXPECT_EQ(mc, message.ChooseContent(Language::english)); mc = MessageContent("content1", Language::english); message = Message(Message::say, MessageContents({mc})); - EXPECT_EQ(mc, message.ChooseContent(Language::any)); + EXPECT_EQ(mc, message.ChooseContent(Language::english)); EXPECT_EQ(mc, message.ChooseContent(Language::french)); EXPECT_EQ(mc, message.ChooseContent(Language::english)); @@ -188,7 +188,7 @@ namespace loot { MessageContent("content1", Language::english), MessageContent("content1", Language::german), })); - EXPECT_EQ(mc, message.ChooseContent(Language::any)); + EXPECT_EQ(mc, message.ChooseContent(Language::english)); EXPECT_EQ(mc, message.ChooseContent(Language::french)); EXPECT_EQ(mc, message.ChooseContent(Language::english)); @@ -197,13 +197,13 @@ namespace loot { MessageContent("content1", Language::english), MessageContent("content1", Language::french), })); - EXPECT_EQ(MessageContent("content1", Language::german), message.ChooseContent(Language::any)); + EXPECT_EQ(MessageContent("content1", Language::german), message.ChooseContent(Language::english)); EXPECT_EQ(MessageContent("content1", Language::french), message.ChooseContent(Language::french)); EXPECT_EQ(MessageContent("content1", Language::english), message.ChooseContent(Language::english)); mc = MessageContent("content1", Language::german); message = Message(Message::say, MessageContents({mc})); - EXPECT_EQ(mc, message.ChooseContent(Language::any)); + EXPECT_EQ(mc, message.ChooseContent(Language::english)); EXPECT_EQ(mc, message.ChooseContent(Language::french)); } diff --git a/src/tests/backend/metadata/test_plugin_dirty_info.h b/src/tests/backend/metadata/test_plugin_dirty_info.h index d632885c..7dde296d 100644 --- a/src/tests/backend/metadata/test_plugin_dirty_info.h +++ b/src/tests/backend/metadata/test_plugin_dirty_info.h @@ -53,35 +53,35 @@ namespace loot { message = PluginDirtyInfo(0x12345678, 2, 10, 30, "cleaner").AsMessage(); EXPECT_EQ(Message::warn, message.Type()); - EXPECT_EQ("Contains 2 ITM records, 10 deleted references and 30 deleted navmeshes. Clean with cleaner.", message.ChooseContent(Language::any).Str()); + EXPECT_EQ("Contains 2 ITM records, 10 deleted references and 30 deleted navmeshes. Clean with cleaner.", message.ChooseContent(Language::english).Str()); message = PluginDirtyInfo(0x12345678, 0, 0, 0, "cleaner").AsMessage(); EXPECT_EQ(Message::warn, message.Type()); - EXPECT_EQ("Clean with cleaner.", message.ChooseContent(Language::any).Str()); + EXPECT_EQ("Clean with cleaner.", message.ChooseContent(Language::english).Str()); message = PluginDirtyInfo(0x12345678, 0, 10, 30, "cleaner").AsMessage(); EXPECT_EQ(Message::warn, message.Type()); - EXPECT_EQ("Contains 10 deleted references and 30 deleted navmeshes. Clean with cleaner.", message.ChooseContent(Language::any).Str()); + EXPECT_EQ("Contains 10 deleted references and 30 deleted navmeshes. Clean with cleaner.", message.ChooseContent(Language::english).Str()); message = PluginDirtyInfo(0x12345678, 0, 0, 30, "cleaner").AsMessage(); EXPECT_EQ(Message::warn, message.Type()); - EXPECT_EQ("Contains 30 deleted navmeshes. Clean with cleaner.", message.ChooseContent(Language::any).Str()); + EXPECT_EQ("Contains 30 deleted navmeshes. Clean with cleaner.", message.ChooseContent(Language::english).Str()); message = PluginDirtyInfo(0x12345678, 0, 10, 0, "cleaner").AsMessage(); EXPECT_EQ(Message::warn, message.Type()); - EXPECT_EQ("Contains 10 deleted references. Clean with cleaner.", message.ChooseContent(Language::any).Str()); + EXPECT_EQ("Contains 10 deleted references. Clean with cleaner.", message.ChooseContent(Language::english).Str()); message = PluginDirtyInfo(0x12345678, 2, 0, 30, "cleaner").AsMessage(); EXPECT_EQ(Message::warn, message.Type()); - EXPECT_EQ("Contains 2 ITM records and 30 deleted navmeshes. Clean with cleaner.", message.ChooseContent(Language::any).Str()); + EXPECT_EQ("Contains 2 ITM records and 30 deleted navmeshes. Clean with cleaner.", message.ChooseContent(Language::english).Str()); message = PluginDirtyInfo(0x12345678, 2, 0, 0, "cleaner").AsMessage(); EXPECT_EQ(Message::warn, message.Type()); - EXPECT_EQ("Contains 2 ITM records. Clean with cleaner.", message.ChooseContent(Language::any).Str()); + EXPECT_EQ("Contains 2 ITM records. Clean with cleaner.", message.ChooseContent(Language::english).Str()); message = PluginDirtyInfo(0x12345678, 2, 10, 0, "cleaner").AsMessage(); EXPECT_EQ(Message::warn, message.Type()); - EXPECT_EQ("Contains 2 ITM records and 10 deleted references. Clean with cleaner.", message.ChooseContent(Language::any).Str()); + EXPECT_EQ("Contains 2 ITM records and 10 deleted references. Clean with cleaner.", message.ChooseContent(Language::english).Str()); } TEST_F(PluginDirtyInfoTest, EqualityOperator) { From a48a936c22212166d84fd68b9630ce2d787cad2c Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Fri, 25 Mar 2016 22:38:14 +0000 Subject: [PATCH 23/38] Improve Message tests --- CMakeLists.txt | 2 +- src/tests/backend/metadata/message_test.h | 431 ++++++++++++++++++++++ src/tests/backend/metadata/test_message.h | 421 --------------------- src/tests/main.cpp | 2 +- 4 files changed, 433 insertions(+), 423 deletions(-) create mode 100644 src/tests/backend/metadata/message_test.h delete mode 100644 src/tests/backend/metadata/test_message.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 1152fc1b..88dacfde 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -248,7 +248,7 @@ set (LOOT_TESTS_HEADERS "${CMAKE_SOURCE_DIR}/src/tests/base_game_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/conditional_metadata_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/file_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/location_test.h" - "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/test_message.h" + "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/message_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/test_message_content.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/test_plugin_dirty_info.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/test_plugin_metadata.h" diff --git a/src/tests/backend/metadata/message_test.h b/src/tests/backend/metadata/message_test.h new file mode 100644 index 00000000..8a375de4 --- /dev/null +++ b/src/tests/backend/metadata/message_test.h @@ -0,0 +1,431 @@ +/* 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_TEST_BACKEND_METADATA_MESSAGE +#define LOOT_TEST_BACKEND_METADATA_MESSAGE + +#include "backend/game/game.h" +#include "backend/metadata/message.h" +#include "tests/base_game_test.h" + +namespace loot { + namespace test { + class MessageTest : public BaseGameTest { + protected: + + typedef std::vector MessageContents; + }; + + // Pass an empty first argument, as it's a prefix for the test instantation, + // but we only have the one so no prefix is necessary. + INSTANTIATE_TEST_CASE_P(, + MessageTest, + ::testing::Values( + GameSettings::tes4)); + + TEST_P(MessageTest, defaultConstructorShouldCreateNoteWithNoContent) { + Message message; + EXPECT_EQ(Message::say, message.Type()); + EXPECT_EQ(MessageContents(), message.Content()); + } + + TEST_P(MessageTest, scalarContentConstructorShouldCreateAMessageWithASingleContentString) { + MessageContent content = MessageContent("content1", Language::english); + Message message(Message::warn, content.Str(), "condition1"); + + EXPECT_EQ(Message::warn, message.Type()); + EXPECT_EQ(MessageContents({content}), message.Content()); + EXPECT_EQ("condition1", message.Condition()); + } + + TEST_P(MessageTest, vectorContentConstructorShouldCreateAMessageWithGivenContentStrings) { + MessageContents contents({ + MessageContent("content1", Language::english), + MessageContent("content2", Language::french), + }); + Message message(Message::error, contents, "condition1"); + + EXPECT_EQ(Message::error, message.Type()); + EXPECT_EQ(contents, message.Content()); + EXPECT_EQ("condition1", message.Condition()); + } + + TEST_P(MessageTest, messagesWithDifferentContentStringsShouldBeUnequal) { + Message message1(Message::say, "content1", "condition1"); + Message message2(Message::say, "content2", "condition1"); + + EXPECT_FALSE(message1 == message2); + } + + TEST_P(MessageTest, messagesWithEqualContentStringsShouldBeEqual) { + Message message1(Message::say, MessageContents({MessageContent("content1", Language::english)}), "condition1"); + Message message2(Message::warn, MessageContents({MessageContent("content1", Language::french)}), "condition2"); + + EXPECT_TRUE(message1 == message2); + } + + TEST_P(MessageTest, LessThanOperatorShouldUseCaseInsensitiveLexicographicalContentStringComparison) { + Message message1(Message::say, MessageContents({MessageContent("content1", Language::english)}), "condition1"); + Message message2(Message::warn, MessageContents({MessageContent("content1", Language::french)}), "condition2"); + EXPECT_FALSE(message1 < message2); + EXPECT_FALSE(message2 < message1); + + message1 = Message(Message::say, "content1", "condition1"); + message2 = Message(Message::say, "content2", "condition1"); + EXPECT_TRUE(message1 < message2); + EXPECT_FALSE(message2 < message1); + } + + TEST_P(MessageTest, evalConditionShouldCreateADefaultContentObjectIfNoneExists) { + Game game(GetParam()); + game.SetGamePath(dataPath.parent_path()); + ASSERT_NO_THROW(game.Init(false, localPath)); + + Message message; + EXPECT_TRUE(message.EvalCondition(game, Language::english)); + EXPECT_EQ(MessageContents({MessageContent()}), message.Content()); + } + + TEST_P(MessageTest, evalConditionShouldPickOneContentStringIfMoreThanOneExists) { + Game game(GetParam()); + game.SetGamePath(dataPath.parent_path()); + ASSERT_NO_THROW(game.Init(false, localPath)); + + Message message(Message::say, MessageContents({ + MessageContent("content1", Language::german), + MessageContent("content2", Language::english), + MessageContent("content3", Language::french), + })); + + EXPECT_TRUE(message.EvalCondition(game, Language::french)); + EXPECT_EQ(1, message.Content().size()); + EXPECT_EQ(MessageContent("content3", Language::french), message.Content()[0]); + } + + TEST_P(MessageTest, chooseContentShouldCreateADefaultContentObjectIfNoneExists) { + EXPECT_EQ(MessageContent(), Message().ChooseContent(Language::english)); + } + + TEST_P(MessageTest, chooseContentShouldLeaveTheContentUnchangedIfOnlyOneStringExists) { + MessageContent content("content1", Language::english); + Message message(Message::say, MessageContents({content})); + + EXPECT_EQ(content, message.ChooseContent(Language::french)); + EXPECT_EQ(content, message.ChooseContent(Language::english)); + } + + TEST_P(MessageTest, chooseContentShouldSelectTheEnglishStringIfNoStringExistsForTheGivenLanguage) { + MessageContent content("content1", Language::english); + Message message(Message::say, MessageContents({ + content, + MessageContent("content1", Language::german), + })); + EXPECT_EQ(content, message.ChooseContent(Language::french)); + } + + TEST_P(MessageTest, chooseContentShouldSelectTheStringForTheGivenLanguageIfOneExists) { + MessageContent french("content3", Language::french); + Message message(Message::say, MessageContents({ + MessageContent("content1", Language::german), + MessageContent("content2", Language::english), + french, + })); + + EXPECT_EQ(french, message.ChooseContent(Language::french)); + } + + TEST_P(MessageTest, emittingAsYamlShouldOutputNoteMessageTypeCorrectly) { + Message message(Message::say, "content1"); + YAML::Emitter emitter; + emitter << message; + + EXPECT_STREQ("type: say\n" + "content: 'content1'", emitter.c_str()); + } + + TEST_P(MessageTest, emittingAsYamlShouldOutputWarnMessageTypeCorrectly) { + Message message(Message::warn, "content1"); + YAML::Emitter emitter; + emitter << message; + + EXPECT_STREQ("type: warn\n" + "content: 'content1'", emitter.c_str()); + } + + TEST_P(MessageTest, emittingAsYamlShouldOutputErrorMessageTypeCorrectly) { + Message message(Message::error, "content1"); + YAML::Emitter emitter; + emitter << message; + + EXPECT_STREQ("type: error\n" + "content: 'content1'", emitter.c_str()); + } + + TEST_P(MessageTest, emittingAsYamlShouldOutputConditionIfItIsNotEmpty) { + Message message(Message::say, "content1", "condition1"); + YAML::Emitter emitter; + emitter << message; + + EXPECT_STREQ("type: say\n" + "content: 'content1'\n" + "condition: 'condition1'", emitter.c_str()); + } + + TEST_P(MessageTest, emittingAsYamlShouldOutputMultipleContentStringsAsAList) { + Message message(Message::say, MessageContents({ + MessageContent("content1", Language::english), + MessageContent("content2", Language::german) + })); + YAML::Emitter emitter; + emitter << message; + + EXPECT_STREQ("type: say\n" + "content:\n" + " - lang: en\n" + " str: 'content1'\n" + " - lang: de\n" + " str: 'content2'", emitter.c_str()); + } + + TEST_P(MessageTest, encodingAsYamlShouldStoreNoteMessageTypeCorrectly) { + Message message(Message::say, "content1"); + YAML::Node node; + node = message; + + EXPECT_EQ("say", node["type"].as()); + } + + TEST_P(MessageTest, encodingAsYamlShouldStoreWarningMessageTypeCorrectly) { + Message message(Message::warn, "content1"); + YAML::Node node; + node = message; + + EXPECT_EQ("warn", node["type"].as()); + } + + TEST_P(MessageTest, encodingAsYamlShouldStoreErrorMessageTypeCorrectly) { + Message message(Message::error, "content1"); + YAML::Node node; + node = message; + + EXPECT_EQ("error", node["type"].as()); + } + + TEST_P(MessageTest, encodingAsYamlShouldOmitConditionFieldIfItIsEmpty) { + Message message(Message::say, "content1"); + YAML::Node node; + node = message; + + EXPECT_FALSE(node["condition"]); + } + + TEST_P(MessageTest, encodingAsYamlShouldStoreConditionFieldIfItIsNotEmpty) { + Message message(Message::say, "content1", "condition1"); + YAML::Node node; + node = message; + + EXPECT_EQ("condition1", node["condition"].as()); + } + + TEST_P(MessageTest, encodingAsYamlShouldStoreASingleContentStringInAVector) { + Message message(Message::say, "content1"); + YAML::Node node; + node = message; + + EXPECT_EQ(message.Content(), node["content"].as()); + } + + TEST_P(MessageTest, encodingAsYamlShouldMultipleContentStringsInAVector) { + MessageContents contents({ + MessageContent("content1", Language::english), + MessageContent("content2", Language::french), + }); + Message message(Message::say, contents); + YAML::Node node; + node = message; + + EXPECT_EQ(contents, node["content"].as()); + } + + TEST_P(MessageTest, decodingFromYamlShouldSetNoteTypeCorrectly) { + YAML::Node node = YAML::Load("type: say\n" + "content: content1"); + Message message = node.as(); + + EXPECT_EQ(Message::say, message.Type()); + } + + TEST_P(MessageTest, decodingFromYamlShouldSetWarningTypeCorrectly) { + YAML::Node node = YAML::Load("type: warn\n" + "content: content1"); + Message message = node.as(); + + EXPECT_EQ(Message::warn, message.Type()); + } + + TEST_P(MessageTest, decodingFromYamlShouldSetErrorTypeCorrectly) { + YAML::Node node = YAML::Load("type: error\n" + "content: content1"); + Message message = node.as(); + + EXPECT_EQ(Message::error, message.Type()); + } + + TEST_P(MessageTest, decodingFromYamlShouldHandleAnUnrecognisedTypeAsANote) { + YAML::Node node = YAML::Load("type: invalid\n" + "content: content1"); + Message message = node.as(); + + EXPECT_EQ(Message::say, message.Type()); + } + + TEST_P(MessageTest, decodingFromYamlShouldLeaveTheConditionEmptyIfNoneIsPresent) { + YAML::Node node = YAML::Load("type: say\n" + "content: content1"); + Message message = node.as(); + + EXPECT_TRUE(message.Condition().empty()); + } + + TEST_P(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.Condition()); + } + + TEST_P(MessageTest, decodingFromYamlShouldStoreAScalarContentValueCorrectly) { + YAML::Node node = YAML::Load("type: say\n" + "content: content1\n"); + Message message = node.as(); + MessageContents expectedContent({MessageContent("content1", Language::english)}); + + EXPECT_EQ(expectedContent, message.Content()); + } + + TEST_P(MessageTest, decodingFromYamlShouldStoreAListOfContentStringsCorrectly) { + YAML::Node node = YAML::Load("type: say\n" + "content:\n" + " - lang: en\n" + " str: content1\n" + " - lang: de\n" + " str: content2"); + Message message = node.as(); + + EXPECT_EQ(MessageContents({ + MessageContent("content1", Language::english), + MessageContent("content2", Language::german), + }), message.Content()); + } + + TEST_P(MessageTest, decodingFromYamlShouldNotThrowIfTheOnlyContentStringIsNotEnglish) { + YAML::Node node = YAML::Load("type: say\n" + "content:\n" + " - lang: fr\n" + " str: content1"); + + EXPECT_NO_THROW(Message message = node.as()); + } + + TEST_P(MessageTest, decodingFromYamlShouldThrowIfMultipleContentStringsAreGivenAndNoneAreEnglish) { + YAML::Node node = YAML::Load("type: say\n" + "content:\n" + " - lang: de\n" + " str: content1\n" + " - lang: fr\n" + " str: content2"); + + EXPECT_THROW(node.as(), YAML::RepresentationException); + } + + TEST_P(MessageTest, decodingFromYamlShouldApplySubstitutionsWhenThereIsOnlyOneContentString) { + YAML::Node node = YAML::Load("type: say\n" + "content: con%1%tent1\n" + "subs:\n" + " - sub1"); + Message message = node.as(); + + EXPECT_EQ(MessageContents({MessageContent("consub1tent1", Language::english)}), message.Content()); + } + + TEST_P(MessageTest, decodingFromYamlShouldApplySubstitutionsToAllContentStrings) { + YAML::Node node = YAML::Load("type: say\n" + "content:\n" + " - lang: en\n" + " str: content1 %1%\n" + " - lang: de\n" + " str: content2 %1%\n" + "subs:\n" + " - sub"); + Message message = node.as(); + + EXPECT_EQ(MessageContents({ + MessageContent("content1 sub", Language::english), + MessageContent("content2 sub", Language::german), + }), message.Content()); + } + + TEST_P(MessageTest, decodingFromYamlShouldThrowIfTheContentStringExpectsMoreSubstitutionsThanExist) { + YAML::Node node = YAML::Load("type: say\n" + "content: '%1% %2%'\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_P(MessageTest, decodingFromYamlShouldIgnoreSubstitutionSyntaxIfNoSubstitutionsExist) { + YAML::Node node = YAML::Load("type: say\n" + "content: con%1%tent1\n"); + Message message = node.as(); + + EXPECT_EQ(MessageContents({MessageContent("con%1%tent1", Language::english)}), message.Content()); + } + + TEST_P(MessageTest, decodingFromYamlShouldThrowIfAnInvalidConditionIsGiven) { + YAML::Node node = YAML::Load("type: say\n" + "content: content1\n" + "condition: invalid"); + + EXPECT_THROW(node.as(), YAML::RepresentationException); + } + + TEST_P(MessageTest, decodingFromYamlShouldThrowIfAScalarIsGiven) { + YAML::Node node = YAML::Load("scalar"); + + EXPECT_THROW(node.as(), YAML::RepresentationException); + } + + TEST_P(MessageTest, decodingFromYamlShouldThrowIfAListIsGiven) { + YAML::Node node = YAML::Load("[0, 1, 2]"); + + EXPECT_THROW(node.as(), YAML::RepresentationException); + } + } +} + +#endif diff --git a/src/tests/backend/metadata/test_message.h b/src/tests/backend/metadata/test_message.h deleted file mode 100644 index b561e223..00000000 --- a/src/tests/backend/metadata/test_message.h +++ /dev/null @@ -1,421 +0,0 @@ -/* 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_TEST_BACKEND_METADATA_MESSAGE -#define LOOT_TEST_BACKEND_METADATA_MESSAGE - -#include "backend/metadata/message.h" -#include "tests/fixtures.h" - -namespace loot { - namespace test { - class MessageTest : public SkyrimTest {}; - - typedef std::vector MessageContents; - - TEST_F(MessageTest, ConstructorsAndDataAccess) { - Message message; - EXPECT_EQ(Message::say, message.Type()); - EXPECT_EQ(MessageContents(), message.Content()); - - message = Message(Message::say, "content1", "condition1"); - EXPECT_EQ(Message::say, message.Type()); - EXPECT_EQ(MessageContents({ - MessageContent("content1", Language::english) - }), message.Content()); - EXPECT_EQ("condition1", message.Condition()); - - MessageContents mc({MessageContent("content1", Language::english)}); - message = Message(Message::say, mc, "condition1"); - EXPECT_EQ(Message::say, message.Type()); - EXPECT_EQ(mc, message.Content()); - EXPECT_EQ("condition1", message.Condition()); - } - - TEST_F(MessageTest, EqualityOperator) { - Message message1, message2; - EXPECT_TRUE(message1 == message2); - - message1 = Message(Message::say, "content1", "condition1"); - message2 = Message(Message::say, "content1", "condition2"); - EXPECT_TRUE(message1 == message2); - - message1 = Message(Message::say, "content1", "condition1"); - message2 = Message(Message::say, "content2", "condition1"); - EXPECT_FALSE(message1 == message2); - - message1 = Message(Message::say, "content1", "condition1"); - message2 = Message(Message::warn, "content1", "condition1"); - EXPECT_TRUE(message1 == message2); - - message1 = Message(Message::say, "content1", "condition1"); - message2 = Message(Message::say, MessageContents({MessageContent("content1", Language::english)}), "condition1"); - EXPECT_TRUE(message1 == message2); - - message1 = Message(Message::say, "content1", "condition1"); - message2 = Message(Message::say, MessageContents({MessageContent("content2", Language::english)}), "condition1"); - EXPECT_FALSE(message1 == message2); - - message1 = Message(Message::say, MessageContents({MessageContent("content1", Language::english)}), "condition1"); - message2 = Message(Message::say, MessageContents({MessageContent("content1", Language::english)}), "condition1"); - EXPECT_TRUE(message1 == message2); - - message1 = Message(Message::say, MessageContents({MessageContent("content1", Language::english)}), "condition1"); - message2 = Message(Message::say, MessageContents({MessageContent("content2", Language::english)}), "condition1"); - EXPECT_FALSE(message1 == message2); - - message1 = Message(Message::say, MessageContents({MessageContent("content1", Language::english)}), "condition1"); - message2 = Message(Message::say, MessageContents({MessageContent("content1", Language::french)}), "condition1"); - EXPECT_TRUE(message1 == message2); - } - - TEST_F(MessageTest, LessThanOperator) { - Message message1, message2; - EXPECT_FALSE(message1 < message2); - EXPECT_FALSE(message2 < message1); - - message1 = Message(Message::say, "content1", "condition1"); - message2 = Message(Message::say, "content1", "condition1"); - EXPECT_FALSE(message1 < message2); - EXPECT_FALSE(message2 < message1); - - message1 = Message(Message::say, "content1", "condition1"); - message2 = Message(Message::say, "content1", "condition2"); - EXPECT_FALSE(message1 < message2); - EXPECT_FALSE(message2 < message1); - - message1 = Message(Message::say, "content1", "condition1"); - message2 = Message(Message::warn, "content1", "condition1"); - EXPECT_FALSE(message1 < message2); - EXPECT_FALSE(message2 < message1); - - message1 = Message(Message::say, "", "condition1"); - message2 = Message(Message::say, "content1", "condition1"); - EXPECT_TRUE(message1 < message2); - EXPECT_FALSE(message2 < message1); - - message1 = Message(Message::say, "content1", "condition1"); - message2 = Message(Message::say, "", "condition1"); - EXPECT_FALSE(message1 < message2); - EXPECT_TRUE(message2 < message1); - - message1 = Message(Message::say, "content1", "condition1"); - message2 = Message(Message::say, MessageContents({MessageContent("content1", Language::english)}), "condition1"); - EXPECT_FALSE(message1 < message2); - EXPECT_FALSE(message2 < message1); - - message1 = Message(Message::say, "content1", "condition1"); - message2 = Message(Message::say, MessageContents({MessageContent("content2", Language::english)}), "condition1"); - EXPECT_TRUE(message1 < message2); - EXPECT_FALSE(message2 < message1); - - message1 = Message(Message::say, MessageContents({MessageContent("content1", Language::english)}), "condition1"); - message2 = Message(Message::say, MessageContents({MessageContent("content1", Language::english)}), "condition1"); - EXPECT_FALSE(message1 < message2); - EXPECT_FALSE(message2 < message1); - - message1 = Message(Message::say, MessageContents({MessageContent("content1", Language::english)}), "condition1"); - message2 = Message(Message::say, MessageContents({MessageContent("content2", Language::english)}), "condition1"); - EXPECT_TRUE(message1 < message2); - EXPECT_FALSE(message2 < message1); - - message1 = Message(Message::say, MessageContents({MessageContent("content1", Language::english)}), "condition1"); - message2 = Message(Message::say, MessageContents({MessageContent("content1", Language::french)}), "condition1"); - EXPECT_FALSE(message1 < message2); - EXPECT_FALSE(message2 < message1); - } - - TEST_F(MessageTest, EvalCondition) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); - - Message message; - EXPECT_TRUE(message.EvalCondition(game, Language::english)); - EXPECT_EQ(1, message.Content().size()); - - message = Message(Message::say, MessageContents({ - MessageContent("content1", Language::german), - MessageContent("content1", Language::english), - MessageContent("content1", Language::french), - })); - EXPECT_TRUE(message.EvalCondition(game, Language::french)); - EXPECT_EQ(1, message.Content().size()); - } - - TEST_F(MessageTest, ChooseContent) { - MessageContent mc; - Message message; - EXPECT_EQ(mc, message.ChooseContent(Language::english)); - EXPECT_EQ(mc, message.ChooseContent(Language::french)); - EXPECT_EQ(mc, message.ChooseContent(Language::english)); - - mc = MessageContent("content1", Language::english); - message = Message(Message::say, "content1"); - EXPECT_EQ(mc, message.ChooseContent(Language::english)); - EXPECT_EQ(mc, message.ChooseContent(Language::french)); - EXPECT_EQ(mc, message.ChooseContent(Language::english)); - - mc = MessageContent("content1", Language::english); - message = Message(Message::say, MessageContents({mc})); - EXPECT_EQ(mc, message.ChooseContent(Language::english)); - EXPECT_EQ(mc, message.ChooseContent(Language::french)); - EXPECT_EQ(mc, message.ChooseContent(Language::english)); - - mc = MessageContent("content1", Language::english); - message = Message(Message::say, MessageContents({ - MessageContent("content1", Language::english), - MessageContent("content1", Language::german), - })); - EXPECT_EQ(mc, message.ChooseContent(Language::english)); - EXPECT_EQ(mc, message.ChooseContent(Language::french)); - EXPECT_EQ(mc, message.ChooseContent(Language::english)); - - message = Message(Message::say, MessageContents({ - MessageContent("content1", Language::german), - MessageContent("content1", Language::english), - MessageContent("content1", Language::french), - })); - EXPECT_EQ(MessageContent("content1", Language::german), message.ChooseContent(Language::english)); - EXPECT_EQ(MessageContent("content1", Language::french), message.ChooseContent(Language::french)); - EXPECT_EQ(MessageContent("content1", Language::english), message.ChooseContent(Language::english)); - - mc = MessageContent("content1", Language::german); - message = Message(Message::say, MessageContents({mc})); - EXPECT_EQ(mc, message.ChooseContent(Language::english)); - EXPECT_EQ(mc, message.ChooseContent(Language::french)); - } - - TEST_F(MessageTest, YamlEmitter) { - Message message(Message::say, "content1"); - YAML::Emitter e1; - e1 << message; - EXPECT_STREQ("type: say\n" - "content: 'content1'", e1.c_str()); - - message = Message(Message::warn, "content1"); - YAML::Emitter e2; - e2 << message; - EXPECT_STREQ("type: warn\n" - "content: 'content1'", e2.c_str()); - - message = Message(Message::error, "content1"); - YAML::Emitter e3; - e3 << message; - EXPECT_STREQ("type: error\n" - "content: 'content1'", e3.c_str()); - - message = Message(Message::say, "content1", "condition1"); - YAML::Emitter e4; - e4 << message; - EXPECT_STREQ("type: say\n" - "content: 'content1'\n" - "condition: 'condition1'", e4.c_str()); - - message = Message(Message::say, MessageContents({ - MessageContent("content1", Language::english), - })); - YAML::Emitter e5; - e5 << message; - EXPECT_STREQ("type: say\n" - "content: 'content1'", e5.c_str()); - - message = Message(Message::say, MessageContents({ - MessageContent("content1", Language::english), - MessageContent("content2", Language::german) - })); - YAML::Emitter e6; - e6 << message; - EXPECT_STREQ("type: say\n" - "content:\n" - " - lang: en\n" - " str: 'content1'\n" - " - lang: de\n" - " str: 'content2'", e6.c_str()); - } - - TEST_F(MessageTest, YamlEncode) { - YAML::Node node; - - MessageContents mcs({MessageContent("content1", Language::english)}); - Message message(Message::say, "content1"); - node = message; - EXPECT_EQ("say", node["type"].as()); - EXPECT_EQ(mcs, node["content"].as()); - EXPECT_FALSE(node["condition"]); - - message = Message(Message::warn, "content1"); - node = message; - EXPECT_EQ("warn", node["type"].as()); - EXPECT_EQ(mcs, node["content"].as()); - EXPECT_FALSE(node["condition"]); - - message = Message(Message::error, "content1"); - node = message; - EXPECT_EQ("error", node["type"].as()); - EXPECT_EQ(mcs, node["content"].as()); - EXPECT_FALSE(node["condition"]); - - message = Message(Message::say, "content1", "condition1"); - node = message; - EXPECT_EQ("say", node["type"].as()); - EXPECT_EQ(mcs, node["content"].as()); - EXPECT_EQ("condition1", node["condition"].as()); - - mcs = MessageContents({ - MessageContent("content1", Language::english), - MessageContent("content2", Language::french), - }); - message = Message(Message::say, mcs); - node = message; - EXPECT_EQ("say", node["type"].as()); - EXPECT_EQ(mcs, node["content"].as()); - EXPECT_FALSE(node["condition"]); - } - - TEST_F(MessageTest, YamlDecode) { - YAML::Node node = YAML::Load("type: say\n" - "content: content1"); - Message message = node.as(); - EXPECT_EQ(Message::say, message.Type()); - EXPECT_EQ(MessageContents({MessageContent("content1", Language::english)}), message.Content()); - EXPECT_EQ("", message.Condition()); - - node = YAML::Load("type: warn\n" - "content: content1"); - message = node.as(); - EXPECT_EQ(Message::warn, message.Type()); - EXPECT_EQ(MessageContents({MessageContent("content1", Language::english)}), message.Content()); - EXPECT_EQ("", message.Condition()); - - node = YAML::Load("type: error\n" - "content: content1"); - message = node.as(); - EXPECT_EQ(Message::error, message.Type()); - EXPECT_EQ(MessageContents({MessageContent("content1", Language::english)}), message.Content()); - EXPECT_EQ("", message.Condition()); - - node = YAML::Load("type: invalid\n" - "content: content1"); - message = node.as(); - EXPECT_EQ(Message::say, message.Type()); - EXPECT_EQ(MessageContents({MessageContent("content1", Language::english)}), message.Content()); - EXPECT_EQ("", message.Condition()); - - node = YAML::Load("type: say\n" - "content: content1\n" - "condition: 'file(\"Foo.esp\")'"); - message = node.as(); - EXPECT_EQ(Message::say, message.Type()); - EXPECT_EQ(MessageContents({MessageContent("content1", Language::english)}), message.Content()); - EXPECT_EQ("file(\"Foo.esp\")", message.Condition()); - - node = YAML::Load("type: say\n" - "content:\n" - " - lang: en\n" - " str: content1\n" - " - lang: de\n" - " str: content2"); - message = node.as(); - EXPECT_EQ(Message::say, message.Type()); - EXPECT_EQ(MessageContents({ - MessageContent("content1", Language::english), - MessageContent("content2", Language::german), - }), message.Content()); - EXPECT_EQ("", message.Condition()); - - node = YAML::Load("type: say\n" - "content:\n" - " - lang: fr\n" - " str: content1"); - message = node.as(); - EXPECT_EQ(Message::say, message.Type()); - EXPECT_EQ(MessageContents({MessageContent("content1", Language::french)}), message.Content()); - EXPECT_EQ("", message.Condition()); - - // Throw because no English string is given in a multilingual message. - node = YAML::Load("type: say\n" - "content:\n" - " - lang: de\n" - " str: content1\n" - " - lang: fr\n" - " str: content2"); - EXPECT_THROW(node.as(), YAML::RepresentationException); - - node = YAML::Load("type: say\n" - "content: con%1%tent1\n" - "subs:\n" - " - sub1"); - message = node.as(); - EXPECT_EQ(Message::say, message.Type()); - EXPECT_EQ(MessageContents({MessageContent("consub1tent1", Language::english)}), message.Content()); - EXPECT_EQ("", message.Condition()); - - // Check that subs apply to all languages of a multilingual message. - node = YAML::Load("type: say\n" - "content:\n" - " - lang: en\n" - " str: content1 %1%\n" - " - lang: de\n" - " str: content2 %1%\n" - "subs:\n" - " - sub"); - message = node.as(); - EXPECT_EQ(Message::say, message.Type()); - EXPECT_EQ(MessageContents({ - MessageContent("content1 sub", Language::english), - MessageContent("content2 sub", Language::german), - }), message.Content()); - EXPECT_EQ("", message.Condition()); - - // Throw because there aren't the same number of subs as referred to in the content string. - node = YAML::Load("type: say\n" - "content: '%1% %2%'\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. - node = YAML::Load("type: say\n" - "content: con%1%tent1\n"); - message = node.as(); - EXPECT_EQ(Message::say, message.Type()); - EXPECT_EQ(MessageContents({MessageContent("con%1%tent1", Language::english)}), message.Content()); - EXPECT_EQ("", message.Condition()); - - node = YAML::Load("type: say\n" - "content: content1\n" - "condition: invalid"); - EXPECT_THROW(node.as(), YAML::RepresentationException); - - node = YAML::Load("scalar"); - EXPECT_THROW(node.as(), YAML::RepresentationException); - - node = YAML::Load("[0, 1, 2]"); - EXPECT_THROW(node.as(), YAML::RepresentationException); - } - } -} - -#endif diff --git a/src/tests/main.cpp b/src/tests/main.cpp index 7d4aab65..a3ef1ed5 100644 --- a/src/tests/main.cpp +++ b/src/tests/main.cpp @@ -54,7 +54,7 @@ #include "backend/metadata/conditional_metadata_test.h" #include "backend/metadata/file_test.h" #include "backend/metadata/location_test.h" -#include "backend/metadata/test_message.h" +#include "backend/metadata/message_test.h" #include "backend/metadata/test_message_content.h" #include "backend/metadata/test_plugin_dirty_info.h" #include "backend/metadata/test_plugin_metadata.h" From 7d3080c948f0f28ebbf97a365f0d25fc4676ab54 Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Sat, 26 Mar 2016 10:10:22 +0000 Subject: [PATCH 24/38] Throw if constructing a non-English multilingual message This matches the behaviour for when converting from YAML, ensuring that a non-English multilingual message can never be created. --- src/backend/metadata/message.cpp | 13 ++++++++++++- src/tests/backend/metadata/message_test.h | 8 ++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/backend/metadata/message.cpp b/src/backend/metadata/message.cpp index 92f6fb8f..a5d0eb8e 100644 --- a/src/backend/metadata/message.cpp +++ b/src/backend/metadata/message.cpp @@ -24,6 +24,7 @@ #include "message.h" #include "../helpers/language.h" +#include "../error.h" #include @@ -42,7 +43,17 @@ namespace loot { } Message::Message(const unsigned int type, const std::vector& content, - const std::string& condition) : _type(type), _content(content), ConditionalMetadata(condition) {} + const std::string& condition) : _type(type), _content(content), ConditionalMetadata(condition) { + if (content.size() > 1) { + bool englishStringExists = false; + for (const auto &mc : content) { + if (mc.Language() == loot::Language::english) + englishStringExists = true; + } + if (!englishStringExists) + throw loot::error(error::invalid_args, "bad conversion: multilingual messages must contain an English content string"); + } + } bool Message::operator < (const Message& rhs) const { if (!_content.empty() && !rhs.Content().empty()) diff --git a/src/tests/backend/metadata/message_test.h b/src/tests/backend/metadata/message_test.h index 8a375de4..1c6e2c3a 100644 --- a/src/tests/backend/metadata/message_test.h +++ b/src/tests/backend/metadata/message_test.h @@ -71,6 +71,14 @@ namespace loot { EXPECT_EQ("condition1", message.Condition()); } + TEST_P(MessageTest, vectorContentConstructorShouldThrowIfMultipleContentStringsAreGivenAndNoneAreEnglish) { + MessageContents contents({ + MessageContent("content1", Language::german), + MessageContent("content2", Language::french), + }); + EXPECT_ANY_THROW(Message(Message::error, contents, "condition1")); + } + TEST_P(MessageTest, messagesWithDifferentContentStringsShouldBeUnequal) { Message message1(Message::say, "content1", "condition1"); Message message2(Message::say, "content2", "condition1"); From bc3e06a5d9f229d5bb9287ed5a6ab768f1923716 Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Sat, 26 Mar 2016 10:45:50 +0000 Subject: [PATCH 25/38] Improve MessageContent tests --- CMakeLists.txt | 2 +- .../backend/metadata/message_content_test.h | 116 ++++++++++++++++++ .../backend/metadata/test_message_content.h | 112 ----------------- src/tests/main.cpp | 2 +- 4 files changed, 118 insertions(+), 114 deletions(-) create mode 100644 src/tests/backend/metadata/message_content_test.h delete mode 100644 src/tests/backend/metadata/test_message_content.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 88dacfde..25cc7666 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -249,7 +249,7 @@ set (LOOT_TESTS_HEADERS "${CMAKE_SOURCE_DIR}/src/tests/base_game_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/file_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/location_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/message_test.h" - "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/test_message_content.h" + "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/message_content_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/test_plugin_dirty_info.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/test_plugin_metadata.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/test_tag.h" diff --git a/src/tests/backend/metadata/message_content_test.h b/src/tests/backend/metadata/message_content_test.h new file mode 100644 index 00000000..3b6bc4fc --- /dev/null +++ b/src/tests/backend/metadata/message_content_test.h @@ -0,0 +1,116 @@ +/* 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_TEST_BACKEND_METADATA_MESSAGE_CONTENT +#define LOOT_TEST_BACKEND_METADATA_MESSAGE_CONTENT + +#include "backend/metadata/message_content.h" + +#include + +namespace loot { + namespace test { + TEST(MessageContent, defaultConstructorShouldSetEmptyEnglishLanguageString) { + MessageContent content; + + EXPECT_TRUE(content.Str().empty()); + EXPECT_EQ(Language::english, content.Language()); + } + + TEST(MessageContent, contentConstructorShouldStoreGivenStringAndLanguage) { + MessageContent content("content", Language::french); + + EXPECT_EQ("content", content.Str()); + EXPECT_EQ(Language::french, content.Language()); + } + + TEST(MessageContent, contentShouldBeEqualIfStringsAreCaseInsensitivelyEqual) { + MessageContent content1("content", Language::english); + MessageContent content2("Content", Language::french); + + EXPECT_TRUE(content1 == content2); + } + + TEST(MessageContent, contentShouldBeUnequalIfStringsAreNotCaseInsensitivelyEqual) { + MessageContent content1("content1", Language::french); + MessageContent content2("content2", Language::french); + + EXPECT_FALSE(content1 == content2); + } + + TEST(MessageContent, LessThanOperatorShouldUseCaseInsensitiveLexicographicalComparison) { + MessageContent content1("content", Language::english); + MessageContent content2("Content", Language::french); + + EXPECT_FALSE(content1 < content2); + EXPECT_FALSE(content2 < content1); + + content1 = MessageContent("content1", Language::french); + content2 = MessageContent("content2", Language::english); + + EXPECT_TRUE(content1 < content2); + EXPECT_FALSE(content2 < content1); + } + + TEST(MessageContent, emittingAsYamlShouldOutputDataCorrectly) { + MessageContent content("content", Language::french); + YAML::Emitter emitter; + emitter << content; + + EXPECT_EQ("lang: " + Language(content.Language()).Locale() + + "\nstr: '" + content.Str() + "'", emitter.c_str()); + } + + TEST(MessageContent, encodingAsYamlShouldOutputDataCorrectly) { + MessageContent content("content", Language::french); + YAML::Node node; + node = content; + + EXPECT_EQ(content.Str(), node["str"].as()); + EXPECT_EQ(Language(Language::french).Locale(), node["lang"].as()); + } + + TEST(MessageContent, decodingFromYamlShouldSetDataCorrectly) { + YAML::Node node = YAML::Load("{str: content, lang: de}"); + MessageContent content = node.as(); + + EXPECT_EQ("content", content.Str()); + EXPECT_EQ(Language::german, content.Language()); + } + + TEST(MessageContent, decodingFromYamlScalarShouldThrow) { + YAML::Node node = YAML::Load("scalar"); + + EXPECT_ANY_THROW(node.as()); + } + + TEST(MessageContent, decodingFromYamlListShouldThrow) { + YAML::Node node = YAML::Load("[0, 1, 2]"); + + EXPECT_ANY_THROW(node.as()); + } + } +} + +#endif diff --git a/src/tests/backend/metadata/test_message_content.h b/src/tests/backend/metadata/test_message_content.h deleted file mode 100644 index daa7251c..00000000 --- a/src/tests/backend/metadata/test_message_content.h +++ /dev/null @@ -1,112 +0,0 @@ -/* 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_TEST_BACKEND_METADATA_MESSAGE_CONTENT -#define LOOT_TEST_BACKEND_METADATA_MESSAGE_CONTENT - -#include "backend/metadata/message_content.h" -#include "tests/fixtures.h" - -namespace loot { - namespace test { - TEST(MessageContent, ConstructorsAndDataAccess) { - MessageContent mc; - EXPECT_EQ("", mc.Str()); - EXPECT_EQ(Language::english, mc.Language()); - - mc = MessageContent("content", Language::french); - EXPECT_EQ("content", mc.Str()); - EXPECT_EQ(Language::french, mc.Language()); - } - - TEST(MessageContent, EqualityOperator) { - MessageContent mc1, mc2; - EXPECT_TRUE(mc1 == mc2); - - mc1 = MessageContent("content", Language::french); - mc2 = MessageContent("Content", Language::french); - EXPECT_TRUE(mc1 == mc2); - - mc1 = MessageContent("content1", Language::french); - mc2 = MessageContent("content2", Language::french); - EXPECT_FALSE(mc1 == mc2); - - mc1 = MessageContent("content", Language::english); - mc2 = MessageContent("Content", Language::french); - EXPECT_TRUE(mc1 == mc2); - } - - TEST(MessageContent, LessThanOperator) { - MessageContent mc1, mc2; - EXPECT_FALSE(mc1 < mc2); - EXPECT_FALSE(mc2 < mc1); - - mc1 = MessageContent("content", Language::french); - mc2 = MessageContent("Content", Language::french); - EXPECT_FALSE(mc1 < mc2); - EXPECT_FALSE(mc2 < mc1); - - mc1 = MessageContent("content", Language::english); - mc2 = MessageContent("content", Language::french); - EXPECT_FALSE(mc1 < mc2); - EXPECT_FALSE(mc2 < mc1); - - mc1 = MessageContent("content1", Language::english); - mc2 = MessageContent("content2", Language::english); - EXPECT_TRUE(mc1 < mc2); - EXPECT_FALSE(mc2 < mc1); - } - - TEST(MessageContent, YamlEmitter) { - MessageContent mc("content", Language::french); - YAML::Emitter e1; - e1 << mc; - EXPECT_STREQ("lang: fr\nstr: 'content'", e1.c_str()); - } - - TEST(MessageContent, YamlEncode) { - YAML::Node node; - - MessageContent mc("content", Language::french); - node = mc; - EXPECT_EQ("content", node["str"].as()); - EXPECT_EQ("fr", node["lang"].as()); - } - - TEST(MessageContent, YamlDecode) { - YAML::Node node = YAML::Load("{str: content, lang: de}"); - MessageContent mc = node.as(); - EXPECT_EQ("content", mc.Str()); - EXPECT_EQ(Language::german, mc.Language()); - - node = YAML::Load("scalar"); - EXPECT_ANY_THROW(node.as()); - - node = YAML::Load("[0, 1, 2]"); - EXPECT_ANY_THROW(node.as()); - } - } -} - -#endif diff --git a/src/tests/main.cpp b/src/tests/main.cpp index a3ef1ed5..390067f7 100644 --- a/src/tests/main.cpp +++ b/src/tests/main.cpp @@ -55,7 +55,7 @@ #include "backend/metadata/file_test.h" #include "backend/metadata/location_test.h" #include "backend/metadata/message_test.h" -#include "backend/metadata/test_message_content.h" +#include "backend/metadata/message_content_test.h" #include "backend/metadata/test_plugin_dirty_info.h" #include "backend/metadata/test_plugin_metadata.h" #include "backend/metadata/test_tag.h" From 180fad64708b055af3c7c055ba17cff750f2cbdf Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Sat, 26 Mar 2016 11:41:40 +0000 Subject: [PATCH 26/38] Improve PluginDirtyInfo tests --- CMakeLists.txt | 2 +- ..._dirty_info.h => plugin_dirty_info_test.h} | 169 ++++++++---------- src/tests/main.cpp | 2 +- 3 files changed, 73 insertions(+), 100 deletions(-) rename src/tests/backend/metadata/{test_plugin_dirty_info.h => plugin_dirty_info_test.h} (55%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 25cc7666..90126edd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -250,7 +250,7 @@ set (LOOT_TESTS_HEADERS "${CMAKE_SOURCE_DIR}/src/tests/base_game_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/location_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/message_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/message_content_test.h" - "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/test_plugin_dirty_info.h" + "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/plugin_dirty_info_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/test_plugin_metadata.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/test_tag.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/plugin/test_plugin.h" diff --git a/src/tests/backend/metadata/test_plugin_dirty_info.h b/src/tests/backend/metadata/plugin_dirty_info_test.h similarity index 55% rename from src/tests/backend/metadata/test_plugin_dirty_info.h rename to src/tests/backend/metadata/plugin_dirty_info_test.h index 7dde296d..fca0b811 100644 --- a/src/tests/backend/metadata/test_plugin_dirty_info.h +++ b/src/tests/backend/metadata/plugin_dirty_info_test.h @@ -26,21 +26,30 @@ along with LOOT. If not, see #define LOOT_TEST_BACKEND_METADATA_PLUGIN_DIRTY_INFO #include "backend/metadata/plugin_dirty_info.h" -#include "tests/fixtures.h" +#include "tests/base_game_test.h" namespace loot { namespace test { - class PluginDirtyInfoTest : public SkyrimTest {}; + class PluginDirtyInfoTest : public BaseGameTest {}; - TEST_F(PluginDirtyInfoTest, ConstructorsAndDataAccess) { + // Pass an empty first argument, as it's a prefix for the test instantation, + // but we only have the one so no prefix is necessary. + INSTANTIATE_TEST_CASE_P(, + PluginDirtyInfoTest, + ::testing::Values( + GameSettings::tes4)); + + TEST_P(PluginDirtyInfoTest, defaultConstructorShouldLeaveAllCountsAtZeroAndTheUtilityStringEmpty) { PluginDirtyInfo info; EXPECT_EQ(0, info.CRC()); EXPECT_EQ(0, info.ITMs()); EXPECT_EQ(0, info.DeletedRefs()); EXPECT_EQ(0, info.DeletedNavmeshes()); - EXPECT_EQ("", info.CleaningUtility()); + EXPECT_TRUE(info.CleaningUtility().empty()); + } - info = PluginDirtyInfo(0x12345678, 2, 10, 30, "cleaner"); + TEST_P(PluginDirtyInfoTest, contentConstructorShouldStoreAllGivenData) { + PluginDirtyInfo info(0x12345678, 2, 10, 30, "cleaner"); EXPECT_EQ(0x12345678, info.CRC()); EXPECT_EQ(2, info.ITMs()); EXPECT_EQ(10, info.DeletedRefs()); @@ -48,10 +57,8 @@ namespace loot { EXPECT_EQ("cleaner", info.CleaningUtility()); } - TEST_F(PluginDirtyInfoTest, MessageOutput) { - Message message; - - message = PluginDirtyInfo(0x12345678, 2, 10, 30, "cleaner").AsMessage(); + TEST_P(PluginDirtyInfoTest, asMessageShouldOutputAllNonZeroCounts) { + Message message = PluginDirtyInfo(0x12345678, 2, 10, 30, "cleaner").AsMessage(); EXPECT_EQ(Message::warn, message.Type()); EXPECT_EQ("Contains 2 ITM records, 10 deleted references and 30 deleted navmeshes. Clean with cleaner.", message.ChooseContent(Language::english).Str()); @@ -84,12 +91,9 @@ namespace loot { EXPECT_EQ("Contains 2 ITM records and 10 deleted references. Clean with cleaner.", message.ChooseContent(Language::english).Str()); } - TEST_F(PluginDirtyInfoTest, EqualityOperator) { - PluginDirtyInfo info1, info2; - EXPECT_TRUE(info1 == info2); - - info1 = PluginDirtyInfo(0x12345678, 2, 10, 30, "cleaner1"); - info2 = PluginDirtyInfo(0x12345678, 4, 20, 60, "cleaner2"); + TEST_P(PluginDirtyInfoTest, dirtyInfoShouldBeEqualIfCrcValuesAreEqual) { + PluginDirtyInfo info1(0x12345678, 2, 10, 30, "cleaner1"); + PluginDirtyInfo info2(0x12345678, 4, 20, 60, "cleaner2"); EXPECT_TRUE(info1 == info2); info1 = PluginDirtyInfo(0x12345678, 2, 10, 30, "cleaner"); @@ -97,13 +101,9 @@ namespace loot { EXPECT_FALSE(info1 == info2); } - TEST_F(PluginDirtyInfoTest, LessThanOperator) { - PluginDirtyInfo info1, info2; - EXPECT_FALSE(info1 < info2); - EXPECT_FALSE(info2 < info1); - - info1 = PluginDirtyInfo(0x12345678, 2, 10, 30, "cleaner1"); - info2 = PluginDirtyInfo(0x12345678, 4, 20, 60, "cleaner2"); + TEST_P(PluginDirtyInfoTest, LessThanOperatorShouldCompareCrcValues) { + PluginDirtyInfo info1(0x12345678, 2, 10, 30, "cleaner1"); + PluginDirtyInfo info2(0x12345678, 4, 20, 60, "cleaner2"); EXPECT_FALSE(info1 < info2); EXPECT_FALSE(info2 < info1); @@ -113,81 +113,63 @@ namespace loot { EXPECT_FALSE(info2 < info1); } - TEST_F(PluginDirtyInfoTest, EvalConditionTrue) { - Game game(Game::tes5); + TEST_P(PluginDirtyInfoTest, evalConditionShouldBeTrueIfTheCrcGivenMatchesTheRealPluginCrc) { + Game game(GetParam()); game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); - PluginDirtyInfo dirtyInfo = PluginDirtyInfo(0x24F0E2A1, 2, 10, 30, "cleaner"); - EXPECT_TRUE(dirtyInfo.EvalCondition(game, "Blank.esp")); + PluginDirtyInfo dirtyInfo(blankEsmCrc, 2, 10, 30, "cleaner"); + EXPECT_TRUE(dirtyInfo.EvalCondition(game, blankEsm)); } - TEST_F(PluginDirtyInfoTest, EvalConditionFalse) { - Game game(Game::tes5); + TEST_P(PluginDirtyInfoTest, evalConditionShouldBeFalseIfTheCrcGivenDoesNotMatchTheRealPluginCrc) { + Game game(GetParam()); + game.SetGamePath(dataPath.parent_path()); + + PluginDirtyInfo dirtyInfo(0xDEADBEEF, 2, 10, 30, "cleaner"); + EXPECT_FALSE(dirtyInfo.EvalCondition(game, blankEsm)); + } + + TEST_P(PluginDirtyInfoTest, evalConditionShouldBeFalseIfAnEmptyPluginFilenameIsGiven) { + Game game(GetParam()); game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); PluginDirtyInfo dirtyInfo; EXPECT_FALSE(dirtyInfo.EvalCondition(game, "")); - - dirtyInfo = PluginDirtyInfo(0xDEADBEEF, 2, 10, 30, "cleaner"); - EXPECT_FALSE(dirtyInfo.EvalCondition(game, "Blank.esp")); } - TEST_F(PluginDirtyInfoTest, YamlEmitter) { - PluginDirtyInfo info; + TEST_P(PluginDirtyInfoTest, emittingAsYamlShouldOutputAllNonZeroCounts) { + PluginDirtyInfo info(0x12345678, 2, 10, 30, "cleaner"); + YAML::Emitter emitter; + emitter << info; - info = PluginDirtyInfo(0x12345678, 0, 0, 0, "cleaner"); - YAML::Emitter e1; - e1 << info; - EXPECT_STREQ("crc: 0x12345678\nutil: 'cleaner'", e1.c_str()); - - info = PluginDirtyInfo(0x12345678, 2, 0, 0, "cleaner"); - YAML::Emitter e2; - e2 << info; - EXPECT_STREQ("crc: 0x12345678\nutil: 'cleaner'\nitm: 2", e2.c_str()); - - info = PluginDirtyInfo(0x12345678, 2, 10, 0, "cleaner"); - YAML::Emitter e3; - e3 << info; - EXPECT_STREQ("crc: 0x12345678\nutil: 'cleaner'\nitm: 2\nudr: 10", e3.c_str()); - - info = PluginDirtyInfo(0x12345678, 2, 10, 30, "cleaner"); - YAML::Emitter e4; - e4 << info; - EXPECT_STREQ("crc: 0x12345678\nutil: 'cleaner'\nitm: 2\nudr: 10\nnav: 30", e4.c_str()); + EXPECT_STREQ("crc: 0x12345678\nutil: 'cleaner'\nitm: 2\nudr: 10\nnav: 30", emitter.c_str()); } - TEST_F(PluginDirtyInfoTest, YamlEncode) { + TEST_P(PluginDirtyInfoTest, emittingAsYamlShouldOmitAllZeroCounts) { + PluginDirtyInfo info(0x12345678, 0, 0, 0, "cleaner"); + YAML::Emitter emitter; + emitter << info; + + EXPECT_STREQ("crc: 0x12345678\nutil: 'cleaner'", emitter.c_str()); + } + + TEST_P(PluginDirtyInfoTest, encodingAsYamlShouldOmitAllZeroCountFields) { + PluginDirtyInfo info(0x12345678, 0, 0, 0, "cleaner"); YAML::Node node; - PluginDirtyInfo info; - - info = PluginDirtyInfo(0x12345678, 0, 0, 0, "cleaner"); node = info; + EXPECT_EQ(0x12345678, node["crc"].as()); EXPECT_EQ("cleaner", node["util"].as()); EXPECT_FALSE(node["itm"]); EXPECT_FALSE(node["udr"]); EXPECT_FALSE(node["nav"]); + } - info = PluginDirtyInfo(0x12345678, 2, 0, 0, "cleaner"); + TEST_P(PluginDirtyInfoTest, encodingAsYamlShouldOutputAllNonZeroCountFields) { + PluginDirtyInfo info(0x12345678, 2, 10, 30, "cleaner"); + YAML::Node node; node = info; - EXPECT_EQ(0x12345678, node["crc"].as()); - EXPECT_EQ("cleaner", node["util"].as()); - EXPECT_EQ(2, node["itm"].as()); - EXPECT_FALSE(node["udr"]); - EXPECT_FALSE(node["nav"]); - info = PluginDirtyInfo(0x12345678, 2, 10, 0, "cleaner"); - node = info; - EXPECT_EQ(0x12345678, node["crc"].as()); - EXPECT_EQ("cleaner", node["util"].as()); - EXPECT_EQ(2, node["itm"].as()); - EXPECT_EQ(10, node["udr"].as()); - EXPECT_FALSE(node["nav"]); - - info = PluginDirtyInfo(0x12345678, 2, 10, 30, "cleaner"); - node = info; EXPECT_EQ(0x12345678, node["crc"].as()); EXPECT_EQ("cleaner", node["util"].as()); EXPECT_EQ(2, node["itm"].as()); @@ -195,46 +177,37 @@ namespace loot { EXPECT_EQ(30, node["nav"].as()); } - TEST_F(PluginDirtyInfoTest, YamlDecode) { - YAML::Node node; - PluginDirtyInfo info; + TEST_P(PluginDirtyInfoTest, decodingFromYamlShouldLeaveMissingFieldsWithZeroValues) { + YAML::Node node = YAML::Load("{crc: 0x12345678, util: cleaner}"); + PluginDirtyInfo info = node.as(); - node = YAML::Load("{crc: 0x12345678, util: cleaner}"); - info = node.as(); EXPECT_EQ(0x12345678, info.CRC()); EXPECT_EQ(0, info.ITMs()); EXPECT_EQ(0, info.DeletedRefs()); EXPECT_EQ(0, info.DeletedNavmeshes()); EXPECT_EQ("cleaner", info.CleaningUtility()); + } - node = YAML::Load("{crc: 0x12345678, util: cleaner, itm: 2}"); - info = node.as(); - EXPECT_EQ(0x12345678, info.CRC()); - EXPECT_EQ(2, info.ITMs()); - EXPECT_EQ(0, info.DeletedRefs()); - EXPECT_EQ(0, info.DeletedNavmeshes()); - EXPECT_EQ("cleaner", info.CleaningUtility()); + TEST_P(PluginDirtyInfoTest, decodingFromYamlShouldStoreAllNonZeroCounts) { + YAML::Node node = YAML::Load("{crc: 0x12345678, util: cleaner, itm: 2, udr: 10, nav: 30}"); + PluginDirtyInfo info = node.as(); - node = YAML::Load("{crc: 0x12345678, util: cleaner, itm: 2, udr: 10}"); - info = node.as(); - EXPECT_EQ(0x12345678, info.CRC()); - EXPECT_EQ(2, info.ITMs()); - EXPECT_EQ(10, info.DeletedRefs()); - EXPECT_EQ(0, info.DeletedNavmeshes()); - EXPECT_EQ("cleaner", info.CleaningUtility()); - - node = YAML::Load("{crc: 0x12345678, util: cleaner, itm: 2, udr: 10, nav: 30}"); - info = node.as(); EXPECT_EQ(0x12345678, info.CRC()); EXPECT_EQ(2, info.ITMs()); EXPECT_EQ(10, info.DeletedRefs()); EXPECT_EQ(30, info.DeletedNavmeshes()); EXPECT_EQ("cleaner", info.CleaningUtility()); + } + + TEST_P(PluginDirtyInfoTest, decodingFromYamlScalarShouldThrow) { + YAML::Node node = YAML::Load("scalar"); - node = YAML::Load("scalar"); EXPECT_ANY_THROW(node.as()); + } + + TEST_P(PluginDirtyInfoTest, decodingFromYamlListShouldThrow) { + YAML::Node node = YAML::Load("[0, 1, 2]"); - node = YAML::Load("[0, 1, 2]"); EXPECT_ANY_THROW(node.as()); } } diff --git a/src/tests/main.cpp b/src/tests/main.cpp index 390067f7..035ea6cd 100644 --- a/src/tests/main.cpp +++ b/src/tests/main.cpp @@ -56,7 +56,7 @@ #include "backend/metadata/location_test.h" #include "backend/metadata/message_test.h" #include "backend/metadata/message_content_test.h" -#include "backend/metadata/test_plugin_dirty_info.h" +#include "backend/metadata/plugin_dirty_info_test.h" #include "backend/metadata/test_plugin_metadata.h" #include "backend/metadata/test_tag.h" #include "backend/plugin/test_plugin.h" From 8ebd2cfd0e5e1546680ffed068fe6cb5f73a251a Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Mon, 28 Mar 2016 09:56:43 +0100 Subject: [PATCH 27/38] Tidy the PluginMetadata code a little --- src/backend/metadata/plugin_metadata.cpp | 134 +++++++++++++++-------- 1 file changed, 87 insertions(+), 47 deletions(-) diff --git a/src/backend/metadata/plugin_metadata.cpp b/src/backend/metadata/plugin_metadata.cpp index edd37110..7cde12b5 100644 --- a/src/backend/metadata/plugin_metadata.cpp +++ b/src/backend/metadata/plugin_metadata.cpp @@ -50,7 +50,8 @@ namespace loot { if (plugin.HasNameOnly()) return; - //For 'enabled' and 'priority' metadata, use the given plugin's values, but if the 'priority' user value is not explicit, ignore it. + // For 'enabled' and 'priority' metadata, use the given plugin's values, + // but if the 'priority' user value is not explicit, ignore it. enabled = plugin.Enabled(); if (plugin.IsPriorityExplicit()) { Priority(plugin.Priority()); @@ -58,29 +59,24 @@ namespace loot { _isPriorityExplicit = true; } - //Merge the following. If any files in the source already exist in the destination, they will be skipped. Files have display strings and condition strings which aren't considered when comparing them, so will be lost if the plugin being merged in has additional data in these strings. - std::set files = plugin.LoadAfter(); - loadAfter.insert(files.begin(), files.end()); + // Merge the following. If any files in the source already exist in the + // destination, they will be skipped. Files have display strings and + // condition strings which aren't considered when comparing them, so + // will be lost if the plugin being merged in has additional data in + // these strings. + loadAfter.insert(begin(plugin.loadAfter), end(plugin.loadAfter)); + requirements.insert(begin(plugin.requirements), end(plugin.requirements)); + incompatibilities.insert(begin(plugin.incompatibilities), end(plugin.incompatibilities)); - files = plugin.Reqs(); - requirements.insert(files.begin(), files.end()); + // Merge Bash Tags too. Conditions are ignored during comparison, but + // if a tag is added and removed, both instances will be in the set. + tags.insert(begin(plugin.tags), end(plugin.tags)); - files = plugin.Incs(); - incompatibilities.insert(files.begin(), files.end()); + // Messages are in an ordered list, and should be fully merged. + messages.insert(end(messages), begin(plugin.messages), end(plugin.messages)); - //Merge Bash Tags too. Conditions are ignored during comparison, but if a tag is added and removed, both instances will be in the set. - std::set bashTags = plugin.Tags(); - tags.insert(bashTags.begin(), bashTags.end()); - - //Messages are in an ordered list, and should be fully merged. - std::list pMessages = plugin.Messages(); - messages.insert(messages.end(), pMessages.begin(), pMessages.end()); - - set dirtyInfo = plugin.DirtyInfo(); - _dirtyInfo.insert(dirtyInfo.begin(), dirtyInfo.end()); - - set locations = plugin.Locations(); - _locations.insert(locations.begin(), locations.end()); + _dirtyInfo.insert(begin(plugin._dirtyInfo), end(plugin._dirtyInfo)); + _locations.insert(begin(plugin._locations), end(plugin._locations)); return; } @@ -96,19 +92,28 @@ namespace loot { } //Compare this plugin against the given plugin. - set files = plugin.LoadAfter(); set filesDiff; - set_symmetric_difference(loadAfter.begin(), loadAfter.end(), files.begin(), files.end(), inserter(filesDiff, filesDiff.begin())); + set_symmetric_difference(begin(loadAfter), + end(loadAfter), + begin(plugin.loadAfter), + end(plugin.loadAfter), + inserter(filesDiff, begin(filesDiff))); p.LoadAfter(filesDiff); filesDiff.clear(); - files = plugin.Reqs(); - set_symmetric_difference(requirements.begin(), requirements.end(), files.begin(), files.end(), inserter(filesDiff, filesDiff.begin())); + set_symmetric_difference(begin(requirements), + end(requirements), + begin(plugin.requirements), + end(plugin.requirements), + inserter(filesDiff, begin(filesDiff))); p.Reqs(filesDiff); filesDiff.clear(); - files = plugin.Incs(); - set_symmetric_difference(incompatibilities.begin(), incompatibilities.end(), files.begin(), files.end(), inserter(filesDiff, filesDiff.begin())); + set_symmetric_difference(begin(incompatibilities), + end(incompatibilities), + begin(plugin.incompatibilities), + end(plugin.incompatibilities), + inserter(filesDiff, begin(filesDiff))); p.Incs(filesDiff); list msgs1 = plugin.Messages(); @@ -116,22 +121,35 @@ namespace loot { msgs1.sort(); msgs2.sort(); list mDiff; - set_symmetric_difference(msgs2.begin(), msgs2.end(), msgs1.begin(), msgs1.end(), inserter(mDiff, mDiff.begin())); + set_symmetric_difference(begin(msgs2), + end(msgs2), + begin(msgs1), + end(msgs1), + inserter(mDiff, begin(mDiff))); p.Messages(mDiff); - set bashTags = plugin.Tags(); set tagDiff; - set_symmetric_difference(tags.begin(), tags.end(), bashTags.begin(), bashTags.end(), inserter(tagDiff, tagDiff.begin())); + set_symmetric_difference(begin(tags), + end(tags), + begin(plugin.tags), + end(plugin.tags), + inserter(tagDiff, begin(tagDiff))); p.Tags(tagDiff); - set dirtyInfo = plugin.DirtyInfo(); set dirtDiff; - set_symmetric_difference(_dirtyInfo.begin(), _dirtyInfo.end(), dirtyInfo.begin(), dirtyInfo.end(), inserter(dirtDiff, dirtDiff.begin())); + set_symmetric_difference(begin(_dirtyInfo), + end(_dirtyInfo), + begin(plugin._dirtyInfo), + end(plugin._dirtyInfo), + inserter(dirtDiff, begin(dirtDiff))); p.DirtyInfo(dirtDiff); - set locations = plugin.Locations(); set locationsDiff; - set_symmetric_difference(_locations.begin(), _locations.end(), locations.begin(), locations.end(), inserter(locationsDiff, locationsDiff.begin())); + set_symmetric_difference(begin(_locations), + end(_locations), + begin(plugin._locations), + end(plugin._locations), + inserter(locationsDiff, begin(locationsDiff))); p.Locations(locationsDiff); return p; @@ -142,19 +160,28 @@ namespace loot { PluginMetadata p(*this); //Compare this plugin against the given plugin. - set files = plugin.LoadAfter(); set filesDiff; - set_difference(loadAfter.begin(), loadAfter.end(), files.begin(), files.end(), inserter(filesDiff, filesDiff.begin())); + set_difference(begin(loadAfter), + end(loadAfter), + begin(plugin.loadAfter), + end(plugin.loadAfter), + inserter(filesDiff, begin(filesDiff))); p.LoadAfter(filesDiff); filesDiff.clear(); - files = plugin.Reqs(); - set_difference(requirements.begin(), requirements.end(), files.begin(), files.end(), inserter(filesDiff, filesDiff.begin())); + set_difference(begin(requirements), + end(requirements), + begin(plugin.requirements), + end(plugin.requirements), + inserter(filesDiff, begin(filesDiff))); p.Reqs(filesDiff); filesDiff.clear(); - files = plugin.Incs(); - set_difference(incompatibilities.begin(), incompatibilities.end(), files.begin(), files.end(), inserter(filesDiff, filesDiff.begin())); + set_difference(begin(incompatibilities), + end(incompatibilities), + begin(plugin.incompatibilities), + end(plugin.incompatibilities), + inserter(filesDiff, begin(filesDiff))); p.Incs(filesDiff); list msgs1 = plugin.Messages(); @@ -162,22 +189,35 @@ namespace loot { msgs1.sort(); msgs2.sort(); list mDiff; - set_difference(msgs2.begin(), msgs2.end(), msgs1.begin(), msgs1.end(), inserter(mDiff, mDiff.begin())); + set_difference(begin(msgs2), + end(msgs2), + begin(msgs1), + end(msgs1), + inserter(mDiff, begin(mDiff))); p.Messages(mDiff); - set bashTags = plugin.Tags(); set tagDiff; - set_difference(tags.begin(), tags.end(), bashTags.begin(), bashTags.end(), inserter(tagDiff, tagDiff.begin())); + set_difference(begin(tags), + end(tags), + begin(plugin.tags), + end(plugin.tags), + inserter(tagDiff, begin(tagDiff))); p.Tags(tagDiff); - set dirtyInfo = plugin.DirtyInfo(); set dirtDiff; - set_difference(_dirtyInfo.begin(), _dirtyInfo.end(), dirtyInfo.begin(), dirtyInfo.end(), inserter(dirtDiff, dirtDiff.begin())); + set_difference(begin(_dirtyInfo), + end(_dirtyInfo), + begin(plugin._dirtyInfo), + end(plugin._dirtyInfo), + inserter(dirtDiff, begin(dirtDiff))); p.DirtyInfo(dirtDiff); - set locations = plugin.Locations(); set locationsDiff; - set_difference(_locations.begin(), _locations.end(), locations.begin(), locations.end(), inserter(locationsDiff, locationsDiff.begin())); + set_difference(begin(_locations), + end(_locations), + begin(plugin._locations), + end(plugin._locations), + inserter(locationsDiff, begin(locationsDiff))); p.Locations(locationsDiff); return p; From c08ad0fef2377e2fbbc7e677086a092fb8550ee9 Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Mon, 28 Mar 2016 09:56:32 +0100 Subject: [PATCH 28/38] Improve PluginMetadata tests --- CMakeLists.txt | 2 +- .../backend/metadata/plugin_metadata_test.h | 1084 +++++++++++++++++ .../backend/metadata/test_plugin_metadata.h | 953 --------------- src/tests/main.cpp | 2 +- 4 files changed, 1086 insertions(+), 955 deletions(-) create mode 100644 src/tests/backend/metadata/plugin_metadata_test.h delete mode 100644 src/tests/backend/metadata/test_plugin_metadata.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 90126edd..30a8d67a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -251,7 +251,7 @@ set (LOOT_TESTS_HEADERS "${CMAKE_SOURCE_DIR}/src/tests/base_game_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/message_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/message_content_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/plugin_dirty_info_test.h" - "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/test_plugin_metadata.h" + "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/plugin_metadata_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/test_tag.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/plugin/test_plugin.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/test_metadata_list.h" diff --git a/src/tests/backend/metadata/plugin_metadata_test.h b/src/tests/backend/metadata/plugin_metadata_test.h new file mode 100644 index 00000000..4c7e1d69 --- /dev/null +++ b/src/tests/backend/metadata/plugin_metadata_test.h @@ -0,0 +1,1084 @@ +/* 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_TEST_F_BACKEND_METADATA_PLUGIN_METADATA +#define LOOT_TEST_F_BACKEND_METADATA_PLUGIN_METADATA + +#include "backend/metadata/plugin_metadata.h" +#include "tests/base_game_test.h" + +namespace loot { + namespace test { + class PluginMetadataTest : public BaseGameTest {}; + + // Pass an empty first argument, as it's a prefix for the test instantation, + // but we only have the one so no prefix is necessary. + INSTANTIATE_TEST_CASE_P(, + PluginMetadataTest, + ::testing::Values( + GameSettings::tes5)); + + TEST_P(PluginMetadataTest, defaultConstructorShouldLeaveNameEmptyAndEnableMetadataAndLeaveAllOtherFieldsAtTheirDefaults) { + PluginMetadata plugin; + + EXPECT_TRUE(plugin.Name().empty()); + EXPECT_TRUE(plugin.Enabled()); + EXPECT_FALSE(plugin.IsPriorityExplicit()); + EXPECT_FALSE(plugin.IsPriorityGlobal()); + EXPECT_EQ(0, plugin.Priority()); + } + + TEST_P(PluginMetadataTest, stringConstructorShouldSetNameToGivenStringAndEnableMetadataAndLeaveAllOtherFieldsAtTheirDefaults) { + PluginMetadata plugin(blankEsm); + + EXPECT_EQ(blankEsm, plugin.Name()); + EXPECT_TRUE(plugin.Enabled()); + EXPECT_FALSE(plugin.IsPriorityExplicit()); + EXPECT_FALSE(plugin.IsPriorityGlobal()); + EXPECT_EQ(0, plugin.Priority()); + } + + TEST_P(PluginMetadataTest, equalityOperatorShouldUseCaseInsensitiveNameComparisonForNonRegexNames) { + PluginMetadata plugin1(blankEsm); + PluginMetadata plugin2(boost::to_lower_copy(blankEsm)); + EXPECT_TRUE(plugin1 == plugin2); + + plugin1 = PluginMetadata(blankEsm); + plugin2 = PluginMetadata(blankDifferentEsm); + EXPECT_FALSE(plugin1 == plugin2); + } + + TEST_P(PluginMetadataTest, equalityOperatorShouldUseCaseInsensitiveNameComparisonForTwoRegexNames) { + PluginMetadata plugin1("Blan.\\.esm"); + PluginMetadata plugin2("blan.\\.esm"); + EXPECT_TRUE(plugin1 == plugin2); + EXPECT_TRUE(plugin2 == plugin1); + + plugin1 = PluginMetadata("Blan(k|p).esm"); + plugin2 = PluginMetadata("Blan.\\.esm"); + EXPECT_FALSE(plugin1 == plugin2); + EXPECT_FALSE(plugin2 == plugin1); + } + + TEST_P(PluginMetadataTest, equalityOperatorShouldUseRegexMatchingForARegexNameAndANonRegexName) { + PluginMetadata plugin1("Blank.esm"); + PluginMetadata plugin2("Blan.\\.esm"); + EXPECT_TRUE(plugin1 == plugin2); + EXPECT_TRUE(plugin2 == plugin1); + + plugin1 = PluginMetadata("Blan.esm"); + plugin2 = PluginMetadata("Blan.\\.esm"); + EXPECT_FALSE(plugin1 == plugin2); + EXPECT_FALSE(plugin2 == plugin1); + } + + TEST_P(PluginMetadataTest, mergeMetadataShouldNotChangeName) { + PluginMetadata plugin1(blankEsm); + PluginMetadata plugin2(blankDifferentEsm); + + plugin1.MergeMetadata(plugin2); + + EXPECT_EQ(blankEsm, plugin1.Name()); + } + + TEST_P(PluginMetadataTest, mergeMetadataShouldNotUseMergedEnabledStateIfMergedMetadataIsEmpty) { + PluginMetadata plugin1; + PluginMetadata plugin2; + + plugin2.Enabled(false); + ASSERT_TRUE(plugin2.HasNameOnly()); + plugin1.MergeMetadata(plugin2); + + EXPECT_TRUE(plugin1.Enabled()); + } + + TEST_P(PluginMetadataTest, mergeMetadataShouldUseMergedEnabledStateIfMergedMetadataIsNotEmpty) { + PluginMetadata plugin1; + PluginMetadata plugin2; + + plugin2.Enabled(false); + plugin2.SetPriorityExplicit(true); + ASSERT_FALSE(plugin2.HasNameOnly()); + plugin1.MergeMetadata(plugin2); + + EXPECT_FALSE(plugin1.Enabled()); + } + + TEST_P(PluginMetadataTest, mergeMetadataShouldUseMergedNonZeroPriorityValue) { + PluginMetadata plugin1; + PluginMetadata plugin2; + + plugin1.Priority(5); + plugin2.Priority(3); + plugin1.MergeMetadata(plugin2); + + EXPECT_EQ(3, plugin1.Priority()); + } + + TEST_P(PluginMetadataTest, mergeMetadataShouldMergeAnExplicitPriorityValueOfZero) { + PluginMetadata plugin1; + PluginMetadata plugin2; + + plugin1.Priority(5); + plugin2.SetPriorityExplicit(true); + plugin1.MergeMetadata(plugin2); + + EXPECT_EQ(0, plugin1.Priority()); + } + + TEST_P(PluginMetadataTest, mergeMetadataShouldNotMergeNonExplicitGlobalPriorityState) { + PluginMetadata plugin1; + PluginMetadata plugin2; + + plugin2.SetPriorityGlobal(true); + plugin1.MergeMetadata(plugin2); + + EXPECT_FALSE(plugin1.IsPriorityGlobal()); + } + + TEST_P(PluginMetadataTest, mergeMetadataShouldMergeExplicitGlobalPriorityState) { + PluginMetadata plugin1; + PluginMetadata plugin2; + + plugin2.SetPriorityExplicit(true); + plugin2.SetPriorityGlobal(true); + plugin1.MergeMetadata(plugin2); + + EXPECT_TRUE(plugin1.IsPriorityGlobal()); + } + + TEST_P(PluginMetadataTest, mergeMetadataShouldMergeTrueExplicitPriorityState) { + PluginMetadata plugin1; + PluginMetadata plugin2; + + plugin2.SetPriorityExplicit(true); + plugin1.MergeMetadata(plugin2); + + EXPECT_TRUE(plugin1.IsPriorityExplicit()); + } + + TEST_P(PluginMetadataTest, mergeMetadataShouldNotMergeFalseExplicitPriorityState) { + PluginMetadata plugin1; + PluginMetadata plugin2; + + plugin1.SetPriorityExplicit(true); + plugin1.MergeMetadata(plugin2); + + EXPECT_TRUE(plugin1.IsPriorityExplicit()); + } + + TEST_P(PluginMetadataTest, mergeMetadataShouldMergeLoadAfterData) { + PluginMetadata plugin1; + PluginMetadata plugin2; + File file1(blankEsm); + File file2(blankDifferentEsm); + + plugin1.LoadAfter({file1}); + plugin2.LoadAfter({file1, file2}); + plugin1.MergeMetadata(plugin2); + + EXPECT_EQ(std::set({file1, file2}), plugin1.LoadAfter()); + } + + TEST_P(PluginMetadataTest, mergeMetadataShouldMergeRequirementData) { + PluginMetadata plugin1; + PluginMetadata plugin2; + File file1(blankEsm); + File file2(blankDifferentEsm); + + plugin1.Reqs({file1}); + plugin2.Reqs({file1, file2}); + plugin1.MergeMetadata(plugin2); + + EXPECT_EQ(std::set({file1, file2}), plugin1.Reqs()); + } + + TEST_P(PluginMetadataTest, mergeMetadataShouldMergeIncompatibilityData) { + PluginMetadata plugin1; + PluginMetadata plugin2; + File file1(blankEsm); + File file2(blankDifferentEsm); + + plugin1.Incs({file1}); + plugin2.Incs({file1, file2}); + plugin1.MergeMetadata(plugin2); + + EXPECT_EQ(std::set({file1, file2}), plugin1.Incs()); + } + + TEST_P(PluginMetadataTest, mergeMetadataShouldMergeMessages) { + PluginMetadata plugin1; + PluginMetadata plugin2; + Message message(Message::say, "content"); + + plugin1.Messages({message}); + plugin2.Messages({message}); + plugin1.MergeMetadata(plugin2); + + EXPECT_EQ(std::list({message, message}), plugin1.Messages()); + } + + TEST_P(PluginMetadataTest, mergeMetadataShouldMergeTags) { + PluginMetadata plugin1; + PluginMetadata plugin2; + Tag tag1("Relev"); + Tag tag2("Relev", false); + Tag tag3("Delev"); + + plugin1.Tags({tag1}); + plugin2.Tags({tag1, tag2, tag3}); + plugin1.MergeMetadata(plugin2); + + EXPECT_EQ(std::set({tag1, tag2, tag3}), plugin1.Tags()); + } + + TEST_P(PluginMetadataTest, mergeMetadataShouldMergeDirtyInfoData) { + PluginMetadata plugin1; + PluginMetadata plugin2; + PluginDirtyInfo info1(0x5, 1, 2, 3, "utility"); + PluginDirtyInfo info2(0xA, 1, 2, 3, "utility"); + + plugin1.DirtyInfo({info1}); + plugin2.DirtyInfo({info1, info2}); + plugin1.MergeMetadata(plugin2); + + EXPECT_EQ(std::set({info1, info2}), plugin1.DirtyInfo()); + } + + TEST_P(PluginMetadataTest, mergeMetadataShouldMergeLocationData) { + PluginMetadata plugin1; + PluginMetadata plugin2; + Location location1("http://www.example.com/1"); + Location location2("http://www.example.com/2"); + + plugin1.Locations({location1}); + plugin2.Locations({location1, location2}); + plugin1.MergeMetadata(plugin2); + + EXPECT_EQ(std::set({location1, location2}), plugin1.Locations()); + } + + TEST_P(PluginMetadataTest, diffMetadataShouldUseSourcePluginName) { + PluginMetadata plugin1(blankEsm); + PluginMetadata plugin2(blankDifferentEsm); + + PluginMetadata diff = plugin1.DiffMetadata(plugin2); + + EXPECT_EQ(blankEsm, diff.Name()); + } + + TEST_P(PluginMetadataTest, diffMetadataShouldUseSourcePluginEnabledState) { + PluginMetadata plugin1; + PluginMetadata plugin2; + + plugin2.Enabled(false); + PluginMetadata diff = plugin1.DiffMetadata(plugin2); + + EXPECT_TRUE(diff.Enabled()); + + plugin1.Enabled(false); + diff = plugin1.DiffMetadata(plugin2); + + EXPECT_FALSE(diff.Enabled()); + } + + TEST_P(PluginMetadataTest, diffMetadataShouldUseSourcePluginPriorityDataIfItDiffersFromTheTargetPluginPriorityData) { + PluginMetadata plugin1; + PluginMetadata plugin2; + + plugin1.SetPriorityGlobal(true); + PluginMetadata diff = plugin1.DiffMetadata(plugin2); + + EXPECT_EQ(0, diff.Priority()); + EXPECT_FALSE(diff.IsPriorityExplicit()); + EXPECT_TRUE(diff.IsPriorityGlobal()); + + plugin1.Priority(5); + plugin1.SetPriorityGlobal(false); + diff = plugin1.DiffMetadata(plugin2); + + EXPECT_EQ(5, diff.Priority()); + EXPECT_TRUE(diff.IsPriorityExplicit()); + EXPECT_FALSE(diff.IsPriorityGlobal()); + } + + TEST_P(PluginMetadataTest, diffMetadataShouldOutputDefaultPriorityDataIfTheSourceAndTargetPluginPriorityDataMatch) { + PluginMetadata plugin1; + PluginMetadata plugin2; + + plugin1.Priority(5); + plugin1.SetPriorityGlobal(true); + plugin2.Priority(5); + plugin2.SetPriorityGlobal(true); + PluginMetadata diff = plugin1.DiffMetadata(plugin2); + + EXPECT_EQ(0, diff.Priority()); + EXPECT_FALSE(diff.IsPriorityExplicit()); + EXPECT_FALSE(diff.IsPriorityGlobal()); + } + + TEST_P(PluginMetadataTest, diffMetadataShouldOutputLoadAfterDataThatAreNotCommonToBothInputPlugins) { + PluginMetadata plugin1; + PluginMetadata plugin2; + File file1(blankEsm); + File file2(blankDifferentEsm); + File file3(blankEsp); + + plugin1.LoadAfter({file1, file2}); + plugin2.LoadAfter({file1, file3}); + PluginMetadata diff = plugin1.DiffMetadata(plugin2); + + EXPECT_EQ(std::set({file2, file3}), diff.LoadAfter()); + } + + TEST_P(PluginMetadataTest, diffMetadataShouldOutputRequirementsDataThatAreNotCommonToBothInputPlugins) { + PluginMetadata plugin1; + PluginMetadata plugin2; + File file1(blankEsm); + File file2(blankDifferentEsm); + File file3(blankEsp); + + plugin1.Reqs({file1, file2}); + plugin2.Reqs({file1, file3}); + PluginMetadata diff = plugin1.DiffMetadata(plugin2); + + EXPECT_EQ(std::set({file2, file3}), diff.Reqs()); + } + + TEST_P(PluginMetadataTest, diffMetadataShouldOutputIncompatibilityDataThatAreNotCommonToBothInputPlugins) { + PluginMetadata plugin1; + PluginMetadata plugin2; + File file1(blankEsm); + File file2(blankDifferentEsm); + File file3(blankEsp); + + plugin1.Incs({file1, file2}); + plugin2.Incs({file1, file3}); + PluginMetadata diff = plugin1.DiffMetadata(plugin2); + + EXPECT_EQ(std::set({file2, file3}), diff.Incs()); + } + + TEST_P(PluginMetadataTest, diffMetadataShouldOutputMessagesThatAreNotCommonToBothInputPlugins) { + PluginMetadata plugin1; + PluginMetadata plugin2; + Message message1(Message::say, "content1"); + Message message2(Message::say, "content2"); + Message message3(Message::say, "content3"); + + plugin1.Messages({message1, message2}); + plugin2.Messages({message1, message3}); + PluginMetadata diff = plugin1.DiffMetadata(plugin2); + + EXPECT_EQ(std::list({message2, message3}), diff.Messages()); + } + + TEST_P(PluginMetadataTest, diffMetadataShouldOutputTagsThatAreNotCommonToBothInputPlugins) { + PluginMetadata plugin1; + PluginMetadata plugin2; + Tag tag1("Relev"); + Tag tag2("Relev", false); + Tag tag3("Delev"); + + plugin1.Tags({tag1, tag2}); + plugin2.Tags({tag1, tag3}); + PluginMetadata diff = plugin1.DiffMetadata(plugin2); + + EXPECT_EQ(std::set({tag2, tag3}), diff.Tags()); + } + + TEST_P(PluginMetadataTest, diffMetadataShouldOutputDirtyInfoObjectsThatAreNotCommonToBothInputPlugins) { + PluginMetadata plugin1; + PluginMetadata plugin2; + PluginDirtyInfo info1(0x5, 1, 2, 3, "utility"); + PluginDirtyInfo info2(0xA, 1, 2, 3, "utility"); + PluginDirtyInfo info3(0x1, 1, 2, 3, "utility"); + + plugin1.DirtyInfo({info1, info2}); + plugin2.DirtyInfo({info1, info3}); + PluginMetadata diff = plugin1.DiffMetadata(plugin2); + + EXPECT_EQ(std::set({info2, info3}), diff.DirtyInfo()); + } + + TEST_P(PluginMetadataTest, diffMetadataShouldOutputLocationsThatAreNotCommonToBothInputPlugins) { + PluginMetadata plugin1; + PluginMetadata plugin2; + Location location1("http://www.example.com/1"); + Location location2("http://www.example.com/2"); + Location location3("http://www.example.com/3"); + + plugin1.Locations({location1, location2}); + plugin2.Locations({location1, location3}); + PluginMetadata diff = plugin1.DiffMetadata(plugin2); + + EXPECT_EQ(std::set({location2, location3}), diff.Locations()); + } + + TEST_P(PluginMetadataTest, newMetadataShouldUseSourcePluginName) { + PluginMetadata plugin1(blankEsm); + PluginMetadata plugin2(blankDifferentEsm); + + PluginMetadata newMetadata = plugin1.NewMetadata(plugin2); + + EXPECT_EQ(blankEsm, newMetadata.Name()); + } + + TEST_P(PluginMetadataTest, newMetadataShouldUseSourcePluginEnabledState) { + PluginMetadata plugin1; + PluginMetadata plugin2; + + plugin2.Enabled(false); + PluginMetadata newMetadata = plugin1.NewMetadata(plugin2); + + EXPECT_TRUE(newMetadata.Enabled()); + + plugin1.Enabled(false); + newMetadata = plugin1.NewMetadata(plugin2); + + EXPECT_FALSE(newMetadata.Enabled()); + } + + TEST_P(PluginMetadataTest, newMetadataShouldUseSourcePluginPriorityData) { + PluginMetadata plugin1; + PluginMetadata plugin2; + + plugin1.Priority(5); + plugin1.SetPriorityGlobal(true); + PluginMetadata newMetadata = plugin1.NewMetadata(plugin2); + + EXPECT_EQ(5, newMetadata.Priority()); + EXPECT_TRUE(newMetadata.IsPriorityExplicit()); + EXPECT_TRUE(newMetadata.IsPriorityGlobal()); + } + + TEST_P(PluginMetadataTest, newMetadataShouldOutputLoadAfterDataThatAreNotCommonToBothInputPlugins) { + PluginMetadata plugin1; + PluginMetadata plugin2; + File file1(blankEsm); + File file2(blankDifferentEsm); + File file3(blankEsp); + + plugin1.LoadAfter({file1, file2}); + plugin2.LoadAfter({file1, file3}); + PluginMetadata newMetadata = plugin1.NewMetadata(plugin2); + + EXPECT_EQ(std::set({file2}), newMetadata.LoadAfter()); + } + + TEST_P(PluginMetadataTest, newMetadataShouldOutputRequirementsDataThatAreNotCommonToBothInputPlugins) { + PluginMetadata plugin1; + PluginMetadata plugin2; + File file1(blankEsm); + File file2(blankDifferentEsm); + File file3(blankEsp); + + plugin1.Reqs({file1, file2}); + plugin2.Reqs({file1, file3}); + PluginMetadata newMetadata = plugin1.NewMetadata(plugin2); + + EXPECT_EQ(std::set({file2}), newMetadata.Reqs()); + } + + TEST_P(PluginMetadataTest, newMetadataShouldOutputIncompatibilityDataThatAreNotCommonToBothInputPlugins) { + PluginMetadata plugin1; + PluginMetadata plugin2; + File file1(blankEsm); + File file2(blankDifferentEsm); + File file3(blankEsp); + + plugin1.Incs({file1, file2}); + plugin2.Incs({file1, file3}); + PluginMetadata newMetadata = plugin1.NewMetadata(plugin2); + + EXPECT_EQ(std::set({file2}), newMetadata.Incs()); + } + + TEST_P(PluginMetadataTest, newMetadataShouldOutputMessagesThatAreNotCommonToBothInputPlugins) { + PluginMetadata plugin1; + PluginMetadata plugin2; + Message message1(Message::say, "content1"); + Message message2(Message::say, "content2"); + Message message3(Message::say, "content3"); + + plugin1.Messages({message1, message2}); + plugin2.Messages({message1, message3}); + PluginMetadata newMetadata = plugin1.NewMetadata(plugin2); + + EXPECT_EQ(std::list({message2}), newMetadata.Messages()); + } + + TEST_P(PluginMetadataTest, newMetadataShouldOutputTagsThatAreNotCommonToBothInputPlugins) { + PluginMetadata plugin1; + PluginMetadata plugin2; + Tag tag1("Relev"); + Tag tag2("Relev", false); + Tag tag3("Delev"); + + plugin1.Tags({tag1, tag2}); + plugin2.Tags({tag1, tag3}); + PluginMetadata newMetadata = plugin1.NewMetadata(plugin2); + + EXPECT_EQ(std::set({tag2}), newMetadata.Tags()); + } + + TEST_P(PluginMetadataTest, newMetadataShouldOutputDirtyInfoObjectsThatAreNotCommonToBothInputPlugins) { + PluginMetadata plugin1; + PluginMetadata plugin2; + PluginDirtyInfo info1(0x5, 1, 2, 3, "utility"); + PluginDirtyInfo info2(0xA, 1, 2, 3, "utility"); + PluginDirtyInfo info3(0x1, 1, 2, 3, "utility"); + + plugin1.DirtyInfo({info1, info2}); + plugin2.DirtyInfo({info1, info3}); + PluginMetadata newMetadata = plugin1.NewMetadata(plugin2); + + EXPECT_EQ(std::set({info2}), newMetadata.DirtyInfo()); + } + + TEST_P(PluginMetadataTest, newMetadataShouldOutputLocationsThatAreNotCommonToBothInputPlugins) { + PluginMetadata plugin1; + PluginMetadata plugin2; + Location location1("http://www.example.com/1"); + Location location2("http://www.example.com/2"); + Location location3("http://www.example.com/3"); + + plugin1.Locations({location1, location2}); + plugin2.Locations({location1, location3}); + PluginMetadata newMetadata = plugin1.NewMetadata(plugin2); + + EXPECT_EQ(std::set({location2}), newMetadata.Locations()); + } + + TEST_P(PluginMetadataTest, settingPriorityWithAbsoluteValueGreaterOrEqualToGlobalPriorityDivisorShouldThrow) { + PluginMetadata plugin; + EXPECT_ANY_THROW(plugin.Priority(yamlGlobalPriorityDivisor)); + EXPECT_ANY_THROW(plugin.Priority(yamlGlobalPriorityDivisor + 1)); + EXPECT_ANY_THROW(plugin.Priority(-yamlGlobalPriorityDivisor)); + EXPECT_ANY_THROW(plugin.Priority(-yamlGlobalPriorityDivisor - 1)); + } + + TEST_P(PluginMetadataTest, settingPriorityAsGlobalShouldSucceed) { + PluginMetadata plugin; + ASSERT_FALSE(plugin.IsPriorityGlobal()); + plugin.SetPriorityGlobal(true); + EXPECT_TRUE(plugin.IsPriorityGlobal()); + } + + TEST_P(PluginMetadataTest, settingPriorityAsNotGlobalShouldSucceed) { + PluginMetadata plugin; + plugin.SetPriorityGlobal(true); + ASSERT_TRUE(plugin.IsPriorityGlobal()); + plugin.SetPriorityGlobal(false); + EXPECT_FALSE(plugin.IsPriorityGlobal()); + } + + TEST_P(PluginMetadataTest, gettingYamlPriorityValueForAGlobalPriorityShouldReturnValueWithGlobalFlagSet) { + PluginMetadata plugin; + plugin.Priority(10); + plugin.SetPriorityGlobal(true); + EXPECT_EQ(1000010, plugin.GetYamlPriorityValue()); + + plugin.Priority(-20); + EXPECT_EQ(-1000020, plugin.GetYamlPriorityValue()); + } + + TEST_P(PluginMetadataTest, gettingYamlPriorityValueForANonGlobalPriorityShouldReturnValueWithGlobalFlagNotSet) { + PluginMetadata plugin; + plugin.Priority(10); + EXPECT_EQ(10, plugin.GetYamlPriorityValue()); + + plugin.Priority(-20); + EXPECT_EQ(-20, plugin.GetYamlPriorityValue()); + } + + TEST_P(PluginMetadataTest, evalAllConditionsShouldEvaluateAllMetadataConditions) { + Game game(GetParam()); + game.SetGamePath(dataPath.parent_path()); + + PluginMetadata plugin(blankEsm); + + File file1(blankEsp); + File file2(blankDifferentEsm, "", "file(\"" + missingEsp + "\")"); + plugin.LoadAfter({file1, file2}); + plugin.Reqs({file1, file2}); + plugin.Incs({file1, file2}); + + Message message1(Message::say, "content"); + Message message2(Message::say, "content", "file(\"" + missingEsp + "\")"); + plugin.Messages({message1, message2}); + + Tag tag1("Relev"); + Tag tag2("Relev", true, "file(\"" + missingEsp + "\")"); + plugin.Tags({tag1, tag2}); + + PluginDirtyInfo info1(blankEsmCrc, 1, 2, 3, "utility"); + PluginDirtyInfo info2(0xDEADBEEF, 1, 2, 3, "utility"); + plugin.DirtyInfo({info1, info2}); + + EXPECT_NO_THROW(plugin.EvalAllConditions(game, Language::english)); + + std::set expectedFiles({file1}); + EXPECT_EQ(expectedFiles, plugin.LoadAfter()); + EXPECT_EQ(expectedFiles, plugin.Reqs()); + EXPECT_EQ(expectedFiles, plugin.Incs()); + EXPECT_EQ(std::list({message1}), plugin.Messages()); + EXPECT_EQ(std::set({tag1}), plugin.Tags()); + EXPECT_EQ(std::set({info1}), plugin.DirtyInfo()); + } + + TEST_P(PluginMetadataTest, hasNameOnlyShouldBeTrueForADefaultConstructedPluginMetadataObject) { + PluginMetadata plugin; + + EXPECT_TRUE(plugin.HasNameOnly()); + } + + TEST_P(PluginMetadataTest, hasNameOnlyShouldBeTrueForAPluginMetadataObjectConstructedWithAName) { + PluginMetadata plugin(blankEsp); + + EXPECT_TRUE(plugin.HasNameOnly()); + } + + TEST_P(PluginMetadataTest, hasNameOnlyShouldBeTrueIfThePluginMetadataIsDisabled) { + PluginMetadata plugin(blankEsp); + plugin.Enabled(false); + + EXPECT_TRUE(plugin.HasNameOnly()); + } + + TEST_P(PluginMetadataTest, hasNameOnlyShouldBeFalseIfThePriorityValueIsExplicit) { + PluginMetadata plugin(blankEsp); + plugin.SetPriorityExplicit(true); + + EXPECT_FALSE(plugin.HasNameOnly()); + } + + TEST_P(PluginMetadataTest, hasNameOnlyShouldBeFalseIfLoadAfterMetadataExists) { + PluginMetadata plugin(blankEsp); + plugin.LoadAfter({File(blankEsm)}); + + EXPECT_FALSE(plugin.HasNameOnly()); + } + + TEST_P(PluginMetadataTest, hasNameOnlyShouldBeFalseIfRequirementMetadataExists) { + PluginMetadata plugin(blankEsp); + plugin.Reqs({File(blankEsm)}); + + EXPECT_FALSE(plugin.HasNameOnly()); + } + + TEST_P(PluginMetadataTest, hasNameOnlyShouldBeFalseIfIncompatibilityMetadataExists) { + PluginMetadata plugin(blankEsp); + plugin.Incs({File(blankEsm)}); + + EXPECT_FALSE(plugin.HasNameOnly()); + } + + TEST_P(PluginMetadataTest, hasNameOnlyShouldBeFalseIfMessagesExist) { + PluginMetadata plugin(blankEsp); + plugin.Messages({Message(Message::say, "content")}); + + EXPECT_FALSE(plugin.HasNameOnly()); + } + + TEST_P(PluginMetadataTest, hasNameOnlyShouldBeFalseIfTagsExist) { + PluginMetadata plugin(blankEsp); + plugin.Tags({Tag("Relev")}); + + EXPECT_FALSE(plugin.HasNameOnly()); + } + + TEST_P(PluginMetadataTest, hasNameOnlyShouldBeFalseIfDirtyInfoExists) { + PluginMetadata plugin(blankEsp); + plugin.DirtyInfo({PluginDirtyInfo(5, 0, 1, 2, "utility")}); + + EXPECT_FALSE(plugin.HasNameOnly()); + } + + TEST_P(PluginMetadataTest, hasNameOnlyShouldBeFalseIfLocationsExist) { + PluginMetadata plugin(blankEsp); + plugin.Locations({Location("http://www.example.com")}); + + EXPECT_FALSE(plugin.HasNameOnly()); + } + + TEST_P(PluginMetadataTest, isRegexPluginShouldBeFalseForAnEmptyPluginName) { + PluginMetadata plugin; + + EXPECT_FALSE(plugin.IsRegexPlugin()); + } + + TEST_P(PluginMetadataTest, isRegexPluginShouldBeFalseForAnExactPluginFilename) { + PluginMetadata plugin(blankEsm); + + EXPECT_FALSE(plugin.IsRegexPlugin()); + } + + TEST_P(PluginMetadataTest, isRegexPluginShouldBeTrueIfThePluginNameContainsAColon) { + PluginMetadata plugin("Blank:.esm"); + + EXPECT_TRUE(plugin.IsRegexPlugin()); + } + + TEST_P(PluginMetadataTest, isRegexPluginShouldBeTrueIfThePluginNameContainsABackslash) { + PluginMetadata plugin("Blank\\.esm"); + + EXPECT_TRUE(plugin.IsRegexPlugin()); + } + + TEST_P(PluginMetadataTest, isRegexPluginShouldBeTrueIfThePluginNameContainsAnAsterisk) { + PluginMetadata plugin("Blank*.esm"); + + EXPECT_TRUE(plugin.IsRegexPlugin()); + } + + TEST_P(PluginMetadataTest, isRegexPluginShouldBeTrueIfThePluginNameContainsAQuestionMark) { + PluginMetadata plugin("Blank?.esm"); + + EXPECT_TRUE(plugin.IsRegexPlugin()); + } + + TEST_P(PluginMetadataTest, isRegexPluginShouldBeTrueIfThePluginNameContainsAVerticalBar) { + PluginMetadata plugin("Blank|.esm"); + + EXPECT_TRUE(plugin.IsRegexPlugin()); + } + + TEST_P(PluginMetadataTest, emittingAsYamlShouldOutputAPluginWithNoMetadataAsABlankString) { + PluginMetadata plugin(blankEsm); + YAML::Emitter emitter; + emitter << plugin; + + EXPECT_STREQ("", emitter.c_str()); + } + + TEST_P(PluginMetadataTest, emittingAsYamlShouldOutputAPluginWithAnExplicitPriorityCorrectly) { + PluginMetadata plugin(blankEsm); + plugin.SetPriorityExplicit(true); + + YAML::Emitter emitter; + emitter << plugin; + + EXPECT_STREQ("name: 'Blank.esm'\n" + "priority: 0", emitter.c_str()); + } + + TEST_P(PluginMetadataTest, emittingAsYamlShouldOutputAPluginWithAnExplicitPriorityThatIsDisabledCorrectly) { + PluginMetadata plugin(blankEsm); + plugin.SetPriorityExplicit(true); + plugin.Enabled(false); + + YAML::Emitter emitter; + emitter << plugin; + + EXPECT_STREQ("name: 'Blank.esm'\n" + "priority: 0\n" + "enabled: false", emitter.c_str()); + } + + TEST_P(PluginMetadataTest, emittingAsYamlShouldOutputAPluginWithLoadAfterMetadataCorrectly) { + PluginMetadata plugin(blankEsp); + plugin.LoadAfter({File(blankEsm)}); + + YAML::Emitter emitter; + emitter << plugin; + + EXPECT_STREQ("name: 'Blank.esp'\n" + "after:\n" + " - 'Blank.esm'", emitter.c_str()); + } + + TEST_P(PluginMetadataTest, emittingAsYamlShouldOutputAPluginWithRequirementsCorrectly) { + PluginMetadata plugin(blankEsp); + plugin.Reqs({File(blankEsm)}); + + YAML::Emitter emitter; + emitter << plugin; + + EXPECT_STREQ("name: 'Blank.esp'\n" + "req:\n" + " - 'Blank.esm'", emitter.c_str()); + } + + TEST_P(PluginMetadataTest, emittingAsYamlShouldOutputAPluginWithIncompatibilitiesCorrectly) { + PluginMetadata plugin(blankEsp); + plugin.Incs({File(blankEsm)}); + + YAML::Emitter emitter; + emitter << plugin; + + EXPECT_STREQ("name: 'Blank.esp'\n" + "inc:\n" + " - 'Blank.esm'", emitter.c_str()); + } + + TEST_P(PluginMetadataTest, emittingAsYamlShouldOutputAPluginWithMessagesCorrectly) { + PluginMetadata plugin(blankEsp); + plugin.Messages({Message(Message::say, "content")}); + + YAML::Emitter emitter; + emitter << plugin; + + EXPECT_STREQ("name: 'Blank.esp'\n" + "msg:\n" + " - type: say\n" + " content: 'content'", emitter.c_str()); + } + + TEST_P(PluginMetadataTest, emittingAsYamlShouldOutputAPluginWithTagsCorrectly) { + PluginMetadata plugin(blankEsp); + plugin.Tags({Tag("Relev")}); + + YAML::Emitter emitter; + emitter << plugin; + + EXPECT_STREQ("name: 'Blank.esp'\n" + "tag:\n" + " - Relev", emitter.c_str()); + } + + TEST_P(PluginMetadataTest, emittingAsYamlShouldOutputAPluginWithDirtyInfoCorrectly) { + PluginMetadata plugin(blankEsp); + plugin.DirtyInfo({PluginDirtyInfo(5, 0, 1, 2, "utility")}); + + YAML::Emitter emitter; + emitter << plugin; + + EXPECT_STREQ("name: 'Blank.esp'\n" + "dirty:\n" + " - crc: 0x5\n" + " util: 'utility'\n" + " udr: 1\n" + " nav: 2", emitter.c_str()); + } + + TEST_P(PluginMetadataTest, emittingAsYamlShouldOutputAPluginWithLocationsCorrectly) { + PluginMetadata plugin(blankEsp); + plugin.Locations({Location("http://www.example.com")}); + + YAML::Emitter emitter; + emitter << plugin; + + EXPECT_STREQ("name: 'Blank.esp'\n" + "url:\n" + " - 'http://www.example.com'", emitter.c_str()); + } + + TEST_P(PluginMetadataTest, encodingAsYamlShouldOmitAllUnsetFields) { + PluginMetadata plugin(blankEsp); + YAML::Node node; + node = plugin; + + EXPECT_EQ(plugin.Name(), node["name"].as()); + EXPECT_FALSE(node["enabled"]); + EXPECT_FALSE(node["priority"]); + EXPECT_FALSE(node["after"]); + EXPECT_FALSE(node["req"]); + EXPECT_FALSE(node["inc"]); + EXPECT_FALSE(node["msg"]); + EXPECT_FALSE(node["tag"]); + EXPECT_FALSE(node["dirty"]); + EXPECT_FALSE(node["url"]); + } + + TEST_P(PluginMetadataTest, encodingAsYamlShouldSetPriorityFieldIfPriorityIsExplicit) { + PluginMetadata plugin(blankEsp); + plugin.SetPriorityExplicit(true); + YAML::Node node; + node = plugin; + + EXPECT_EQ(0, node["priority"].as()); + } + + TEST_P(PluginMetadataTest, encodingAsYamlShouldSetEnabledFieldIfItIsFalse) { + PluginMetadata plugin(blankEsp); + plugin.Enabled(false); + YAML::Node node; + node = plugin; + + EXPECT_FALSE(node["enabled"].as()); + } + + TEST_P(PluginMetadataTest, encodingAsYamlShouldSetAfterFieldIfLoadAfterMetadataExists) { + PluginMetadata plugin(blankEsp); + plugin.LoadAfter({File(blankEsm)}); + YAML::Node node; + node = plugin; + + EXPECT_EQ(plugin.LoadAfter(), node["after"].as>()); + } + + TEST_P(PluginMetadataTest, encodingAsYamlShouldSetReqFieldIfRequirementsExist) { + PluginMetadata plugin(blankEsp); + plugin.Reqs({File(blankEsm)}); + YAML::Node node; + node = plugin; + + EXPECT_EQ(plugin.Reqs(), node["req"].as>()); + } + + TEST_P(PluginMetadataTest, encodingAsYamlShouldSetIncFieldIfIncompatibilitiesExist) { + PluginMetadata plugin(blankEsp); + plugin.Incs({File(blankEsm)}); + YAML::Node node; + node = plugin; + + EXPECT_EQ(plugin.Incs(), node["inc"].as>()); + } + + TEST_P(PluginMetadataTest, encodingAsYamlShouldSetMsgFieldIfMessagesExist) { + PluginMetadata plugin(blankEsp); + plugin.Messages({Message(Message::say, "content")}); + YAML::Node node; + node = plugin; + + EXPECT_EQ(plugin.Messages(), node["msg"].as>()); + } + + TEST_P(PluginMetadataTest, encodingAsYamlShouldSetTagFieldIfTagsExist) { + PluginMetadata plugin(blankEsp); + plugin.Tags({Tag("Relev")}); + YAML::Node node; + node = plugin; + + EXPECT_EQ(plugin.Tags(), node["tag"].as>()); + } + + TEST_P(PluginMetadataTest, encodingAsYamlShouldSetDirtyFieldIfDirtyInfoExists) { + PluginMetadata plugin(blankEsp); + plugin.DirtyInfo({PluginDirtyInfo(5, 0, 1, 2, "utility")}); + YAML::Node node; + node = plugin; + + EXPECT_EQ(plugin.DirtyInfo(), node["dirty"].as>()); + } + + TEST_P(PluginMetadataTest, encodingAsYamlShouldSetUrlFieldIfLocationsExist) { + PluginMetadata plugin(blankEsp); + plugin.Locations({Location("http://www.example.com")}); + YAML::Node node; + node = plugin; + + EXPECT_EQ(plugin.Locations(), node["url"].as>()); + } + + TEST_P(PluginMetadataTest, decodingFromYamlShouldSetDefaultPriorityValuesIfNoneAreSpecified) { + YAML::Node node = YAML::Load("name: " + blankEsp); + PluginMetadata plugin = node.as(); + + EXPECT_EQ(blankEsp, plugin.Name()); + EXPECT_EQ(0, plugin.Priority()); + EXPECT_FALSE(plugin.IsPriorityExplicit()); + EXPECT_FALSE(plugin.IsPriorityGlobal()); + } + + TEST_P(PluginMetadataTest, decodingFromYamlShouldStoreAllGivenData) { + YAML::Node node = YAML::Load("name: 'Blank.esp'\n" + "priority: 5\n" + "enabled: false\n" + "after:\n" + " - 'Blank.esm'\n" + "req:\n" + " - 'Blank.esm'\n" + "inc:\n" + " - 'Blank.esm'\n" + "msg:\n" + " - type: say\n" + " content: 'content'\n" + "tag:\n" + " - Relev\n" + "dirty:\n" + " - crc: 0x5\n" + " util: 'utility'\n" + " udr: 1\n" + " nav: 2\n" + "url:\n" + " - 'http://www.example.com'"); + PluginMetadata plugin = node.as(); + + EXPECT_EQ("Blank.esp", plugin.Name()); + EXPECT_EQ(5, plugin.Priority()); + EXPECT_TRUE(plugin.IsPriorityExplicit()); + EXPECT_FALSE(plugin.IsPriorityGlobal()); + EXPECT_FALSE(plugin.Enabled()); + EXPECT_EQ(std::set({ + File("Blank.esm") + }), plugin.LoadAfter()); + EXPECT_EQ(std::set({ + File("Blank.esm") + }), plugin.Reqs()); + EXPECT_EQ(std::set({ + File("Blank.esm") + }), plugin.Incs()); + EXPECT_EQ(std::list({ + Message(Message::say, "content") + }), plugin.Messages()); + EXPECT_EQ(std::set({ + Tag("Relev") + }), plugin.Tags()); + EXPECT_EQ(std::set({ + PluginDirtyInfo(5, 0, 1, 2, "utility") + }), plugin.DirtyInfo()); + EXPECT_EQ(std::set({ + Location("http://www.example.com") + }), plugin.Locations()); + } + + TEST_P(PluginMetadataTest, decodingFromYamlWithDirtyInfoInARegexPluginMetadataObjectShouldThrow) { + YAML::Node node = YAML::Load("name: 'Blank\\.esp'\n" + "dirty:\n" + " - crc: 0x5\n" + " util: 'utility'\n" + " udr: 1\n" + " nav: 2"); + + EXPECT_THROW(node.as(), YAML::RepresentationException); + } + + TEST_P(PluginMetadataTest, decodingFromYamlWithAnInvalidRegexNameShouldThrow) { + YAML::Node node = YAML::Load("name: 'RagnvaldBook(Farengar(+Ragnvald)?)?\\.esp'\n" + "dirty:\n" + " - crc: 0x5\n" + " util: 'utility'\n" + " udr: 1\n" + " nav: 2"); + + EXPECT_THROW(node.as(), YAML::RepresentationException); + } + + TEST_P(PluginMetadataTest, decodingFromAYamlScalarShouldThrow) { + YAML::Node node = YAML::Load("scalar"); + + EXPECT_THROW(node.as(), YAML::RepresentationException); + } + + TEST_P(PluginMetadataTest, decodingFromAYamlListShouldThrow) { + YAML::Node node = YAML::Load("[0, 1, 2]"); + + EXPECT_THROW(node.as(), YAML::RepresentationException); + } + } +} + +#endif diff --git a/src/tests/backend/metadata/test_plugin_metadata.h b/src/tests/backend/metadata/test_plugin_metadata.h deleted file mode 100644 index d1d8f323..00000000 --- a/src/tests/backend/metadata/test_plugin_metadata.h +++ /dev/null @@ -1,953 +0,0 @@ -/* 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_TEST_F_BACKEND_METADATA_PLUGIN_METADATA -#define LOOT_TEST_F_BACKEND_METADATA_PLUGIN_METADATA - -#include "backend/metadata/plugin_metadata.h" -#include "tests/fixtures.h" - -namespace loot { - namespace test { - class PluginMetadataTest : public SkyrimTest {}; - - TEST_F(PluginMetadataTest, Constructors) { - PluginMetadata pm; - EXPECT_TRUE(pm.Enabled()); - EXPECT_FALSE(pm.IsPriorityExplicit()); - EXPECT_FALSE(pm.IsPriorityGlobal()); - EXPECT_EQ(0, pm.Priority()); - - pm = PluginMetadata("Blank.esm"); - EXPECT_EQ("Blank.esm", pm.Name()); - EXPECT_TRUE(pm.Enabled()); - EXPECT_FALSE(pm.IsPriorityExplicit()); - EXPECT_FALSE(pm.IsPriorityGlobal()); - EXPECT_EQ(0, pm.Priority()); - } - - TEST_F(PluginMetadataTest, EqualityOperator) { - PluginMetadata pm1, pm2; - EXPECT_TRUE(pm1 == pm2); - - pm1 = PluginMetadata("Blank.esm"); - pm2 = PluginMetadata("blank.esm"); - EXPECT_TRUE(pm1 == pm2); - - pm1 = PluginMetadata("Blank.esm"); - pm2 = PluginMetadata("Blan.\\.esm"); - EXPECT_TRUE(pm1 == pm2); - EXPECT_TRUE(pm2 == pm1); - - pm1 = PluginMetadata("Blan.esm"); - pm2 = PluginMetadata("Blan.\\.esm"); - EXPECT_FALSE(pm1 == pm2); - EXPECT_FALSE(pm2 == pm1); - - pm1 = PluginMetadata("Blan.\\.esm"); - pm2 = PluginMetadata("Blan.\\.esm"); - EXPECT_TRUE(pm1 == pm2); - EXPECT_TRUE(pm2 == pm1); - - pm1 = PluginMetadata("Blan(k|p).esm"); - pm2 = PluginMetadata("Blan.\\.esm"); - EXPECT_FALSE(pm1 == pm2); - EXPECT_FALSE(pm2 == pm1); - } - - TEST_F(PluginMetadataTest, MergeMetadata) { - PluginMetadata pm1(YAML::Load( - "name: 'Blank.esp'\n" - "enabled: false\n" - "priority: 5\n" - "after:\n" - " - 'Blank.esm'\n" - "req:\n" - " - 'Blank.esm'\n" - "inc:\n" - " - 'Blank.esm'\n" - "msg:\n" - " - type: say\n" - " content: 'content'\n" - "tag:\n" - " - Relev\n" - "dirty:\n" - " - crc: 0x5\n" - " util: 'utility'\n" - " udr: 1\n" - " nav: 2\n" - "url:\n" - " - 'http://www.example.com'" - ).as()); - - PluginMetadata pm2(YAML::Load( - "name: 'Blank - Different.esp'\n" - "after:\n" - " - 'Blank.esm'\n" - " - 'Blank.esp'\n" - "req:\n" - " - 'Blank.esm'\n" - " - 'Blank.esp'\n" - "inc:\n" - " - 'Blank.esm'\n" - " - 'Blank.esp'\n" - "msg:\n" - " - type: say\n" - " content: 'content'\n" - "tag:\n" - " - Relev\n" - " - -Relev\n" - " - Delev\n" - "dirty:\n" - " - crc: 0x5\n" - " util: 'utility'\n" - " udr: 1\n" - " nav: 2\n" - " - crc: 0x9\n" - " util: 'utility'\n" - " udr: 1\n" - " nav: 2\n" - "url:\n" - " - 'http://www.example.com'\n" - " - 'http://www.example2.com'" - ).as()); - - EXPECT_NO_THROW(pm1.MergeMetadata(pm2)); - EXPECT_EQ("Blank.esp", pm1.Name()); - EXPECT_TRUE(pm1.Enabled()); - EXPECT_EQ(5, pm1.Priority()); - EXPECT_TRUE(pm1.IsPriorityExplicit()); - EXPECT_FALSE(pm1.IsPriorityGlobal()); - EXPECT_EQ(std::set({ - File("Blank.esm"), - File("Blank.esp"), - }), pm1.LoadAfter()); - EXPECT_EQ(std::set({ - File("Blank.esm"), - File("Blank.esp"), - }), pm1.Reqs()); - EXPECT_EQ(std::set({ - File("Blank.esm"), - File("Blank.esp"), - }), pm1.Incs()); - EXPECT_EQ(std::list({ - Message(Message::say, "content"), - Message(Message::say, "content"), - }), pm1.Messages()); - EXPECT_EQ(std::set({ - Tag("Relev"), - Tag("Relev", false), - Tag("Delev"), - }), pm1.Tags()); - EXPECT_EQ(std::set({ - PluginDirtyInfo(5, 0, 1, 2, "utility"), - PluginDirtyInfo(9, 0, 1, 2, "utility"), - }), pm1.DirtyInfo()); - EXPECT_EQ(std::set({ - Location("http://www.example.com"), - Location("http://www.example2.com"), - }), pm1.Locations()); - - pm2.SetPriorityExplicit(true); - EXPECT_NO_THROW(pm1.MergeMetadata(pm2)); - EXPECT_EQ(0, pm1.Priority()); - EXPECT_TRUE(pm1.IsPriorityExplicit()); - EXPECT_FALSE(pm1.IsPriorityGlobal()); - } - - TEST_F(PluginMetadataTest, DiffMetadata) { - PluginMetadata pm1(YAML::Load( - "name: 'Blank.esp'\n" - "enabled: false\n" - "after:\n" - " - 'Blank.esm'\n" - " - 'Blank - Different.esm'\n" - "req:\n" - " - 'Blank.esm'\n" - " - 'Blank - Different.esm'\n" - "inc:\n" - " - 'Blank.esm'\n" - " - 'Blank - Different.esm'\n" - "msg:\n" - " - type: say\n" - " content: 'content'\n" - " - type: say\n" - " content: 'content2'\n" - "tag:\n" - " - Relev\n" - " - NoMerge\n" - "dirty:\n" - " - crc: 0x5\n" - " util: 'utility'\n" - " udr: 1\n" - " nav: 2\n" - " - crc: 0x1\n" - " util: 'utility'\n" - " udr: 1\n" - " nav: 2\n" - "url:\n" - " - 'http://www.example.com'\n" - " - 'http://www.other-example.com'" - ).as()); - - PluginMetadata pm2(YAML::Load( - "name: 'Blank - Different.esp'\n" - "after:\n" - " - 'Blank.esm'\n" - " - 'Blank.esp'\n" - "req:\n" - " - 'Blank.esm'\n" - " - 'Blank.esp'\n" - "inc:\n" - " - 'Blank.esm'\n" - " - 'Blank.esp'\n" - "msg:\n" - " - type: say\n" - " content: 'content'\n" - " - type: say\n" - " content: 'content3'\n" - "tag:\n" - " - Relev\n" - " - -Relev\n" - " - Delev\n" - "dirty:\n" - " - crc: 0x5\n" - " util: 'utility'\n" - " udr: 1\n" - " nav: 2\n" - " - crc: 0x9\n" - " util: 'utility'\n" - " udr: 1\n" - " nav: 2\n" - "url:\n" - " - 'http://www.example.com'\n" - " - 'http://www.example2.com'" - ).as()); - - PluginMetadata result = pm1.DiffMetadata(pm2); - EXPECT_EQ("Blank.esp", result.Name()); - EXPECT_FALSE(result.Enabled()); - EXPECT_EQ(0, result.Priority()); - EXPECT_FALSE(result.IsPriorityExplicit()); - EXPECT_FALSE(result.IsPriorityGlobal()); - EXPECT_EQ(std::set({ - File("Blank.esp"), - File("Blank - Different.esm"), - }), result.LoadAfter()); - EXPECT_EQ(std::set({ - File("Blank.esp"), - File("Blank - Different.esm"), - }), result.Reqs()); - EXPECT_EQ(std::set({ - File("Blank.esp"), - File("Blank - Different.esm"), - }), result.Incs()); - EXPECT_EQ(std::list({ - Message(Message::say, "content2"), - Message(Message::say, "content3"), - }), result.Messages()); - EXPECT_EQ(std::set({ - Tag("Relev", false), - Tag("Delev"), - Tag("NoMerge"), - }), result.Tags()); - EXPECT_EQ(std::set({ - PluginDirtyInfo(9, 0, 1, 2, "utility"), - PluginDirtyInfo(1, 0, 1, 2, "utility"), - }), result.DirtyInfo()); - EXPECT_EQ(std::set({ - Location("http://www.example2.com"), - Location("http://www.other-example.com"), - }), result.Locations()); - - pm1.Priority(5); - result = pm1.DiffMetadata(pm2); - - EXPECT_EQ(5, result.Priority()); - EXPECT_TRUE(result.IsPriorityExplicit()); - EXPECT_FALSE(result.IsPriorityGlobal()); - } - - TEST_F(PluginMetadataTest, NewMetadata) { - PluginMetadata pm1(YAML::Load( - "name: 'Blank.esp'\n" - "enabled: false\n" - "after:\n" - " - 'Blank.esm'\n" - " - 'Blank - Different.esm'\n" - "req:\n" - " - 'Blank.esm'\n" - " - 'Blank - Different.esm'\n" - "inc:\n" - " - 'Blank.esm'\n" - " - 'Blank - Different.esm'\n" - "msg:\n" - " - type: say\n" - " content: 'content'\n" - " - type: say\n" - " content: 'content2'\n" - "tag:\n" - " - Relev\n" - " - NoMerge\n" - "dirty:\n" - " - crc: 0x5\n" - " util: 'utility'\n" - " udr: 1\n" - " nav: 2\n" - " - crc: 0x1\n" - " util: 'utility'\n" - " udr: 1\n" - " nav: 2\n" - "url:\n" - " - 'http://www.example.com'\n" - " - 'http://www.other-example.com'" - ).as()); - - PluginMetadata pm2(YAML::Load( - "name: 'Blank - Different.esp'\n" - "after:\n" - " - 'Blank.esm'\n" - " - 'Blank.esp'\n" - "req:\n" - " - 'Blank.esm'\n" - " - 'Blank.esp'\n" - "inc:\n" - " - 'Blank.esm'\n" - " - 'Blank.esp'\n" - "msg:\n" - " - type: say\n" - " content: 'content'\n" - " - type: say\n" - " content: 'content3'\n" - "tag:\n" - " - Relev\n" - " - -Relev\n" - " - Delev\n" - "dirty:\n" - " - crc: 0x5\n" - " util: 'utility'\n" - " udr: 1\n" - " nav: 2\n" - " - crc: 0x9\n" - " util: 'utility'\n" - " udr: 1\n" - " nav: 2\n" - "url:\n" - " - 'http://www.example.com'\n" - " - 'http://www.example2.com'" - ).as()); - - PluginMetadata result = pm2.NewMetadata(pm1); - EXPECT_EQ("Blank - Different.esp", result.Name()); - EXPECT_TRUE(result.Enabled()); - EXPECT_EQ(0, result.Priority()); - EXPECT_FALSE(result.IsPriorityExplicit()); - EXPECT_FALSE(result.IsPriorityGlobal()); - EXPECT_EQ(std::set({ - File("Blank.esp") - }), result.LoadAfter()); - EXPECT_EQ(std::set({ - File("Blank.esp") - }), result.Reqs()); - EXPECT_EQ(std::set({ - File("Blank.esp") - }), result.Incs()); - EXPECT_EQ(std::list({ - Message(Message::say, "content3"), - }), result.Messages()); - EXPECT_EQ(std::set({ - Tag("Relev", false), - Tag("Delev"), - }), result.Tags()); - EXPECT_EQ(std::set({ - PluginDirtyInfo(9, 0, 1, 2, "utility") - }), result.DirtyInfo()); - EXPECT_EQ(std::set({ - Location("http://www.example2.com") - }), result.Locations()); - - pm1.Priority(5); - result = pm2.NewMetadata(pm1); - - EXPECT_EQ(0, result.Priority()); - EXPECT_FALSE(result.IsPriorityExplicit()); - EXPECT_FALSE(result.IsPriorityGlobal()); - } - - TEST_F(PluginMetadataTest, Enabled) { - PluginMetadata pm; - ASSERT_TRUE(pm.Enabled()); - pm.Enabled(false); - EXPECT_FALSE(pm.Enabled()); - } - - TEST_F(PluginMetadataTest, SetPriorityExplicit) { - PluginMetadata pm; - ASSERT_FALSE(pm.IsPriorityExplicit()); - pm.SetPriorityExplicit(true); - EXPECT_TRUE(pm.IsPriorityExplicit()); - } - - TEST_F(PluginMetadataTest, Priority) { - PluginMetadata pm; - ASSERT_NE(10, pm.Priority()); - pm.Priority(10); - EXPECT_EQ(10, pm.Priority()); - } - - TEST_F(PluginMetadataTest, settingPriorityWithAbsoluteValueGreaterOrEqualToGlobalPriorityDivisorShouldThrow) { - PluginMetadata pm; - EXPECT_ANY_THROW(pm.Priority(yamlGlobalPriorityDivisor)); - EXPECT_ANY_THROW(pm.Priority(yamlGlobalPriorityDivisor + 1)); - EXPECT_ANY_THROW(pm.Priority(-yamlGlobalPriorityDivisor)); - EXPECT_ANY_THROW(pm.Priority(-yamlGlobalPriorityDivisor - 1)); - } - - TEST_F(PluginMetadataTest, settingPriorityAsGlobalShouldSucceed) { - PluginMetadata pm; - ASSERT_FALSE(pm.IsPriorityGlobal()); - pm.SetPriorityGlobal(true); - EXPECT_TRUE(pm.IsPriorityGlobal()); - } - - TEST_F(PluginMetadataTest, settingPriorityAsNotGlobalShouldSucceed) { - PluginMetadata pm; - pm.SetPriorityGlobal(true); - ASSERT_TRUE(pm.IsPriorityGlobal()); - pm.SetPriorityGlobal(false); - EXPECT_FALSE(pm.IsPriorityGlobal()); - } - - TEST_F(PluginMetadataTest, gettingYamlPriorityValueForAGlobalPriorityShouldReturnValueWithGlobalFlagSet) { - PluginMetadata pm; - pm.Priority(10); - pm.SetPriorityGlobal(true); - EXPECT_EQ(1000010, pm.GetYamlPriorityValue()); - - pm.Priority(-20); - EXPECT_EQ(-1000020, pm.GetYamlPriorityValue()); - } - - TEST_F(PluginMetadataTest, gettingYamlPriorityValueForANonGlobalPriorityShouldReturnValueWithGlobalFlagNotSet) { - PluginMetadata pm; - pm.Priority(10); - EXPECT_EQ(10, pm.GetYamlPriorityValue()); - - pm.Priority(-20); - EXPECT_EQ(-20, pm.GetYamlPriorityValue()); - } - - TEST_F(PluginMetadataTest, LoadAfter) { - PluginMetadata pm; - ASSERT_TRUE(pm.LoadAfter().empty()); - pm.LoadAfter({ - File("Blank.esm") - }); - EXPECT_EQ(std::set({ - File("Blank.esm") - }), pm.LoadAfter()); - } - - TEST_F(PluginMetadataTest, Reqs) { - PluginMetadata pm; - ASSERT_TRUE(pm.Reqs().empty()); - pm.Reqs({ - File("Blank.esm") - }); - EXPECT_EQ(std::set({ - File("Blank.esm") - }), pm.Reqs()); - } - - TEST_F(PluginMetadataTest, Incs) { - PluginMetadata pm; - ASSERT_TRUE(pm.Incs().empty()); - pm.Incs({ - File("Blank.esm") - }); - EXPECT_EQ(std::set({ - File("Blank.esm") - }), pm.Incs()); - } - - TEST_F(PluginMetadataTest, Messages) { - PluginMetadata pm; - ASSERT_TRUE(pm.Messages().empty()); - pm.Messages({ - Message(Message::say, "content") - }); - EXPECT_EQ(std::list({ - Message(Message::say, "content") - }), pm.Messages()); - } - - TEST_F(PluginMetadataTest, Tags) { - PluginMetadata pm; - ASSERT_TRUE(pm.Tags().empty()); - pm.Tags({ - Tag("Relev") - }); - EXPECT_EQ(std::set({ - Tag("Relev") - }), pm.Tags()); - } - - TEST_F(PluginMetadataTest, DirtyInfo) { - PluginMetadata pm; - ASSERT_TRUE(pm.DirtyInfo().empty()); - pm.DirtyInfo({ - PluginDirtyInfo(5, 0, 1, 2, "utility") - }); - EXPECT_EQ(std::set({ - PluginDirtyInfo(5, 0, 1, 2, "utility") - }), pm.DirtyInfo()); - } - - TEST_F(PluginMetadataTest, Locations) { - PluginMetadata pm; - ASSERT_TRUE(pm.Locations().empty()); - pm.Locations({ - Location("http://www.example.com") - }); - EXPECT_EQ(std::set({ - Location("http://www.example.com") - }), pm.Locations()); - } - - TEST_F(PluginMetadataTest, EvalAllConditions) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); - - PluginMetadata pm(YAML::Load( - "name: 'Blank.esp'\n" - "after:\n" - " - name: 'Blank.esm'\n" - " condition: 'file(\"Blank.esm\")'\n" - "req:\n" - " - name: 'Blank.esm'\n" - " condition: 'file(\"Blank.missing.esm\")'\n" - "inc:\n" - " - name: 'Blank.esm'\n" - " condition: 'file(\"Blank.esm\")'\n" - "msg:\n" - " - type: say\n" - " content: 'content'\n" - "tag:\n" - " - name: Relev\n" - " condition: 'file(\"Blank.missing.esm\")'\n" - "dirty:\n" - " - crc: 0x24F0E2A1\n" - " util: 'utility'\n" - " udr: 1\n" - " nav: 2\n" - " - crc: 0xDEADBEEF\n" - " util: 'utility'\n" - " udr: 1\n" - " nav: 2" - ).as()); - - pm.Messages({Message(Message::say, "content")}); - EXPECT_NO_THROW(pm.EvalAllConditions(game, Language::english)); - EXPECT_EQ(std::set({ - File("Blank.esm", "", "file(\"Blank.esm\")") - }), pm.LoadAfter()); - EXPECT_TRUE(pm.Reqs().empty()); - EXPECT_EQ(std::set({ - File("Blank.esm", "", "file(\"Blank.esm\")") - }), pm.Incs()); - EXPECT_EQ(std::list({ - Message(Message::say, "content") - }), pm.Messages()); - EXPECT_TRUE(pm.Tags().empty()); - EXPECT_EQ(std::set({ - PluginDirtyInfo(0x24F0E2A1, 0, 1, 2, "utility") - }), pm.DirtyInfo()); - } - - TEST_F(PluginMetadataTest, HasNameOnly) { - PluginMetadata pm; - EXPECT_TRUE(pm.HasNameOnly()); - - pm = PluginMetadata("Blank.esp"); - EXPECT_TRUE(pm.HasNameOnly()); - - pm = PluginMetadata("Blank.esp"); - pm.Enabled(false); - EXPECT_TRUE(pm.HasNameOnly()); - - pm = PluginMetadata("Blank.esp"); - pm.SetPriorityExplicit(true); - EXPECT_FALSE(pm.HasNameOnly()); - - pm = PluginMetadata("Blank.esp"); - pm.LoadAfter({File("Blank.esm")}); - EXPECT_FALSE(pm.HasNameOnly()); - - pm = PluginMetadata("Blank.esp"); - pm.Reqs({File("Blank.esm")}); - EXPECT_FALSE(pm.HasNameOnly()); - - pm = PluginMetadata("Blank.esp"); - pm.Incs({File("Blank.esm")}); - EXPECT_FALSE(pm.HasNameOnly()); - - pm = PluginMetadata("Blank.esp"); - pm.Messages({Message(Message::say, "content")}); - EXPECT_FALSE(pm.HasNameOnly()); - - pm = PluginMetadata("Blank.esp"); - pm.Tags({Tag("Relev")}); - EXPECT_FALSE(pm.HasNameOnly()); - - pm = PluginMetadata("Blank.esp"); - pm.DirtyInfo({PluginDirtyInfo(5, 0, 1, 2, "utility")}); - EXPECT_FALSE(pm.HasNameOnly()); - - pm = PluginMetadata("Blank.esp"); - pm.Locations({Location("http://www.example.com")}); - EXPECT_FALSE(pm.HasNameOnly()); - } - - TEST_F(PluginMetadataTest, IsRegexPlugin) { - PluginMetadata pm; - EXPECT_FALSE(pm.IsRegexPlugin()); - - pm = PluginMetadata("Blank.esm"); - EXPECT_FALSE(pm.IsRegexPlugin()); - - pm = PluginMetadata("Blank[[:blank:]]- Different.esm"); - EXPECT_TRUE(pm.IsRegexPlugin()); - - pm = PluginMetadata("Blank\\.esm"); - EXPECT_TRUE(pm.IsRegexPlugin()); - - pm = PluginMetadata("Blank - (Different )*Master Dependent.esm"); - EXPECT_TRUE(pm.IsRegexPlugin()); - - pm = PluginMetadata("Blank - (Different )?Master Dependent.esm"); - EXPECT_TRUE(pm.IsRegexPlugin()); - - pm = PluginMetadata("Blank.es(p|m)"); - EXPECT_TRUE(pm.IsRegexPlugin()); - } - - TEST_F(PluginMetadataTest, YamlEmitter) { - PluginMetadata pm("Blank.esp"); - YAML::Emitter e1; - e1 << pm; - EXPECT_STREQ("", e1.c_str()); - - pm.SetPriorityExplicit(true); - YAML::Emitter e2; - e2 << pm; - EXPECT_STREQ("name: 'Blank.esp'\n" - "priority: 0", e2.c_str()); - - pm.Enabled(false); - YAML::Emitter e3; - e3 << pm; - EXPECT_STREQ("name: 'Blank.esp'\n" - "priority: 0\n" - "enabled: false", e3.c_str()); - - pm.LoadAfter({File("Blank.esm")}); - YAML::Emitter e4; - e4 << pm; - EXPECT_STREQ("name: 'Blank.esp'\n" - "priority: 0\n" - "enabled: false\n" - "after:\n" - " - 'Blank.esm'", e4.c_str()); - - pm.Reqs({File("Blank.esm")}); - YAML::Emitter e5; - e5 << pm; - EXPECT_STREQ("name: 'Blank.esp'\n" - "priority: 0\n" - "enabled: false\n" - "after:\n" - " - 'Blank.esm'\n" - "req:\n" - " - 'Blank.esm'", e5.c_str()); - - pm.Incs({File("Blank.esm")}); - YAML::Emitter e6; - e6 << pm; - EXPECT_STREQ("name: 'Blank.esp'\n" - "priority: 0\n" - "enabled: false\n" - "after:\n" - " - 'Blank.esm'\n" - "req:\n" - " - 'Blank.esm'\n" - "inc:\n" - " - 'Blank.esm'", e6.c_str()); - - pm.Messages({Message(Message::say, "content")}); - YAML::Emitter e7; - e7 << pm; - EXPECT_STREQ("name: 'Blank.esp'\n" - "priority: 0\n" - "enabled: false\n" - "after:\n" - " - 'Blank.esm'\n" - "req:\n" - " - 'Blank.esm'\n" - "inc:\n" - " - 'Blank.esm'\n" - "msg:\n" - " - type: say\n" - " content: 'content'", e7.c_str()); - - pm.Tags({Tag("Relev")}); - YAML::Emitter e8; - e8 << pm; - EXPECT_STREQ("name: 'Blank.esp'\n" - "priority: 0\n" - "enabled: false\n" - "after:\n" - " - 'Blank.esm'\n" - "req:\n" - " - 'Blank.esm'\n" - "inc:\n" - " - 'Blank.esm'\n" - "msg:\n" - " - type: say\n" - " content: 'content'\n" - "tag:\n" - " - Relev", e8.c_str()); - - pm.DirtyInfo({PluginDirtyInfo(5, 0, 1, 2, "utility")}); - YAML::Emitter e9; - e9 << pm; - EXPECT_STREQ("name: 'Blank.esp'\n" - "priority: 0\n" - "enabled: false\n" - "after:\n" - " - 'Blank.esm'\n" - "req:\n" - " - 'Blank.esm'\n" - "inc:\n" - " - 'Blank.esm'\n" - "msg:\n" - " - type: say\n" - " content: 'content'\n" - "tag:\n" - " - Relev\n" - "dirty:\n" - " - crc: 0x5\n" - " util: 'utility'\n" - " udr: 1\n" - " nav: 2", e9.c_str()); - - pm.Locations({Location("http://www.example.com")}); - YAML::Emitter e10; - e10 << pm; - EXPECT_STREQ("name: 'Blank.esp'\n" - "priority: 0\n" - "enabled: false\n" - "after:\n" - " - 'Blank.esm'\n" - "req:\n" - " - 'Blank.esm'\n" - "inc:\n" - " - 'Blank.esm'\n" - "msg:\n" - " - type: say\n" - " content: 'content'\n" - "tag:\n" - " - Relev\n" - "dirty:\n" - " - crc: 0x5\n" - " util: 'utility'\n" - " udr: 1\n" - " nav: 2\n" - "url:\n" - " - 'http://www.example.com'", e10.c_str()); - } - - TEST_F(PluginMetadataTest, YamlEncode) { - YAML::Node node; - - PluginMetadata pm("Blank.esp"); - node = pm; - EXPECT_EQ("Blank.esp", node["name"].as()); - EXPECT_FALSE(node["enabled"]); - EXPECT_FALSE(node["priority"]); - EXPECT_FALSE(node["after"]); - EXPECT_FALSE(node["req"]); - EXPECT_FALSE(node["inc"]); - EXPECT_FALSE(node["msg"]); - EXPECT_FALSE(node["tag"]); - EXPECT_FALSE(node["dirty"]); - EXPECT_FALSE(node["url"]); - - pm.SetPriorityExplicit(true); - node = pm; - EXPECT_EQ(0, node["priority"].as()); - - pm.Enabled(false); - node = pm; - EXPECT_FALSE(node["enabled"].as()); - - pm.LoadAfter({File("Blank.esm")}); - node = pm; - EXPECT_EQ(pm.LoadAfter(), node["after"].as>()); - - pm.Reqs({File("Blank.esm")}); - node = pm; - EXPECT_EQ(pm.Reqs(), node["req"].as>()); - - pm.Incs({File("Blank.esm")}); - node = pm; - EXPECT_EQ(pm.Incs(), node["inc"].as>()); - - pm.Messages({Message(Message::say, "content")}); - node = pm; - EXPECT_EQ(pm.Messages(), node["msg"].as>()); - - pm.Tags({Tag("Relev")}); - node = pm; - EXPECT_EQ(pm.Tags(), node["tag"].as>()); - - pm.DirtyInfo({PluginDirtyInfo(5, 0, 1, 2, "utility")}); - node = pm; - EXPECT_EQ(pm.DirtyInfo(), node["dirty"].as>()); - - pm.Locations({Location("http://www.example.com")}); - node = pm; - EXPECT_EQ(pm.Locations(), node["url"].as>()); - } - - TEST_F(PluginMetadataTest, YamlDecode) { - YAML::Node node; - PluginMetadata pm; - - node = YAML::Load("name: Blank.esp"); - pm = node.as(); - EXPECT_EQ("Blank.esp", pm.Name()); - EXPECT_EQ(0, pm.Priority()); - EXPECT_FALSE(pm.IsPriorityExplicit()); - EXPECT_FALSE(pm.IsPriorityGlobal()); - - node = YAML::Load("name: 'Blank.esp'\n" - "priority: 5\n" - "enabled: false\n" - "after:\n" - " - 'Blank.esm'\n" - "req:\n" - " - 'Blank.esm'\n" - "inc:\n" - " - 'Blank.esm'\n" - "msg:\n" - " - type: say\n" - " content: 'content'\n" - "tag:\n" - " - Relev\n" - "dirty:\n" - " - crc: 0x5\n" - " util: 'utility'\n" - " udr: 1\n" - " nav: 2\n" - "url:\n" - " - 'http://www.example.com'"); - pm = node.as(); - EXPECT_EQ("Blank.esp", pm.Name()); - EXPECT_EQ(5, pm.Priority()); - EXPECT_TRUE(pm.IsPriorityExplicit()); - EXPECT_FALSE(pm.IsPriorityGlobal()); - EXPECT_FALSE(pm.Enabled()); - EXPECT_EQ(std::set({ - File("Blank.esm") - }), pm.LoadAfter()); - EXPECT_EQ(std::set({ - File("Blank.esm") - }), pm.Reqs()); - EXPECT_EQ(std::set({ - File("Blank.esm") - }), pm.Incs()); - EXPECT_EQ(std::list({ - Message(Message::say, "content") - }), pm.Messages()); - EXPECT_EQ(std::set({ - Tag("Relev") - }), pm.Tags()); - EXPECT_EQ(std::set({ - PluginDirtyInfo(5, 0, 1, 2, "utility") - }), pm.DirtyInfo()); - EXPECT_EQ(std::set({ - Location("http://www.example.com") - }), pm.Locations()); - - // Don't allow dirty metadata in regex entries. - node = YAML::Load("name: 'Blank\\.esp'\n" - "dirty:\n" - " - crc: 0x5\n" - " util: 'utility'\n" - " udr: 1\n" - " nav: 2"); - EXPECT_THROW(node.as(), YAML::RepresentationException); - - // Don't allow invalid regex. - node = YAML::Load("name: 'RagnvaldBook(Farengar(+Ragnvald)?)?\\.esp'\n" - "dirty:\n" - " - crc: 0x5\n" - " util: 'utility'\n" - " udr: 1\n" - " nav: 2"); - EXPECT_THROW(node.as(), YAML::RepresentationException); - - // Catch condition syntax errors. - node = YAML::Load( - "name: 'Blank.esp'\n" - "after:\n" - " - name: 'Blank.esm'\n" - " condition: 'file(\"Blank.esm\")'\n" - "req:\n" - " - name: 'Blank.esm'\n" - " condition: 'file(\"Blank.missing.esm\")'\n" - "inc:\n" - " - name: 'Blank.esm'\n" - " condition: 'file(\"Blank.esm\")'\n" - "msg:\n" - " - type: say\n" - " content: 'content'\n" - " condition: 'condition'\n" - "tag:\n" - " - name: Relev\n" - " condition: 'file(\"Blank.missing.esm\")'" - ); - EXPECT_THROW(node.as(), YAML::RepresentationException); - - node = YAML::Load("scalar"); - EXPECT_THROW(node.as(), YAML::RepresentationException); - - node = YAML::Load("[0, 1, 2]"); - EXPECT_THROW(node.as(), YAML::RepresentationException); - } - } -} - -#endif diff --git a/src/tests/main.cpp b/src/tests/main.cpp index 035ea6cd..3b681725 100644 --- a/src/tests/main.cpp +++ b/src/tests/main.cpp @@ -57,7 +57,7 @@ #include "backend/metadata/message_test.h" #include "backend/metadata/message_content_test.h" #include "backend/metadata/plugin_dirty_info_test.h" -#include "backend/metadata/test_plugin_metadata.h" +#include "backend/metadata/plugin_metadata_test.h" #include "backend/metadata/test_tag.h" #include "backend/plugin/test_plugin.h" #include "backend/test_metadata_list.h" From 1d7eb4c9ac2923648df94406ba2824cf19ad50e6 Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Wed, 30 Mar 2016 21:52:47 +0100 Subject: [PATCH 29/38] Improve Tag tests --- CMakeLists.txt | 2 +- src/tests/backend/metadata/tag_test.h | 191 ++++++++++++++++++++++++++ src/tests/backend/metadata/test_tag.h | 182 ------------------------ src/tests/main.cpp | 2 +- 4 files changed, 193 insertions(+), 184 deletions(-) create mode 100644 src/tests/backend/metadata/tag_test.h delete mode 100644 src/tests/backend/metadata/test_tag.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 30a8d67a..9bac9ebb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -252,7 +252,7 @@ set (LOOT_TESTS_HEADERS "${CMAKE_SOURCE_DIR}/src/tests/base_game_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/message_content_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/plugin_dirty_info_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/plugin_metadata_test.h" - "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/test_tag.h" + "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/tag_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/plugin/test_plugin.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/test_metadata_list.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/test_masterlist.h" diff --git a/src/tests/backend/metadata/tag_test.h b/src/tests/backend/metadata/tag_test.h new file mode 100644 index 00000000..a140fafd --- /dev/null +++ b/src/tests/backend/metadata/tag_test.h @@ -0,0 +1,191 @@ +/* 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_TEST_BACKEND_METADATA_TAG +#define LOOT_TEST_BACKEND_METADATA_TAG + +#include "backend/metadata/tag.h" + +#include + +namespace loot { + namespace test { + TEST(Tag, defaultConstructorShouldSetEmptyNameAndConditionStringsForATagAddition) { + Tag tag; + + EXPECT_TRUE(tag.Name().empty()); + EXPECT_TRUE(tag.IsAddition()); + EXPECT_TRUE(tag.Condition().empty()); + } + + TEST(Tag, dataConstructorShouldSetFieldsToGivenValues) { + Tag tag("name", false, "condition"); + + EXPECT_EQ("name", tag.Name()); + EXPECT_FALSE(tag.IsAddition()); + EXPECT_EQ("condition", tag.Condition()); + } + + TEST(Tag, tagsWithCaseInsensitiveEqualNamesAndEqualAdditionStatesShouldBeEqual) { + Tag tag1("Name", true, "condition1"); + Tag tag2("name", true, "condition2"); + + EXPECT_TRUE(tag1 == tag2); + } + + TEST(Tags, tagsWithUnequalNamesShouldNotBeEqual) { + Tag tag1("name1"); + Tag tag2("name2"); + + EXPECT_FALSE(tag1 == tag2); + } + + TEST(Tag, tagsWithUnequalAdditionStatesShouldNotBeEqual) { + Tag tag1("Name", true); + Tag tag2("name", false); + + EXPECT_FALSE(tag1 == tag2); + } + + TEST(Tag, lessThanOperatorShouldCaseInsensitivelyLexicographicallyCompareNameStrings) { + Tag tag1("Name"); + Tag tag2("name"); + + EXPECT_FALSE(tag1 < tag2); + EXPECT_FALSE(tag2 < tag1); + + tag1 = Tag("name1"); + tag2 = Tag("name2"); + + EXPECT_TRUE(tag1 < tag2); + EXPECT_FALSE(tag2 < tag1); + } + + TEST(Tag, lessThanOperatorShouldTreatTagAdditionsAsBeingLessThanRemovals) { + Tag tag1("name", true); + Tag tag2("name", false); + + EXPECT_TRUE(tag1 < tag2); + EXPECT_FALSE(tag2 < tag1); + } + + TEST(Tag, emittingAsYamlShouldOutputOnlyTheNameStringIfTheTagIsAnAdditionWithNoCondition) { + Tag tag("name1"); + YAML::Emitter emitter; + emitter << tag; + + EXPECT_EQ(tag.Name(), emitter.c_str()); + } + + TEST(Tag, emittingAsYamlShouldOutputOnlyTheNameStringPrefixedWithAHyphenIfTheTagIsARemovalWithNoCondition) { + Tag tag("name1", false); + YAML::Emitter emitter; + emitter << tag; + + EXPECT_EQ("-" + tag.Name(), 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.Name(), node["name"].as()); + } + + TEST(Tag, encodingAsYamlShouldOutputTheNameFieldWithAHyphenPrefixIfTheTagIsARemoval) { + Tag tag("name1", false); + YAML::Node node; + node = tag; + + EXPECT_EQ("-" + tag.Name(), node["name"].as()); + } + + TEST(Tag, encodingAsYamlShouldOutputTheConditionFieldIfTheConditionStringIsNotEmpty) { + Tag tag("name1", true, "condition1"); + YAML::Node node; + node = tag; + + EXPECT_EQ(tag.Name(), node["name"].as()); + EXPECT_EQ(tag.Condition(), node["condition"].as()); + } + + TEST(Tag, decodingFromYamlScalarShouldSetNameCorrectly) { + YAML::Node node = YAML::Load("name1"); + Tag tag = node.as(); + + EXPECT_EQ("name1", tag.Name()); + EXPECT_TRUE(tag.IsAddition()); + EXPECT_EQ("", tag.Condition()); + } + + TEST(Tag, decodingFromYamlScalarShouldSetAdditionStateCorrectly) { + YAML::Node node = YAML::Load("-name1"); + Tag tag = node.as(); + + EXPECT_EQ("name1", tag.Name()); + EXPECT_FALSE(tag.IsAddition()); + EXPECT_EQ("", tag.Condition()); + } + + TEST(Tag, decodingFromYamlMapShouldSetDataCorrectly) { + YAML::Node node = YAML::Load("{name: name1, condition: 'file(\"Foo.esp\")'}"); + Tag tag = node.as(); + + EXPECT_EQ("name1", tag.Name()); + EXPECT_TRUE(tag.IsAddition()); + EXPECT_EQ("file(\"Foo.esp\")", tag.Condition()); + } + + 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/backend/metadata/test_tag.h b/src/tests/backend/metadata/test_tag.h deleted file mode 100644 index 89f7cfea..00000000 --- a/src/tests/backend/metadata/test_tag.h +++ /dev/null @@ -1,182 +0,0 @@ -/* 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_TEST_BACKEND_METADATA_TAG -#define LOOT_TEST_BACKEND_METADATA_TAG - -#include "backend/metadata/tag.h" -#include "tests/fixtures.h" - -namespace loot { - namespace test { - TEST(Tag, ConstructorsAndDataAccess) { - Tag tag; - EXPECT_EQ("", tag.Name()); - EXPECT_TRUE(tag.IsAddition()); - EXPECT_EQ("", tag.Condition()); - - tag = Tag("name"); - EXPECT_EQ("name", tag.Name()); - EXPECT_TRUE(tag.IsAddition()); - EXPECT_EQ("", tag.Condition()); - - tag = Tag("name", false); - EXPECT_EQ("name", tag.Name()); - EXPECT_FALSE(tag.IsAddition()); - EXPECT_EQ("", tag.Condition()); - - // Not a valid condition, but not evaluating it in this test. - tag = Tag("name", false, "condition"); - EXPECT_EQ("name", tag.Name()); - EXPECT_FALSE(tag.IsAddition()); - EXPECT_EQ("condition", tag.Condition()); - } - - TEST(Tag, EqualityOperator) { - Tag tag1, tag2; - EXPECT_TRUE(tag1 == tag2); - - // Not valid conditions, but not evaluating them in this test. - tag1 = Tag("name", true, "condition1"); - tag2 = Tag("name", true, "condition2"); - EXPECT_TRUE(tag1 == tag2); - - tag1 = Tag("name"); - tag2 = Tag("Name"); - EXPECT_TRUE(tag1 == tag2); - - tag1 = Tag("name", true); - tag2 = Tag("name", false); - EXPECT_FALSE(tag1 == tag2); - - tag1 = Tag("name1"); - tag2 = Tag("name2"); - EXPECT_FALSE(tag1 == tag2); - } - - TEST(Tag, LessThanOperator) { - Tag tag1, tag2; - EXPECT_FALSE(tag1 < tag2); - EXPECT_FALSE(tag2 < tag1); - - tag1 = Tag("name", true, "condition1"); - tag2 = Tag("name", true, "condition2"); - EXPECT_FALSE(tag1 < tag2); - EXPECT_FALSE(tag2 < tag1); - - tag1 = Tag("name"); - tag2 = Tag("Name"); - EXPECT_FALSE(tag1 < tag2); - EXPECT_FALSE(tag2 < tag1); - - tag1 = Tag("name1"); - tag2 = Tag("name2"); - EXPECT_TRUE(tag1 < tag2); - EXPECT_FALSE(tag2 < tag1); - - tag1 = Tag("name", true); - tag2 = Tag("name", false); - EXPECT_TRUE(tag1 < tag2); - EXPECT_FALSE(tag2 < tag1); - } - - TEST(Tag, YamlEmitter) { - Tag tag("name1"); - YAML::Emitter e1; - e1 << tag; - EXPECT_STREQ("name1", e1.c_str()); - - tag = Tag("name1", false); - YAML::Emitter e2; - e2 << tag; - EXPECT_STREQ("-name1", e2.c_str()); - - tag = Tag("name1", true, "condition1"); - YAML::Emitter e3; - e3 << tag; - EXPECT_STREQ("name: name1\ncondition: 'condition1'", e3.c_str()); - - tag = Tag("name1", false, "condition1"); - YAML::Emitter e4; - e4 << tag; - EXPECT_STREQ("name: -name1\ncondition: 'condition1'", e4.c_str()); - } - - TEST(Tag, YamlEncode) { - YAML::Node node; - - Tag tag("name1"); - node = tag; - EXPECT_EQ("name1", node["name"].as()); - EXPECT_FALSE(node["condition"]); - - tag = Tag("name1", false); - node = tag; - EXPECT_EQ("-name1", node["name"].as()); - EXPECT_FALSE(node["condition"]); - - tag = Tag("name1", false, "condition1"); - node = tag; - EXPECT_EQ("-name1", node["name"].as()); - EXPECT_EQ("condition1", node["condition"].as()); - } - - TEST(Tag, YamlDecode) { - YAML::Node node; - Tag tag; - - node = YAML::Load("name1"); - tag = node.as(); - EXPECT_EQ("name1", tag.Name()); - EXPECT_TRUE(tag.IsAddition()); - EXPECT_EQ("", tag.Condition()); - - node = YAML::Load("-name1"); - tag = node.as(); - EXPECT_EQ("name1", tag.Name()); - EXPECT_FALSE(tag.IsAddition()); - EXPECT_EQ("", tag.Condition()); - - node = YAML::Load("{name: -name1}"); - tag = node.as(); - EXPECT_EQ("name1", tag.Name()); - EXPECT_FALSE(tag.IsAddition()); - EXPECT_EQ("", tag.Condition()); - - node = YAML::Load("{name: name1, condition: 'file(\"Foo.esp\")'}"); - tag = node.as(); - EXPECT_EQ("name1", tag.Name()); - EXPECT_TRUE(tag.IsAddition()); - EXPECT_EQ("file(\"Foo.esp\")", tag.Condition()); - - node = YAML::Load("{name: name1, condition: invalid}"); - EXPECT_THROW(node.as(), YAML::RepresentationException); - - node = YAML::Load("[0, 1, 2]"); - EXPECT_THROW(node.as(), YAML::RepresentationException); - } - } -} - -#endif diff --git a/src/tests/main.cpp b/src/tests/main.cpp index 3b681725..cd03bf57 100644 --- a/src/tests/main.cpp +++ b/src/tests/main.cpp @@ -58,7 +58,7 @@ #include "backend/metadata/message_content_test.h" #include "backend/metadata/plugin_dirty_info_test.h" #include "backend/metadata/plugin_metadata_test.h" -#include "backend/metadata/test_tag.h" +#include "backend/metadata/tag_test.h" #include "backend/plugin/test_plugin.h" #include "backend/test_metadata_list.h" #include "backend/test_masterlist.h" From cd4fb5e810ded6a5dfe6368d0304ec028de15c83 Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Thu, 31 Mar 2016 19:22:51 +0100 Subject: [PATCH 30/38] Ghost a plugin to test ghosting support --- src/tests/base_game_test.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/tests/base_game_test.h b/src/tests/base_game_test.h index d5a683c5..6d1a1afd 100644 --- a/src/tests/base_game_test.h +++ b/src/tests/base_game_test.h @@ -82,10 +82,20 @@ namespace loot { // Set initial load order and active plugins. setLoadOrder(getInitialLoadOrder()); setActivePlugins(getInitialActivePlugins()); + + // Ghost a plugin. + ASSERT_FALSE(boost::filesystem::exists(dataPath / (blankMasterDependentEsm + ".ghost"))); + ASSERT_NO_THROW(boost::filesystem::rename(dataPath / blankMasterDependentEsm, dataPath / (blankMasterDependentEsm + ".ghost"))); + ASSERT_TRUE(boost::filesystem::exists(dataPath / (blankMasterDependentEsm + ".ghost"))); } inline virtual void TearDown() { ASSERT_NO_THROW(boost::filesystem::remove(dataPath / masterFile)); + + // Unghost the ghosted plugin. + ASSERT_TRUE(boost::filesystem::exists(dataPath / (blankMasterDependentEsm + ".ghost"))); + ASSERT_NO_THROW(boost::filesystem::rename(dataPath / (blankMasterDependentEsm + ".ghost"), dataPath / blankMasterDependentEsm)); + ASSERT_FALSE(boost::filesystem::exists(dataPath / (blankMasterDependentEsm + ".ghost"))); } inline std::list getLoadOrder() { From 644879f5feda22aa85bbb45f1f42e8d2a9f8c4a3 Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Thu, 31 Mar 2016 19:33:15 +0100 Subject: [PATCH 31/38] Fix Fallout 4 archive detection --- src/backend/plugin/plugin.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/backend/plugin/plugin.cpp b/src/backend/plugin/plugin.cpp index bfac994b..ac54106c 100644 --- a/src/backend/plugin/plugin.cpp +++ b/src/backend/plugin/plugin.cpp @@ -92,15 +92,21 @@ namespace loot { _isActive = game.IsPluginActive(Name()); // Get whether the plugin loads an archive (BSA/BA2) or not. + string archiveExtension; + if (game.Id() == Game::fo4) + archiveExtension = ".ba2"; + else + archiveExtension = ".bsa"; + if (game.Id() == Game::tes5 || game.Id() == Game::fo4) { // Skyrim and Fallout 4 plugins only load archives that exactly match their basename. - _loadsArchive = boost::filesystem::exists(game.DataPath() / (Name().substr(0, Name().length() - 3) + "bsa")); + _loadsArchive = boost::filesystem::exists(game.DataPath() / (Name().substr(0, Name().length() - 4) + archiveExtension)); } else if (game.Id() != Game::tes4 || boost::iends_with(Name(), ".esp")) { //Oblivion .esp files and FO3, FNV plugins can load BSAs which begin with the plugin basename. string basename = Name().substr(0, Name().length() - 4); for (boost::filesystem::directory_iterator it(game.DataPath()); it != boost::filesystem::directory_iterator(); ++it) { - if (it->path().extension().string() == ".bsa" && boost::istarts_with(it->path().filename().string(), basename)) { + if (boost::iequals(it->path().extension().string(), archiveExtension) && boost::istarts_with(it->path().filename().string(), basename)) { _loadsArchive = true; break; } From f08103e5c177cf853ec796aaf5c44ea4f711a2f1 Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Thu, 31 Mar 2016 20:43:25 +0100 Subject: [PATCH 32/38] Improve Plugin tests --- CMakeLists.txt | 2 +- src/tests/backend/plugin/plugin_test.h | 311 +++++++++++++++++++++++++ src/tests/backend/plugin/test_plugin.h | 258 -------------------- src/tests/base_game_test.h | 1 + src/tests/main.cpp | 2 +- 5 files changed, 314 insertions(+), 260 deletions(-) create mode 100644 src/tests/backend/plugin/plugin_test.h delete mode 100644 src/tests/backend/plugin/test_plugin.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 9bac9ebb..33da5b64 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -253,7 +253,7 @@ set (LOOT_TESTS_HEADERS "${CMAKE_SOURCE_DIR}/src/tests/base_game_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/plugin_dirty_info_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/plugin_metadata_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/tag_test.h" - "${CMAKE_SOURCE_DIR}/src/tests/backend/plugin/test_plugin.h" + "${CMAKE_SOURCE_DIR}/src/tests/backend/plugin/plugin_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/test_metadata_list.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/test_masterlist.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/test_plugin_sorter.h" diff --git a/src/tests/backend/plugin/plugin_test.h b/src/tests/backend/plugin/plugin_test.h new file mode 100644 index 00000000..f29def82 --- /dev/null +++ b/src/tests/backend/plugin/plugin_test.h @@ -0,0 +1,311 @@ +/* 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_TEST_BACKEND_PLUGIN +#define LOOT_TEST_BACKEND_PLUGIN + +#include "backend/plugin/plugin.h" +#include "tests/base_game_test.h" + +namespace loot { + namespace test { + class PluginTest : public BaseGameTest { + protected: + PluginTest() : + emptyFile("EmptyFile.esm"), + nonPluginFile("NotAPlugin.esm") {} + + inline void SetUp() { + BaseGameTest::SetUp(); + + game = Game(GetParam()); + game.SetGamePath(dataPath.parent_path()); + game.Init(false, localPath); + + // Write out an empty file. + boost::filesystem::ofstream out(dataPath / emptyFile); + out.close(); + ASSERT_TRUE(boost::filesystem::exists(dataPath / emptyFile)); + + // Write out an non-empty, non-plugin file. + out.open(dataPath / nonPluginFile); + out << "This isn't a valid plugin file."; + out.close(); + ASSERT_TRUE(boost::filesystem::exists(dataPath / nonPluginFile)); + + if (GetParam() == GameSettings::tes4 || GetParam() == GameSettings::fo4) { + // Create a dummy BSA file. + out.open(dataPath / getArchiveName()); + out.close(); + } + } + + inline void TearDown() { + BaseGameTest::TearDown(); + + boost::filesystem::remove(dataPath / emptyFile); + boost::filesystem::remove(dataPath / nonPluginFile); + + if (GetParam() == GameSettings::tes4 || GetParam() == GameSettings::fo4) + boost::filesystem::remove(dataPath / getArchiveName()); + } + + Game game; + + const std::string emptyFile; + const std::string nonPluginFile; + + private: + inline std::string getArchiveName() { + if (GetParam() == GameSettings::fo4) + return "Blank.ba2"; + else + return "Blank.bsa"; + } + }; + + // Pass an empty first argument, as it's a prefix for the test instantation, + // but we only have the one so no prefix is necessary. + INSTANTIATE_TEST_CASE_P(, + PluginTest, + ::testing::Values( + GameSettings::tes4, + GameSettings::tes5, + GameSettings::fo3, + GameSettings::fonv, + GameSettings::fo4)); + + TEST_P(PluginTest, loadingHeaderOnlyShouldReadHeaderData) { + Plugin plugin(game, blankEsm, true); + + EXPECT_EQ(blankEsm, plugin.Name()); + EXPECT_TRUE(plugin.getMasters().empty()); + EXPECT_TRUE(plugin.isMasterFile()); + EXPECT_FALSE(plugin.IsEmpty()); + EXPECT_EQ("v5.0", plugin.getDescription()); + } + + TEST_P(PluginTest, loadingHeaderOnlyShouldNotReadFieldsOrCalculateCrc) { + Plugin plugin(game, blankEsm, true); + + EXPECT_TRUE(plugin.getFormIds().empty()); + EXPECT_EQ(0, plugin.Crc()); + } + + TEST_P(PluginTest, loadingWholePluginShouldReadHeaderData) { + Plugin plugin(game, blankEsm, true); + + EXPECT_EQ(blankEsm, plugin.Name()); + EXPECT_TRUE(plugin.getMasters().empty()); + EXPECT_TRUE(plugin.isMasterFile()); + EXPECT_FALSE(plugin.IsEmpty()); + EXPECT_EQ("v5.0", plugin.getDescription()); + } + + TEST_P(PluginTest, loadingWholePluginShouldReadFields) { + Plugin plugin(game, blankMasterDependentEsm, false); + + EXPECT_EQ(4, plugin.NumOverrideFormIDs()); + } + + TEST_P(PluginTest, loadingWholePluginShouldCalculateCrc) { + Plugin plugin(game, blankEsm, false); + + EXPECT_EQ(blankEsmCrc, plugin.Crc()); + } + + TEST_P(PluginTest, loadingANonMasterPluginShouldReadTheMasterFlagAsFalse) { + Plugin plugin(game, blankMasterDependentEsp, true); + + EXPECT_FALSE(plugin.isMasterFile()); + } + + TEST_P(PluginTest, loadingAPluginWithMastersShouldReadThemCorrectly) { + Plugin plugin(game, blankMasterDependentEsp, true); + + EXPECT_EQ(std::vector({ + blankEsm + }), plugin.getMasters()); + } + + TEST_P(PluginTest, loadsArchiveShouldReturnTrueForAPluginThatLoadsAnArchive) { + EXPECT_TRUE(Plugin(game, blankEsp, true).LoadsArchive()); + } + + TEST_P(PluginTest, loadsArchiveShouldReturnFalseForAPluginThatDoesNotLoadAnArchive) { + EXPECT_FALSE(Plugin(game, blankDifferentEsm, true).LoadsArchive()); + } + + TEST_P(PluginTest, loadsArchiveShouldReturnFalseForAPluginWithARegexFilename) { + EXPECT_FALSE(Plugin(game, "Blank\\.esp", true).LoadsArchive()); + } + + TEST_P(PluginTest, isValidShouldReturnTrueForAValidPlugin) { + EXPECT_TRUE(Plugin::IsValid(blankEsm, game)); + } + + TEST_P(PluginTest, isValidShouldReturnFalseForANonPluginFile) { + EXPECT_FALSE(Plugin::IsValid(nonPluginFile, game)); + } + + TEST_P(PluginTest, isValidShouldReturnFalseForAnEmptyFile) { + EXPECT_FALSE(Plugin::IsValid(emptyFile, game)); + } + + TEST_P(PluginTest, isActiveShouldReturnTrueForAPluginThatIsActive) { + EXPECT_TRUE(Plugin(game, blankEsm, true).IsActive()); + } + + TEST_P(PluginTest, isActiveShouldReturnFalseForAPluginThatIsNotActive) { + EXPECT_FALSE(Plugin(game, blankEsp, true).IsActive()); + } + + TEST_P(PluginTest, lessThanOperatorShouldUseCaseInsensitiveLexicographicalNameComparison) { + Plugin plugin1(game, "Blank.esp", true); + Plugin plugin2(game, "blank.esp", true); + + EXPECT_FALSE(plugin1 < plugin2); + EXPECT_FALSE(plugin2 < plugin1); + + plugin1 = Plugin(game, "blank.esm", true); + plugin2 = Plugin(game, "blank.esp", true); + + EXPECT_TRUE(plugin1 < plugin2); + EXPECT_FALSE(plugin2 < plugin1); + } + + TEST_P(PluginTest, doFormIDsOverlapShouldReturnFalseForTwoPluginsWithOnlyHeadersLoaded) { + Plugin plugin1(game, blankEsm, true); + Plugin plugin2(game, blankMasterDependentEsm, true); + + EXPECT_FALSE(plugin1.DoFormIDsOverlap(plugin2)); + EXPECT_FALSE(plugin2.DoFormIDsOverlap(plugin1)); + } + + TEST_P(PluginTest, doFormIDsOverlapShouldReturnFalseIfThePluginsHaveUnrelatedRecords) { + Plugin plugin1(game, blankEsm, false); + Plugin plugin2(game, blankEsp, false); + + EXPECT_FALSE(plugin1.DoFormIDsOverlap(plugin2)); + EXPECT_FALSE(plugin2.DoFormIDsOverlap(plugin1)); + } + + TEST_P(PluginTest, doFormIDsOverlapShouldReturnTrueIfOnePluginOverridesTheOthersRecords) { + Plugin plugin1(game, blankEsm, false); + Plugin plugin2(game, blankMasterDependentEsm, false); + + EXPECT_TRUE(plugin1.DoFormIDsOverlap(plugin2)); + EXPECT_TRUE(plugin2.DoFormIDsOverlap(plugin1)); + } + + TEST_P(PluginTest, overlapFormIDsShouldReturnAnEmptySetForTwoPluginsWithOnlyHeadersLoaded) { + Plugin plugin1(game, blankEsm, true); + Plugin plugin2(game, blankMasterDependentEsm, true); + + EXPECT_TRUE(plugin1.OverlapFormIDs(plugin2).empty()); + EXPECT_TRUE(plugin2.OverlapFormIDs(plugin1).empty()); + } + + TEST_P(PluginTest, overlapFormIDsShouldReturnAnEmptySetIfThePluginsHaveUnrelatedRecords) { + Plugin plugin1(game, blankEsm, false); + Plugin plugin2(game, blankEsp, false); + + EXPECT_TRUE(plugin1.OverlapFormIDs(plugin2).empty()); + EXPECT_TRUE(plugin2.OverlapFormIDs(plugin1).empty()); + } + + TEST_P(PluginTest, overlapFormIDsShouldReturnTheFormIDsOfRecordsAddedByOnePluginAndOverriddenByTheOther) { + Plugin plugin1(game, blankEsm, false); + Plugin plugin2(game, blankMasterDependentEsm, false); + + std::set expectedFormIds({ + libespm::FormId(blankEsm, std::vector(), 0xCF0), + libespm::FormId(blankEsm, std::vector(), 0xCF1), + libespm::FormId(blankEsm, std::vector(), 0xCF2), + libespm::FormId(blankEsm, std::vector(), 0xCF3), + }); + EXPECT_EQ(expectedFormIds, plugin1.OverlapFormIDs(plugin2)); + EXPECT_EQ(expectedFormIds, plugin2.OverlapFormIDs(plugin1)); + } + + TEST_P(PluginTest, checkInstallValidityShouldCheckThatRequirementsArePresent) { + Plugin plugin(game, blankEsm, false); + plugin.Reqs({ + File(missingEsp), + File(blankEsp), + }); + + EXPECT_FALSE(plugin.CheckInstallValidity(game)); + EXPECT_EQ(std::list({ + Message(Message::error, "This plugin requires \"" + missingEsp + "\" to be installed, but it is missing."), + }), plugin.Messages()); + } + + TEST_P(PluginTest, checkInstallValidityShouldCheckThatIncompatibilitiesAreAbsent) { + Plugin plugin(game, blankEsm, false); + plugin.Incs({ + File(missingEsp), + File(masterFile), + }); + + EXPECT_FALSE(plugin.CheckInstallValidity(game)); + EXPECT_EQ(std::list({ + Message(Message::error, "This plugin is incompatible with \"" + masterFile + "\", but both are present."), + }), plugin.Messages()); + } + + TEST_P(PluginTest, checkInstallValidityShouldGenerateMessagesFromDirtyInfo) { + Plugin plugin(game, blankEsm, false); + plugin.DirtyInfo({ + PluginDirtyInfo(blankEsmCrc, 0, 1, 2, "utility1"), + PluginDirtyInfo(0xDEADBEEF, 0, 5, 10, "utility2"), + }); + + EXPECT_TRUE(plugin.CheckInstallValidity(game)); + EXPECT_EQ(std::list({ + PluginDirtyInfo(blankEsmCrc, 0, 1, 2, "utility1").AsMessage(), + PluginDirtyInfo(0xDEADBEEF, 0, 5, 10, "utility2").AsMessage(), + }), plugin.Messages()); + } + + TEST_P(PluginTest, checkInstallValidityShouldCheckIfAPluginsMastersAreAllPresentAndActiveIfNoFilterTagIsPresent) { + Plugin plugin(game, blankDifferentMasterDependentEsp, false); + + EXPECT_FALSE(plugin.CheckInstallValidity(game)); + EXPECT_EQ(std::list({ + Message(Message::error, "This plugin requires \"" + blankDifferentEsm + "\" to be active, but it is inactive."), + }), plugin.Messages()); + } + + TEST_P(PluginTest, checkInstallValidityShouldNotCheckIfAPluginsMastersAreAllActiveIfAFilterTagIsPresent) { + Plugin plugin(game, blankDifferentMasterDependentEsp, false); + plugin.Tags({Tag("Filter")}); + + EXPECT_FALSE(plugin.CheckInstallValidity(game)); + EXPECT_TRUE(plugin.Messages().empty()); + } + } +} + +#endif diff --git a/src/tests/backend/plugin/test_plugin.h b/src/tests/backend/plugin/test_plugin.h deleted file mode 100644 index cffefa83..00000000 --- a/src/tests/backend/plugin/test_plugin.h +++ /dev/null @@ -1,258 +0,0 @@ -/* 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_TEST_BACKEND_PLUGIN -#define LOOT_TEST_BACKEND_PLUGIN - -#include "backend/plugin/plugin.h" -#include "tests/fixtures.h" - -namespace loot { - namespace test { - class PluginTest : public SkyrimTest { - protected: - inline virtual void SetUp() { - SkyrimTest::SetUp(); - - game = Game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); - } - - Game game; - }; - - TEST_F(PluginTest, ConstructorsAndDataAccess) { - Plugin plugin(game, "Blank.esm", true); - EXPECT_EQ("Blank.esm", plugin.Name()); - EXPECT_TRUE(plugin.getFormIds().empty()); - EXPECT_TRUE(plugin.getMasters().empty()); - EXPECT_TRUE(plugin.isMasterFile()); - EXPECT_FALSE(plugin.IsEmpty()); - EXPECT_EQ("v5.0", plugin.getDescription()); - EXPECT_EQ(0, plugin.Crc()); - - plugin = Plugin(game, "Blank.esm", false); - EXPECT_EQ("Blank.esm", plugin.Name()); - EXPECT_EQ(std::set({ - libespm::FormId("Blank.esm", std::vector(), 0xCF0), - libespm::FormId("Blank.esm", std::vector(), 0xCF1), - libespm::FormId("Blank.esm", std::vector(), 0xCF2), - libespm::FormId("Blank.esm", std::vector(), 0xCF3), - libespm::FormId("Blank.esm", std::vector(), 0xCF4), - libespm::FormId("Blank.esm", std::vector(), 0xCF5), - libespm::FormId("Blank.esm", std::vector(), 0xCF6), - libespm::FormId("Blank.esm", std::vector(), 0xCF7), - libespm::FormId("Blank.esm", std::vector(), 0xCF8), - libespm::FormId("Blank.esm", std::vector(), 0xCF9), - }), plugin.getFormIds()); - EXPECT_TRUE(plugin.getMasters().empty()); - EXPECT_TRUE(plugin.isMasterFile()); - EXPECT_FALSE(plugin.IsEmpty()); - EXPECT_EQ("v5.0", plugin.getDescription()); - EXPECT_EQ(0x187BE342, plugin.Crc()); - - plugin = Plugin(game, "Blank - Master Dependent.esp", false); - EXPECT_EQ("Blank - Master Dependent.esp", plugin.Name()); - EXPECT_FALSE(plugin.IsEmpty()); - EXPECT_FALSE(plugin.isMasterFile()); - EXPECT_EQ(std::set({ - libespm::FormId("Blank.esm", std::vector(), 0xCF0), - libespm::FormId("Blank.esm", std::vector(), 0xCF1), - libespm::FormId("Blank - Master Dependent.esp", std::vector(), 0xCE9), - libespm::FormId("Blank - Master Dependent.esp", std::vector(), 0xCEA), - }), plugin.getFormIds()); - EXPECT_EQ(std::vector({ - "Blank.esm" - }), plugin.getMasters()); - EXPECT_EQ("", plugin.getDescription()); - EXPECT_EQ(0x832152DC, plugin.Crc()); - } - - TEST_F(PluginTest, LoadsArchive) { - EXPECT_FALSE(Plugin(game, "Blank - Different.esm", true).LoadsArchive()); - EXPECT_FALSE(Plugin(game, "Blank\\.esm", true).LoadsArchive()); - EXPECT_TRUE(Plugin(game, "Blank.esm", true).LoadsArchive()); - } - - TEST_F(PluginTest, IsValid) { - EXPECT_TRUE(Plugin::IsValid("Blank.esm", game)); - EXPECT_FALSE(Plugin::IsValid("NotAPlugin.esm", game)); - EXPECT_FALSE(Plugin::IsValid("EmptyFile.esm", game)); - } - - TEST_F(PluginTest, IsActive) { - Plugin plugin(game, "Blank.esm", true); - EXPECT_TRUE(plugin.IsActive()); - - plugin = Plugin(game, "Blank.esp", true); - EXPECT_FALSE(plugin.IsActive()); - } - - TEST_F(PluginTest, EqualityOperator) { - Plugin plugin1(game, "Blank.esm", true); - Plugin plugin2(game, "blank.esm", true); - EXPECT_TRUE(plugin1 == plugin2); - EXPECT_TRUE(plugin2 == plugin1); - - plugin2 = Plugin(game, "Blank.esp", true); - EXPECT_FALSE(plugin1 == plugin2); - EXPECT_FALSE(plugin2 == plugin1); - - plugin2 = Plugin(game, "Blan.\\.esm", true); - EXPECT_TRUE(plugin1 == plugin2); - EXPECT_TRUE(plugin2 == plugin1); - - plugin1 = Plugin(game, "Blan.esm", true); - EXPECT_FALSE(plugin1 == plugin2); - EXPECT_FALSE(plugin2 == plugin1); - - plugin1 = Plugin(game, "Blan.\\.esm", true); - EXPECT_TRUE(plugin1 == plugin2); - EXPECT_TRUE(plugin2 == plugin1); - - plugin1 = Plugin(game, "Blan(k|p).esm", true); - EXPECT_FALSE(plugin1 == plugin2); - EXPECT_FALSE(plugin2 == plugin1); - } - - TEST_F(PluginTest, InequalityOperator) { - Plugin plugin1(game, "Blank.esm", true); - Plugin plugin2(game, "blank.esm", true); - EXPECT_FALSE(plugin1 != plugin2); - EXPECT_FALSE(plugin2 != plugin1); - - plugin2 = Plugin(game, "Blank.esp", true); - EXPECT_TRUE(plugin1 != plugin2); - EXPECT_TRUE(plugin2 != plugin1); - - plugin2 = Plugin(game, "Blan.\\.esm", true); - EXPECT_FALSE(plugin1 != plugin2); - EXPECT_FALSE(plugin2 != plugin1); - - plugin1 = Plugin(game, "Blan.esm", true); - EXPECT_TRUE(plugin1 != plugin2); - EXPECT_TRUE(plugin2 != plugin1); - - plugin1 = Plugin(game, "Blan.\\.esm", true); - EXPECT_FALSE(plugin1 != plugin2); - EXPECT_FALSE(plugin2 != plugin1); - - plugin1 = Plugin(game, "Blan(k|p).esm", true); - EXPECT_TRUE(plugin1 != plugin2); - EXPECT_TRUE(plugin2 != plugin1); - } - - TEST_F(PluginTest, DoFormIDsOverlap) { - Plugin plugin1(game, "Blank.esm", true); - Plugin plugin2(game, "blank.esm", true); - EXPECT_FALSE(plugin1.DoFormIDsOverlap(plugin2)); - EXPECT_FALSE(plugin2.DoFormIDsOverlap(plugin1)); - - plugin1 = Plugin(game, "Blank.esm", true); - plugin2 = Plugin(game, "Blank - Master Dependent.esm", true); - EXPECT_FALSE(plugin1.DoFormIDsOverlap(plugin2)); - EXPECT_FALSE(plugin2.DoFormIDsOverlap(plugin1)); - - plugin1 = Plugin(game, "Blank.esm", false); - plugin2 = Plugin(game, "Blank.esp", false); - EXPECT_FALSE(plugin1.DoFormIDsOverlap(plugin2)); - EXPECT_FALSE(plugin2.DoFormIDsOverlap(plugin1)); - - plugin1 = Plugin(game, "Blank.esm", false); - plugin2 = Plugin(game, "Blank - Master Dependent.esm", false); - EXPECT_TRUE(plugin1.DoFormIDsOverlap(plugin2)); - EXPECT_TRUE(plugin2.DoFormIDsOverlap(plugin1)); - } - - TEST_F(PluginTest, OverlapFormIDs) { - Plugin plugin1(game, "Blank.esm", true); - Plugin plugin2(game, "blank.esm", true); - EXPECT_TRUE(plugin1.OverlapFormIDs(plugin2).empty()); - EXPECT_TRUE(plugin2.OverlapFormIDs(plugin1).empty()); - - plugin1 = Plugin(game, "Blank.esm", true); - plugin2 = Plugin(game, "Blank - Master Dependent.esm", true); - EXPECT_TRUE(plugin1.OverlapFormIDs(plugin2).empty()); - EXPECT_TRUE(plugin2.OverlapFormIDs(plugin1).empty()); - - plugin1 = Plugin(game, "Blank.esm", false); - plugin2 = Plugin(game, "Blank.esp", false); - EXPECT_TRUE(plugin1.OverlapFormIDs(plugin2).empty()); - EXPECT_TRUE(plugin2.OverlapFormIDs(plugin1).empty()); - - plugin1 = Plugin(game, "Blank.esm", false); - plugin2 = Plugin(game, "Blank - Master Dependent.esm", false); - EXPECT_EQ(std::set({ - libespm::FormId("Blank.esm", std::vector(), 0xCF0), - libespm::FormId("Blank.esm", std::vector(), 0xCF1), - libespm::FormId("Blank.esm", std::vector(), 0xCF2), - libespm::FormId("Blank.esm", std::vector(), 0xCF3), - }), plugin1.OverlapFormIDs(plugin2)); - EXPECT_EQ(std::set({ - libespm::FormId("Blank.esm", std::vector(), 0xCF0), - libespm::FormId("Blank.esm", std::vector(), 0xCF1), - libespm::FormId("Blank.esm", std::vector(), 0xCF2), - libespm::FormId("Blank.esm", std::vector(), 0xCF3), - }), plugin2.OverlapFormIDs(plugin1)); - } - - TEST_F(PluginTest, CheckInstallValidity) { - Plugin plugin(game, "Blank.esm", false); - plugin.Reqs({ - File("Blank.missing.esm"), - File("Blank.esp"), - File("Blank - Master Dependent.esm"), - }); - plugin.Incs({ - File("Blank - Different.esm"), - File("Skyrim.esm"), - }); - plugin.DirtyInfo({ - PluginDirtyInfo(0x187BE342, 0, 1, 2, "utility1"), - PluginDirtyInfo(0xDEADBEEF, 0, 5, 10, "utility2"), - }); - EXPECT_TRUE(plugin.CheckInstallValidity(game)); - EXPECT_EQ(std::list({ - Message(Message::error, "This plugin requires \"Blank.missing.esm\" to be installed, but it is missing."), - Message(Message::error, "This plugin is incompatible with \"Skyrim.esm\", but both are present."), - PluginDirtyInfo(0x187BE342, 0, 1, 2, "utility1").AsMessage(), - PluginDirtyInfo(0xDEADBEEF, 0, 5, 10, "utility2").AsMessage(), - }), plugin.Messages()); - - plugin = Plugin(game, "Blank - Different Master Dependent.esp", false); - EXPECT_FALSE(plugin.CheckInstallValidity(game)); - EXPECT_EQ(std::list({ - Message(Message::error, "This plugin requires \"Blank - Different.esm\" to be active, but it is inactive."), - }), plugin.Messages()); - - plugin = Plugin(game, "Blank - Different Master Dependent.esp", false); - plugin.Tags({Tag("Filter")}); - EXPECT_FALSE(plugin.CheckInstallValidity(game)); - EXPECT_TRUE(plugin.Messages().empty()); - } - } -} - -#endif diff --git a/src/tests/base_game_test.h b/src/tests/base_game_test.h index 6d1a1afd..be755b76 100644 --- a/src/tests/base_game_test.h +++ b/src/tests/base_game_test.h @@ -145,6 +145,7 @@ namespace loot { return std::unordered_set({ masterFile, blankEsm, + blankDifferentMasterDependentEsp, }); } diff --git a/src/tests/main.cpp b/src/tests/main.cpp index cd03bf57..079cdea0 100644 --- a/src/tests/main.cpp +++ b/src/tests/main.cpp @@ -59,7 +59,7 @@ #include "backend/metadata/plugin_dirty_info_test.h" #include "backend/metadata/plugin_metadata_test.h" #include "backend/metadata/tag_test.h" -#include "backend/plugin/test_plugin.h" +#include "backend/plugin/plugin_test.h" #include "backend/test_metadata_list.h" #include "backend/test_masterlist.h" #include "backend/test_plugin_sorter.h" From 4e3d1b64a60c56ce09aadb0eb5952cc818f14b54 Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Thu, 31 Mar 2016 21:12:48 +0100 Subject: [PATCH 33/38] Fix tests broken by introduction of ghosted plugin --- src/tests/backend/game/game_test.h | 17 ++++++++--------- src/tests/base_game_test.h | 9 ++++++--- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/tests/backend/game/game_test.h b/src/tests/backend/game/game_test.h index 077af4b6..4ad16b99 100644 --- a/src/tests/backend/game/game_test.h +++ b/src/tests/backend/game/game_test.h @@ -170,21 +170,20 @@ namespace loot { // First set reverse timestamps to be sure. time_t time = boost::filesystem::last_write_time(dataPath / masterFile); for (size_t i = 1; i < loadOrder.size(); ++i) { + if (!boost::filesystem::exists(dataPath / loadOrder[i])) + loadOrder[i] += ".ghost"; + boost::filesystem::last_write_time(dataPath / loadOrder[i], time - i * 60); ASSERT_EQ(time - i * 60, boost::filesystem::last_write_time(dataPath / loadOrder[i])); } EXPECT_NO_THROW(game.RedatePlugins()); - if (GetParam() == Game::tes5) { - for (size_t i = 0; i < loadOrder.size(); ++i) { - ASSERT_EQ(time + i * 60, boost::filesystem::last_write_time(dataPath / loadOrder[i])); - } - } - else { - for (size_t i = 0; i < loadOrder.size(); ++i) { - ASSERT_EQ(time - i * 60, boost::filesystem::last_write_time(dataPath / loadOrder[i])); - } + time_t interval = 60; + if (GetParam() != Game::tes5) + interval *= -1; + for (size_t i = 0; i < loadOrder.size(); ++i) { + EXPECT_EQ(time + i * interval, boost::filesystem::last_write_time(dataPath / loadOrder[i])); } } diff --git a/src/tests/base_game_test.h b/src/tests/base_game_test.h index be755b76..7d827cb2 100644 --- a/src/tests/base_game_test.h +++ b/src/tests/base_game_test.h @@ -103,9 +103,12 @@ namespace loot { if (isLoadOrderTimestampBased(GetParam())) { std::map loadOrder; for (boost::filesystem::directory_iterator it(dataPath); it != boost::filesystem::directory_iterator(); ++it) { - if (boost::filesystem::is_regular_file(it->status()) && - (boost::ends_with(it->path().filename().string(), ".esp") || boost::ends_with(it->path().filename().string(), ".esm"))) { - loadOrder.emplace(boost::filesystem::last_write_time(it->path()), it->path().filename().string()); + if (boost::filesystem::is_regular_file(it->status())) { + std::string filename = it->path().filename().string(); + if (boost::ends_with(filename, ".ghost")) + filename = it->path().stem().string(); + if (boost::ends_with(filename, ".esp") || boost::ends_with(filename, ".esm")) + loadOrder.emplace(boost::filesystem::last_write_time(it->path()), filename); } } for (const auto& plugin : loadOrder) From 06d70e624d125c3300fa43c0305c961ab13a2202 Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Fri, 1 Apr 2016 22:14:15 +0100 Subject: [PATCH 34/38] Improve Masterlist tests --- CMakeLists.txt | 2 +- src/tests/backend/masterlist_test.h | 215 ++++++++++++++++++++++++++++ src/tests/backend/test_masterlist.h | 171 ---------------------- src/tests/base_game_test.h | 2 + src/tests/main.cpp | 2 +- 5 files changed, 219 insertions(+), 173 deletions(-) create mode 100644 src/tests/backend/masterlist_test.h delete mode 100644 src/tests/backend/test_masterlist.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 33da5b64..b03e48ac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -254,8 +254,8 @@ set (LOOT_TESTS_HEADERS "${CMAKE_SOURCE_DIR}/src/tests/base_game_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/plugin_metadata_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/tag_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/plugin/plugin_test.h" + "${CMAKE_SOURCE_DIR}/src/tests/backend/masterlist_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/test_metadata_list.h" - "${CMAKE_SOURCE_DIR}/src/tests/backend/test_masterlist.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/test_plugin_sorter.h" "${CMAKE_SOURCE_DIR}/src/tests/gui/loot_settings_test.h" "${CMAKE_SOURCE_DIR}/src/tests/gui/loot_state_test.h") diff --git a/src/tests/backend/masterlist_test.h b/src/tests/backend/masterlist_test.h new file mode 100644 index 00000000..a663ac51 --- /dev/null +++ b/src/tests/backend/masterlist_test.h @@ -0,0 +1,215 @@ +/* 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_TEST_BACKEND_MASTERLIST +#define LOOT_TEST_BACKEND_MASTERLIST + +#include "backend/masterlist.h" +#include "tests/base_game_test.h" + +namespace loot { + namespace test { + class MasterlistTest : public BaseGameTest { + protected: + MasterlistTest() : + repoBranch("master"), + repoUrl("https://github.com/loot/testing-metadata.git"), + masterlistPath(localPath / "masterlist.yaml") {} + + void SetUp() { + BaseGameTest::SetUp(); + + ASSERT_FALSE(boost::filesystem::exists(masterlistPath)); + ASSERT_FALSE(boost::filesystem::exists(localPath / ".git")); + + ASSERT_NO_THROW(boost::filesystem::create_directories(g_path_local / Game(GetParam()).FolderName())); + } + + void TearDown() { + BaseGameTest::TearDown(); + + ASSERT_NO_THROW(boost::filesystem::remove(masterlistPath)); + ASSERT_NO_THROW(boost::filesystem::remove_all(localPath / ".git")); + + ASSERT_NO_THROW(boost::filesystem::remove(g_path_local / Game(GetParam()).FolderName() / "masterlist.yaml")); + ASSERT_NO_THROW(boost::filesystem::remove_all(g_path_local / Game(GetParam()).FolderName() / ".git")); + } + + const std::string repoUrl; + const std::string repoBranch; + + const boost::filesystem::path masterlistPath; + }; + + // Pass an empty first argument, as it's a prefix for the test instantation, + // but we only have the one so no prefix is necessary. + INSTANTIATE_TEST_CASE_P(, + MasterlistTest, + ::testing::Values( + GameSettings::tes4, + GameSettings::tes5, + GameSettings::fo3, + GameSettings::fonv, + GameSettings::fo4)); + + TEST_P(MasterlistTest, updateWithGameParameterShouldReturnTrueIfNoMasterlistExists) { + Game game(GetParam()); + game.SetGamePath(dataPath.parent_path()); + game.SetRepoURL(repoUrl); + game.SetRepoBranch(repoBranch); + ASSERT_NO_THROW(game.Init(false, localPath)); + + // This may fail on Windows if a 'real' LOOT install is also present. + Masterlist masterlist; + EXPECT_TRUE(masterlist.Update(game)); + EXPECT_TRUE(boost::filesystem::exists(game.MasterlistPath())); + } + + TEST_P(MasterlistTest, updateWithGameParameterShouldReturnFalseIfAnUpToDateMasterlistExists) { + Game game(GetParam()); + game.SetGamePath(dataPath.parent_path()); + game.SetRepoURL(repoUrl); + game.SetRepoBranch(repoBranch); + ASSERT_NO_THROW(game.Init(false, localPath)); + + // This may fail on Windows if a 'real' LOOT install is also present. + Masterlist masterlist; + EXPECT_TRUE(masterlist.Update(game)); + EXPECT_TRUE(boost::filesystem::exists(game.MasterlistPath())); + + EXPECT_FALSE(masterlist.Update(game)); + EXPECT_TRUE(boost::filesystem::exists(game.MasterlistPath())); + } + + TEST_P(MasterlistTest, updateWithSeparateParametersShouldThrowIfAnInvalidPathIsGiven) { + Masterlist masterlist; + + EXPECT_ANY_THROW(masterlist.Update(";//\?", repoUrl, repoBranch)); + } + + TEST_P(MasterlistTest, updateWithSeparateParametersShouldThrowIfABlankPathIsGiven) { + Masterlist masterlist; + + EXPECT_ANY_THROW(masterlist.Update("", repoUrl, repoBranch)); + } + + TEST_P(MasterlistTest, updateWithSeparateParametersShouldThrowIfABranchThatDoesNotExistIsGiven) { + Masterlist masterlist; + + EXPECT_ANY_THROW(masterlist.Update(masterlistPath, + repoUrl, + "missing-branch")); + } + + TEST_P(MasterlistTest, updateWithSeparateParametersShouldThrowIfABlankBranchIsGiven) { + Masterlist masterlist; + + EXPECT_ANY_THROW(masterlist.Update(masterlistPath, repoUrl, "")); + } + + TEST_P(MasterlistTest, updateWithSeparateParametersShouldThrowIfAUrlThatDoesNotExistIsGiven) { + Masterlist masterlist; + + EXPECT_ANY_THROW(masterlist.Update(masterlistPath, + "https://github.com/loot/does-not-exist.git", + repoBranch)); + } + + TEST_P(MasterlistTest, updateWithSeparateParametersShouldThrowIfABlankUrlIsGiven) { + Masterlist masterlist; + EXPECT_ANY_THROW(masterlist.Update(masterlistPath, "", repoBranch)); + } + + TEST_P(MasterlistTest, updateWithSeparateParametersShouldReturnTrueIfNoMasterlistExists) { + Masterlist masterlist; + EXPECT_TRUE(masterlist.Update(masterlistPath, + repoUrl, + repoBranch)); + } + + TEST_P(MasterlistTest, updateWithSeparateParametersShouldReturnFalseIfAnUpToDateMasterlistExists) { + Masterlist masterlist; + + EXPECT_TRUE(masterlist.Update(masterlistPath, + repoUrl, + repoBranch)); + + EXPECT_FALSE(masterlist.Update(masterlistPath, + repoUrl, + repoBranch)); + } + + TEST_P(MasterlistTest, getInfoShouldThrowIfNoMasterlistExistsAtTheGivenPath) { + Masterlist masterlist; + EXPECT_ANY_THROW(masterlist.GetInfo(masterlistPath, false)); + } + + TEST_P(MasterlistTest, getInfoShouldThrowIfTheGivenPathDoesNotBelongToAGitRepository) { + ASSERT_NO_THROW(boost::filesystem::copy("./testing-metadata/masterlist.yaml", masterlistPath)); + + Masterlist masterlist; + EXPECT_ANY_THROW(masterlist.GetInfo(masterlistPath, false)); + } + + TEST_P(MasterlistTest, getInfoShouldReturnRevisionAndDateStringsOfTheCorrectLengthsWhenRequestingALongId) { + Masterlist masterlist; + ASSERT_TRUE(masterlist.Update(masterlistPath, + repoUrl, + repoBranch)); + + Masterlist::Info info = masterlist.GetInfo(masterlistPath, false); + EXPECT_EQ(40, info.revision.length()); + EXPECT_EQ(10, info.date.length()); + } + + TEST_P(MasterlistTest, getInfoShouldReturnRevisionAndDateStringsOfTheCorrectLengthsWhenRequestingAShortId) { + Masterlist masterlist; + ASSERT_TRUE(masterlist.Update(masterlistPath, + repoUrl, + repoBranch)); + + Masterlist::Info info = masterlist.GetInfo(masterlistPath, true); + EXPECT_GE((unsigned)40, info.revision.length()); + EXPECT_LE((unsigned)7, info.revision.length()); + EXPECT_EQ(10, info.date.length()); + } + + TEST_P(MasterlistTest, getInfoShouldAppendSuffixesToReturnedStringsIfTheMasterlistHasBeenEdited) { + Masterlist masterlist; + ASSERT_TRUE(masterlist.Update(masterlistPath, + repoUrl, + repoBranch)); + boost::filesystem::ofstream out(masterlistPath); + out.close(); + + Masterlist::Info info = masterlist.GetInfo(masterlistPath, false); + EXPECT_EQ(49, info.revision.length()); + EXPECT_EQ(" (edited)", info.revision.substr(40)); + EXPECT_EQ(19, info.date.length()); + EXPECT_EQ(" (edited)", info.date.substr(10)); + } + } +} + +#endif diff --git a/src/tests/backend/test_masterlist.h b/src/tests/backend/test_masterlist.h deleted file mode 100644 index 5a97d60b..00000000 --- a/src/tests/backend/test_masterlist.h +++ /dev/null @@ -1,171 +0,0 @@ -/* 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_TEST_BACKEND_MASTERLIST -#define LOOT_TEST_BACKEND_MASTERLIST - -#include "backend/masterlist.h" -#include "tests/fixtures.h" - -namespace loot { - namespace test { - class MasterlistTest : public SkyrimTest { - protected: -#ifndef _WIN32 - void SetUp() { - SkyrimTest::SetUp(); - - ASSERT_NO_THROW(boost::filesystem::create_directories(g_path_local / "Skyrim")); - } - - void TearDown() { - SkyrimTest::TearDown(); - - ASSERT_NO_THROW(boost::filesystem::remove_all(g_path_local)); - } -#endif - }; - - TEST_F(MasterlistTest, Update_Game) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - game.SetRepoURL("https://github.com/loot/testing-metadata.git"); - game.SetRepoBranch("master"); - ASSERT_NO_THROW(game.Init(false, localPath)); - - // This may fail on Windows if a 'real' LOOT install is also present. - Masterlist masterlist; - EXPECT_TRUE(masterlist.Update(game)); - EXPECT_TRUE(boost::filesystem::exists(game.MasterlistPath())); - - EXPECT_FALSE(masterlist.Update(game)); - EXPECT_TRUE(boost::filesystem::exists(game.MasterlistPath())); - } - - TEST_F(MasterlistTest, Update_NonGame_InvalidPath) { - Masterlist masterlist; - EXPECT_ANY_THROW(masterlist.Update(";//\?", - "https://github.com/loot/testing-metadata.git", - "master")); - } - - TEST_F(MasterlistTest, Update_NonGame_EmptyPath) { - Masterlist masterlist; - EXPECT_ANY_THROW(masterlist.Update("", - "https://github.com/loot/testing-metadata.git", - "master")); - } - - TEST_F(MasterlistTest, Update_NonGame_InvalidBranch) { - Masterlist masterlist; - EXPECT_ANY_THROW(masterlist.Update(masterlistPath, - "https://github.com/loot/testing-metadata.git", - "missing-branch")); - } - - TEST_F(MasterlistTest, Update_NonGame_EmptyBranch) { - Masterlist masterlist; - EXPECT_ANY_THROW(masterlist.Update(masterlistPath, - "https://github.com/loot/testing-metadata.git", - "")); - } - - TEST_F(MasterlistTest, Update_NonGame_InvalidUrl) { - Masterlist masterlist; - EXPECT_ANY_THROW(masterlist.Update(masterlistPath, - "https://github.com/loot/does-not-exist.git", - "master")); - } - - TEST_F(MasterlistTest, Update_NonGame_EmptyUrl) { - Masterlist masterlist; - EXPECT_ANY_THROW(masterlist.Update(masterlistPath, - "", - "master")); - } - - TEST_F(MasterlistTest, Update_NonGame) { - Masterlist masterlist; - EXPECT_TRUE(masterlist.Update(masterlistPath, - "https://github.com/loot/testing-metadata.git", - "master")); - - EXPECT_FALSE(masterlist.Update(masterlistPath, - "https://github.com/loot/testing-metadata.git", - "master")); - } - - TEST_F(MasterlistTest, GetInfo_NoMasterlist) { - Masterlist masterlist; - EXPECT_ANY_THROW(masterlist.GetInfo(masterlistPath, false)); - } - - TEST_F(MasterlistTest, GetInfo_NoRepository) { - ASSERT_NO_THROW(boost::filesystem::copy("./testing-metadata/masterlist.yaml", masterlistPath)); - - Masterlist masterlist; - EXPECT_ANY_THROW(masterlist.GetInfo(masterlistPath, false)); - } - - TEST_F(MasterlistTest, GetInfo_LongID) { - Masterlist masterlist; - ASSERT_TRUE(masterlist.Update(masterlistPath, - "https://github.com/loot/testing-metadata.git", - "master")); - - Masterlist::Info info = masterlist.GetInfo(masterlistPath, false); - EXPECT_EQ(40, info.revision.length()); - EXPECT_EQ(10, info.date.length()); - } - - TEST_F(MasterlistTest, GetInfo_ShortID) { - Masterlist masterlist; - ASSERT_TRUE(masterlist.Update(masterlistPath, - "https://github.com/loot/testing-metadata.git", - "master")); - - Masterlist::Info info = masterlist.GetInfo(masterlistPath, true); - EXPECT_GE((unsigned)40, info.revision.length()); - EXPECT_LE((unsigned)7, info.revision.length()); - EXPECT_EQ(10, info.date.length()); - } - - TEST_F(MasterlistTest, GetInfo_Edited) { - Masterlist masterlist; - ASSERT_TRUE(masterlist.Update(masterlistPath, - "https://github.com/loot/testing-metadata.git", - "master")); - boost::filesystem::ofstream out(masterlistPath); - out.close(); - - Masterlist::Info info = masterlist.GetInfo(masterlistPath, false); - EXPECT_EQ(49, info.revision.length()); - EXPECT_EQ(" (edited)", info.revision.substr(40)); - EXPECT_EQ(19, info.date.length()); - EXPECT_EQ(" (edited)", info.date.substr(10)); - } - } -} - -#endif diff --git a/src/tests/base_game_test.h b/src/tests/base_game_test.h index 7d827cb2..eb2d9035 100644 --- a/src/tests/base_game_test.h +++ b/src/tests/base_game_test.h @@ -90,6 +90,8 @@ namespace loot { } inline virtual void TearDown() { + ASSERT_NO_THROW(boost::filesystem::remove_all(localPath)); + ASSERT_NO_THROW(boost::filesystem::remove(dataPath / masterFile)); // Unghost the ghosted plugin. diff --git a/src/tests/main.cpp b/src/tests/main.cpp index 079cdea0..c0efd943 100644 --- a/src/tests/main.cpp +++ b/src/tests/main.cpp @@ -61,7 +61,7 @@ #include "backend/metadata/tag_test.h" #include "backend/plugin/plugin_test.h" #include "backend/test_metadata_list.h" -#include "backend/test_masterlist.h" +#include "backend/masterlist_test.h" #include "backend/test_plugin_sorter.h" #include "gui/loot_settings_test.h" #include "gui/loot_state_test.h" From 5c8dee547cd2b7238e5f73f9cb0cbc5749fa66bf Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Sat, 2 Apr 2016 10:47:18 +0100 Subject: [PATCH 35/38] Improve MetadataList tests --- CMakeLists.txt | 2 +- src/tests/backend/metadata_list_test.h | 296 +++++++++++++++++++++++++ src/tests/backend/test_metadata_list.h | 251 --------------------- src/tests/main.cpp | 2 +- 4 files changed, 298 insertions(+), 253 deletions(-) create mode 100644 src/tests/backend/metadata_list_test.h delete mode 100644 src/tests/backend/test_metadata_list.h diff --git a/CMakeLists.txt b/CMakeLists.txt index b03e48ac..38826f4d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -255,7 +255,7 @@ set (LOOT_TESTS_HEADERS "${CMAKE_SOURCE_DIR}/src/tests/base_game_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata/tag_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/plugin/plugin_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/masterlist_test.h" - "${CMAKE_SOURCE_DIR}/src/tests/backend/test_metadata_list.h" + "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata_list_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/test_plugin_sorter.h" "${CMAKE_SOURCE_DIR}/src/tests/gui/loot_settings_test.h" "${CMAKE_SOURCE_DIR}/src/tests/gui/loot_state_test.h") diff --git a/src/tests/backend/metadata_list_test.h b/src/tests/backend/metadata_list_test.h new file mode 100644 index 00000000..1f66edde --- /dev/null +++ b/src/tests/backend/metadata_list_test.h @@ -0,0 +1,296 @@ +/* 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_TEST_BACKEND_METADATA_LIST +#define LOOT_TEST_BACKEND_METADATA_LIST + +#include "backend/metadata_list.h" +#include "tests/base_game_test.h" + +namespace loot { + namespace test { + class MetadataListTest : public BaseGameTest { + protected: + MetadataListTest() : + metadataPath("./testing-metadata/masterlist.yaml"), + savedMetadataPath("./testing-metadata/saved.masterlist.yaml"), + missingMetadataPath("./missing-metadata.yaml"), + invalidMetadataPaths({"./testing-metadata/invalid/non_unique.yaml"}) { + PluginMetadataToString = [](const PluginMetadata& plugin) { + return plugin.Name(); + }; + } + + inline virtual void SetUp() { + BaseGameTest::SetUp(); + + ASSERT_TRUE(boost::filesystem::exists(metadataPath)); + ASSERT_FALSE(boost::filesystem::exists(savedMetadataPath)); + + for (const auto& path : invalidMetadataPaths) { + ASSERT_TRUE(boost::filesystem::exists(path)); + } + } + + inline virtual void TearDown() { + BaseGameTest::TearDown(); + + ASSERT_TRUE(boost::filesystem::exists(metadataPath)); + ASSERT_NO_THROW(boost::filesystem::remove(savedMetadataPath)); + + for (const auto& path : invalidMetadataPaths) { + ASSERT_TRUE(boost::filesystem::exists(path)); + } + } + + const boost::filesystem::path metadataPath; + const boost::filesystem::path savedMetadataPath; + const boost::filesystem::path missingMetadataPath; + const std::vector invalidMetadataPaths; + + std::function PluginMetadataToString; + }; + + // Pass an empty first argument, as it's a prefix for the test instantation, + // but we only have the one so no prefix is necessary. + INSTANTIATE_TEST_CASE_P(, + MetadataListTest, + ::testing::Values( + GameSettings::tes4)); + + TEST_P(MetadataListTest, loadShouldLoadGlobalMessages) { + MetadataList metadataList; + + EXPECT_NO_THROW(metadataList.Load(metadataPath)); + EXPECT_EQ(std::list({ + Message(Message::say, "A global message."), + }), metadataList.Messages()); + } + + TEST_P(MetadataListTest, loadShouldLoadPluginMetadata) { + MetadataList metadataList; + + EXPECT_NO_THROW(metadataList.Load(metadataPath)); + // Non-regex plugins can be outputted in any order, and regex entries can + // match each other, so convert the list to a set of strings for + // comparison. + std::list result(metadataList.Plugins()); + std::set names; + std::transform(begin(result), + end(result), + std::insert_iterator>(names, begin(names)), + PluginMetadataToString); + + EXPECT_EQ(std::set({ + blankEsm, + blankEsp, + "Blank.+\\.esp", + "Blank.+(Different)?.*\\.esp", + }), names); + } + + TEST_P(MetadataListTest, loadShouldThrowIfAnInvalidMetadataFileIsGiven) { + MetadataList ml; + for (const auto& path : invalidMetadataPaths) { + EXPECT_ANY_THROW(ml.Load(path)); + } + } + + TEST_P(MetadataListTest, loadShouldClearExistingDataIfAnInvalidMetadataFileIsGiven) { + MetadataList metadataList; + + ASSERT_NO_THROW(metadataList.Load(metadataPath)); + ASSERT_FALSE(metadataList.Messages().empty()); + ASSERT_FALSE(metadataList.Plugins().empty()); + + EXPECT_ANY_THROW(metadataList.Load(blankEsm)); + EXPECT_TRUE(metadataList.Messages().empty()); + EXPECT_TRUE(metadataList.Plugins().empty()); + } + + TEST_P(MetadataListTest, loadShouldClearExistingDataIfAMissingMetadataFileIsGiven) { + MetadataList metadataList; + + ASSERT_NO_THROW(metadataList.Load(metadataPath)); + ASSERT_FALSE(metadataList.Messages().empty()); + ASSERT_FALSE(metadataList.Plugins().empty()); + + EXPECT_ANY_THROW(metadataList.Load(missingMetadataPath)); + EXPECT_TRUE(metadataList.Messages().empty()); + EXPECT_TRUE(metadataList.Plugins().empty()); + } + + TEST_P(MetadataListTest, saveShouldWriteTheLoadedMetadataToTheGivenFilePath) { + MetadataList metadataList; + ASSERT_NO_THROW(metadataList.Load(metadataPath)); + + EXPECT_NO_THROW(metadataList.Save(savedMetadataPath)); + + EXPECT_TRUE(boost::filesystem::exists(savedMetadataPath)); + + // Check the new file contains the same metadata. + EXPECT_NO_THROW(metadataList.Load(savedMetadataPath)); + + EXPECT_EQ(std::list({ + Message(Message::say, "A global message."), + }), metadataList.Messages()); + + // Non-regex plugins can be outputted in any order, and regex entries can + // match each other, so convert the list to a set of strings for + // comparison. + std::list result(metadataList.Plugins()); + std::set names; + std::transform(begin(result), + end(result), + std::insert_iterator>(names, begin(names)), + PluginMetadataToString); + EXPECT_EQ(std::set({ + blankEsm, + blankEsp, + "Blank.+\\.esp", + "Blank.+(Different)?.*\\.esp", + }), names); + } + + TEST_P(MetadataListTest, clearShouldClearLoadedMessagesAndPlugins) { + MetadataList metadataList; + ASSERT_NO_THROW(metadataList.Load(metadataPath)); + ASSERT_FALSE(metadataList.Messages().empty()); + ASSERT_FALSE(metadataList.Plugins().empty()); + + metadataList.clear(); + EXPECT_TRUE(metadataList.Messages().empty()); + EXPECT_TRUE(metadataList.Plugins().empty()); + } + + TEST_P(MetadataListTest, findPluginShouldReturnAnEmptyPluginObjectIfTheGivenPluginIsNotInTheMetadataList) { + MetadataList metadataList; + PluginMetadata plugin = metadataList.FindPlugin(PluginMetadata(blankDifferentEsm)); + + EXPECT_EQ(blankDifferentEsm, plugin.Name()); + EXPECT_TRUE(plugin.HasNameOnly()); + } + + TEST_P(MetadataListTest, findPluginShouldReturnTheMetadataObjectInTheMetadataListIfOneExistsForTheGivenPlugin) { + MetadataList metadataList; + ASSERT_NO_THROW(metadataList.Load(metadataPath)); + + PluginMetadata plugin = metadataList.FindPlugin(PluginMetadata(blankDifferentEsp)); + + EXPECT_EQ(blankDifferentEsp, plugin.Name()); + EXPECT_EQ(std::set({ + File(blankEsm), + }), plugin.LoadAfter()); + EXPECT_EQ(std::set({ + File(blankEsp), + }), plugin.Incs()); + } + + TEST_P(MetadataListTest, addPluginShouldStoreGivenSpecificPluginMetadata) { + MetadataList metadataList; + ASSERT_NO_THROW(metadataList.Load(metadataPath)); + ASSERT_TRUE(metadataList.FindPlugin(PluginMetadata(blankDifferentEsm)).HasNameOnly()); + + PluginMetadata plugin(blankDifferentEsm); + plugin.Priority(1000); + metadataList.AddPlugin(plugin); + + plugin = metadataList.FindPlugin(plugin); + + EXPECT_EQ(blankDifferentEsm, plugin.Name()); + EXPECT_EQ(1000, plugin.Priority()); + } + + TEST_P(MetadataListTest, addPluginShouldStoreGivenRegexPluginMetadata) { + MetadataList metadataList; + ASSERT_NO_THROW(metadataList.Load(metadataPath)); + + PluginMetadata plugin(".+Dependent\\.esp"); + plugin.Priority(-10); + metadataList.AddPlugin(plugin); + + plugin = metadataList.FindPlugin(PluginMetadata(blankPluginDependentEsp)); + + EXPECT_EQ(-10, plugin.Priority()); + } + + TEST_P(MetadataListTest, addPluginShouldThrowIfAMatchingPluginAlreadyExists) { + MetadataList metadataList; + ASSERT_NO_THROW(metadataList.Load(metadataPath)); + + PluginMetadata plugin = metadataList.FindPlugin(PluginMetadata(blankEsm)); + ASSERT_EQ(blankEsm, plugin.Name()); + ASSERT_FALSE(plugin.HasNameOnly()); + + ASSERT_ANY_THROW(metadataList.AddPlugin(PluginMetadata(blankEsm))); + } + + TEST_P(MetadataListTest, erasePluginShouldRemoveStoredMetadatForTheGivenPlugin) { + MetadataList metadataList; + ASSERT_NO_THROW(metadataList.Load(metadataPath)); + + PluginMetadata plugin = metadataList.FindPlugin(PluginMetadata(blankEsp)); + ASSERT_EQ(blankEsp, plugin.Name()); + ASSERT_FALSE(plugin.HasNameOnly()); + + metadataList.ErasePlugin(plugin); + + plugin = metadataList.FindPlugin(plugin); + EXPECT_EQ(blankEsp, plugin.Name()); + EXPECT_TRUE(plugin.HasNameOnly()); + } + + TEST_P(MetadataListTest, evalAllConditionsShouldEvaluateTheConditionsForThePluginsStoredInTeMetadataList) { + Game game(GetParam()); + game.SetGamePath(dataPath.parent_path()); + ASSERT_NO_THROW(game.Init(false, localPath)); + + MetadataList metadataList; + ASSERT_NO_THROW(metadataList.Load(metadataPath)); + + PluginMetadata plugin = metadataList.FindPlugin(PluginMetadata(blankEsm)); + ASSERT_EQ(std::list({ + Message(Message::warn, "This is a warning."), + Message(Message::say, "This message should be removed when evaluating conditions."), + }), plugin.Messages()); + + plugin = metadataList.FindPlugin(PluginMetadata(blankEsp)); + ASSERT_EQ(blankEsp, plugin.Name()); + ASSERT_FALSE(plugin.HasNameOnly()); + + EXPECT_NO_THROW(metadataList.EvalAllConditions(game, Language::english)); + + plugin = metadataList.FindPlugin(PluginMetadata(blankEsm)); + EXPECT_EQ(std::list({ + Message(Message::warn, "This is a warning."), + }), plugin.Messages()); + + plugin = metadataList.FindPlugin(PluginMetadata(blankEsp)); + EXPECT_EQ(blankEsp, plugin.Name()); + EXPECT_TRUE(plugin.HasNameOnly()); + } + } +} + +#endif diff --git a/src/tests/backend/test_metadata_list.h b/src/tests/backend/test_metadata_list.h deleted file mode 100644 index bcc3475b..00000000 --- a/src/tests/backend/test_metadata_list.h +++ /dev/null @@ -1,251 +0,0 @@ -/* 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_TEST_BACKEND_METADATA_LIST -#define LOOT_TEST_BACKEND_METADATA_LIST - -#include "backend/metadata_list.h" -#include "tests/fixtures.h" - -namespace loot { - namespace test { - class MetadataListTest : public SkyrimTest { - protected: - MetadataListTest() : - metadataPath("./testing-metadata/masterlist.yaml"), - savedMetadataPath("./testing-metadata/saved.masterlist.yaml"), - invalidMetadataPaths({"./testing-metadata/invalid/non_unique.yaml"}) { - PluginMetadataToString = [](const PluginMetadata& plugin) { - return plugin.Name(); - }; - } - - inline virtual void SetUp() { - SkyrimTest::SetUp(); - - ASSERT_TRUE(boost::filesystem::exists(metadataPath)); - ASSERT_FALSE(boost::filesystem::exists(savedMetadataPath)); - - for (const auto& path : invalidMetadataPaths) { - ASSERT_TRUE(boost::filesystem::exists(path)); - } - } - - inline virtual void TearDown() { - SkyrimTest::TearDown(); - - ASSERT_TRUE(boost::filesystem::exists(metadataPath)); - ASSERT_NO_THROW(boost::filesystem::remove(savedMetadataPath)); - - for (const auto& path : invalidMetadataPaths) { - ASSERT_TRUE(boost::filesystem::exists(path)); - } - } - - const boost::filesystem::path metadataPath; - const boost::filesystem::path savedMetadataPath; - const std::vector invalidMetadataPaths; - - std::function PluginMetadataToString; - }; - - TEST_F(MetadataListTest, Load) { - MetadataList ml; - EXPECT_NO_THROW(ml.Load(metadataPath)); - EXPECT_EQ(std::list({ - Message(Message::say, "A global message."), - }), ml.Messages()); - - // Non-regex plugins can be outputted in any order, and regex entries can - // match each other, so convert the list to a set of strings for - // comparison. - std::list result(ml.Plugins()); - std::set names; - std::transform(result.begin(), - result.end(), - std::insert_iterator>(names, names.begin()), - PluginMetadataToString); - EXPECT_EQ(std::set({ - "Blank.esm", - "Blank.esp", - "Blank.+\\.esp", - "Blank.+(Different)?.*\\.esp", - }), names); - - EXPECT_ANY_THROW(ml.Load("NotAPlugin.esm")); - EXPECT_TRUE(ml.Messages().empty()); - EXPECT_TRUE(ml.Plugins().empty()); - - // Fill the list again. - ASSERT_NO_THROW(ml.Load(metadataPath)); - - EXPECT_ANY_THROW(ml.Load("Blank.missing.esm")); - EXPECT_TRUE(ml.Messages().empty()); - EXPECT_TRUE(ml.Plugins().empty()); - } - - TEST_F(MetadataListTest, Load_Invalid) { - MetadataList ml; - for (const auto& path : invalidMetadataPaths) { - EXPECT_ANY_THROW(ml.Load(path)); - } - } - - TEST_F(MetadataListTest, Save) { - MetadataList ml; - ASSERT_NO_THROW(ml.Load(metadataPath)); - - EXPECT_NO_THROW(ml.Save(savedMetadataPath)); - EXPECT_TRUE(boost::filesystem::exists(savedMetadataPath)); - EXPECT_NO_THROW(ml.Load(savedMetadataPath)); - - EXPECT_EQ(std::list({ - Message(Message::say, "A global message."), - }), ml.Messages()); - - // Non-regex plugins can be outputted in any order, and regex entries can - // match each other, so convert the list to a set of strings for - // comparison. - std::list result(ml.Plugins()); - std::set names; - std::transform(result.begin(), - result.end(), - std::insert_iterator>(names, names.begin()), - PluginMetadataToString); - EXPECT_EQ(std::set({ - "Blank.esm", - "Blank.esp", - "Blank.+\\.esp", - "Blank.+(Different)?.*\\.esp", - }), names); - } - - TEST_F(MetadataListTest, clear) { - MetadataList ml; - ASSERT_NO_THROW(ml.Load(metadataPath)); - ASSERT_FALSE(ml.Messages().empty()); - ASSERT_FALSE(ml.Plugins().empty()); - - ml.clear(); - EXPECT_TRUE(ml.Messages().empty()); - EXPECT_TRUE(ml.Plugins().empty()); - } - - TEST_F(MetadataListTest, FindPlugin) { - MetadataList ml; - ASSERT_NO_THROW(ml.Load(metadataPath)); - - PluginMetadata pm = ml.FindPlugin(PluginMetadata("Blank - Different.esm")); - EXPECT_EQ("Blank - Different.esm", pm.Name()); - EXPECT_TRUE(pm.HasNameOnly()); - - pm = ml.FindPlugin(PluginMetadata("Blank - Different.esp")); - EXPECT_EQ("Blank - Different.esp", pm.Name()); - EXPECT_EQ(std::set({ - File("Blank.esm"), - }), pm.LoadAfter()); - EXPECT_EQ(std::set({ - File("Blank.esp"), - }), pm.Incs()); - } - - TEST_F(MetadataListTest, AddPlugin) { - MetadataList ml; - ASSERT_NO_THROW(ml.Load(metadataPath)); - - PluginMetadata pm = ml.FindPlugin(PluginMetadata("Blank - Different.esm")); - ASSERT_EQ("Blank - Different.esm", pm.Name()); - ASSERT_TRUE(pm.HasNameOnly()); - - pm.Priority(1000); - ml.AddPlugin(pm); - pm = ml.FindPlugin(pm); - EXPECT_EQ("Blank - Different.esm", pm.Name()); - EXPECT_EQ(1000, pm.Priority()); - - pm = PluginMetadata(".+Dependent\\.esp"); - pm.Priority(-10); - ml.AddPlugin(pm); - pm = ml.FindPlugin(PluginMetadata("Blank - Plugin Dependent.esp")); - EXPECT_EQ(-10, pm.Priority()); - } - - TEST_F(MetadataListTest, AddPlugin_NonUnique) { - MetadataList ml; - ASSERT_NO_THROW(ml.Load(metadataPath)); - - PluginMetadata pm = ml.FindPlugin(PluginMetadata("Blank.esm")); - ASSERT_EQ("Blank.esm", pm.Name()); - ASSERT_FALSE(pm.HasNameOnly()); - - ASSERT_ANY_THROW(ml.AddPlugin(PluginMetadata("Blank.esm"))); - } - - TEST_F(MetadataListTest, ErasePlugin) { - MetadataList ml; - ASSERT_NO_THROW(ml.Load(metadataPath)); - - PluginMetadata pm = ml.FindPlugin(PluginMetadata("Blank.esp")); - ASSERT_EQ("Blank.esp", pm.Name()); - ASSERT_FALSE(pm.HasNameOnly()); - - ml.ErasePlugin(pm); - pm = ml.FindPlugin(pm); - ASSERT_EQ("Blank.esp", pm.Name()); - ASSERT_TRUE(pm.HasNameOnly()); - } - - TEST_F(MetadataListTest, EvalAllConditions) { - Game game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); - - MetadataList ml; - ASSERT_NO_THROW(ml.Load(metadataPath)); - - PluginMetadata pm = ml.FindPlugin(PluginMetadata("Blank.esm")); - ASSERT_EQ(std::list({ - Message(Message::warn, "This is a warning."), - Message(Message::say, "This message should be removed when evaluating conditions."), - }), pm.Messages()); - - pm = ml.FindPlugin(PluginMetadata("Blank.esp")); - ASSERT_EQ("Blank.esp", pm.Name()); - ASSERT_FALSE(pm.HasNameOnly()); - - EXPECT_NO_THROW(ml.EvalAllConditions(game, Language::english)); - - pm = ml.FindPlugin(PluginMetadata("Blank.esm")); - EXPECT_EQ(std::list({ - Message(Message::warn, "This is a warning."), - }), pm.Messages()); - - pm = ml.FindPlugin(PluginMetadata("Blank.esp")); - EXPECT_EQ("Blank.esp", pm.Name()); - EXPECT_TRUE(pm.HasNameOnly()); - } - } -} - -#endif diff --git a/src/tests/main.cpp b/src/tests/main.cpp index c0efd943..1ba22401 100644 --- a/src/tests/main.cpp +++ b/src/tests/main.cpp @@ -60,8 +60,8 @@ #include "backend/metadata/plugin_metadata_test.h" #include "backend/metadata/tag_test.h" #include "backend/plugin/plugin_test.h" -#include "backend/test_metadata_list.h" #include "backend/masterlist_test.h" +#include "backend/metadata_list_test.h" #include "backend/test_plugin_sorter.h" #include "gui/loot_settings_test.h" #include "gui/loot_state_test.h" From e8ccb1cfa188b8f09e2744f7640ff6cd9f94320d Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Sat, 2 Apr 2016 11:48:01 +0100 Subject: [PATCH 36/38] Improve PluginSorter tests --- CMakeLists.txt | 7 +- src/tests/backend/plugin_sorter_test.h | 242 ++++++++++++++++++++++ src/tests/backend/test_plugin_sorter.h | 272 ------------------------- src/tests/main.cpp | 2 +- 4 files changed, 246 insertions(+), 277 deletions(-) create mode 100644 src/tests/backend/plugin_sorter_test.h delete mode 100644 src/tests/backend/test_plugin_sorter.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 38826f4d..50315406 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -216,7 +216,6 @@ set (LOOT_TESTS_SRC ${LOOT_SRC} "${CMAKE_SOURCE_DIR}/src/tests/main.cpp") set (LOOT_TESTS_HEADERS "${CMAKE_SOURCE_DIR}/src/tests/base_game_test.h" - "${CMAKE_SOURCE_DIR}/src/tests/fixtures.h" "${CMAKE_SOURCE_DIR}/src/tests/printers.h" "${CMAKE_SOURCE_DIR}/src/tests/api/api_game_operations_test.h" @@ -256,9 +255,9 @@ set (LOOT_TESTS_HEADERS "${CMAKE_SOURCE_DIR}/src/tests/base_game_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/plugin/plugin_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/masterlist_test.h" "${CMAKE_SOURCE_DIR}/src/tests/backend/metadata_list_test.h" - "${CMAKE_SOURCE_DIR}/src/tests/backend/test_plugin_sorter.h" - "${CMAKE_SOURCE_DIR}/src/tests/gui/loot_settings_test.h" - "${CMAKE_SOURCE_DIR}/src/tests/gui/loot_state_test.h") + "${CMAKE_SOURCE_DIR}/src/tests/backend/plugin_sorter_test.h" + "${CMAKE_SOURCE_DIR}/src/tests/gui/loot_settings_test.h" + "${CMAKE_SOURCE_DIR}/src/tests/gui/loot_state_test.h") source_group("Header Files\\backend" FILES ${LOOT_HEADERS}) source_group("Header Files\\gui" FILES ${LOOT_GUI_HEADERS}) diff --git a/src/tests/backend/plugin_sorter_test.h b/src/tests/backend/plugin_sorter_test.h new file mode 100644 index 00000000..f053676e --- /dev/null +++ b/src/tests/backend/plugin_sorter_test.h @@ -0,0 +1,242 @@ +/* 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_TEST_BACKEND_PLUGIN_SORTER +#define LOOT_TEST_BACKEND_PLUGIN_SORTER + +#include "backend/plugin_sorter.h" +#include "tests/base_game_test.h" + +namespace loot { + namespace test { + class PluginSorterTest : public BaseGameTest { + protected: + inline virtual void SetUp() { + BaseGameTest::SetUp(); + + game = Game(GetParam()); + game.SetGamePath(dataPath.parent_path()); + ASSERT_NO_THROW(game.Init(false, localPath)); + } + + Game game; + }; + + // Pass an empty first argument, as it's a prefix for the test instantation, + // but we only have the one so no prefix is necessary. + INSTANTIATE_TEST_CASE_P(, + PluginSorterTest, + ::testing::Values( + GameSettings::tes4)); + + TEST_P(PluginSorterTest, sortingWithNoLoadedPluginsShouldReturnAnEmptyList) { + PluginSorter sorter; + std::list sorted = sorter.Sort(game, Language::english); + + EXPECT_TRUE(sorted.empty()); + } + + TEST_P(PluginSorterTest, sortingShouldNotMakeUnnecessaryChangesToAnExistingLoadOrder) { + ASSERT_NO_THROW(game.LoadPlugins(false)); + + PluginSorter ps; + std::list expectedSortedOrder = getLoadOrder(); + + std::list sorted = ps.Sort(game, Language::english); + EXPECT_TRUE(std::equal(begin(sorted), end(sorted), begin(expectedSortedOrder))); + + // Check stability. + sorted = ps.Sort(game, Language::english); + EXPECT_TRUE(std::equal(begin(sorted), end(sorted), begin(expectedSortedOrder))); + } + + TEST_P(PluginSorterTest, sortingShouldClearExistingGameMessages) { + ASSERT_NO_THROW(game.LoadPlugins(false)); + game.AppendMessage(Message(Message::say, "1")); + ASSERT_FALSE(game.GetMessages().empty()); + + PluginSorter ps; + std::list sorted = ps.Sort(game, Language::english); + EXPECT_TRUE(game.GetMessages().empty()); + } + + TEST_P(PluginSorterTest, failedSortShouldNotClearExistingGameMessages) { + ASSERT_NO_THROW(game.LoadPlugins(false)); + PluginMetadata plugin(blankEsm); + plugin.LoadAfter({File(blankMasterDependentEsm)}); + game.GetUserlist().AddPlugin(plugin); + game.AppendMessage(Message(Message::say, "1")); + ASSERT_FALSE(game.GetMessages().empty()); + + PluginSorter ps; + EXPECT_ANY_THROW(ps.Sort(game, Language::english)); + EXPECT_FALSE(game.GetMessages().empty()); + } + + TEST_P(PluginSorterTest, sortingShouldEvaluateRelativePriorities) { + ASSERT_NO_THROW(game.LoadPlugins(false)); + PluginMetadata plugin(blankDifferentMasterDependentEsp); + plugin.Priority(-100000); + plugin.SetPriorityGlobal(true); + game.GetUserlist().AddPlugin(plugin); + + PluginSorter ps; + std::list expectedSortedOrder({ + masterFile, + blankEsm, + blankDifferentEsm, + blankMasterDependentEsm, + blankDifferentMasterDependentEsm, + blankDifferentMasterDependentEsp, + blankEsp, + blankDifferentEsp, + blankMasterDependentEsp, + blankPluginDependentEsp, + blankDifferentPluginDependentEsp, + }); + + std::list sorted = ps.Sort(game, Language::english); + EXPECT_TRUE(std::equal(begin(sorted), end(sorted), begin(expectedSortedOrder))); + } + + TEST_P(PluginSorterTest, sortingWithPrioritiesShouldInheritRecursivelyRegardlessOfEvaluationOrder) { + ASSERT_NO_THROW(game.LoadPlugins(false)); + + // Set Blank.esp's priority. + PluginMetadata plugin(blankEsp); + plugin.Priority(2); + game.GetUserlist().AddPlugin(plugin); + + // Load Blank - Master Dependent.esp after Blank.esp so that it + // inherits Blank.esp's priority. + plugin = PluginMetadata(blankMasterDependentEsp); + plugin.LoadAfter({ + File(blankEsp), + }); + game.GetUserlist().AddPlugin(plugin); + + // Load Blank - Different.esp after Blank - Master Dependent.esp, so + // that it inherits its inherited priority. + plugin = PluginMetadata(blankDifferentEsp); + plugin.LoadAfter({ + File(blankMasterDependentEsp), + }); + game.GetUserlist().AddPlugin(plugin); + + // Set Blank - Different Master Dependent.esp to have a higher priority + // than 0 but lower than Blank.esp. Need to also make it a global priority + // because it doesn't otherwise conflict with the other plugins. + plugin = PluginMetadata(blankDifferentMasterDependentEsp); + plugin.Priority(1); + plugin.SetPriorityGlobal(true); + game.GetUserlist().AddPlugin(plugin); + + PluginSorter ps; + std::list expectedSortedOrder({ + masterFile, + blankEsm, + blankDifferentEsm, + blankMasterDependentEsm, + blankDifferentMasterDependentEsm, + blankDifferentMasterDependentEsp, + blankEsp, + blankMasterDependentEsp, + blankDifferentEsp, + blankPluginDependentEsp, + blankDifferentPluginDependentEsp, + }); + + std::list sorted = ps.Sort(game, Language::english); + EXPECT_TRUE(std::equal(begin(sorted), end(sorted), begin(expectedSortedOrder))); + } + + TEST_P(PluginSorterTest, sortingShouldUseLoadAfterMetadataWhenDecidingRelativePluginPositions) { + ASSERT_NO_THROW(game.LoadPlugins(false)); + PluginMetadata plugin(blankEsp); + plugin.LoadAfter({ + File(blankDifferentEsp), + File(blankDifferentPluginDependentEsp), + }); + game.GetUserlist().AddPlugin(plugin); + + PluginSorter ps; + std::list expectedSortedOrder({ + masterFile, + blankEsm, + blankDifferentEsm, + blankMasterDependentEsm, + blankDifferentMasterDependentEsm, + blankDifferentEsp, + blankMasterDependentEsp, + blankDifferentMasterDependentEsp, + blankDifferentPluginDependentEsp, + blankEsp, + blankPluginDependentEsp, + }); + + std::list sorted = ps.Sort(game, Language::english); + EXPECT_TRUE(std::equal(begin(sorted), end(sorted), begin(expectedSortedOrder))); + } + + TEST_P(PluginSorterTest, sortingShouldUseRequirementMetadataWhenDecidingRelativePluginPositions) { + ASSERT_NO_THROW(game.LoadPlugins(false)); + PluginMetadata plugin(blankEsp); + plugin.Reqs({ + File(blankDifferentEsp), + File(blankDifferentPluginDependentEsp), + }); + game.GetUserlist().AddPlugin(plugin); + + PluginSorter ps; + std::list expectedSortedOrder({ + masterFile, + blankEsm, + blankDifferentEsm, + blankMasterDependentEsm, + blankDifferentMasterDependentEsm, + blankDifferentEsp, + blankMasterDependentEsp, + blankDifferentMasterDependentEsp, + blankDifferentPluginDependentEsp, + blankEsp, + blankPluginDependentEsp, + }); + + std::list sorted = ps.Sort(game, Language::english); + EXPECT_TRUE(std::equal(begin(sorted), end(sorted), begin(expectedSortedOrder))); + } + + TEST_P(PluginSorterTest, sortingShouldThrowIfACyclicInteractionIsEncountered) { + ASSERT_NO_THROW(game.LoadPlugins(false)); + PluginMetadata plugin(blankEsm); + plugin.LoadAfter({File(blankMasterDependentEsm)}); + game.GetUserlist().AddPlugin(plugin); + + PluginSorter ps; + EXPECT_ANY_THROW(ps.Sort(game, Language::english)); + } + } +} + +#endif diff --git a/src/tests/backend/test_plugin_sorter.h b/src/tests/backend/test_plugin_sorter.h deleted file mode 100644 index 9f9aa847..00000000 --- a/src/tests/backend/test_plugin_sorter.h +++ /dev/null @@ -1,272 +0,0 @@ -/* 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_TEST_BACKEND_PLUGIN_SORTER -#define LOOT_TEST_BACKEND_PLUGIN_SORTER - -#include "backend/plugin_sorter.h" -#include "tests/fixtures.h" - -namespace loot { - namespace test { - class PluginSorterTest : public SkyrimTest { - protected: - inline virtual void SetUp() { - SkyrimTest::SetUp(); - - game = Game(Game::tes5); - game.SetGamePath(dataPath.parent_path()); - ASSERT_NO_THROW(game.Init(false, localPath)); - } - - inline std::list GetExpectedSortedOrder() const { - return std::list({ - "Skyrim.esm", - "Blank.esm", - "Blank - Different.esm", - "Blank - Master Dependent.esm", - "Blank - Different Master Dependent.esm", - "Blank.esp", - "Blank - Different.esp", - "Blank - Master Dependent.esp", - "Blank - Different Master Dependent.esp", - "Blank - Plugin Dependent.esp", - "Blank - Different Plugin Dependent.esp", - }); - } - - inline static std::list GetActualSortedOrder(const std::list& sortedPlugins) { - std::list output; - std::transform(begin(sortedPlugins), - end(sortedPlugins), - std::back_inserter(output), - [](const Plugin& plugin) { - return plugin.Name(); - }); - return output; - } - - Game game; - std::function callback; - }; - - TEST_F(PluginSorterTest, Sort_NoPlugins) { - PluginSorter ps; - std::list sorted = ps.Sort(game, Language::english); - EXPECT_TRUE(sorted.empty()); - } - - TEST_F(PluginSorterTest, Sort) { - ASSERT_NO_THROW(game.LoadPlugins(false)); - - PluginSorter ps; - std::list expectedSortedOrder = GetExpectedSortedOrder(); - - std::list sorted = ps.Sort(game, Language::english); - EXPECT_TRUE(std::equal(begin(sorted), end(sorted), begin(expectedSortedOrder))); - - // Check stability. - sorted = ps.Sort(game, Language::english); - EXPECT_TRUE(std::equal(begin(sorted), end(sorted), begin(expectedSortedOrder))); - } - - TEST_F(PluginSorterTest, sortingShouldClearExistingGameMessages) { - ASSERT_NO_THROW(game.LoadPlugins(false)); - game.AppendMessage(Message(Message::say, "1")); - ASSERT_FALSE(game.GetMessages().empty()); - - PluginSorter ps; - std::list sorted = ps.Sort(game, Language::english); - EXPECT_TRUE(game.GetMessages().empty()); - } - - TEST_F(PluginSorterTest, failedSortShouldNotClearExistingGameMessages) { - ASSERT_NO_THROW(game.LoadPlugins(false)); - PluginMetadata plugin("Blank.esm"); - plugin.LoadAfter({File("Blank - Master Dependent.esm")}); - game.GetUserlist().AddPlugin(plugin); - game.AppendMessage(Message(Message::say, "1")); - ASSERT_FALSE(game.GetMessages().empty()); - - PluginSorter ps; - EXPECT_ANY_THROW(ps.Sort(game, Language::english)); - EXPECT_FALSE(game.GetMessages().empty()); - } - - TEST_F(PluginSorterTest, Sort_HeadersOnly) { - ASSERT_NO_THROW(game.LoadPlugins(true)); - - PluginSorter ps; - std::list expectedSortedOrder = GetExpectedSortedOrder(); - - std::list sorted = ps.Sort(game, Language::english); - EXPECT_TRUE(std::equal(begin(sorted), end(sorted), begin(expectedSortedOrder))); - } - - TEST_F(PluginSorterTest, Sort_WithPriority) { - ASSERT_NO_THROW(game.LoadPlugins(false)); - PluginMetadata plugin("Blank - Different Master Dependent.esp"); - plugin.Priority(-100000); - plugin.SetPriorityGlobal(true); - game.GetUserlist().AddPlugin(plugin); - - PluginSorter ps; - std::list expectedSortedOrder({ - "Skyrim.esm", - "Blank.esm", - "Blank - Different.esm", - "Blank - Master Dependent.esm", - "Blank - Different Master Dependent.esm", - "Blank - Different Master Dependent.esp", - "Blank.esp", - "Blank - Different.esp", - "Blank - Master Dependent.esp", - "Blank - Plugin Dependent.esp", - "Blank - Different Plugin Dependent.esp", - }); - - std::list sorted = ps.Sort(game, Language::english); - EXPECT_TRUE(std::equal(begin(sorted), end(sorted), begin(expectedSortedOrder))); - } - - TEST_F(PluginSorterTest, sortingWithPrioritiesShouldInheritRecursivelyRegardlessOfEvaluationOrder) { - ASSERT_NO_THROW(game.LoadPlugins(false)); - - // Set Blank.esp's priority. - PluginMetadata plugin("Blank.esp"); - plugin.Priority(2); - game.GetUserlist().AddPlugin(plugin); - - // Load Blank - Master Dependent.esp after Blank.esp so that it - // inherits Blank.esp's priority. - plugin = PluginMetadata("Blank - Master Dependent.esp"); - plugin.LoadAfter({ - File("Blank.esp"), - }); - game.GetUserlist().AddPlugin(plugin); - - // Load Blank - Different.esp after Blank - Master Dependent.esp, so - // that it inherits its inherited priority. - plugin = PluginMetadata("Blank - Different.esp"); - plugin.LoadAfter({ - File("Blank - Master Dependent.esp"), - }); - game.GetUserlist().AddPlugin(plugin); - - // Set Blank - Different Master Dependent.esp to have a higher priority - // than 0 but lower than Blank.esp. Need to also make it a global priority - // because it doesn't otherwise conflict with the other plugins. - plugin = PluginMetadata("Blank - Different Master Dependent.esp"); - plugin.Priority(1); - plugin.SetPriorityGlobal(true); - game.GetUserlist().AddPlugin(plugin); - - PluginSorter ps; - std::list expectedSortedOrder({ - "Skyrim.esm", - "Blank.esm", - "Blank - Different.esm", - "Blank - Master Dependent.esm", - "Blank - Different Master Dependent.esm", - "Blank - Different Master Dependent.esp", - "Blank.esp", - "Blank - Master Dependent.esp", - "Blank - Different.esp", - "Blank - Plugin Dependent.esp", - "Blank - Different Plugin Dependent.esp", - }); - - std::list actualSortedOrder = GetActualSortedOrder(ps.Sort(game, Language::english)); - EXPECT_EQ(expectedSortedOrder, actualSortedOrder); - } - - TEST_F(PluginSorterTest, Sort_WithLoadAfter) { - ASSERT_NO_THROW(game.LoadPlugins(false)); - PluginMetadata plugin("Blank.esp"); - plugin.LoadAfter({ - File("Blank - Different.esp"), - File("Blank - Different Plugin Dependent.esp"), - }); - game.GetUserlist().AddPlugin(plugin); - - PluginSorter ps; - std::list expectedSortedOrder({ - "Skyrim.esm", - "Blank.esm", - "Blank - Different.esm", - "Blank - Master Dependent.esm", - "Blank - Different Master Dependent.esm", - "Blank - Different.esp", - "Blank - Master Dependent.esp", - "Blank - Different Master Dependent.esp", - "Blank - Different Plugin Dependent.esp", - "Blank.esp", - "Blank - Plugin Dependent.esp", - }); - - std::list sorted = ps.Sort(game, Language::english); - EXPECT_TRUE(std::equal(begin(sorted), end(sorted), begin(expectedSortedOrder))); - } - - TEST_F(PluginSorterTest, Sort_WithRequirements) { - ASSERT_NO_THROW(game.LoadPlugins(false)); - PluginMetadata plugin("Blank.esp"); - plugin.Reqs({ - File("Blank - Different.esp"), - File("Blank - Different Plugin Dependent.esp"), - }); - game.GetUserlist().AddPlugin(plugin); - - PluginSorter ps; - std::list expectedSortedOrder({ - "Skyrim.esm", - "Blank.esm", - "Blank - Different.esm", - "Blank - Master Dependent.esm", - "Blank - Different Master Dependent.esm", - "Blank - Different.esp", - "Blank - Master Dependent.esp", - "Blank - Different Master Dependent.esp", - "Blank - Different Plugin Dependent.esp", - "Blank.esp", - "Blank - Plugin Dependent.esp", - }); - - std::list sorted = ps.Sort(game, Language::english); - EXPECT_TRUE(std::equal(begin(sorted), end(sorted), begin(expectedSortedOrder))); - } - - TEST_F(PluginSorterTest, Sort_HasCycle) { - ASSERT_NO_THROW(game.LoadPlugins(false)); - PluginMetadata plugin("Blank.esm"); - plugin.LoadAfter({File("Blank - Master Dependent.esm")}); - game.GetUserlist().AddPlugin(plugin); - - PluginSorter ps; - EXPECT_ANY_THROW(ps.Sort(game, Language::english)); - } - } -} - -#endif diff --git a/src/tests/main.cpp b/src/tests/main.cpp index 1ba22401..a7db99bb 100644 --- a/src/tests/main.cpp +++ b/src/tests/main.cpp @@ -62,7 +62,7 @@ #include "backend/plugin/plugin_test.h" #include "backend/masterlist_test.h" #include "backend/metadata_list_test.h" -#include "backend/test_plugin_sorter.h" +#include "backend/plugin_sorter_test.h" #include "gui/loot_settings_test.h" #include "gui/loot_state_test.h" From 9b75caa7559f1911838e884415989a4da7702716 Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Sat, 2 Apr 2016 11:48:07 +0100 Subject: [PATCH 37/38] Remove unused test fixtures --- src/tests/fixtures.h | 214 ------------------------------------------- 1 file changed, 214 deletions(-) delete mode 100644 src/tests/fixtures.h diff --git a/src/tests/fixtures.h b/src/tests/fixtures.h deleted file mode 100644 index 3ce5db0f..00000000 --- a/src/tests/fixtures.h +++ /dev/null @@ -1,214 +0,0 @@ -/* LOOT - -A load order optimisation tool for Oblivion, Skyrim, Fallout 3 and -Fallout: New Vegas. - -Copyright (C) 2013-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_TEST_FIXTURES -#define LOOT_TEST_FIXTURES - -#include "printers.h" - -#include - -#include -#include - -namespace loot { - namespace test { - class GenericGameTest : public ::testing::Test { - protected: - GenericGameTest(const std::string& gameName) - : dataPath("./" + gameName + "/Data"), - localPath("./local/" + gameName), - missingPath("./missing"), - masterFile(gameName + ".esm"), - masterlistPath(localPath / "masterlist.yaml"), - userlistPath(localPath / "userlist.yaml"), - resourcePath(dataPath / "resource" / "detail" / "resource.txt") {} - - inline virtual void SetUp() { - ASSERT_NO_THROW(boost::filesystem::create_directories(localPath)); - ASSERT_TRUE(boost::filesystem::exists(localPath)); - - ASSERT_FALSE(boost::filesystem::exists(masterlistPath)); - ASSERT_FALSE(boost::filesystem::exists(userlistPath)); - ASSERT_FALSE(boost::filesystem::exists(localPath / ".git")); - ASSERT_FALSE(boost::filesystem::exists(missingPath)); - - ASSERT_TRUE(boost::filesystem::exists(dataPath / "Blank.esm")); - ASSERT_TRUE(boost::filesystem::exists(dataPath / "Blank - Different.esm")); - ASSERT_TRUE(boost::filesystem::exists(dataPath / "Blank - Master Dependent.esm")); - ASSERT_TRUE(boost::filesystem::exists(dataPath / "Blank - Different Master Dependent.esm")); - ASSERT_TRUE(boost::filesystem::exists(dataPath / "Blank.esp")); - ASSERT_TRUE(boost::filesystem::exists(dataPath / "Blank - Different.esp")); - ASSERT_TRUE(boost::filesystem::exists(dataPath / "Blank - Master Dependent.esp")); - ASSERT_TRUE(boost::filesystem::exists(dataPath / "Blank - Different Master Dependent.esp")); - ASSERT_TRUE(boost::filesystem::exists(dataPath / "Blank - Plugin Dependent.esp")); - ASSERT_TRUE(boost::filesystem::exists(dataPath / "Blank - Different Plugin Dependent.esp")); - - ASSERT_FALSE(boost::filesystem::exists(dataPath / "Blank.missing.esm")); - ASSERT_FALSE(boost::filesystem::exists(dataPath / "Blank.missing.esp")); - - // Ghost a plugin. - ASSERT_FALSE(boost::filesystem::exists(dataPath / "Blank - Master Dependent.esm.ghost")); - ASSERT_NO_THROW(boost::filesystem::rename(dataPath / "Blank - Master Dependent.esm", dataPath / "Blank - Master Dependent.esm.ghost")); - ASSERT_TRUE(boost::filesystem::exists(dataPath / "Blank - Master Dependent.esm.ghost")); - - // Write out an empty file. - boost::filesystem::ofstream out(dataPath / "EmptyFile.esm"); - out.close(); - ASSERT_TRUE(boost::filesystem::exists(dataPath / "EmptyFile.esm")); - - // Write out an empty resource file. - ASSERT_NO_THROW(boost::filesystem::create_directories(resourcePath.parent_path())); - out.open(resourcePath); - out.close(); - ASSERT_TRUE(boost::filesystem::exists(resourcePath)); - - // Write out an non-empty, non-plugin file. - out.open(dataPath / "NotAPlugin.esm"); - out << "This isn't a valid plugin file."; - out.close(); - ASSERT_TRUE(boost::filesystem::exists(dataPath / "NotAPlugin.esm")); - - // LOOT expects the game master file to be present, so mock it. - ASSERT_FALSE(boost::filesystem::exists(dataPath / masterFile)); - ASSERT_NO_THROW(boost::filesystem::copy_file(dataPath / "Blank.esm", dataPath / masterFile)); - ASSERT_TRUE(boost::filesystem::exists(dataPath / masterFile)); - - setLoadOrder(); - - // Set Oblivion's active plugins to a known list before running the test. - boost::filesystem::ofstream activePlugins(localPath / "plugins.txt"); - activePlugins - << masterFile << std::endl - << "Blank.esm" << std::endl - << "Blank - Different Master Dependent.esp" << std::endl; - activePlugins.close(); - } - - inline virtual void TearDown() { - // Unghost the ghosted plugin. - ASSERT_TRUE(boost::filesystem::exists(dataPath / "Blank - Master Dependent.esm.ghost")); - ASSERT_NO_THROW(boost::filesystem::rename(dataPath / "Blank - Master Dependent.esm.ghost", dataPath / "Blank - Master Dependent.esm")); - ASSERT_FALSE(boost::filesystem::exists(dataPath / "Blank - Master Dependent.esm.ghost")); - - // Delete generated files. - ASSERT_NO_THROW(boost::filesystem::remove(dataPath / "EmptyFile.esm")); - ASSERT_NO_THROW(boost::filesystem::remove(resourcePath)); - ASSERT_NO_THROW(boost::filesystem::remove(dataPath / "NotAPlugin.esm")); - ASSERT_FALSE(boost::filesystem::exists(dataPath / "EmptyFile.esm")); - ASSERT_FALSE(boost::filesystem::exists(resourcePath)); - ASSERT_FALSE(boost::filesystem::exists(dataPath / "NotAPlugin.esm")); - - // Masterlist & userlist may have been created during test, so delete them. - ASSERT_NO_THROW(boost::filesystem::remove(masterlistPath)); - ASSERT_NO_THROW(boost::filesystem::remove(userlistPath)); - - // Also remove the ".git" folder if it has been created. - ASSERT_NO_THROW(boost::filesystem::remove_all(localPath / ".git")); - - // Delete the mock Oblivion.esm. - ASSERT_TRUE(boost::filesystem::exists(dataPath / masterFile)); - ASSERT_NO_THROW(boost::filesystem::remove(dataPath / masterFile)); - ASSERT_FALSE(boost::filesystem::exists(dataPath / masterFile)); - - // Delete existing plugins.txt. - ASSERT_NO_THROW(boost::filesystem::remove(localPath / "plugins.txt")); - - // Delete loadorder.txt if it exists. - ASSERT_NO_THROW(boost::filesystem::remove(localPath / "loadorder.txt")); - } - - const boost::filesystem::path dataPath; - const boost::filesystem::path localPath; - const boost::filesystem::path missingPath; - - const std::string masterFile; - - const boost::filesystem::path masterlistPath; - const boost::filesystem::path userlistPath; - - const boost::filesystem::path resourcePath; - private: - inline std::list GetExpectedSortedOrder() const { - return std::list({ - masterFile, - "Blank.esm", - "Blank - Different.esm", - "Blank - Master Dependent.esm", // Ghosted - "Blank - Different Master Dependent.esm", - "Blank.esp", - "Blank - Different.esp", - "Blank - Master Dependent.esp", - "Blank - Different Master Dependent.esp", - "Blank - Plugin Dependent.esp", - "Blank - Different Plugin Dependent.esp" - }); - } - - inline void setLoadOrder() { - if (isTimestampLoadOrderMethod()) { - time_t modificationTime = time(NULL); // Current time. - for (const auto &plugin : GetExpectedSortedOrder()) { - if (boost::filesystem::exists(dataPath / boost::filesystem::path(plugin + ".ghost"))) { - boost::filesystem::last_write_time(dataPath / boost::filesystem::path(plugin + ".ghost"), modificationTime); - } - else { - boost::filesystem::last_write_time(dataPath / plugin, modificationTime); - } - modificationTime += 60; - } - } - else { - boost::filesystem::ofstream loadOrder(localPath / "loadorder.txt"); - for (const auto &plugin : GetExpectedSortedOrder()) - loadOrder << plugin << std::endl; - loadOrder.close(); - } - } - - inline bool isTimestampLoadOrderMethod() { - return masterFile == "Oblivion.esm"; - } - }; - - class OblivionTest : public GenericGameTest { - protected: - OblivionTest() : GenericGameTest("Oblivion") {} - }; - - class SkyrimTest : public GenericGameTest { - protected: - SkyrimTest() : GenericGameTest("Skyrim") {} - - inline virtual void SetUp() { - GenericGameTest::SetUp(); - - ASSERT_TRUE(boost::filesystem::exists(dataPath / "Blank.bsa")); - ASSERT_TRUE(boost::filesystem::exists(dataPath / "Blank.bsl")); - } - }; - } -} - -#endif From 81f5748063063e30eb3688da933f95acad3f5eb2 Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Sat, 2 Apr 2016 12:47:05 +0100 Subject: [PATCH 38/38] Fix PR checking on Travis Don't return false if the Travis build is for a pull request. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index cbc67911..e202e8fa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -43,7 +43,7 @@ before_script: - cmake .. -DPROJECT_STATIC_RUNTIME=OFF -DBUILD_SHARED_LIBS=OFF script: - - '[ "${TRAVIS_PULL_REQUEST}" = "false" ] && npm test || false' + - if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then npm test; fi - make tests && ./tests before_deploy: