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 int err = ngCount_ + exceptionCount_;
90 int total = okCount_ + err;
91 std::cout << "ctest:name=" << getBaseName(*argv)
92 << ", module=" << list_.size()
93 << ", total=" << total
94 << ", ok=" << okCount_
95 << ", ng=" << ngCount_
96 << ", exception=" << exceptionCount_ << std::endl;
97 return err > 0 ? 1 : 0;
98 } else {
99 std::cout << msg << std::endl;
100 return 1;
101 }
102 }
103 static inline AutoRun& getInstance()
104 {
105 static AutoRun instance;
106 return instance;
107 }
108private:
109 Func init_;
110 Func term_;
111 int okCount_;
112 int ngCount_;
113 int exceptionCount_;
114 UnitTestList list_;
115};
116
117static AutoRun& autoRun = AutoRun::getInstance();
118
119inline void test(bool ret, const std::string& msg, const std::string& param, const char *file, int line)
120{
121 autoRun.set(ret);
122 if (!ret) {
123 printf("%s(%d):ctest:%s(%s);\n", file, line, msg.c_str(), param.c_str());
124 }
125}
126
127template<typename T, typename U>
128bool isEqual(const T& lhs, const U& rhs)
129{
130 return lhs == rhs;
131}
132
133// avoid warning of comparision of integers of different signs
134inline bool isEqual(size_t lhs, int rhs)
135{
136 return lhs == size_t(rhs);
137}
138inline bool isEqual(int lhs, size_t rhs)
139{
140 return size_t(lhs) == rhs;
141}
142inline bool isEqual(const char *lhs, const char *rhs)
143{
144 return strcmp(lhs, rhs) == 0;
145}
146inline bool isEqual(char *lhs, const char *rhs)
147{
148 return strcmp(lhs, rhs) == 0;
149}
150inline bool isEqual(const char *lhs, char *rhs)
151{
152 return strcmp(lhs, rhs) == 0;
153}
154inline bool isEqual(char *lhs, char *rhs)
155{
156 return strcmp(lhs, rhs) == 0;
157}
158// avoid to compare float directly
159inline bool isEqual(float lhs, float rhs)
160{
161 union fi {
162 float f;
163 uint32_t i;
164 } lfi, rfi;
165 lfi.f = lhs;
166 rfi.f = rhs;
167 return lfi.i == rfi.i;
168}
169// avoid to compare double directly
170inline bool isEqual(double lhs, double rhs)
171{
172 union di {
173 double d;
174 uint64_t i;
175 } ldi, rdi;
176 ldi.d = lhs;
177 rdi.d = rhs;
178 return ldi.i == rdi.i;
179}
180
181} } // cybozu::test
182
183#ifndef CYBOZU_TEST_DISABLE_AUTO_RUN
184int main(int argc, char *argv[])
185{
186 return cybozu::test::autoRun.run(argc, argv);
187}
188#endif
189
194#define CYBOZU_TEST_ASSERT(x) cybozu::test::test(!!(x), "CYBOZU_TEST_ASSERT", #x, __FILE__, __LINE__)
195
201#define CYBOZU_TEST_EQUAL(x, y) { \
202 bool _cybozu_eq = cybozu::test::isEqual(x, y); \
203 cybozu::test::test(_cybozu_eq, "CYBOZU_TEST_EQUAL", #x ", " #y, __FILE__, __LINE__); \
204 if (!_cybozu_eq) { \
205 std::cout << "ctest: lhs=" << (x) << std::endl; \
206 std::cout << "ctest: rhs=" << (y) << std::endl; \
207 } \
208}
214#define CYBOZU_TEST_NEAR(x, y, eps) { \
215 bool _cybozu_isNear = fabs((x) - (y)) < eps; \
216 cybozu::test::test(_cybozu_isNear, "CYBOZU_TEST_NEAR", #x ", " #y, __FILE__, __LINE__); \
217 if (!_cybozu_isNear) { \
218 std::cout << "ctest: lhs=" << (x) << std::endl; \
219 std::cout << "ctest: rhs=" << (y) << std::endl; \
220 } \
221}
222
223#define CYBOZU_TEST_EQUAL_POINTER(x, y) { \
224 bool _cybozu_eq = x == y; \
225 cybozu::test::test(_cybozu_eq, "CYBOZU_TEST_EQUAL_POINTER", #x ", " #y, __FILE__, __LINE__); \
226 if (!_cybozu_eq) { \
227 std::cout << "ctest: lhs=" << static_cast<const void*>(x) << std::endl; \
228 std::cout << "ctest: rhs=" << static_cast<const void*>(y) << std::endl; \
229 } \
230}
237#define CYBOZU_TEST_EQUAL_ARRAY(x, y, n) { \
238 for (size_t _cybozu_test_i = 0, _cybozu_ie = (size_t)(n); _cybozu_test_i < _cybozu_ie; _cybozu_test_i++) { \
239 bool _cybozu_eq = cybozu::test::isEqual((x)[_cybozu_test_i], (y)[_cybozu_test_i]); \
240 cybozu::test::test(_cybozu_eq, "CYBOZU_TEST_EQUAL_ARRAY", #x ", " #y ", " #n, __FILE__, __LINE__); \
241 if (!_cybozu_eq) { \
242 std::cout << "ctest: i=" << _cybozu_test_i << std::endl; \
243 std::cout << "ctest: lhs=" << (x)[_cybozu_test_i] << std::endl; \
244 std::cout << "ctest: rhs=" << (y)[_cybozu_test_i] << std::endl; \
245 } \
246 } \
247}
248
253#define CYBOZU_TEST_FAIL(msg) cybozu::test::test(false, "CYBOZU_TEST_FAIL", msg, __FILE__, __LINE__)
254
258#define CYBOZU_TEST_EXCEPTION_MESSAGE(statement, Exception, msg) \
259{ \
260 int _cybozu_ret = 0; \
261 std::string _cybozu_errMsg; \
262 try { \
263 statement; \
264 _cybozu_ret = 1; \
265 } catch (const Exception& _cybozu_e) { \
266 _cybozu_errMsg = _cybozu_e.what(); \
267 if (_cybozu_errMsg.find(msg) == std::string::npos) { \
268 _cybozu_ret = 2; \
269 } \
270 } catch (...) { \
271 _cybozu_ret = 3; \
272 } \
273 if (_cybozu_ret) { \
274 cybozu::test::test(false, "CYBOZU_TEST_EXCEPTION_MESSAGE", #statement ", " #Exception ", " #msg, __FILE__, __LINE__); \
275 if (_cybozu_ret == 1) { \
276 std::cout << "ctest: no exception" << std::endl; \
277 } else if (_cybozu_ret == 2) { \
278 std::cout << "ctest: bad exception msg:" << _cybozu_errMsg << std::endl; \
279 } else { \
280 std::cout << "ctest: unexpected exception" << std::endl; \
281 } \
282 } else { \
283 cybozu::test::autoRun.set(true); \
284 } \
285}
286
287#define CYBOZU_TEST_EXCEPTION(statement, Exception) \
288{ \
289 int _cybozu_ret = 0; \
290 try { \
291 statement; \
292 _cybozu_ret = 1; \
293 } catch (const Exception&) { \
294 } catch (...) { \
295 _cybozu_ret = 2; \
296 } \
297 if (_cybozu_ret) { \
298 cybozu::test::test(false, "CYBOZU_TEST_EXCEPTION", #statement ", " #Exception, __FILE__, __LINE__); \
299 if (_cybozu_ret == 1) { \
300 std::cout << "ctest: no exception" << std::endl; \
301 } else { \
302 std::cout << "ctest: unexpected exception" << std::endl; \
303 } \
304 } else { \
305 cybozu::test::autoRun.set(true); \
306 } \
307}
308
312#define CYBOZU_TEST_NO_EXCEPTION(statement) \
313try { \
314 statement; \
315 cybozu::test::autoRun.set(true); \
316} catch (...) { \
317 cybozu::test::test(false, "CYBOZU_TEST_NO_EXCEPTION", #statement, __FILE__, __LINE__); \
318}
319
324#define CYBOZU_TEST_AUTO(name) \
325void cybozu_test_ ## name(); \
326struct cybozu_test_local_ ## name { \
327 cybozu_test_local_ ## name() \
328 { \
329 cybozu::test::autoRun.append(#name, cybozu_test_ ## name); \
330 } \
331} cybozu_test_local_instance_ ## name; \
332void cybozu_test_ ## name()
333
338#define CYBOZU_TEST_AUTO_WITH_FIXTURE(name, Fixture) \
339void cybozu_test_ ## name(); \
340void cybozu_test_real_ ## name() \
341{ \
342 Fixture f; \
343 cybozu_test_ ## name(); \
344} \
345struct cybozu_test_local_ ## name { \
346 cybozu_test_local_ ## name() \
347 { \
348 cybozu::test::autoRun.append(#name, cybozu_test_real_ ## name); \
349 } \
350} cybozu_test_local_instance_ ## name; \
351void cybozu_test_ ## name()
352
358#define CYBOZU_TEST_SETUP_FIXTURE(Fixture) \
359Fixture *cybozu_test_local_fixture; \
360void cybozu_test_local_init() \
361{ \
362 cybozu_test_local_fixture = new Fixture(); \
363} \
364void cybozu_test_local_term() \
365{ \
366 delete cybozu_test_local_fixture; \
367} \
368struct cybozu_test_local_fixture_setup_ { \
369 cybozu_test_local_fixture_setup_() \
370 { \
371 cybozu::test::autoRun.setup(cybozu_test_local_init, cybozu_test_local_term); \
372 } \
373} 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:103
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
static const Reg16 di(Operand::DI)
bool isEqual(const T &lhs, const U &rhs)
Definition test.hpp:126
@ test
Unit testing utility error code.
Definition error.hpp:96
#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