]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/any/test/test.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / libs / any / test / test.hpp
1 // what: simple unit test framework
2 // who: developed by Kevlin Henney
3 // when: November 2000
4 // where: tested with BCC 5.5, MSVC 6.0, and g++ 2.91
5
6 #ifndef TEST_INCLUDED
7 #define TEST_INCLUDED
8
9 #include <boost/config.hpp>
10 #include <exception>
11 #include <iostream>
12 #ifdef BOOST_NO_STRINGSTREAM
13 #include <strstream> // for out-of-the-box g++ pre-2.95.3
14 #else
15 #include <sstream>
16 #endif
17 #include <string>
18
19 namespace any_tests // test tuple comprises name and nullary function (object)
20 {
21 template<typename string_type, typename function_type>
22 struct test
23 {
24 string_type name;
25 function_type action;
26
27 static test make(string_type name, function_type action)
28 {
29 test result; // MSVC aggreggate initializer bugs
30 result.name = name;
31 result.action = action;
32 return result;
33 }
34 };
35 }
36
37 namespace any_tests // failure exception used to indicate checked test failures
38 {
39 class failure : public std::exception
40 {
41 public: // struction (default cases are OK)
42
43 failure(const std::string & why) throw()
44 : reason(why)
45 {
46 }
47
48 ~failure() throw() {}
49
50 public: // usage
51
52 virtual const char * what() const throw()
53 {
54 return reason.c_str();
55 }
56
57 private: // representation
58
59 std::string reason;
60
61 };
62 }
63
64 namespace any_tests // not_implemented exception used to mark unimplemented tests
65 {
66 class not_implemented : public std::exception
67 {
68 public: // usage (default ctor and dtor are OK)
69
70 virtual const char * what() const throw()
71 {
72 return "not implemented";
73 }
74
75 };
76 }
77
78 namespace any_tests // test utilities
79 {
80 inline void check(bool condition, const std::string & description)
81 {
82 if(!condition)
83 {
84 throw failure(description);
85 }
86 }
87
88 inline void check_true(bool value, const std::string & description)
89 {
90 check(value, "expected true: " + description);
91 }
92
93 inline void check_false(bool value, const std::string & description)
94 {
95 check(!value, "expected false: " + description);
96 }
97
98 template<typename lhs_type, typename rhs_type>
99 void check_equal(
100 const lhs_type & lhs, const rhs_type & rhs,
101 const std::string & description)
102 {
103 check(lhs == rhs, "expected equal values: " + description);
104 }
105
106 template<typename lhs_type, typename rhs_type>
107 void check_unequal(
108 const lhs_type & lhs, const rhs_type & rhs,
109 const std::string & description)
110 {
111 check(lhs != rhs, "expected unequal values: " + description);
112 }
113
114 inline void check_null(const void * ptr, const std::string & description)
115 {
116 check(!ptr, "expected null pointer: " + description);
117 }
118
119 inline void check_non_null(const void * ptr, const std::string & description)
120 {
121 check(ptr != 0, "expected non-null pointer: " + description);
122 }
123 }
124
125 #define TEST_CHECK_THROW(expression, exception, description) \
126 try \
127 { \
128 expression; \
129 throw ::any_tests::failure(description); \
130 } \
131 catch(exception &) \
132 { \
133 }
134
135 namespace any_tests // memory tracking (enabled if test new and delete linked in)
136 {
137 class allocations
138 {
139 public: // singleton access
140
141 static allocations & instance()
142 {
143 static allocations singleton;
144 return singleton;
145 }
146
147 public: // logging
148
149 void clear()
150 {
151 alloc_count = dealloc_count = 0;
152 }
153
154 void allocation()
155 {
156 ++alloc_count;
157 }
158
159 void deallocation()
160 {
161 ++dealloc_count;
162 }
163
164 public: // reporting
165
166 unsigned long allocated() const
167 {
168 return alloc_count;
169 }
170
171 unsigned long deallocated() const
172 {
173 return dealloc_count;
174 }
175
176 bool balanced() const
177 {
178 return alloc_count == dealloc_count;
179 }
180
181 private: // structors (default dtor is fine)
182
183 allocations()
184 : alloc_count(0), dealloc_count(0)
185 {
186 }
187
188 private: // prevention
189
190 allocations(const allocations &);
191 allocations & operator=(const allocations &);
192
193 private: // state
194
195 unsigned long alloc_count, dealloc_count;
196
197 };
198 }
199
200 namespace any_tests // tester is the driver class for a sequence of tests
201 {
202 template<typename test_iterator>
203 class tester
204 {
205 public: // structors (default destructor is OK)
206
207 tester(test_iterator first_test, test_iterator after_last_test)
208 : begin(first_test), end(after_last_test)
209 {
210 }
211
212 public: // usage
213
214 bool operator()(); // returns true if all tests passed
215
216 private: // representation
217
218 test_iterator begin, end;
219
220 private: // prevention
221
222 tester(const tester &);
223 tester &operator=(const tester &);
224
225 };
226
227 #if defined(__GNUC__) && defined(__SGI_STL_PORT) && (__GNUC__ < 3)
228 // function scope using declarations don't work:
229 using namespace std;
230 #endif
231
232 template<typename test_iterator>
233 bool tester<test_iterator>::operator()()
234 {
235 using std::cerr;
236 using std::endl;
237 using std::ends;
238 using std::exception;
239 using std::flush;
240 using std::string;
241
242 unsigned long passed = 0, failed = 0, unimplemented = 0;
243
244 for(test_iterator current = begin; current != end; ++current)
245 {
246 cerr << "[" << current->name << "] " << flush;
247 string result = "passed"; // optimistic
248
249 try
250 {
251 allocations::instance().clear();
252 current->action();
253
254 if(!allocations::instance().balanced())
255 {
256 unsigned long allocated = allocations::instance().allocated();
257 unsigned long deallocated = allocations::instance().deallocated();
258 #ifdef BOOST_NO_STRINGSTREAM
259 std::ostrstream report;
260 #else
261 std::ostringstream report;
262 #endif
263 report << "new/delete ("
264 << allocated << " allocated, "
265 << deallocated << " deallocated)"
266 << ends;
267 const string text = report.str();
268 #ifdef BOOST_NO_STRINGSTREAM
269 report.freeze(false);
270 #endif
271 throw failure(text);
272 }
273
274 ++passed;
275 }
276 catch(const failure & caught)
277 {
278 (result = "failed: ") += caught.what();
279 ++failed;
280 }
281 catch(const not_implemented &)
282 {
283 result = "not implemented";
284 ++unimplemented;
285 }
286 catch(const exception & caught)
287 {
288 (result = "exception: ") += caught.what();
289 ++failed;
290 }
291 catch(...)
292 {
293 result = "failed with unknown exception";
294 ++failed;
295 }
296
297 cerr << result << endl;
298 }
299
300 cerr << (passed + failed) << " tests: "
301 << passed << " passed, "
302 << failed << " failed";
303
304 if(unimplemented)
305 {
306 cerr << " (" << unimplemented << " not implemented)";
307 }
308
309 cerr << endl;
310
311 return failed == 0;
312 }
313 }
314
315 #endif
316
317 // Copyright Kevlin Henney, 2000. All rights reserved.
318 //
319 // Distributed under the Boost Software License, Version 1.0. (See
320 // accompanying file LICENSE_1_0.txt or copy at
321 // http://www.boost.org/LICENSE_1_0.txt)