Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion external/languages
Submodule languages updated 1 files
+2 −2 rttr-de.po
4 changes: 2 additions & 2 deletions tests/languages/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Copyright (C) 2005 - 2021 Settlers Freaks <sf-team at siedler25.org>
# Copyright (C) 2005 - 2026 Settlers Freaks <sf-team at siedler25.org>
#
# SPDX-License-Identifier: GPL-2.0-or-later

configure_file(languageFiles.h.cmake languageFiles.h)
add_testcase(NAME LanguageFiles
LIBS mygettext s25util::common Boost::filesystem rttr::vld
LIBS s25Common mygettext s25util::common Boost::filesystem rttr::vld
INCLUDES ${CMAKE_CURRENT_BINARY_DIR}
COST 15
)
Expand Down
82 changes: 47 additions & 35 deletions tests/languages/testLanguageFiles.cpp
Original file line number Diff line number Diff line change
@@ -1,27 +1,42 @@
// Copyright (C) 2005 - 2021 Settlers Freaks (sf-team at siedler25.org)
// Copyright (C) 2005 - 2026 Settlers Freaks (sf-team at siedler25.org)
//
// SPDX-License-Identifier: GPL-2.0-or-later

#define BOOST_TEST_MODULE RTTR_LanguageFiles

#include "helpers/OptionalIO.h"
#include "languageFiles.h"
#include "mygettext/readCatalog.h"
#include "s25util/utf8.h"
#include <boost/filesystem.hpp>
#include <boost/format.hpp>
#include <boost/test/unit_test.hpp>
#include <map>
#include <optional>

#if RTTR_HAS_VLD
# include <vld.h>
#endif

namespace {
struct FormatProperties
{
int numParameters;
std::optional<int> numParameters;
};

static std::map<std::string, FormatProperties> getGoldMapping()
FormatProperties getFormatProperties(const std::string& str)
{
try
{
const boost::format fmt(str);
return FormatProperties{fmt.expected_args()};
} catch(const std::exception&)
{
return FormatProperties{std::nullopt};
}
}

std::map<std::string, FormatProperties> getGoldMapping()
{
const std::map<std::string, std::string> translations =
mygettext::readCatalog(std::string(RTTR_TRANSLATION_DIR) + "/rttr-en_GB.mo", "UTF-8");
Expand All @@ -30,19 +45,12 @@ static std::map<std::string, FormatProperties> getGoldMapping()
{
if(entry.first.empty())
continue;
try
{
const boost::format fmt(entry.first);
result.emplace(std::make_pair(entry.first, FormatProperties{fmt.expected_args()}));
} catch(const std::exception&)
{
result.emplace(std::make_pair(entry.first, FormatProperties{0}));
}
result.emplace(entry.first, getFormatProperties(entry.first));
}
return result;
}

static std::string replaceLF(std::string s)
std::string replaceLF(std::string s)
{
size_t index = 0;
while((index = s.find('\n')) != std::string::npos)
Expand All @@ -51,41 +59,45 @@ static std::string replaceLF(std::string s)
}
return s;
}
} // namespace

// GCC until 10 has issues comparing std::optional in BOOST_TEST
#if defined(__GNUC__) && __GNUC__ < 10
# define BOOST_TEST_OPTIONAL BOOST_CHECK
#else
# define BOOST_TEST_OPTIONAL BOOST_TEST
#endif

BOOST_AUTO_TEST_CASE(AllFilesHaveValidFormat)
{
const auto goldMapping = getGoldMapping();
for(const auto& it : boost::filesystem::directory_iterator(RTTR_TRANSLATION_DIR))
for(const auto& itFile : boost::filesystem::directory_iterator(RTTR_TRANSLATION_DIR))
{
if(!is_regular_file(it.status()) || it.path().extension() != ".mo")
if(!is_regular_file(itFile.status()) || itFile.path().extension() != ".mo")
continue; // LCOV_EXCL_LINE
const auto translatedStrings = mygettext::readCatalog(it.path().string(), "UTF-8");
const auto translatedStrings = mygettext::readCatalog(itFile.path().string(), "UTF-8");

BOOST_TEST_CONTEXT("Locale: " << it.path().stem())
for(const auto& entry : goldMapping)
BOOST_TEST_CONTEXT("Locale: " << itFile.path().stem())
for(const auto& entry : translatedStrings)
{
const auto it = translatedStrings.find(entry.first);
if(it == translatedStrings.end())
continue; // Not translated
BOOST_TEST_CONTEXT("Entry '" << replaceLF(it->first) << "' => '" << replaceLF(it->second) << "'")
const auto itGoldEntry = goldMapping.find(entry.first);
const auto& [origTxt, translation] = entry;
BOOST_TEST_CONTEXT("Entry '" << replaceLF(origTxt) << "' => '" << replaceLF(translation) << "'")
{
BOOST_TEST(s25util::isValidUTF8(it->second));
BOOST_TEST(s25util::isValidUTF8(translation));
// Note: "Check 50%" is invalid (ends in %) but "50% checked" is not and translations might move the %
// around Hence rely on the number of format args which should be consistent
try
{
const boost::format fmt(it->second);
BOOST_TEST(fmt.expected_args() == entry.second.numParameters);
} catch(const std::exception&)
FormatProperties origProps = getFormatProperties(origTxt);
FormatProperties transProps = getFormatProperties(translation);
// Orig text replacements must match with gold version
// Might not exist if orig text is not "translated" (already in English)
if(itGoldEntry != goldMapping.end())
BOOST_TEST_OPTIONAL(origProps.numParameters == itGoldEntry->second.numParameters);
if(origProps.numParameters.has_value() == transProps.numParameters.has_value())
{
// Should have been a format string
if(entry.second.numParameters > 0)
{
// LCOV_EXCL_START
BOOST_TEST_ERROR("Invalid format string");
// LCOV_EXCL_STOP
}
}
BOOST_TEST_OPTIONAL(origProps.numParameters == transProps.numParameters);
} else if(origProps.numParameters > 0)
BOOST_TEST_ERROR("Invalid format string in translation"); // LCOV_EXCL_LINE
}
}
}
Expand Down
14 changes: 9 additions & 5 deletions tests/s25Main/network/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,21 +33,22 @@ BOOST_AUTO_TEST_CASE(TestServer_Works)
return result;
};
BOOST_TEST(!runServer());
BOOST_TEST_REQUIRE(server.listen(1337));
const auto port = server.tryListen();
BOOST_TEST_REQUIRE(port > 0);
BOOST_TEST(runServer());

Socket sock;
BOOST_TEST_REQUIRE(sock.Connect("localhost", 1337, false));
BOOST_TEST_REQUIRE(sock.Connect("localhost", port, false));
BOOST_TEST(server.run(true));
BOOST_TEST_REQUIRE(server.connections.size() == 1u);
BOOST_TEST(server.stop());
BOOST_TEST_REQUIRE(server.connections.empty());

BOOST_TEST_REQUIRE(server.listen(1337));
BOOST_TEST_REQUIRE(server.listen(port));
Socket sock2;
BOOST_TEST_REQUIRE(sock.Connect("localhost", 1337, false));
BOOST_TEST_REQUIRE(sock.Connect("localhost", port, false));
BOOST_TEST(server.run(true));
BOOST_TEST_REQUIRE(sock2.Connect("localhost", 1337, false));
BOOST_TEST_REQUIRE(sock2.Connect("localhost", port, false));
BOOST_TEST(server.run(true));
BOOST_TEST_REQUIRE(server.connections.size() == 2u);
BOOST_TEST(runServer());
Expand All @@ -58,7 +59,10 @@ BOOST_AUTO_TEST_CASE(TestServer_Works)
for(int i = 0; i < 5; i++)
{
if(server.connections.size() == 2u)
{
sock.Sleep(50); // LCOV_EXCL_LINE
BOOST_TEST(runServer()); // LCOV_EXCL_LINE
}
}
}
BOOST_TEST(server.connections.size() == 1u);
Expand Down
Loading