mirror of
https://github.com/loot/libloot.git
synced 2026-07-27 14:16:01 -07:00
Improve LoadOrderHandler tests and refactor fixtures
This commit is contained in:
+1
-1
@@ -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"
|
||||
|
||||
@@ -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<std::string> getExpectedLoadOrder() const {
|
||||
return std::vector<std::string>({
|
||||
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<std::string> loadOrder = getExpectedLoadOrder();
|
||||
std::vector<std::string> 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
|
||||
|
||||
@@ -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
|
||||
<http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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<std::string> loadOrder({
|
||||
masterFile,
|
||||
blankEsm,
|
||||
blankMasterDependentEsm,
|
||||
blankDifferentEsm,
|
||||
blankDifferentMasterDependentEsm,
|
||||
blankDifferentEsp,
|
||||
blankDifferentPluginDependentEsp,
|
||||
blankEsp,
|
||||
blankMasterDependentEsp,
|
||||
blankDifferentMasterDependentEsp,
|
||||
blankPluginDependentEsp,
|
||||
});
|
||||
|
||||
EXPECT_THROW(loh.SetLoadOrder(std::list<std::string>()), error);
|
||||
}
|
||||
|
||||
TEST_P(LoadOrderHandlerTest, setLoadOrderShouldSetTheLoadOrder) {
|
||||
GameSettings game(GetParam());
|
||||
game.SetGamePath(dataPath.parent_path());
|
||||
ASSERT_NO_THROW(loh.Init(game, localPath));
|
||||
|
||||
std::list<std::string> loadOrder({
|
||||
masterFile,
|
||||
blankEsm,
|
||||
blankMasterDependentEsm,
|
||||
blankDifferentEsm,
|
||||
blankDifferentMasterDependentEsm,
|
||||
blankDifferentEsp,
|
||||
blankDifferentPluginDependentEsp,
|
||||
blankEsp,
|
||||
blankMasterDependentEsp,
|
||||
blankDifferentMasterDependentEsp,
|
||||
blankPluginDependentEsp,
|
||||
});
|
||||
|
||||
EXPECT_NO_THROW(loh.SetLoadOrder(loadOrder));
|
||||
EXPECT_EQ(loadOrder, getLoadOrder());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -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
|
||||
<http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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<std::string> 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<std::string> 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<std::string> 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
|
||||
@@ -27,6 +27,10 @@ along with LOOT. If not, see
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/filesystem/fstream.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
#include <unordered_set>
|
||||
|
||||
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<std::string> getLoadOrder() {
|
||||
std::list<std::string> actual;
|
||||
if (isLoadOrderTimestampBased(GetParam())) {
|
||||
std::map<time_t, std::string> 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<std::string> getInitialLoadOrder() const {
|
||||
return std::vector<std::string>({
|
||||
masterFile,
|
||||
blankEsm,
|
||||
blankDifferentEsm,
|
||||
blankMasterDependentEsm,
|
||||
blankDifferentMasterDependentEsm,
|
||||
blankEsp,
|
||||
blankDifferentEsp,
|
||||
blankMasterDependentEsp,
|
||||
blankDifferentMasterDependentEsp,
|
||||
blankPluginDependentEsp,
|
||||
blankDifferentPluginDependentEsp,
|
||||
});
|
||||
}
|
||||
|
||||
inline std::unordered_set<std::string> getInitialActivePlugins() const {
|
||||
return std::unordered_set<std::string>({
|
||||
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<std::string>& 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<std::string>& 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;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user