2
0
mirror of https://github.com/boostorg/locale.git synced 2026-01-19 04:22:08 +00:00

Add TEST_CONTEXT

Avoid to require manual output in anticipation of failures.
This commit is contained in:
Alexander Grund
2024-11-24 20:01:01 +01:00
parent 9f4424d7db
commit f0d95b079b
5 changed files with 45 additions and 18 deletions

View File

@@ -10,6 +10,7 @@
#define BOOST_LOCALE_UNIT_TEST_HPP
#include <boost/locale/config.hpp>
#include <boost/config/helper_macros.hpp>
#include <cstdlib>
#include <iomanip>
#include <iostream>
@@ -33,8 +34,10 @@ namespace boost { namespace locale { namespace test {
/// Name/path of current executable
std::string exe_name;
class test_context;
struct test_result {
test_result() : error_counter(0), test_counter(0)
test_result()
{
#if defined(_MSC_VER) && (_MSC_VER > 1310)
// disable message boxes on assert(), abort()
@@ -46,8 +49,9 @@ namespace boost { namespace locale { namespace test {
_CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
#endif
}
int error_counter;
int test_counter;
int error_counter = 0;
int test_counter = 0;
const test_context* context = nullptr;
};
inline test_result& results()
{
@@ -55,9 +59,32 @@ namespace boost { namespace locale { namespace test {
return instance;
}
class test_context {
const test_context* oldCtx_;
const std::string msg_;
public:
test_context(std::string ctx) : oldCtx_(results().context), msg_(std::move(ctx)) { results().context = this; }
~test_context() { results().context = oldCtx_; }
friend std::ostream& operator<<(std::ostream& os, const test_context& c)
{
const test_context* current = &c;
os << "CONTEXT: ";
std::string indent = "\n\t";
do {
os << indent << current->msg_;
indent += '\t';
} while((current = current->oldCtx_) != nullptr);
return os;
}
};
inline void report_error(const char* expr, const char* file, int line)
{
std::cerr << "Error at " << file << '#' << line << ": " << expr << std::endl;
const auto* context = results().context;
if(context)
std::cerr << ' ' << *context << std::endl;
if(++boost::locale::test::results().error_counter > BOOST_LOCALE_ERROR_LIMIT)
throw std::runtime_error("Error limits reached, stopping unit test");
}
@@ -97,6 +124,10 @@ namespace boost { namespace locale { namespace test {
BOOST_LOCALE_START_CONST_CONDITION \
} while(0) BOOST_LOCALE_END_CONST_CONDITION
#define TEST_CONTEXT(expr) \
boost::locale::test::test_context BOOST_JOIN(test_context_, __COUNTER__)( \
static_cast<const std::stringstream&>(std::stringstream{} << expr).str())
void test_main(int argc, char** argv);
int main(int argc, char** argv)

View File

@@ -31,10 +31,8 @@ void test_plural_expr_rand(const T& ref, const char* expr)
const auto n = getRandValue(minVal, maxVal);
const auto result = ptr(n);
const auto refResult = ref(n);
if(result != refResult) {
std::cerr << "Expression: " << expr << "; n=" << n << '\n'; // LCOV_EXCL_LINE
TEST_EQ(result, refResult); // LCOV_EXCL_LINE
}
TEST_CONTEXT("Expression: " << expr << "; n=" << n);
TEST_EQ(result, refResult);
}
}

View File

@@ -53,10 +53,8 @@ void test_codecvt_in_n_m(const cvt_type& cvt, int n, int m)
std::mbstate_t mb2 = mb;
std::codecvt_base::result r = cvt.in(mb, from, end, from_next, to, to_end, to_next);
int count = cvt.length(mb2, from, end, to_end - to);
const int count = cvt.length(mb2, from, end, to_end - to);
TEST_EQ(memcmp(&mb, &mb2, sizeof(mb)), 0);
if(count != from_next - from)
std::cout << count << " " << from_next - from << std::endl; // LCOV_EXCL_LINE
TEST_EQ(count, from_next - from);
if(r == cvt_type::partial) {

View File

@@ -832,10 +832,9 @@ void test_simple_encodings()
const auto encodings = get_simple_encodings();
for(auto it = encodings.begin(), end = encodings.end(); it != end; ++it) {
TEST_EQ(normalize_encoding(*it), *it); // Must be normalized
const auto it2 = std::find(it + 1, end, *it);
TEST(it2 == end);
if(it2 != end)
std::cerr << "Duplicate entry: " << *it << '\n'; // LCOV_EXCL_LINE
TEST_CONTEXT("Entry: " << *it);
// Must be unique
TEST(std::find(it + 1, end, *it) == end);
}
const auto it = std::is_sorted_until(encodings.begin(), encodings.end());
TEST(it == encodings.end());
@@ -852,10 +851,9 @@ void test_win_codepages()
auto is_same_win_codepage = [&it](const windows_encoding& rhs) -> bool {
return it->codepage == rhs.codepage && std::strcmp(it->name, rhs.name) == 0;
};
const auto* it2 = std::find_if(it + 1, end, is_same_win_codepage);
TEST(it2 == end);
if(it2 != end)
std::cerr << "Duplicate entry: " << it->name << ':' << it->codepage << '\n'; // LCOV_EXCL_LINE
TEST_CONTEXT("Entry: " << it->name << ':' << it->codepage);
// Must be unique
TEST(std::find_if(it + 1, end, is_same_win_codepage) == end);
}
const auto cmp = [](const windows_encoding& rhs, const windows_encoding& lhs) -> bool { return rhs < lhs.name; };
const auto* it = std::is_sorted_until(all_windows_encodings, std::end(all_windows_encodings), cmp);

View File

@@ -300,6 +300,7 @@ void test_parse_fail_impl(std::basic_istringstream<CharType>& ss, int line)
#define TEST_MIN_MAX_POSIX(type) \
do { \
TEST_CONTEXT(#type); \
const std::string minval = as_posix_string(std::numeric_limits<type>::min()); \
const std::string maxval = as_posix_string(std::numeric_limits<type>::max()); \
TEST_MIN_MAX_FMT(as::posix, type, minval, maxval); \
@@ -340,6 +341,7 @@ void test_as_posix(const std::string& e_charset = "UTF-8")
localization_backend_manager::global(backend);
for(const std::string name : {"en_US", "ru_RU", "de_DE"}) {
const std::locale loc = boost::locale::generator{}(name + "." + e_charset);
TEST_CONTEXT("Locale " << (name + "." + e_charset));
TEST_MIN_MAX_POSIX(int16_t);
TEST_MIN_MAX_POSIX(uint16_t);