From e8ccb1cfa188b8f09e2744f7640ff6cd9f94320d Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Sat, 2 Apr 2016 11:48:01 +0100 Subject: [PATCH] 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"