mirror of
https://github.com/loot/libloot.git
synced 2026-07-27 14:16:01 -07:00
Refactor CheckInstallValidity() into GUI's Game
So that it can be more easily tested.
This commit is contained in:
@@ -56,7 +56,7 @@ protected:
|
||||
|
||||
auto messages = metadata.Messages();
|
||||
auto statusMessages = file->GetStatusMessages();
|
||||
auto validityMessages = CheckInstallValidity(file, metadata);
|
||||
auto validityMessages = state_.getCurrentGame().CheckInstallValidity(file, metadata);
|
||||
messages.insert(end(messages), begin(statusMessages), end(statusMessages));
|
||||
messages.insert(end(messages), begin(validityMessages), end(validityMessages));
|
||||
metadata.Messages(messages);
|
||||
@@ -155,49 +155,6 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<Message> CheckInstallValidity(std::shared_ptr<const PluginInterface> plugin, const PluginMetadata& metadata) {
|
||||
BOOST_LOG_TRIVIAL(trace) << "Checking that the current install is valid according to " << plugin->GetName() << "'s data.";
|
||||
std::vector<Message> messages;
|
||||
if (state_.getCurrentGame().IsPluginActive(plugin->GetName())) {
|
||||
auto pluginExists = [&](const std::string& file) {
|
||||
return boost::filesystem::exists(state_.getCurrentGame().DataPath() / file)
|
||||
|| ((boost::iends_with(file, ".esp") || boost::iends_with(file, ".esm")) && boost::filesystem::exists(state_.getCurrentGame().DataPath() / (file + ".ghost")));
|
||||
};
|
||||
auto tags = metadata.Tags();
|
||||
if (tags.find(Tag("Filter")) == std::end(tags)) {
|
||||
for (const auto &master : plugin->GetMasters()) {
|
||||
if (!pluginExists(master)) {
|
||||
BOOST_LOG_TRIVIAL(error) << "\"" << plugin->GetName() << "\" requires \"" << master << "\", but it is missing.";
|
||||
messages.push_back(Message(MessageType::error, (boost::format(boost::locale::translate("This plugin requires \"%1%\" to be installed, but it is missing.")) % master).str()));
|
||||
} else if (!state_.getCurrentGame().IsPluginActive(master)) {
|
||||
BOOST_LOG_TRIVIAL(error) << "\"" << plugin->GetName() << "\" requires \"" << master << "\", but it is inactive.";
|
||||
messages.push_back(Message(MessageType::error, (boost::format(boost::locale::translate("This plugin requires \"%1%\" to be active, but it is inactive.")) % master).str()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto &req : metadata.Reqs()) {
|
||||
if (!pluginExists(req.Name())) {
|
||||
BOOST_LOG_TRIVIAL(error) << "\"" << plugin->GetName() << "\" requires \"" << req.Name() << "\", but it is missing.";
|
||||
messages.push_back(Message(MessageType::error, (boost::format(boost::locale::translate("This plugin requires \"%1%\" to be installed, but it is missing.")) % req.Name()).str()));
|
||||
}
|
||||
}
|
||||
for (const auto &inc : metadata.Incs()) {
|
||||
if (pluginExists(inc.Name()) && state_.getCurrentGame().IsPluginActive(inc.Name())) {
|
||||
BOOST_LOG_TRIVIAL(error) << "\"" << plugin->GetName() << "\" is incompatible with \"" << inc.Name() << "\", but both are present.";
|
||||
messages.push_back(Message(MessageType::error, (boost::format(boost::locale::translate("This plugin is incompatible with \"%1%\", but both are present.")) % inc.Name()).str()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Also generate dirty messages.
|
||||
for (const auto &element : metadata.DirtyInfo()) {
|
||||
messages.push_back(element.AsMessage());
|
||||
}
|
||||
|
||||
return messages;
|
||||
}
|
||||
|
||||
LootState& state_;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -128,6 +128,49 @@ std::set<std::shared_ptr<const PluginInterface>> Game::GetPlugins() const {
|
||||
return gameHandle_->GetLoadedPlugins();
|
||||
}
|
||||
|
||||
std::vector<Message> Game::CheckInstallValidity(std::shared_ptr<const PluginInterface> plugin, const PluginMetadata & metadata) {
|
||||
BOOST_LOG_TRIVIAL(trace) << "Checking that the current install is valid according to " << plugin->GetName() << "'s data.";
|
||||
std::vector<Message> messages;
|
||||
if (IsPluginActive(plugin->GetName())) {
|
||||
auto pluginExists = [&](const std::string& file) {
|
||||
return boost::filesystem::exists(DataPath() / file)
|
||||
|| ((boost::iends_with(file, ".esp") || boost::iends_with(file, ".esm")) && boost::filesystem::exists(DataPath() / (file + ".ghost")));
|
||||
};
|
||||
auto tags = metadata.Tags();
|
||||
if (tags.find(Tag("Filter")) == std::end(tags)) {
|
||||
for (const auto &master : plugin->GetMasters()) {
|
||||
if (!pluginExists(master)) {
|
||||
BOOST_LOG_TRIVIAL(error) << "\"" << plugin->GetName() << "\" requires \"" << master << "\", but it is missing.";
|
||||
messages.push_back(Message(MessageType::error, (boost::format(boost::locale::translate("This plugin requires \"%1%\" to be installed, but it is missing.")) % master).str()));
|
||||
} else if (!IsPluginActive(master)) {
|
||||
BOOST_LOG_TRIVIAL(error) << "\"" << plugin->GetName() << "\" requires \"" << master << "\", but it is inactive.";
|
||||
messages.push_back(Message(MessageType::error, (boost::format(boost::locale::translate("This plugin requires \"%1%\" to be active, but it is inactive.")) % master).str()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto &req : metadata.Reqs()) {
|
||||
if (!pluginExists(req.Name())) {
|
||||
BOOST_LOG_TRIVIAL(error) << "\"" << plugin->GetName() << "\" requires \"" << req.Name() << "\", but it is missing.";
|
||||
messages.push_back(Message(MessageType::error, (boost::format(boost::locale::translate("This plugin requires \"%1%\" to be installed, but it is missing.")) % req.Name()).str()));
|
||||
}
|
||||
}
|
||||
for (const auto &inc : metadata.Incs()) {
|
||||
if (pluginExists(inc.Name()) && IsPluginActive(inc.Name())) {
|
||||
BOOST_LOG_TRIVIAL(error) << "\"" << plugin->GetName() << "\" is incompatible with \"" << inc.Name() << "\", but both are present.";
|
||||
messages.push_back(Message(MessageType::error, (boost::format(boost::locale::translate("This plugin is incompatible with \"%1%\", but both are present.")) % inc.Name()).str()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Also generate dirty messages.
|
||||
for (const auto &element : metadata.DirtyInfo()) {
|
||||
messages.push_back(element.AsMessage());
|
||||
}
|
||||
|
||||
return messages;
|
||||
}
|
||||
|
||||
void Game::RedatePlugins() {
|
||||
if (Type() != GameType::tes5 && Type() != GameType::tes5se) {
|
||||
BOOST_LOG_TRIVIAL(warning) << "Cannot redate plugins for game " << Name();
|
||||
|
||||
@@ -51,6 +51,7 @@ public:
|
||||
|
||||
std::shared_ptr<const PluginInterface> GetPlugin(const std::string& name) const;
|
||||
std::set<std::shared_ptr<const PluginInterface>> GetPlugins() const;
|
||||
std::vector<Message> CheckInstallValidity(std::shared_ptr<const PluginInterface> plugin, const PluginMetadata& metadata);
|
||||
|
||||
void RedatePlugins(); //Change timestamps to match load order (Skyrim only).
|
||||
|
||||
|
||||
@@ -171,6 +171,82 @@ TEST_P(GameTest, initShouldNotThrowIfGameAndLocalPathsAreNotEmpty) {
|
||||
EXPECT_NO_THROW(game.Init());
|
||||
}
|
||||
|
||||
TEST_P(GameTest, checkInstallValidityShouldCheckThatRequirementsArePresent) {
|
||||
Game game = Game(GameSettings(GetParam()).SetGamePath(dataPath.parent_path()), "", localPath);
|
||||
game.LoadAllInstalledPlugins(true);
|
||||
|
||||
PluginMetadata metadata(blankEsm);
|
||||
metadata.Reqs({
|
||||
File(missingEsp),
|
||||
File(blankEsp),
|
||||
});
|
||||
|
||||
auto messages = game.CheckInstallValidity(game.GetPlugin(blankEsm), metadata);
|
||||
EXPECT_EQ(std::vector<Message>({
|
||||
Message(MessageType::error, "This plugin requires \"" + missingEsp + "\" to be installed, but it is missing."),
|
||||
}), messages);
|
||||
}
|
||||
|
||||
TEST_P(GameTest, checkInstallValidityShouldCheckThatIncompatibilitiesAreAbsent) {
|
||||
Game game = Game(GameSettings(GetParam()).SetGamePath(dataPath.parent_path()), "", localPath);
|
||||
game.LoadAllInstalledPlugins(true);
|
||||
|
||||
PluginMetadata metadata(blankEsm);
|
||||
metadata.Incs({
|
||||
File(missingEsp),
|
||||
File(masterFile),
|
||||
});
|
||||
|
||||
auto messages = game.CheckInstallValidity(game.GetPlugin(blankEsm), metadata);
|
||||
EXPECT_EQ(std::vector<Message>({
|
||||
Message(MessageType::error, "This plugin is incompatible with \"" + masterFile + "\", but both are present."),
|
||||
}), messages);
|
||||
}
|
||||
|
||||
TEST_P(GameTest, checkInstallValidityShouldGenerateMessagesFromDirtyInfo) {
|
||||
Game game = Game(GameSettings(GetParam()).SetGamePath(dataPath.parent_path()), "", localPath);
|
||||
game.LoadAllInstalledPlugins(true);
|
||||
|
||||
PluginMetadata metadata(blankEsm);
|
||||
const std::vector<MessageContent> info = std::vector<MessageContent>({
|
||||
MessageContent("info", LanguageCode::english),
|
||||
});
|
||||
|
||||
metadata.DirtyInfo({
|
||||
PluginCleaningData(blankEsmCrc, "utility1", info, 0, 1, 2),
|
||||
PluginCleaningData(0xDEADBEEF, "utility2", info, 0, 5, 10),
|
||||
});
|
||||
|
||||
auto messages = game.CheckInstallValidity(game.GetPlugin(blankEsm), metadata);
|
||||
EXPECT_EQ(std::vector<Message>({
|
||||
PluginCleaningData(blankEsmCrc, "utility1", info, 0, 1, 2).AsMessage(),
|
||||
PluginCleaningData(0xDEADBEEF, "utility2", info, 0, 5, 10).AsMessage(),
|
||||
}), messages);
|
||||
}
|
||||
|
||||
TEST_P(GameTest, checkInstallValidityShouldCheckIfAPluginsMastersAreAllPresentAndActiveIfNoFilterTagIsPresent) {
|
||||
Game game = Game(GameSettings(GetParam()).SetGamePath(dataPath.parent_path()), "", localPath);
|
||||
game.LoadAllInstalledPlugins(true);
|
||||
|
||||
PluginMetadata metadata(blankDifferentMasterDependentEsp);
|
||||
|
||||
auto messages = game.CheckInstallValidity(game.GetPlugin(blankDifferentMasterDependentEsp), metadata);
|
||||
EXPECT_EQ(std::vector<Message>({
|
||||
Message(MessageType::error, "This plugin requires \"" + blankDifferentEsm + "\" to be active, but it is inactive."),
|
||||
}), messages);
|
||||
}
|
||||
|
||||
TEST_P(GameTest, checkInstallValidityShouldNotCheckIfAPluginsMastersAreAllActiveIfAFilterTagIsPresent) {
|
||||
Game game = Game(GameSettings(GetParam()).SetGamePath(dataPath.parent_path()), "", localPath);
|
||||
game.LoadAllInstalledPlugins(true);
|
||||
|
||||
PluginMetadata metadata(blankDifferentMasterDependentEsp);
|
||||
metadata.Tags({Tag("Filter")});
|
||||
|
||||
auto messages = game.CheckInstallValidity(game.GetPlugin(blankDifferentMasterDependentEsp), metadata);
|
||||
EXPECT_TRUE(messages.empty());
|
||||
}
|
||||
|
||||
TEST_P(GameTest, redatePluginsShouldRedatePluginsForSkyrimAndSkyrimSEAndDoNothingForOtherGames) {
|
||||
Game game = Game(GameSettings(GetParam()).SetGamePath(dataPath.parent_path()), "", localPath);
|
||||
game.Init();
|
||||
|
||||
Reference in New Issue
Block a user