diff --git a/src/api/plugin/plugin_sorter.cpp b/src/api/plugin/plugin_sorter.cpp index 126ebd50..798b1179 100644 --- a/src/api/plugin/plugin_sorter.cpp +++ b/src/api/plugin/plugin_sorter.cpp @@ -50,7 +50,7 @@ PluginSortingData::PluginSortingData(const Plugin& plugin, std::string PluginSortingData::GetName() const { return plugin_.GetName(); } bool PluginSortingData::IsMaster() const { - return plugin_.IsMaster() || plugin_.IsLightMaster(); + return plugin_.IsMaster() || (plugin_.IsLightMaster() && !boost::iends_with(plugin_.GetName(), ".esp")); } bool PluginSortingData::LoadsArchive() const { return plugin_.LoadsArchive(); } diff --git a/src/tests/api/internals/plugin/plugin_sorter_test.h b/src/tests/api/internals/plugin/plugin_sorter_test.h index b5b2a970..de96fd9c 100644 --- a/src/tests/api/internals/plugin/plugin_sorter_test.h +++ b/src/tests/api/internals/plugin/plugin_sorter_test.h @@ -34,10 +34,20 @@ namespace loot { namespace test { class PluginSorterTest : public CommonGameTestFixture { protected: - PluginSorterTest() : game_(GetParam(), dataPath.parent_path(), localPath) {} + PluginSorterTest() : + game_(GetParam(), dataPath.parent_path(), localPath), + blankEslEsp("Blank.esl.esp") {} + + void TearDown() { + CommonGameTestFixture::TearDown(); + + if (GetParam() == GameType::fo4 || GetParam() == GameType::tes5se) { + boost::filesystem::remove(dataPath / blankEslEsp); + } + } void loadInstalledPlugins(Game& game_, bool headersOnly) { - const std::vector plugins({ + std::vector plugins({ masterFile, blankEsm, blankDifferentEsm, @@ -50,16 +60,26 @@ protected: blankPluginDependentEsp, blankDifferentPluginDependentEsp, }); + + if (GetParam() == GameType::fo4 || GetParam() == GameType::tes5se) { + plugins.push_back(blankEsl); + + if (boost::filesystem::exists(dataPath / blankEslEsp)) { + plugins.push_back(blankEslEsp); + } + } + game_.IdentifyMainMasterFile(masterFile); game_.LoadPlugins(plugins, headersOnly); } Game game_; + const std::string blankEslEsp; }; // 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(GameType::tes4)); +INSTANTIATE_TEST_CASE_P(, PluginSorterTest, ::testing::Values(GameType::tes4, GameType::fo4)); TEST_P(PluginSorterTest, sortingWithNoLoadedPluginsShouldReturnAnEmptyList) { PluginSorter sorter; @@ -68,6 +88,30 @@ TEST_P(PluginSorterTest, sortingWithNoLoadedPluginsShouldReturnAnEmptyList) { EXPECT_TRUE(sorted.empty()); } +TEST_P(PluginSorterTest, + lightMasterFlaggedEspFilesShouldNotBeTreatedAsMasters) { + if (GetParam() == GameType::fo4 || GetParam() == GameType::tes5se) { + ASSERT_NO_THROW( + boost::filesystem::copy(dataPath / blankEsl, dataPath / blankEslEsp)); + } + + ASSERT_NO_THROW(loadInstalledPlugins(game_, false)); + + auto esp = PluginSortingData(*dynamic_cast(game_.GetPlugin(blankEsp).get()), PluginMetadata()); + EXPECT_FALSE(esp.IsMaster()); + + auto master = PluginSortingData(*dynamic_cast(game_.GetPlugin(blankEsm).get()), PluginMetadata()); + EXPECT_TRUE(master.IsMaster()); + + if (GetParam() == GameType::fo4 || GetParam() == GameType::tes5se) { + auto lightMaster = PluginSortingData(*dynamic_cast(game_.GetPlugin(blankEsl).get()), PluginMetadata()); + EXPECT_TRUE(lightMaster.IsMaster()); + + auto lightMasterEsp = PluginSortingData(*dynamic_cast(game_.GetPlugin(blankEslEsp).get()), PluginMetadata()); + EXPECT_FALSE(lightMasterEsp.IsMaster()); + } +} + TEST_P(PluginSorterTest, sortingShouldNotMakeUnnecessaryChangesToAnExistingLoadOrder) { ASSERT_NO_THROW(loadInstalledPlugins(game_, false)); @@ -106,6 +150,10 @@ TEST_P(PluginSorterTest, sortingShouldEvaluateRelativeGlobalPriorities) { blankDifferentPluginDependentEsp, }); + if (GetParam() == GameType::fo4 || GetParam() == GameType::tes5se) { + expectedSortedOrder.insert(expectedSortedOrder.begin() + 5, blankEsl); + } + std::vector sorted = ps.Sort(game_); EXPECT_EQ(expectedSortedOrder, sorted); } @@ -158,6 +206,10 @@ TEST_P( blankDifferentPluginDependentEsp, }); + if (GetParam() == GameType::fo4 || GetParam() == GameType::tes5se) { + expectedSortedOrder.insert(expectedSortedOrder.begin() + 5, blankEsl); + } + std::vector sorted = ps.Sort(game_); EXPECT_EQ(expectedSortedOrder, sorted); } @@ -186,6 +238,10 @@ TEST_P(PluginSorterTest, blankPluginDependentEsp, }); + if (GetParam() == GameType::fo4 || GetParam() == GameType::tes5se) { + expectedSortedOrder.insert(expectedSortedOrder.begin() + 5, blankEsl); + } + std::vector sorted = ps.Sort(game_); EXPECT_EQ(expectedSortedOrder, sorted); } @@ -214,6 +270,10 @@ TEST_P(PluginSorterTest, blankPluginDependentEsp, }); + if (GetParam() == GameType::fo4 || GetParam() == GameType::tes5se) { + expectedSortedOrder.insert(expectedSortedOrder.begin() + 5, blankEsl); + } + std::vector sorted = ps.Sort(game_); EXPECT_EQ(expectedSortedOrder, sorted); }