Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
test.hpp
Go to the documentation of this file.
1#pragma once
9#include <stdio.h>
10#include <string.h>
11#include <string>
12#include <list>
13#include <iostream>
14#include <utility>
15#if defined(_MSC_VER) && (MSC_VER <= 1500)
16 #include <cybozu/inttype.hpp>
17#else
18 #include <stdint.h>
19#endif
20
21namespace cybozu { namespace test {
22
23class AutoRun {
24 typedef void (*Func)();
25 typedef std::list<std::pair<const char*, Func> > UnitTestList;
26public:
28 : init_(0)
29 , term_(0)
30 , okCount_(0)
31 , ngCount_(0)
32 , exceptionCount_(0)
33 {
34 }
35 void setup(Func init, Func term)
36 {
37 init_ = init;
38 term_ = term;
39 }
40 void append(const char *name, Func func)
41 {
42 list_.push_back(std::make_pair(name, func));
43 }
44 void set(bool isOK)
45 {
46 if (isOK) {
47 okCount_++;
48 } else {
49 ngCount_++;
50 }
51 }
52 std::string getBaseName(const std::string& name) const
53 {
54#ifdef _WIN32
55 const char sep = '\\';
56#else
57 const char sep = '/';
58#endif
59 size_t pos = name.find_last_of(sep);
60 std::string ret = name.substr(pos + 1);
61 pos = ret.find('.');
62 return ret.substr(0, pos);
63 }
64 int run(int, char *argv[])
65 {
66 std::string msg;
67 try {
68 if (init_) init_();
69 for (UnitTestList::const_iterator i = list_.begin(), ie = list_.end(); i != ie; ++i) {
70 std::cout << "ctest:module=" << i->first << std::endl;
71 try {
72 (i->second)();
73 } catch (std::exception& e) {
74 exceptionCount_++;
75 std::cout << "ctest: " << i->first << " is stopped by exception " << e.what() << std::endl;
76 } catch (...) {
77 exceptionCount_++;
78 std::cout << "ctest: " << i->first << " is stopped by unknown exception" << std::endl;
79 }
80 }
81 if (term_) term_();
82 } catch (std::exception& e) {
83 msg = std::string("ctest:err:") + e.what();
84 } catch (...) {
85 msg = "ctest:err: catch unknown exception";
86 }
87 fflush(stdout);
88 if (msg.empty()) {
89 std::cout << "ctest:name=" << getBaseName(*argv)
90 << ", module=" << list_.size()
91 << ", total=" << (okCount_ + ngCount_ + exceptionCount_)
92 << ", ok=" << okCount_
93 << ", ng=" << ngCount_
94 << ", exception=" << exceptionCount_ << std::endl;
95 return 0;
96 } else {
97 std::cout << msg << std::endl;
98 return 1;
99 }
100 }
101 static inline AutoRun& getInstance()
102 {
103 static AutoRun instance;
104 return instance;
105 }
106private:
107 Func init_;
108 Func term_;
109 int okCount_;
110 int ngCount_;
111 int exceptionCount_;
112 UnitTestList list_;
113};
114
115static AutoRun& autoRun = AutoRun::getInstance();
116
117inline void test(bool ret, const std::string& msg, const std::string& param, const char *file, int line)
118{
119 autoRun.set(ret);
120 if (!ret) {
121 printf("%s(%d):ctest:%s(%s);\n", file, line, msg.c_str(), param.c_str());
122 }
123}
124
125template<typename T, typename U>
126bool isEqual(const T& lhs, const U& rhs)
127{
128 return lhs == rhs;
129}
130
131// avoid warning of comparision of integers of different signs
132inline bool isEqual(size_t lhs, int rhs)
133{
134 return lhs == size_t(rhs);
135}
136inline bool isEqual(int lhs, size_t rhs)
137{
138 return size_t(lhs) == rhs;
139}
140inline bool isEqual(const char *lhs, const char *rhs)
141{
142 return strcmp(lhs, rhs) == 0;
143}
144inline bool isEqual(char *lhs, const char *rhs)
145{
146 return strcmp(lhs, rhs) == 0;
147}
148inline bool isEqual(const char *lhs, char *rhs)
149{
150 return strcmp(lhs, rhs) == 0;
151}
152inline bool isEqual(char *lhs, char *rhs)
153{
154 return strcmp(lhs, rhs) == 0;
155}
156// avoid to compare float directly
157inline bool isEqual(float lhs, float rhs)
158{
159 union fi {
160 float f;
161 uint32_t i;
162 } lfi, rfi;
163 lfi.f = lhs;
164 rfi.f = rhs;
165 return lfi.i == rfi.i;
166}
167// avoid to compare double directly
168inline bool isEqual(double lhs, double rhs)
169{
170 union di {
171 double d;
172 uint64_t i;
173 } ldi, rdi;
174 ldi.d = lhs;
175 rdi.d = rhs;
176 return ldi.i == rdi.i;
177}
178
179} } // cybozu::test
180
181#ifndef CYBOZU_TEST_DISABLE_AUTO_RUN
182int main(int argc, char *argv[])
183{
184 return cybozu::test::autoRun.run(argc, argv);
185}
186#endif
187
192#define CYBOZU_TEST_ASSERT(x) cybozu::test::test(!!(x), "CYBOZU_TEST_ASSERT", #x, __FILE__, __LINE__)
193
199#define CYBOZU_TEST_EQUAL(x, y) { \
200 bool eq = cybozu::test::isEqual(x, y); \
201 cybozu::test::test(eq, "CYBOZU_TEST_EQUAL", #x ", " #y, __FILE__, __LINE__); \
202 if (!eq) { \
203 std::cout << "ctest: lhs=" << (x) << std::endl; \
204 std::cout << "ctest: rhs=" << (y) << std::endl; \
205 } \
206}
212#define CYBOZU_TEST_NEAR(x, y, eps) { \
213 bool isNear = fabs((x) - (y)) < eps; \
214 cybozu::test::test(isNear, "CYBOZU_TEST_NEAR", #x ", " #y, __FILE__, __LINE__); \
215 if (!isNear) { \
216 std::cout << "ctest: lhs=" << (x) << std::endl; \
217 std::cout << "ctest: rhs=" << (y) << std::endl; \
218 } \
219}
220
221#define CYBOZU_TEST_EQUAL_POINTER(x, y) { \
222 bool eq = x == y; \
223 cybozu::test::test(eq, "CYBOZU_TEST_EQUAL_POINTER", #x ", " #y, __FILE__, __LINE__); \
224 if (!eq) { \
225 std::cout << "ctest: lhs=" << static_cast<const void*>(x) << std::endl; \
226 std::cout << "ctest: rhs=" << static_cast<const void*>(y) << std::endl; \
227 } \
228}
235#define CYBOZU_TEST_EQUAL_ARRAY(x, y, n) { \
236 for (size_t i = 0, ie = (size_t)(n); i < ie; i++) { \
237 bool eq = cybozu::test::isEqual(x, y); \
238 cybozu::test::test(eq, "CYBOZU_TEST_EQUAL_ARRAY", #x ", " #y, __FILE__, __LINE__); \
239 if (!eq) { \
240 std::cout << "ctest: i=" << i << std::endl; \
241 std::cout << "ctest: lhs=" << (x) << std::endl; \
242 std::cout << "ctest: rhs=" << (y) << std::endl; \
243 } \
244 } \
245}
246
251#define CYBOZU_TEST_FAIL(msg) cybozu::test::test(false, "CYBOZU_TEST_FAIL", msg, __FILE__, __LINE__)
252
256#define CYBOZU_TEST_EXCEPTION_MESSAGE(statement, Exception, msg) \
257{ \
258 int ret = 0; \
259 std::string errMsg; \
260 try { \
261 statement; \
262 ret = 1; \
263 } catch (const Exception& e) { \
264 errMsg = e.what(); \
265 if (errMsg.find(msg) == std::string::npos) { \
266 ret = 2; \
267 } \
268 } catch (...) { \
269 ret = 3; \
270 } \
271 if (ret) { \
272 cybozu::test::test(false, "CYBOZU_TEST_EXCEPTION_MESSAGE", #statement ", " #Exception ", " #msg, __FILE__, __LINE__); \
273 if (ret == 1) { \
274 std::cout << "ctest: no exception" << std::endl; \
275 } else if (ret == 2) { \
276 std::cout << "ctest: bad exception msg:" << errMsg << std::endl; \
277 } else { \
278 std::cout << "ctest: unexpected exception" << std::endl; \
279 } \
280 } else { \
281 cybozu::test::autoRun.set(true); \
282 } \
283}
284
285#define CYBOZU_TEST_EXCEPTION(statement, Exception) \
286{ \
287 int ret = 0; \
288 try { \
289 statement; \
290 ret = 1; \
291 } catch (const Exception&) { \
292 } catch (...) { \
293 ret = 2; \
294 } \
295 if (ret) { \
296 cybozu::test::test(false, "CYBOZU_TEST_EXCEPTION", #statement ", " #Exception, __FILE__, __LINE__); \
297 if (ret == 1) { \
298 std::cout << "ctest: no exception" << std::endl; \
299 } else { \
300 std::cout << "ctest: unexpected exception" << std::endl; \
301 } \
302 } else { \
303 cybozu::test::autoRun.set(true); \
304 } \
305}
306
310#define CYBOZU_TEST_NO_EXCEPTION(statement) \
311try { \
312 statement; \
313 cybozu::test::autoRun.set(true); \
314} catch (...) { \
315 cybozu::test::test(false, "CYBOZU_TEST_NO_EXCEPTION", #statement, __FILE__, __LINE__); \
316}
317
322#define CYBOZU_TEST_AUTO(name) \
323void cybozu_test_ ## name(); \
324struct cybozu_test_local_ ## name { \
325 cybozu_test_local_ ## name() \
326 { \
327 cybozu::test::autoRun.append(#name, cybozu_test_ ## name); \
328 } \
329} cybozu_test_local_instance_ ## name; \
330void cybozu_test_ ## name()
331
336#define CYBOZU_TEST_AUTO_WITH_FIXTURE(name, Fixture) \
337void cybozu_test_ ## name(); \
338void cybozu_test_real_ ## name() \
339{ \
340 Fixture f; \
341 cybozu_test_ ## name(); \
342} \
343struct cybozu_test_local_ ## name { \
344 cybozu_test_local_ ## name() \
345 { \
346 cybozu::test::autoRun.append(#name, cybozu_test_real_ ## name); \
347 } \
348} cybozu_test_local_instance_ ## name; \
349void cybozu_test_ ## name()
350
356#define CYBOZU_TEST_SETUP_FIXTURE(Fixture) \
357Fixture *cybozu_test_local_fixture; \
358void cybozu_test_local_init() \
359{ \
360 cybozu_test_local_fixture = new Fixture(); \
361} \
362void cybozu_test_local_term() \
363{ \
364 delete cybozu_test_local_fixture; \
365} \
366struct cybozu_test_local_fixture_setup_ { \
367 cybozu_test_local_fixture_setup_() \
368 { \
369 cybozu::test::autoRun.setup(cybozu_test_local_init, cybozu_test_local_term); \
370 } \
371} cybozu_test_local_fixture_setup_instance_;
std::string name
void append(const char *name, Func func)
Definition test.hpp:40
std::string getBaseName(const std::string &name) const
Definition test.hpp:52
void setup(Func init, Func term)
Definition test.hpp:35
static AutoRun & getInstance()
Definition test.hpp:101
int run(int, char *argv[])
Definition test.hpp:64
void set(bool isOK)
Definition test.hpp:44
char ** argv
void init()
Definition lib_test.cpp:3
bool isEqual(const T &lhs, const U &rhs)
Definition test.hpp:126
#define T(meth, val, expected)
unsigned int uint32_t
Definition stdint.h:126
unsigned __int64 uint64_t
Definition stdint.h:136
Definition dtoa.c:306
CK_ULONG d
CK_RV ret