1//
2// unit_test.hpp
3// ~~~~~~~~~~~~~
4//
5// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6//
7// Distributed under the Boost Software License, Version 1.0. (See accompanying
8// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9//
10
11#ifndef UNIT_TEST_HPP
12#define UNIT_TEST_HPP
13
14#include <boost/asio/detail/config.hpp>
15#include <iostream>
16#include <boost/asio/detail/atomic_count.hpp>
17
18#if defined(__sun)
19# include <stdlib.h> // Needed for lrand48.
20#endif // defined(__sun)
21
22#if defined(__BORLANDC__)
23
24// Prevent use of intrinsic for strcmp.
25# include <cstring>
26# undef strcmp
27
28// Suppress error about condition always being true.
29# pragma option -w-ccc
30
31#endif // defined(__BORLANDC__)
32
33#if defined(BOOST_ASIO_MSVC)
34# pragma warning (disable:4127)
35# pragma warning (push)
36# pragma warning (disable:4244)
37# pragma warning (disable:4702)
38#endif // defined(BOOST_ASIO_MSVC)
39
40#if !defined(BOOST_ASIO_TEST_IOSTREAM)
41# define BOOST_ASIO_TEST_IOSTREAM std::cerr
42#endif // !defined(BOOST_ASIO_TEST_IOSTREAM)
43
44namespace boost {
45namespace asio {
46namespace detail {
47
48inline const char*& test_name()
49{
50 static const char* name = 0;
51 return name;
52}
53
54inline atomic_count& test_errors()
55{
56 static atomic_count errors(0);
57 return errors;
58}
59
60inline void begin_test_suite(const char* name)
61{
62 boost::asio::detail::test_name();
63 boost::asio::detail::test_errors();
64 BOOST_ASIO_TEST_IOSTREAM << name << " test suite begins" << std::endl;
65}
66
67inline int end_test_suite(const char* name)
68{
69 BOOST_ASIO_TEST_IOSTREAM << name << " test suite ends" << std::endl;
70 BOOST_ASIO_TEST_IOSTREAM << "\n*** ";
71 long errors = boost::asio::detail::test_errors();
72 if (errors == 0)
73 BOOST_ASIO_TEST_IOSTREAM << "No errors detected.";
74 else if (errors == 1)
75 BOOST_ASIO_TEST_IOSTREAM << "1 error detected.";
76 else
77 BOOST_ASIO_TEST_IOSTREAM << errors << " errors detected." << std::endl;
78 BOOST_ASIO_TEST_IOSTREAM << std::endl;
79 return errors == 0 ? 0 : 1;
80}
81
82template <void (*Test)()>
83inline void run_test(const char* name)
84{
85 test_name() = name;
86 long errors_before = boost::asio::detail::test_errors();
87 Test();
88 if (test_errors() == errors_before)
89 BOOST_ASIO_TEST_IOSTREAM << name << " passed" << std::endl;
90 else
91 BOOST_ASIO_TEST_IOSTREAM << name << " failed" << std::endl;
92}
93
94template <void (*)()>
95inline void compile_test(const char* name)
96{
97 BOOST_ASIO_TEST_IOSTREAM << name << " passed" << std::endl;
98}
99
100#if defined(BOOST_ASIO_NO_EXCEPTIONS)
101
102template <typename T>
103void throw_exception(const T& t)
104{
105 BOOST_ASIO_TEST_IOSTREAM << "Exception: " << t.what() << std::endl;
106 std::abort();
107}
108
109#endif // defined(BOOST_ASIO_NO_EXCEPTIONS)
110
111} // namespace detail
112} // namespace asio
113} // namespace boost
114
115#define BOOST_ASIO_CHECK(expr) \
116 do { if (!(expr)) { \
117 BOOST_ASIO_TEST_IOSTREAM << __FILE__ << "(" << __LINE__ << "): " \
118 << boost::asio::detail::test_name() << ": " \
119 << "check '" << #expr << "' failed" << std::endl; \
120 ++boost::asio::detail::test_errors(); \
121 } } while (0)
122
123#define BOOST_ASIO_CHECK_MESSAGE(expr, msg) \
124 do { if (!(expr)) { \
125 BOOST_ASIO_TEST_IOSTREAM << __FILE__ << "(" << __LINE__ << "): " \
126 << boost::asio::detail::test_name() << ": " \
127 << msg << std::endl; \
128 ++boost::asio::detail::test_errors(); \
129 } } while (0)
130
131#define BOOST_ASIO_WARN_MESSAGE(expr, msg) \
132 do { if (!(expr)) { \
133 BOOST_ASIO_TEST_IOSTREAM << __FILE__ << "(" << __LINE__ << "): " \
134 << boost::asio::detail::test_name() << ": " \
135 << msg << std::endl; \
136 } } while (0)
137
138#define BOOST_ASIO_ERROR(msg) \
139 do { \
140 BOOST_ASIO_TEST_IOSTREAM << __FILE__ << "(" << __LINE__ << "): " \
141 << boost::asio::detail::test_name() << ": " \
142 << msg << std::endl; \
143 ++boost::asio::detail::test_errors(); \
144 } while (0)
145
146#define BOOST_ASIO_TEST_SUITE(name, tests) \
147 int main() \
148 { \
149 boost::asio::detail::begin_test_suite(name); \
150 tests \
151 return boost::asio::detail::end_test_suite(name); \
152 }
153
154#define BOOST_ASIO_TEST_CASE(test) \
155 boost::asio::detail::run_test<&test>(#test);
156
157#define BOOST_ASIO_COMPILE_TEST_CASE(test) \
158 boost::asio::detail::compile_test<&test>(#test);
159
160inline void null_test()
161{
162}
163
164#if defined(__GNUC__) && defined(_AIX)
165
166// AIX needs this symbol defined in asio, even if it doesn't do anything.
167int test_main(int, char**)
168{
169}
170
171#endif // defined(__GNUC__) && defined(_AIX)
172
173#if defined(BOOST_ASIO_MSVC)
174# pragma warning (pop)
175#endif // defined(BOOST_ASIO_MSVC)
176
177#endif // UNIT_TEST_HPP
178