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:
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user