Skip to content

Commit a1b6268

Browse files
committed
Add TEST_CONTEXT
Avoid to require manual output in anticipation of failures.
1 parent 9f4424d commit a1b6268

File tree

5 files changed

+45
-18
lines changed

5 files changed

+45
-18
lines changed

test/boostLocale/test/unit_test.hpp

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#define BOOST_LOCALE_UNIT_TEST_HPP
1111

1212
#include <boost/locale/config.hpp>
13+
#include <boost/config/helper_macros.hpp>
1314
#include <cstdlib>
1415
#include <iomanip>
1516
#include <iostream>
@@ -33,8 +34,10 @@ namespace boost { namespace locale { namespace test {
3334
/// Name/path of current executable
3435
std::string exe_name;
3536

37+
class test_context;
38+
3639
struct test_result {
37-
test_result() : error_counter(0), test_counter(0)
40+
test_result()
3841
{
3942
#if defined(_MSC_VER) && (_MSC_VER > 1310)
4043
// disable message boxes on assert(), abort()
@@ -46,18 +49,42 @@ namespace boost { namespace locale { namespace test {
4649
_CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
4750
#endif
4851
}
49-
int error_counter;
50-
int test_counter;
52+
int error_counter = 0;
53+
int test_counter = 0;
54+
const test_context* context = nullptr;
5155
};
5256
inline test_result& results()
5357
{
5458
static test_result instance;
5559
return instance;
5660
}
5761

62+
class test_context {
63+
const test_context* oldCtx_;
64+
const std::string msg_;
65+
66+
public:
67+
test_context(std::string ctx) : oldCtx_(results().context), msg_(std::move(ctx)) { results().context = this; }
68+
~test_context() { results().context = oldCtx_; }
69+
friend std::ostream& operator<<(std::ostream& os, const test_context& c)
70+
{
71+
const test_context* current = &c;
72+
os << "CONTEXT: ";
73+
std::string indent = "\n\t";
74+
do {
75+
os << indent << current->msg_;
76+
indent += '\t';
77+
} while((current = current->oldCtx_) != nullptr);
78+
return os;
79+
}
80+
};
81+
5882
inline void report_error(const char* expr, const char* file, int line)
5983
{
6084
std::cerr << "Error at " << file << '#' << line << ": " << expr << std::endl;
85+
const auto* context = results().context;
86+
if(context)
87+
std::cerr << ' ' << *context << std::endl;
6188
if(++boost::locale::test::results().error_counter > BOOST_LOCALE_ERROR_LIMIT)
6289
throw std::runtime_error("Error limits reached, stopping unit test");
6390
}
@@ -97,6 +124,10 @@ namespace boost { namespace locale { namespace test {
97124
BOOST_LOCALE_START_CONST_CONDITION \
98125
} while(0) BOOST_LOCALE_END_CONST_CONDITION
99126

127+
#define TEST_CONTEXT(expr) \
128+
boost::locale::test::test_context BOOST_JOIN(test_context_, __COUNTER__)( \
129+
static_cast<const std::stringstream&>(std::stringstream{} << expr).str())
130+
100131
void test_main(int argc, char** argv);
101132

102133
int main(int argc, char** argv)

test/test_catalog.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,8 @@ void test_plural_expr_rand(const T& ref, const char* expr)
3131
const auto n = getRandValue(minVal, maxVal);
3232
const auto result = ptr(n);
3333
const auto refResult = ref(n);
34-
if(result != refResult) {
35-
std::cerr << "Expression: " << expr << "; n=" << n << '\n'; // LCOV_EXCL_LINE
36-
TEST_EQ(result, refResult); // LCOV_EXCL_LINE
37-
}
34+
TEST_CONTEXT("Expression: " << expr << "; n=" << n);
35+
TEST_EQ(result, refResult);
3836
}
3937
}
4038

test/test_codecvt.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,8 @@ void test_codecvt_in_n_m(const cvt_type& cvt, int n, int m)
5353
std::mbstate_t mb2 = mb;
5454
std::codecvt_base::result r = cvt.in(mb, from, end, from_next, to, to_end, to_next);
5555

56-
int count = cvt.length(mb2, from, end, to_end - to);
56+
const int count = cvt.length(mb2, from, end, to_end - to);
5757
TEST_EQ(memcmp(&mb, &mb2, sizeof(mb)), 0);
58-
if(count != from_next - from)
59-
std::cout << count << " " << from_next - from << std::endl; // LCOV_EXCL_LINE
6058
TEST_EQ(count, from_next - from);
6159

6260
if(r == cvt_type::partial) {

test/test_encoding.cpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -832,10 +832,9 @@ void test_simple_encodings()
832832
const auto encodings = get_simple_encodings();
833833
for(auto it = encodings.begin(), end = encodings.end(); it != end; ++it) {
834834
TEST_EQ(normalize_encoding(*it), *it); // Must be normalized
835-
const auto it2 = std::find(it + 1, end, *it);
836-
TEST(it2 == end);
837-
if(it2 != end)
838-
std::cerr << "Duplicate entry: " << *it << '\n'; // LCOV_EXCL_LINE
835+
TEST_CONTEXT("Entry: " << *it);
836+
// Must be unique
837+
TEST(std::find(it + 1, end, *it) == end);
839838
}
840839
const auto it = std::is_sorted_until(encodings.begin(), encodings.end());
841840
TEST(it == encodings.end());
@@ -852,10 +851,9 @@ void test_win_codepages()
852851
auto is_same_win_codepage = [&it](const windows_encoding& rhs) -> bool {
853852
return it->codepage == rhs.codepage && std::strcmp(it->name, rhs.name) == 0;
854853
};
855-
const auto* it2 = std::find_if(it + 1, end, is_same_win_codepage);
856-
TEST(it2 == end);
857-
if(it2 != end)
858-
std::cerr << "Duplicate entry: " << it->name << ':' << it->codepage << '\n'; // LCOV_EXCL_LINE
854+
TEST_CONTEXT("Entry: " << it->name << ':' << it->codepage);
855+
// Must be unique
856+
TEST(std::find_if(it + 1, end, is_same_win_codepage) == end);
859857
}
860858
const auto cmp = [](const windows_encoding& rhs, const windows_encoding& lhs) -> bool { return rhs < lhs.name; };
861859
const auto* it = std::is_sorted_until(all_windows_encodings, std::end(all_windows_encodings), cmp);

test/test_formatting.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,7 @@ void test_parse_fail_impl(std::basic_istringstream<CharType>& ss, int line)
300300

301301
#define TEST_MIN_MAX_POSIX(type) \
302302
do { \
303+
TEST_CONTEXT(#type); \
303304
const std::string minval = as_posix_string(std::numeric_limits<type>::min()); \
304305
const std::string maxval = as_posix_string(std::numeric_limits<type>::max()); \
305306
TEST_MIN_MAX_FMT(as::posix, type, minval, maxval); \
@@ -340,6 +341,7 @@ void test_as_posix(const std::string& e_charset = "UTF-8")
340341
localization_backend_manager::global(backend);
341342
for(const std::string name : {"en_US", "ru_RU", "de_DE"}) {
342343
const std::locale loc = boost::locale::generator{}(name + "." + e_charset);
344+
TEST_CONTEXT("Locale " << (name + "." + e_charset));
343345
TEST_MIN_MAX_POSIX(int16_t);
344346
TEST_MIN_MAX_POSIX(uint16_t);
345347

0 commit comments

Comments
 (0)