// // unit_test.hpp // ~~~~~~~~~~~~~ // // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // 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) // #ifndef UNIT_TEST_HPP #define UNIT_TEST_HPP #include "asio/detail/config.hpp" #include #include "asio/detail/atomic_count.hpp" #if defined(__sun) # include // Needed for lrand48. #endif // defined(__sun) #if defined(__BORLANDC__) && !defined(__clang__) // Prevent use of intrinsic for strcmp. # include # undef strcmp // Suppress error about condition always being true. # pragma option -w-ccc #endif // defined(__BORLANDC__) && !defined(__clang__) #if defined(ASIO_MSVC) # pragma warning (disable:4127) # pragma warning (push) # pragma warning (disable:4244) # pragma warning (disable:4702) #endif // defined(ASIO_MSVC) #if !defined(ASIO_TEST_IOSTREAM) # define ASIO_TEST_IOSTREAM std::cerr #endif // !defined(ASIO_TEST_IOSTREAM) namespace asio { namespace detail { inline const char*& test_name() { static const char* name = 0; return name; } inline atomic_count& test_errors() { static atomic_count errors(0); return errors; } inline void begin_test_suite(const char* name) { asio::detail::test_name(); asio::detail::test_errors(); ASIO_TEST_IOSTREAM << name << " test suite begins" << std::endl; } inline int end_test_suite(const char* name) { ASIO_TEST_IOSTREAM << name << " test suite ends" << std::endl; ASIO_TEST_IOSTREAM << "\n*** "; long errors = asio::detail::test_errors(); if (errors == 0) ASIO_TEST_IOSTREAM << "No errors detected."; else if (errors == 1) ASIO_TEST_IOSTREAM << "1 error detected."; else ASIO_TEST_IOSTREAM << errors << " errors detected." << std::endl; ASIO_TEST_IOSTREAM << std::endl; return errors == 0 ? 0 : 1; } template inline void run_test(const char* name) { test_name() = name; long errors_before = asio::detail::test_errors(); Test(); if (test_errors() == errors_before) ASIO_TEST_IOSTREAM << name << " passed" << std::endl; else ASIO_TEST_IOSTREAM << name << " failed" << std::endl; } template inline void compile_test(const char* name) { ASIO_TEST_IOSTREAM << name << " passed" << std::endl; } #if defined(ASIO_NO_EXCEPTIONS) template void throw_exception(const T& t) { ASIO_TEST_IOSTREAM << "Exception: " << t.what() << std::endl; std::abort(); } #endif // defined(ASIO_NO_EXCEPTIONS) } // namespace detail } // namespace asio #define ASIO_CHECK(expr) \ do { if (!(expr)) { \ ASIO_TEST_IOSTREAM << __FILE__ << "(" << __LINE__ << "): " \ << asio::detail::test_name() << ": " \ << "check '" << #expr << "' failed" << std::endl; \ ++asio::detail::test_errors(); \ } } while (0) #define ASIO_CHECK_MESSAGE(expr, msg) \ do { if (!(expr)) { \ ASIO_TEST_IOSTREAM << __FILE__ << "(" << __LINE__ << "): " \ << asio::detail::test_name() << ": " \ << msg << std::endl; \ ++asio::detail::test_errors(); \ } } while (0) #define ASIO_WARN_MESSAGE(expr, msg) \ do { if (!(expr)) { \ ASIO_TEST_IOSTREAM << __FILE__ << "(" << __LINE__ << "): " \ << asio::detail::test_name() << ": " \ << msg << std::endl; \ } } while (0) #define ASIO_ERROR(msg) \ do { \ ASIO_TEST_IOSTREAM << __FILE__ << "(" << __LINE__ << "): " \ << asio::detail::test_name() << ": " \ << msg << std::endl; \ ++asio::detail::test_errors(); \ } while (0) #define ASIO_TEST_SUITE(name, tests) \ int main() \ { \ asio::detail::begin_test_suite(name); \ tests \ return asio::detail::end_test_suite(name); \ } #define ASIO_TEST_CASE(test) \ asio::detail::run_test<&test>(#test); #define ASIO_TEST_CASE2(test1, test2) \ asio::detail::run_test<&test1, test2>(#test1 "," #test2); #define ASIO_TEST_CASE3(test1, test2, test3) \ asio::detail::run_test<&test1, test2, test3>( \ #test1 "," #test2 "," #test3); #define ASIO_TEST_CASE4(test1, test2, test3, test4) \ asio::detail::run_test<&test1, test2, test3, test4>( \ #test1 "," #test2 "," #test3 "," #test4); #define ASIO_TEST_CASE5(test1, test2, test3, test4, test5) \ asio::detail::run_test<&test1, test2, test3, test4, test5>( \ #test1 "," #test2 "," #test3 "," #test4 "," #test5); #define ASIO_COMPILE_TEST_CASE(test) \ asio::detail::compile_test<&test>(#test); inline void null_test() { } #if defined(__GNUC__) && defined(_AIX) // AIX needs this symbol defined in asio, even if it doesn't do anything. int test_main(int, char**) { } #endif // defined(__GNUC__) && defined(_AIX) #if defined(ASIO_MSVC) # pragma warning (pop) #endif // defined(ASIO_MSVC) #endif // UNIT_TEST_HPP