diff --git a/doc/lightweight_test.qbk b/doc/lightweight_test.qbk index 4b9abd1..c7ef180 100644 --- a/doc/lightweight_test.qbk +++ b/doc/lightweight_test.qbk @@ -36,6 +36,8 @@ When using `lightweight_test.hpp`, *do not forget* to #define BOOST_ERROR(message) /*unspecified*/ #define BOOST_TEST_EQ(expr1, expr2) /*unspecified*/ #define BOOST_TEST_NE(expr1, expr2) /*unspecified*/ +#define BOOST_TEST_CSTR_EQ(expr1, expr2) /*unspecified*/ +#define BOOST_TEST_CSTR_NE(expr1, expr2) /*unspecified*/ #define BOOST_TEST_THROWS(expr, excep) /*unspecified*/ namespace boost @@ -101,6 +103,26 @@ message containing both expressions. [endsect] +[section BOOST_TEST_CSTR_EQ] + +`` +BOOST_TEST_CSTR_EQ(expr1, expr2) +`` + +Specialization of BOOST_TEST_EQ which interprets expr1 and expr2 as pointers to null-terminated byte strings (C strings). If `std::strcmp(expr1, expr2) != 0`, increase the error count and output a message containing both expressions. + +[endsect] + +[section BOOST_TEST_CSTR_NE] + +`` +BOOST_TEST_CSTR_NE(expr1, expr2) +`` + +Specialization of BOOST_TEST_NE which interprets expr1 and expr2 as pointers to null-terminated byte strings (C strings). If `std::strcmp(expr1, expr2) == 0`, increase the error count and output a message containing both expressions. + +[endsect] + [section BOOST_TEST_THROWS] `` diff --git a/include/boost/core/lightweight_test.hpp b/include/boost/core/lightweight_test.hpp index d6db024..804c8f4 100644 --- a/include/boost/core/lightweight_test.hpp +++ b/include/boost/core/lightweight_test.hpp @@ -23,6 +23,7 @@ #include #include #include +#include // IDE's like Visual Studio perform better if output goes to std::cout or // some other stream, so allow user to configure output stream: @@ -101,6 +102,12 @@ inline void throw_failed_impl(char const * excep, char const * file, int line, c # pragma GCC diagnostic ignored "-Wsign-compare" #endif +// specialize test output for char pointers to avoid printing as cstring +template inline const T& test_output_impl(const T& v) { return v; } +inline const void* test_output_impl(const char* v) { return v; } +inline const void* test_output_impl(const unsigned char* v) { return v; } +inline const void* test_output_impl(const signed char* v) { return v; } + template inline void test_eq_impl( char const * expr1, char const * expr2, char const * file, int line, char const * function, T const & t, U const & u ) { @@ -113,7 +120,7 @@ template inline void test_eq_impl( char const * expr1, char co BOOST_LIGHTWEIGHT_TEST_OSTREAM << file << "(" << line << "): test '" << expr1 << " == " << expr2 << "' failed in function '" << function << "': " - << "'" << t << "' != '" << u << "'" << std::endl; + << "'" << test_output_impl(t) << "' != '" << test_output_impl(u) << "'" << std::endl; ++test_errors(); } } @@ -130,6 +137,40 @@ template inline void test_ne_impl( char const * expr1, char co BOOST_LIGHTWEIGHT_TEST_OSTREAM << file << "(" << line << "): test '" << expr1 << " != " << expr2 << "' failed in function '" << function << "': " + << "'" << test_output_impl(t) << "' == '" << test_output_impl(u) << "'" << std::endl; + ++test_errors(); + } +} + +inline void test_cstr_eq_impl( char const * expr1, char const * expr2, + char const * file, int line, char const * function, char const * const t, char const * const u ) +{ + if( std::strcmp(t, u) == 0 ) + { + report_errors_remind(); + } + else + { + BOOST_LIGHTWEIGHT_TEST_OSTREAM + << file << "(" << line << "): test '" << expr1 << " == " << expr2 + << "' failed in function '" << function << "': " + << "'" << t << "' != '" << u << "'" << std::endl; + ++test_errors(); + } +} + +inline void test_cstr_ne_impl( char const * expr1, char const * expr2, + char const * file, int line, char const * function, char const * const t, char const * const u ) +{ + if( std::strcmp(t, u) != 0 ) + { + report_errors_remind(); + } + else + { + BOOST_LIGHTWEIGHT_TEST_OSTREAM + << file << "(" << line << "): test '" << expr1 << " == " << expr2 + << "' failed in function '" << function << "': " << "'" << t << "' == '" << u << "'" << std::endl; ++test_errors(); } @@ -177,6 +218,9 @@ inline int report_errors() #define BOOST_TEST_EQ(expr1,expr2) ( ::boost::detail::test_eq_impl(#expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) ) #define BOOST_TEST_NE(expr1,expr2) ( ::boost::detail::test_ne_impl(#expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) ) +#define BOOST_TEST_CSTR_EQ(expr1,expr2) ( ::boost::detail::test_cstr_eq_impl(#expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) ) +#define BOOST_TEST_CSTR_NE(expr1,expr2) ( ::boost::detail::test_cstr_ne_impl(#expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) ) + #ifndef BOOST_NO_EXCEPTIONS #define BOOST_TEST_THROWS( EXPR, EXCEP ) \ try { \ diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index f93ff51..31ba00f 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -76,6 +76,8 @@ run-fail lightweight_test_fail7.cpp ; run-fail lightweight_test_fail7.cpp : : : off : lightweight_test_fail7_no_rtti ; run-fail lightweight_test_fail8.cpp ; run-fail lightweight_test_fail8.cpp : : : off : lightweight_test_fail8_no_rtti ; +run-fail lightweight_test_fail9.cpp ; +run-fail lightweight_test_fail10.cpp ; run is_same_test.cpp ; diff --git a/test/lightweight_test_fail10.cpp b/test/lightweight_test_fail10.cpp new file mode 100644 index 0000000..388c47e --- /dev/null +++ b/test/lightweight_test_fail10.cpp @@ -0,0 +1,18 @@ +// +// Negative test for BOOST_TEST_EQ on const char* +// +// Copyright (c) 2017 Hans Dembinski +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt +// + +#include + +int main() +{ + BOOST_TEST_EQ("xab"+1 , "yab"+1); // compares addresses, not cstrings + + return boost::report_errors(); +} diff --git a/test/lightweight_test_fail9.cpp b/test/lightweight_test_fail9.cpp new file mode 100644 index 0000000..a87a4f1 --- /dev/null +++ b/test/lightweight_test_fail9.cpp @@ -0,0 +1,18 @@ +// +// Negative test for BOOST_TEST_CSTR_EQ +// +// Copyright (c) 2017 Hans Dembinski +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt +// + +#include + +int main() +{ + BOOST_TEST_CSTR_EQ("x" , "y"); + + return boost::report_errors(); +} diff --git a/test/lightweight_test_test.cpp b/test/lightweight_test_test.cpp index d4808a1..a3b04a9 100644 --- a/test/lightweight_test_test.cpp +++ b/test/lightweight_test_test.cpp @@ -64,11 +64,15 @@ int main() BOOST_TEST_EQ( ++x, ++y ); BOOST_TEST_EQ( x++, y++ ); + BOOST_TEST_CSTR_EQ("xabc"+1, "yabc"+1); // equal cstrings, different addresses + BOOST_TEST_EQ( &y, &y ); // BOOST_TEST_NE BOOST_TEST_NE( ++x, y ); BOOST_TEST_NE( &x, &y ); + BOOST_TEST_NE("xabc"+1, "yabc"+1); // equal cstrings, different addresses + BOOST_TEST_CSTR_NE("x", "y"); // BOOST_TEST_THROWS