diff --git a/CMakeLists.txt b/CMakeLists.txt index ca2fb10d..9480fd2f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -125,7 +125,8 @@ set(PSEUDOSEM_INCLUDE_DIRS "${SOURCE_DIR}/include") ExternalProject_Add(testing-metadata PREFIX "external" - URL "https://github.com/loot/testing-metadata/archive/1.3.0.tar.gz" + GIT_REPOSITORY "https://github.com/loot/testing-metadata" + GIT_TAG "1.3.0" CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "") diff --git a/src/tests/api/interface/api_game_operations_test.h b/src/tests/api/interface/api_game_operations_test.h index 2de9a385..ca5b8486 100644 --- a/src/tests/api/interface/api_game_operations_test.h +++ b/src/tests/api/interface/api_game_operations_test.h @@ -54,13 +54,6 @@ protected: GetParam(), dataPath.parent_path().string(), localPath.string()); } - virtual void TearDown() { - CommonGameTestFixture::TearDown(); - - // The masterlist may have been created during the test, so delete it. - ASSERT_NO_THROW(boost::filesystem::remove(masterlistPath)); - } - void GenerateMasterlist() { using std::endl; diff --git a/src/tests/api/interface/create_game_handle_test.h b/src/tests/api/interface/create_game_handle_test.h index e76f7985..5e9f9d41 100644 --- a/src/tests/api/interface/create_game_handle_test.h +++ b/src/tests/api/interface/create_game_handle_test.h @@ -62,15 +62,6 @@ protected: #endif } - void TearDown() { - CommonGameTestFixture::TearDown(); - - boost::filesystem::remove(gamePathSymlink); - boost::filesystem::remove(localPathSymlink); - boost::filesystem::remove(gamePathJunctionLink); - boost::filesystem::remove(localPathJunctionLink); - } - std::shared_ptr handle_; const boost::filesystem::path gamePathSymlink; @@ -92,18 +83,15 @@ INSTANTIATE_TEST_CASE_P(, TEST_P(CreateGameHandleTest, shouldSucceedIfPassedValidParametersWithRelativePaths) { + using boost::filesystem::relative; EXPECT_NO_THROW(handle_ = CreateGameHandle(GetParam(), - dataPath.parent_path().string(), - localPath.string())); + relative(dataPath.parent_path()).string(), + relative(localPath).string())); EXPECT_NE(nullptr, handle_); } TEST_P(CreateGameHandleTest, shouldSucceedIfPassedValidParametersWithAbsolutePaths) { - boost::filesystem::path game = - boost::filesystem::current_path() / dataPath.parent_path(); - boost::filesystem::path local = boost::filesystem::current_path() / localPath; - EXPECT_NO_THROW(handle_ = CreateGameHandle(GetParam(), dataPath.parent_path().string(), localPath.string())); diff --git a/src/tests/api/interface/database_interface_test.h b/src/tests/api/interface/database_interface_test.h index f63fc1c2..b76d97a6 100644 --- a/src/tests/api/interface/database_interface_test.h +++ b/src/tests/api/interface/database_interface_test.h @@ -50,25 +50,6 @@ protected: ASSERT_FALSE(boost::filesystem::exists(minimalOutputPath_)); } - void TearDown() { - if (boost::filesystem::exists(minimalOutputPath_)) { - boost::filesystem::permissions(minimalOutputPath_, - boost::filesystem::perms::add_perms | - boost::filesystem::perms::owner_write); - } - - ApiGameOperationsTest::TearDown(); - - // The userlist may have been created during the test, so delete it. - ASSERT_NO_THROW(boost::filesystem::remove(userlistPath_)); - - // Also remove the ".git" folder if it has been created. - ASSERT_NO_THROW( - boost::filesystem::remove_all(masterlistPath.parent_path() / ".git")); - - ASSERT_NO_THROW(boost::filesystem::remove(minimalOutputPath_)); - } - std::string GetExpectedMinimalContent() const { using std::endl; diff --git a/src/tests/api/interface/game_interface_test.h b/src/tests/api/interface/game_interface_test.h index 83f1def0..7e1c62b7 100644 --- a/src/tests/api/interface/game_interface_test.h +++ b/src/tests/api/interface/game_interface_test.h @@ -49,12 +49,6 @@ protected: blankDifferentPluginDependentEsp, }) {} - void TearDown() { - ApiGameOperationsTest::TearDown(); - - boost::filesystem::remove(dataPath / emptyFile); - } - const std::string emptyFile; const std::vector pluginsToLoad; }; diff --git a/src/tests/api/internals/game/load_order_handler_test.h b/src/tests/api/internals/game/load_order_handler_test.h index cfc7f701..8119a6a1 100644 --- a/src/tests/api/internals/game/load_order_handler_test.h +++ b/src/tests/api/internals/game/load_order_handler_test.h @@ -52,8 +52,6 @@ protected: } } - void TearDown() { CommonGameTestFixture::TearDown(); } - void initialiseHandler() { ASSERT_NO_THROW( loadOrderHandler_.Init(GetParam(), dataPath.parent_path(), localPath)); diff --git a/src/tests/api/internals/helpers/git_helper_test.h b/src/tests/api/internals/helpers/git_helper_test.h index 529157c7..36e41ec7 100644 --- a/src/tests/api/internals/helpers/git_helper_test.h +++ b/src/tests/api/internals/helpers/git_helper_test.h @@ -30,55 +30,80 @@ along with LOOT. If not, see #include #include "loot/exception/git_state_error.h" +#include "tests/common_game_test_fixture.h" namespace loot { namespace test { class GitHelperTest : public ::testing::Test { protected: - GitHelperTest() : parentRepoRoot(GetRepoRoot()) {} + GitHelperTest() : + rootTestPath(getRootTestPath()), + repoRoot(rootTestPath / "testing-metadata"), + repoSubdirectory(repoRoot / "invalid"), + changedFile("LICENSE"), + unchangedFile("README.md"), + untrackedFile("untracked.txt") {} inline void SetUp() { - ASSERT_TRUE(boost::filesystem::exists(parentRepoRoot / "README.md")); + using boost::filesystem::exists; - // 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")); + copy(boost::filesystem::absolute("./testing-metadata"), repoRoot); + ASSERT_TRUE(exists(repoRoot)); + ASSERT_TRUE(exists(repoSubdirectory)); + ASSERT_TRUE(boost::filesystem::exists(repoRoot / unchangedFile)); - // Edit CONTRIBUTING.md - boost::filesystem::ofstream out(parentRepoRoot / "CONTRIBUTING.md"); - out.close(); + // Run git reset --hard to ensure there are no changes in the working copy. + // The initial checkout can detect changes due to line ending mismatch. + auto currentPath = boost::filesystem::current_path(); + boost::filesystem::current_path(repoRoot); + system("git reset --hard"); + boost::filesystem::current_path(currentPath); + + // Edit a tracked file + boost::filesystem::ofstream changedOut(repoRoot / changedFile); + changedOut.close(); + ASSERT_TRUE(exists(repoRoot / changedFile)); + + // Create a new file in the repository + boost::filesystem::ofstream untrackedOut(repoRoot / untrackedFile); + untrackedOut.close(); + ASSERT_TRUE(exists(repoRoot / untrackedFile)); + + // Create a new file outside the repository + boost::filesystem::ofstream outOfRepoOut(rootTestPath / untrackedFile); + outOfRepoOut.close(); + ASSERT_TRUE(exists(rootTestPath / untrackedFile)); } inline 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")); + // Grant write permissions to everything in rootTestPath + // in case the test made anything read only. + for (const auto& path : boost::filesystem::recursive_directory_iterator(rootTestPath)) { + boost::filesystem::permissions(path, boost::filesystem::perms::all_all | boost::filesystem::perms::add_perms); + } + boost::filesystem::remove_all(rootTestPath); } GitHelper git_; - const boost::filesystem::path parentRepoRoot; + const boost::filesystem::path rootTestPath; + const boost::filesystem::path repoRoot; + const boost::filesystem::path repoSubdirectory; + + const std::string changedFile; + const std::string unchangedFile; + const std::string untrackedFile; 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(); + void copy(const boost::filesystem::path& from, const boost::filesystem::path& to) { + if (boost::filesystem::is_directory(from)) { + boost::filesystem::create_directories(to); + for (auto entry : boost::filesystem::directory_iterator(from)) { + copy(entry.path(), to / entry.path().filename()); + } + } else { + boost::filesystem::copy(from, to); } - - return dir; } }; @@ -93,34 +118,32 @@ TEST_F(GitHelperTest, destructorShouldCallLibgit2CleanupFunction) { } TEST_F(GitHelperTest, isRepositoryShouldReturnTrueForARepositoryRoot) { - EXPECT_TRUE(GitHelper::IsRepository(parentRepoRoot)); + EXPECT_TRUE(GitHelper::IsRepository(repoRoot)); } TEST_F(GitHelperTest, isRepositoryShouldReturnFalseForRepositorySubdirectory) { - EXPECT_FALSE(GitHelper::IsRepository(boost::filesystem::current_path())); + EXPECT_FALSE(GitHelper::IsRepository(repoSubdirectory)); } TEST_F(GitHelperTest, isFileDifferentShouldThrowIfGivenANonRepositoryPath) { - EXPECT_THROW(GitHelper::IsFileDifferent(boost::filesystem::current_path(), - "README.md"), + EXPECT_THROW(GitHelper::IsFileDifferent(rootTestPath, untrackedFile), GitStateError); } TEST_F(GitHelperTest, isFileDifferentShouldReturnFalseForAnUntrackedFile) { // New files not in the index are not tracked by Git, so aren't considered // different. - EXPECT_FALSE( - GitHelper::IsFileDifferent(parentRepoRoot, "CONTRIBUTING.md.copy")); + EXPECT_FALSE(GitHelper::IsFileDifferent(repoRoot, untrackedFile)); } TEST_F(GitHelperTest, isFileDifferentShouldReturnFalseForAnUnchangedTrackedFile) { - EXPECT_FALSE(GitHelper::IsFileDifferent(parentRepoRoot, "README.md")); + EXPECT_FALSE(GitHelper::IsFileDifferent(repoRoot, unchangedFile)); } TEST_F(GitHelperTest, - DISABLED_isFileDifferentShouldReturnTrueForAChangedTrackedFile) { - EXPECT_TRUE(GitHelper::IsFileDifferent(parentRepoRoot, "CONTRIBUTING.md")); + isFileDifferentShouldReturnTrueForAChangedTrackedFile) { + EXPECT_TRUE(GitHelper::IsFileDifferent(repoRoot, changedFile)); } } } diff --git a/src/tests/api/internals/masterlist_test.h b/src/tests/api/internals/masterlist_test.h index 1a83c4e2..bb24ac58 100644 --- a/src/tests/api/internals/masterlist_test.h +++ b/src/tests/api/internals/masterlist_test.h @@ -42,16 +42,15 @@ protected: void SetUp() { CommonGameTestFixture::SetUp(); + auto sourceDirectory = getSourceMetadataFilesPath(); + boost::filesystem::copy(sourceDirectory / "masterlist.yaml", + metadataFilesPath / "masterlist.yaml"); + ASSERT_TRUE(boost::filesystem::exists(metadataFilesPath / "masterlist.yaml")); + ASSERT_FALSE(boost::filesystem::exists(masterlistPath)); ASSERT_FALSE(boost::filesystem::exists(localPath / ".git")); } - void TearDown() { - CommonGameTestFixture::TearDown(); - - ASSERT_NO_THROW(boost::filesystem::remove(masterlistPath)); - } - const std::string repoUrl; const std::string repoBranch; const std::string oldBranch; @@ -147,8 +146,8 @@ TEST_P(MasterlistTest, getInfoShouldThrowIfNoMasterlistExistsAtTheGivenPath) { TEST_P(MasterlistTest, getInfoShouldThrowIfTheGivenPathDoesNotBelongToAGitRepository) { - ASSERT_NO_THROW(boost::filesystem::copy("./testing-metadata/masterlist.yaml", - masterlistPath)); + ASSERT_NO_THROW(boost::filesystem::copy(metadataFilesPath / "masterlist.yaml", + masterlistPath)); Masterlist masterlist; EXPECT_THROW(masterlist.GetInfo(masterlistPath, false), GitStateError); @@ -195,8 +194,8 @@ TEST_P( TEST_P(MasterlistTest, isLatestShouldThrowIfTheGivenPathDoesNotBelongToAGitRepository) { - ASSERT_NO_THROW(boost::filesystem::copy("./testing-metadata/masterlist.yaml", - masterlistPath)); + ASSERT_NO_THROW(boost::filesystem::copy(metadataFilesPath / "masterlist.yaml", + masterlistPath)); EXPECT_THROW(Masterlist::IsLatest(masterlistPath, repoBranch), GitStateError); } diff --git a/src/tests/api/internals/metadata/condition_grammar_test.h b/src/tests/api/internals/metadata/condition_grammar_test.h index 8f9d22ba..26082435 100644 --- a/src/tests/api/internals/metadata/condition_grammar_test.h +++ b/src/tests/api/internals/metadata/condition_grammar_test.h @@ -60,12 +60,6 @@ protected: ASSERT_TRUE(boost::filesystem::exists(resourcePath)); } - inline void TearDown() { - CommonGameTestFixture::TearDown(); - - ASSERT_NO_THROW(boost::filesystem::remove(resourcePath)); - } - std::string IntToHexString(const uint32_t value) { std::stringstream stream; stream << std::hex << value; diff --git a/src/tests/api/internals/metadata_list_test.h b/src/tests/api/internals/metadata_list_test.h index 4b575e72..73bf5938 100644 --- a/src/tests/api/internals/metadata_list_test.h +++ b/src/tests/api/internals/metadata_list_test.h @@ -34,32 +34,35 @@ namespace test { class MetadataListTest : public CommonGameTestFixture { protected: MetadataListTest() : - metadataPath("./testing-metadata/masterlist.yaml"), - savedMetadataPath("./testing-metadata/saved.masterlist.yaml"), - missingMetadataPath("./missing-metadata.yaml"), - invalidMetadataPaths({"./testing-metadata/invalid/non_map_root.yaml", - "./testing-metadata/invalid/non_unique.yaml"}) {} + metadataPath(metadataFilesPath / "masterlist.yaml"), + savedMetadataPath(metadataFilesPath / "saved.masterlist.yaml"), + missingMetadataPath(metadataFilesPath / "missing-metadata.yaml"), + invalidMetadataPaths( + {metadataFilesPath / "invalid" / "non_map_root.yaml", + metadataFilesPath / "invalid" / "non_unique.yaml"}) {} inline virtual void SetUp() { CommonGameTestFixture::SetUp(); - ASSERT_TRUE(boost::filesystem::exists(metadataPath)); - ASSERT_FALSE(boost::filesystem::exists(savedMetadataPath)); + using boost::filesystem::copy; + using boost::filesystem::exists; - for (const auto& path : invalidMetadataPaths) { - ASSERT_TRUE(boost::filesystem::exists(path)); - } + auto sourceDirectory = getSourceMetadataFilesPath(); + + copy(sourceDirectory / "masterlist.yaml", metadataPath); + ASSERT_TRUE(exists(metadataPath)); + + copyInvalidMetadataFile(sourceDirectory, "non_map_root.yaml"); + copyInvalidMetadataFile(sourceDirectory, "non_unique.yaml"); + + ASSERT_FALSE(exists(savedMetadataPath)); + ASSERT_FALSE(exists(missingMetadataPath)); } - inline virtual void TearDown() { - CommonGameTestFixture::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)); - } + void copyInvalidMetadataFile(const boost::filesystem::path& sourceDirectory, const std::string& file) { + boost::filesystem::create_directories(metadataFilesPath / "invalid"); + boost::filesystem::copy(sourceDirectory / "invalid" / file, metadataFilesPath / "invalid" / file); + ASSERT_TRUE(boost::filesystem::exists(metadataFilesPath / "invalid" / file)); } static std::string PluginMetadataToString(const PluginMetadata& metadata) { @@ -131,10 +134,12 @@ TEST_P(MetadataListTest, loadShouldLoadGroups) { EXPECT_TRUE(groups.find(Group("default"))->GetAfterGroups().empty()); EXPECT_EQ(1, groups.count(Group("group1"))); - EXPECT_EQ(std::unordered_set({ "group2" }), groups.find(Group("group1"))->GetAfterGroups()); + EXPECT_EQ(std::unordered_set({"group2"}), + groups.find(Group("group1"))->GetAfterGroups()); EXPECT_EQ(1, groups.count(Group("group2"))); - EXPECT_EQ(std::unordered_set({ "default" }), groups.find(Group("group2"))->GetAfterGroups()); + EXPECT_EQ(std::unordered_set({"default"}), + groups.find(Group("group2"))->GetAfterGroups()); } TEST_P(MetadataListTest, loadShouldThrowIfAnInvalidMetadataFileIsGiven) { @@ -188,8 +193,9 @@ TEST_P(MetadataListTest, saveShouldWriteTheLoadedMetadataToTheGivenFilePath) { EXPECT_EQ(std::set({"C.Climate", "Relev"}), metadataList.BashTags()); - EXPECT_EQ(std::unordered_set({ Group("default"), Group("group1"), Group("group2") }), - metadataList.Groups()); + EXPECT_EQ(std::unordered_set( + {Group("default"), Group("group1"), Group("group2")}), + metadataList.Groups()); EXPECT_EQ(std::vector({ Message(MessageType::say, "A global message."), @@ -232,9 +238,7 @@ TEST_P(MetadataListTest, setGroupsShouldReplaceExistingGroups) { MetadataList metadataList; ASSERT_NO_THROW(metadataList.Load(metadataPath)); - metadataList.SetGroups({ - Group("group4") - }); + metadataList.SetGroups({Group("group4")}); auto groups = metadataList.Groups(); diff --git a/src/tests/api/internals/plugin_test.h b/src/tests/api/internals/plugin_test.h index 946e2be1..f0bca1b9 100644 --- a/src/tests/api/internals/plugin_test.h +++ b/src/tests/api/internals/plugin_test.h @@ -69,21 +69,6 @@ protected: out.close(); } - void TearDown() { - CommonGameTestFixture::TearDown(); - - boost::filesystem::remove(dataPath / emptyFile); -#ifndef _WIN32 - boost::filesystem::remove(dataPath / lowercaseBlankEsp); -#endif - boost::filesystem::remove(dataPath / blankArchive); - boost::filesystem::remove(dataPath / blankSuffixArchive); - - if (GetParam() != GameType::fo4 && GetParam() != GameType::tes5se) { - boost::filesystem::remove(dataPath / blankEsl); - } - } - Game game_; const std::string emptyFile; diff --git a/src/tests/api/internals/sorting/plugin_sorter_test.h b/src/tests/api/internals/sorting/plugin_sorter_test.h index d1b92bc2..c1ce6a33 100644 --- a/src/tests/api/internals/sorting/plugin_sorter_test.h +++ b/src/tests/api/internals/sorting/plugin_sorter_test.h @@ -37,21 +37,10 @@ class PluginSorterTest : public CommonGameTestFixture { protected: PluginSorterTest() : game_(GetParam(), dataPath.parent_path(), localPath), - masterlistPath_("./userlist.yaml"), + masterlistPath_(metadataFilesPath / "userlist.yaml"), cccPath_(dataPath.parent_path() / getCCCFilename()), blankEslEsp("Blank.esl.esp") {} - void TearDown() { - CommonGameTestFixture::TearDown(); - - if (GetParam() == GameType::fo4 || GetParam() == GameType::tes5se) { - boost::filesystem::remove(dataPath / blankEslEsp); - } - - boost::filesystem::remove(masterlistPath_); - boost::filesystem::remove(cccPath_); - } - void loadInstalledPlugins(Game &game_, bool headersOnly) { std::vector plugins({ masterFile, diff --git a/src/tests/common_game_test_fixture.h b/src/tests/common_game_test_fixture.h index 473fed51..cf9fb7d5 100644 --- a/src/tests/common_game_test_fixture.h +++ b/src/tests/common_game_test_fixture.h @@ -32,20 +32,33 @@ along with LOOT. If not, see #include #include #include +#include +#include +#include #include "loot/enum/game_type.h" namespace loot { namespace test { + +boost::filesystem::path getRootTestPath() { + auto directoryName = "LOOT-" + boost::lexical_cast( + (boost::uuids::random_generator())()); + + return boost::filesystem::absolute(boost::filesystem::temp_directory_path() / + directoryName); +} + class CommonGameTestFixture : public ::testing::TestWithParam { protected: CommonGameTestFixture() : french("fr"), german("de"), - missingPath("./missing"), - dataPath(getPluginsPath()), - localPath(getLocalPath()), - lootDataPath("./local/LOOT"), + rootTestPath(getRootTestPath()), + missingPath(rootTestPath / "missing"), + dataPath(rootTestPath / "game" / "Data"), + localPath(rootTestPath / "local" / "game"), + metadataFilesPath(rootTestPath / "metadata"), masterFile(getMasterFile()), missingEsp("Blank.missing.esp"), nonPluginFile("NotAPlugin.esm"), @@ -69,69 +82,73 @@ protected: } void assertInitialState() { - ASSERT_NO_THROW(boost::filesystem::create_directories(localPath)); - ASSERT_NO_THROW(boost::filesystem::create_directories(lootDataPath)); - ASSERT_TRUE(boost::filesystem::exists(localPath)); + using boost::filesystem::create_directories; + using boost::filesystem::exists; - ASSERT_FALSE(boost::filesystem::exists(missingPath)); - ASSERT_FALSE(boost::filesystem::exists(dataPath / missingEsp)); + create_directories(dataPath); + ASSERT_TRUE(exists(dataPath)); - 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)); + create_directories(localPath); + ASSERT_TRUE(exists(localPath)); + + create_directories(metadataFilesPath); + ASSERT_TRUE(exists(metadataFilesPath)); + + auto sourcePluginsPath = getSourcePluginsPath(); + + copyPlugin(sourcePluginsPath, blankEsm); + copyPlugin(sourcePluginsPath, blankDifferentEsm); + copyPlugin(sourcePluginsPath, blankMasterDependentEsm); + copyPlugin(sourcePluginsPath, blankDifferentMasterDependentEsm); + copyPlugin(sourcePluginsPath, blankEsp); + copyPlugin(sourcePluginsPath, blankDifferentEsp); + copyPlugin(sourcePluginsPath, blankMasterDependentEsp); + copyPlugin(sourcePluginsPath, blankDifferentMasterDependentEsp); + copyPlugin(sourcePluginsPath, blankPluginDependentEsp); + copyPlugin(sourcePluginsPath, blankDifferentPluginDependentEsp); + + if (GetParam() == GameType::tes5se || GetParam() == GameType::tes5vr || + GetParam() == GameType::fo4 || GetParam() == GameType::fo4vr) { + copyPlugin(sourcePluginsPath, blankEsl); + } // 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)); + ASSERT_NO_THROW( + boost::filesystem::copy_file(dataPath / blankEsm, dataPath / masterFile)); + ASSERT_TRUE(exists(dataPath / masterFile)); // Set initial load order and active plugins. setLoadOrder(getInitialLoadOrder()); // 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"))); + ASSERT_FALSE(exists(dataPath / blankMasterDependentEsm)); + ASSERT_TRUE(exists(dataPath / (blankMasterDependentEsm + ".ghost"))); // Write out an non-empty, non-plugin file. boost::filesystem::ofstream out(dataPath / nonPluginFile); out << "This isn't a valid plugin file."; out.close(); - ASSERT_TRUE(boost::filesystem::exists(dataPath / nonPluginFile)); + ASSERT_TRUE(exists(dataPath / nonPluginFile)); + + ASSERT_FALSE(exists(missingPath)); + ASSERT_FALSE(exists(dataPath / missingEsp)); + } + + void copyPlugin(const boost::filesystem::path& sourceParentPath, const std::string& filename) { + boost::filesystem::copy_file(sourceParentPath / filename, dataPath / filename); + ASSERT_TRUE(boost::filesystem::exists(dataPath / filename)); } void TearDown() { - ASSERT_NO_THROW(boost::filesystem::remove_all(localPath)); - ASSERT_NO_THROW(boost::filesystem::remove_all(lootDataPath)); - - 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"))); - - ASSERT_NO_THROW(boost::filesystem::remove(dataPath / nonPluginFile)); - ASSERT_NO_THROW(boost::filesystem::remove(dataPath / invalidPlugin)); + // Grant write permissions to everything in rootTestPath + // in case the test made anything read only. + for (const auto& path : boost::filesystem::recursive_directory_iterator(rootTestPath)) { + boost::filesystem::permissions(path, boost::filesystem::perms::all_all | boost::filesystem::perms::add_perms); + } + boost::filesystem::remove_all(rootTestPath); } std::vector readFileLines(const boost::filesystem::path& file) { @@ -212,6 +229,9 @@ protected: return loadOrder; } +private: + const boost::filesystem::path rootTestPath; + protected: const std::string french; const std::string german; @@ -219,7 +239,7 @@ protected: const boost::filesystem::path missingPath; const boost::filesystem::path dataPath; const boost::filesystem::path localPath; - const boost::filesystem::path lootDataPath; + const boost::filesystem::path metadataFilesPath; const std::string masterFile; const std::string missingEsp; @@ -239,17 +259,13 @@ protected: const uint32_t blankEsmCrc; -private: - inline boost::filesystem::path getLocalPath() const { - if (GetParam() == GameType::tes4) - return "./local/Oblivion"; - else if (GetParam() == GameType::fo4 || GetParam() == GameType::tes5se) - return "./local/SkyrimSE"; - else - return "./local/Skyrim"; + static boost::filesystem::path getSourceMetadataFilesPath() { + return boost::filesystem::absolute("./testing-metadata"); } - inline boost::filesystem::path getPluginsPath() const { +private: + boost::filesystem::path getSourcePluginsPath() const { + using boost::filesystem::absolute; if (GetParam() == GameType::tes4) return "./Oblivion/Data"; else if (GetParam() == GameType::fo4 || GetParam() == GameType::tes5se)