si_test.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. #ifndef _TEST_H_
  2. #define _TEST_H_
  3. /* Simple unit testing.*/
  4. struct Test_ ;
  5. typedef struct Test_ Test;
  6. struct Test_ {
  7. int count;
  8. int ok;
  9. int failed;
  10. };
  11. /*
  12. * The header file carries it's own implementation around,
  13. * which is fine for simple test programs.
  14. */
  15. #ifndef TESTING_NO_IMPLEMENTATION
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <stdarg.h>
  19. #include <string.h>
  20. #include <math.h>
  21. // some cute ANSI colors, can be disabled by defining TESTING_NO_ANSI
  22. #ifndef TESTING_NO_ANSI
  23. #define TEST_ANSI_R(S) ("\033[1;31m" S "\033[0m")
  24. #define TEST_ANSI_G(S) ("\033[1;32m" S "\033[0m")
  25. #define TEST_ANSI_Y(S) ("\033[1;33m" S "\033[0m")
  26. #else
  27. #define TEST_ANSI_R(S) (S)
  28. #define TEST_ANSI_G(S) (S)
  29. #define TEST_ANSI_Y(S) (S)
  30. #endif
  31. #define TEST_UNUSED(x) ((void)(x))
  32. /* Epsilon for double and float comparisons*/
  33. #ifndef TEST_DOUBLE_EPSILON
  34. #define TEST_DOUBLE_EPSILON 0.0000000001
  35. #endif
  36. #ifndef TEST_FLOAT_EPSILON
  37. #define TEST_FLOAT_EPSILON 0.0000001
  38. #endif
  39. /** Initializes the test. */
  40. static Test * test_init(Test * test) {
  41. test->failed = test->ok = test->count = 0;
  42. return test;
  43. }
  44. /** Adds one OK test.*/
  45. static Test * test_ok(Test * test) {
  46. test->count ++;
  47. test->ok ++;
  48. return test;
  49. }
  50. /** Fails one test with variable arguments. */
  51. static Test * test_fail_va(Test * test, const char * fmt, va_list ap) {
  52. test->count ++;
  53. test->failed++;
  54. fprintf(stderr, TEST_ANSI_R("Test %d failed: "), test->count);
  55. vfprintf(stderr, fmt, ap);
  56. fprintf(stderr, "\n");
  57. return test;
  58. }
  59. /** Fails one test. */
  60. static Test * test_fail(Test * test, const char * fmt, ...) {
  61. va_list ap;
  62. va_start(ap, fmt);
  63. test_fail_va(test, fmt, ap);
  64. va_end(ap);
  65. return test;
  66. }
  67. /**
  68. Reports the results of the tests. Retuns nonzero if there were errors, zero if no errors, so it can be called in main as return test_report(&test);
  69. */
  70. static int test_report(Test * test) {
  71. if (test->ok == test->count) {
  72. fprintf(stderr, TEST_ANSI_G("SUCCESS: %d/%d \n"), test->ok, test->count);
  73. return 0;
  74. } else {
  75. fprintf(stderr, TEST_ANSI_R("FAILED: %d/%d \n"), test->ok, test->count);
  76. return 1;
  77. }
  78. }
  79. /** Tests if an assertion is true with variable arguments. */
  80. static Test * test_assert_va(Test * test, int assert, const char * fmt,
  81. va_list ap) {
  82. if(assert) { // if the assertion is true
  83. test_ok(test);
  84. } else {
  85. test_fail_va(test, fmt, ap);
  86. }
  87. return test;
  88. }
  89. /** Tests if a certain asertion is true, failing if it false. */
  90. static Test * test_assert(Test * test, int assert, const char * fmt, ...) {
  91. va_list ap;
  92. va_start(ap, fmt);
  93. test_assert_va(test, assert, fmt, ap);
  94. va_end(ap);
  95. return test;
  96. }
  97. /** Tests if a pointer is null, faling the test if it's not so. */
  98. static Test * test_null(Test * test, void * ptr, const char * explain) {
  99. return test_assert(test, ptr == NULL,
  100. "Pointer should be null: %p; %s", ptr, explain);
  101. }
  102. /** Tests if a pointer is not null, faling the test if it is NULL. */
  103. static Test * test_notnull(Test * test, void * ptr, const char * explain) {
  104. return test_assert(test, ptr != NULL,
  105. "Pointer should be not null: %p; %s", ptr, explain);
  106. }
  107. /** Tests if two strings are equal according to strcmp. */
  108. static Test * test_streq(Test * test, char * s1, char * s2, const char * explain) {
  109. return test_assert(test, strcmp(s1, s2) == 0,
  110. "Strings should be equal: >%s< >%s<; %s ", s1, s2, explain);
  111. }
  112. /** Tests if two strings are equal according to strncmp. */
  113. static Test * test_streqn(Test * test, char * s1, size_t n, char * s2,
  114. const char * explain) {
  115. return test_assert(test, strncmp(s1, s2, n) == 0,
  116. "Strings should be equal: >%s< >%s<; %s ", s1, s2, explain);
  117. }
  118. /** Tests if two memory areas are equal according to memcmp. */
  119. static Test * test_memeq(Test * test, void * m1, size_t n, void * m2,
  120. const char * explain) {
  121. if(!m2) return test_fail(test,
  122. "Memory should be equal but pointer was null: %p %p; %s", m1, m2, explain);
  123. return test_assert(test, memcmp(m1, m2, n) == 0,
  124. "Memory should be equal: %p %p; %s ", m1, m2, explain);
  125. }
  126. /** Tests if two pointers are equal */
  127. static Test * test_ptreq(Test * test, void *p1, void * p2, const char * explain)
  128. {
  129. return test_assert(test, p1 == p2,
  130. "Pointers should be equal: %p %p; %s ", p1, p2, explain);
  131. }
  132. /** Tests if two pointers are unequal */
  133. static Test * test_ptrneq(Test * test, void *p1, void * p2,
  134. const char * explain) {
  135. return test_assert(test, p1 != p2,
  136. "Pointers should not be equall: %p %p; %s ", p1, p2, explain);
  137. }
  138. /** Tests if two integers are equal */
  139. static Test * test_inteq(Test * test, int i1, int i2, const char * explain) {
  140. return test_assert(test, i1 == i2,
  141. "Integers should be equal: %d %d; %s ", i1, i2, explain);
  142. }
  143. /** Tests if two integers are not equal */
  144. static Test * test_intneq(Test * test, int i1, int i2, const char * explain) {
  145. return test_assert(test, i1 != i2,
  146. "Integers should not be equal: %d %d; %s ", i1, i2, explain);
  147. }
  148. /** Tests if two long integers are equal */
  149. static Test * test_longeq(Test * test, long i1, long i2, const char * explain) {
  150. return test_assert(test, i1 == i2,
  151. "Integers should be equal: %ld %ld; %s ", i1, i2, explain);
  152. }
  153. /** Tests if two long integers are not equal */
  154. static Test * test_longneq(Test * test, long i1, long i2, const char * explain) {
  155. return test_assert(test, i1 != i2,
  156. "Integers should not be equal: %ld %ld; %s ", i1, i2, explain);
  157. }
  158. /** Tests if two doubles are equal within TEST_DOUBLE_EPSILON */
  159. static Test * test_doubleeq(Test * test, double d1, double d2, const char * explain) {
  160. double delta = fabs(d2 - d1);
  161. return test_assert(test, delta < TEST_DOUBLE_EPSILON,
  162. "Doubles should not be equal: %lf %lf; %s ", d1, d2, explain);
  163. }
  164. /** Tests if two doubles are not more different than TEST_DOUBLE_EPSILON */
  165. static Test * test_doubleneq(Test * test, double d1, double d2, const char * explain) {
  166. double delta = fabs(d2 - d1);
  167. return test_assert(test, delta >= TEST_DOUBLE_EPSILON,
  168. "Doubles should not be equal: %lf %lf; %s ", d1, d2, explain);
  169. }
  170. /** Tests if two floats are equal within TEST_FLOAT_EPSILON */
  171. static Test * test_floateq(Test * test, float d1, float d2, const char * explain) {
  172. float delta = fabsf(d2 - d1);
  173. return test_assert(test, delta < TEST_FLOAT_EPSILON,
  174. "Doubles should not be equal: %lf %lf; %s ", d1, d2, explain);
  175. }
  176. /** Tests if two floats are not more different than TEST_FLOAT_EPSILON */
  177. static Test * test_floatneq(Test * test, float d1, float d2, const char * explain) {
  178. float delta = fabsf(d2 - d1);
  179. return test_assert(test, delta >= TEST_FLOAT_EPSILON,
  180. "Doubles should not be equal: %lf %lf; %s ", d1, d2, explain);
  181. }
  182. /** Tests if an integer has a true value */
  183. static Test * test_true(Test * test, int boole, const char * explain) {
  184. return test_assert(test, boole,
  185. "Boolean should be TRUE: %d; %s ", boole, explain);
  186. }
  187. /** Tests if an integer has a false value */
  188. static Test * test_false(Test * test, int boole, const char * explain) {
  189. return test_assert(test, (!boole),
  190. "Boolean should be FALSE: %d; %s ", boole, explain);
  191. }
  192. /** This only exists to supress spurious compiler warnings. */
  193. static Test * warning_supressor(Test * test) {
  194. if(!test) return NULL;
  195. test_streq(test, "", "", "");
  196. test_streqn(test, "", 0, "", "");
  197. test_memeq(test, "", 0, "", "");
  198. test_inteq(test, 0, 0, "");
  199. test_intneq(test, 0, 0, "");
  200. test_true(test, 0, "");
  201. test_false(test, 0, "");
  202. test_null(test, 0, "");
  203. test_notnull(test, 0, "");
  204. test_ptreq(test, NULL, NULL, "");
  205. test_ptrneq(test, NULL, NULL, "");
  206. TEST_UNUSED(warning_supressor);
  207. return test_fail(test, "");
  208. }
  209. /* Macros to help with calling tested functions.
  210. * Important notice: these macros assume that a Test * _t exists.
  211. */
  212. #define PP_TOSTR_AID(VAL) #VAL
  213. #define PP_TOSTR(VAL) PP_TOSTR_AID(VAL)
  214. #define PP_PASTE(FIRST, SECOND) FIRST##SECOND
  215. #define PP_JOINSTR(FIRST, SECOND) (FIRST SECOND)
  216. #define PP_JOINSTR3(A1, A2, A3) (A1 A2 A3)
  217. #define PP_LINE_STR() PP_TOSTR(__LINE__)
  218. #define PP_FILE_STR() PP_TOSTR(__FILE__)
  219. #define PP_LONGLINE_STR() PP_JOINSTR(" line nr:", PP_LINE_STR())
  220. #define TEST_LINE(CALL) \
  221. PP_JOINSTR(PP_TOSTR(CALL), " " PP_FILE_STR() " line nr:" PP_LINE_STR())
  222. #define TEST_CAID(CALL, TEXT) CALL,TEXT
  223. #define TEST_CALL(CALL) TEST_CAID(CALL, TEST_LINE(CALL))
  224. #define TEST_TRUE(CALL) test_true(_t, (int)TEST_CALL(CALL))
  225. #define TEST_FALSE(CALL) test_false(_t, (int)TEST_CALL(CALL))
  226. #define TEST_ASSERT(CALL) test_assert(_t, TEST_CALL(CALL))
  227. #define TEST_NULL(CALL) test_null(_t, TEST_CALL(CALL))
  228. #define TEST_NOTNULL(CALL) test_notnull(_t, TEST_CALL(CALL))
  229. #define TEST_STREQ(STR, CALL) \
  230. test_streq(_t, (char *)STR, (char *)TEST_CALL(CALL))
  231. #define TEST_STREQN(STR, SIZE, CALL) \
  232. test_streqn(_t, (char *)STR, SIZE, (char *)TEST_CALL(CALL))
  233. #define TEST_MEMEQ(MEM, SIZE, CALL) test_memeq(_t, MEM, SIZE,TEST_CALL(CALL))
  234. #define TEST_PTREQ(PTR, CALL) test_ptreq(_t, PTR, TEST_CALL(CALL))
  235. #define TEST_PTRNEQ(PTR, CALL) test_ptrneq(_t, PTR, TEST_CALL(CALL))
  236. #define TEST_INTEQ(INT, CALL) test_inteq(_t, INT, TEST_CALL(CALL))
  237. #define TEST_INTNEQ(INT, CALL) test_intneq(_t, INT, TEST_CALL(CALL))
  238. #define TEST_LONGEQ(INT, CALL) test_longeq(_t, INT, TEST_CALL(CALL))
  239. #define TEST_LONGNEQ(INT, CALL) test_longneq(_t, INT, TEST_CALL(CALL))
  240. #define TEST_DOUBLEEQ(INT, CALL) test_doubleeq(_t, INT, TEST_CALL(CALL))
  241. #define TEST_DOUBLENEQ(INT, CALL) test_doubleneq(_t, INT, TEST_CALL(CALL))
  242. #define TEST_FLOATEQ(INT, CALL) test_floateq(_t, INT, TEST_CALL(CALL))
  243. #define TEST_FLOATNEQ(INT, CALL) test_floatneq(_t, INT, TEST_CALL(CALL))
  244. #define TEST_ZERO(CALL) TEST_INTEQ(0, CALL)
  245. /* Other utility macros. They are syntactic, so you may dislike them.
  246. But, they are very handy for unit testing C. :)
  247. */
  248. #define TEST_FUNC(NAME) Test * test_##NAME(Test * _t)
  249. #define TEST_DONE() return _t
  250. #define TEST_RUN(NAME) test_##NAME(_t)
  251. #define TEST_INIT() Test _st ; Test * _t ; _t = &_st ; test_init(_t)
  252. #define TEST_REPORT() return test_report(_t);
  253. #endif
  254. #endif