tester.hxx 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. #ifndef TESTER_HPP
  2. #define TESTER_HPP
  3. #include <iostream>
  4. #include <iomanip>
  5. #include <thread>
  6. #include <csignal>
  7. #ifndef __FUNCTION_NAME__
  8. #if defined (WIN32) || defined (_WIN32) || defined (_WIN64) || defined (__CYGWIN__) //WINDOWS
  9. #define __FUNCTION_NAME__ __FUNCTION__
  10. #else //*NIX
  11. #define __FUNCTION_NAME__ __func__
  12. #endif
  13. #endif
  14. #if defined (_WIN32) || defined (_WIN64) || defined (__CYGWIN__)
  15. #define IF_WINDOWS(expression) expression
  16. #define IF_LINUX(expression)
  17. #define IF_UNIX(expression)
  18. #define IF_ONLY_UNIX(expression)
  19. #define IF_MAC_OS_X(expression)
  20. #define IF_FREEBSD(expression)
  21. #define IF_ANDROID(expression)
  22. #define OS_TYPE "Windows"
  23. #elif defined (__linux__) || defined (linux) || defined (__linux)
  24. #define IF_WINDOWS(expression)
  25. #define IF_LINUX(expression) expression
  26. #define IF_UNIX(expression) expression
  27. #define IF_ONLY_UNIX(expression)
  28. #define IF_MAC_OS_X(expression)
  29. #define IF_FREEBSD(expression)
  30. #define IF_ANDROID(expression)
  31. #define OS_TYPE "Linux"
  32. #elif defined (unix) || defined (__unix) || defined (__unix__)
  33. #define IF_WINDOWS(expression)
  34. #define IF_LINUX(expression)
  35. #define IF_UNIX(expression) expression
  36. #define IF_ONLY_UNIX(expression) expression
  37. #define IF_MAC_OS_X(expression)
  38. #define IF_FREEBSD(expression)
  39. #define IF_ANDROID(expression)
  40. #define OS_TYPE "Unix"
  41. #elif defined(__APPLE__) || defined(__MACH__)
  42. #define IF_WINDOWS(expression)
  43. #define IF_LINUX(expression)
  44. #define IF_UNIX(expression) expression
  45. #define IF_ONLY_UNIX(expression)
  46. #define IF_MAC_OS_X(expression) expression
  47. #define IF_FREEBSD(expression)
  48. #define IF_ANDROID(expression)
  49. #define OS_TYPE "Max OS X"
  50. #elif defined(__FreeBSD__)
  51. #define IF_WINDOWS(expression)
  52. #define IF_LINUX(expression)
  53. #define IF_UNIX(expression) expression
  54. #define IF_ONLY_UNIX(expression)
  55. #define IF_MAC_OS_X(expression)
  56. #define IF_FREEBSD(expression) expression
  57. #define IF_ANDROID(expression)
  58. #define OS_TYPE "FreeBSD"
  59. #elif defined(__ANDROID__)
  60. #define IF_WINDOWS(expression)
  61. #define IF_LINUX(expression)
  62. #define IF_UNIX(expression) expression
  63. #define IF_ONLY_UNIX(expression)
  64. #define IF_MAC_OS_X(expression)
  65. #define IF_FREEBSD(expression)
  66. #define IF_ANDROID(expression) expression
  67. #define OS_TYPE "Android"
  68. #else
  69. #define IF_WINDOWS(expression)
  70. #define IF_LINUX(expression)
  71. #define IF_UNIX(expression)
  72. #define IF_ONLY_UNIX(expression)
  73. #define IF_MAC_OS_X(expression)
  74. #define IF_FREEBSD(expression)
  75. #define IF_ANDROID(expression)
  76. #define OS_TYPE "Unknown"
  77. #endif
  78. #ifdef TEST_FULL_INFO
  79. #define INFO << "(@path: " __FILE__ ":" << __LINE__ << " @func: " << __FUNCTION_NAME__ << " @thread: #" << std::hex << std::this_thread::get_id() << std::dec << ") "
  80. #else
  81. #define INFO
  82. #endif
  83. extern thread_local size_t log_depth;
  84. #define GRP_PUSH ++log_depth;
  85. #define GRP_POP if(log_depth) std::cout << std::string(log_depth - 1, '|') << "+---\n\r"; std::cout.flush(); --log_depth;
  86. #define GRP(expression) GRP_PUSH expression GRP_POP
  87. // Test utilits
  88. #define SEPARATOR std::cout << "\x1B[97m=============================================================================\033[0m\n\r"; std::cout.flush();
  89. #define PRINT_RUN(expression) \
  90. std::cout << std::string(log_depth, '|') INFO << "\x1B[93m[r]\x1B[33m: " << #expression << "\033[0m\n\r"; std::cout.flush(); \
  91. expression
  92. #define TEST_ANNOUNCE(MSG) \
  93. std::cout << std::string(log_depth, '|') INFO << "[T]: " #MSG << "\033[0m\n\r"; std::cout.flush();
  94. #define NORMAL_TXT "\033[0m"
  95. #define WHITE_TXT "\x1B[97m"
  96. #define RED_TXT "\x1B[97;101m"
  97. #define GREEN_TXT "\x1B[32m"
  98. #define LOG(INF) \
  99. std::cout << std::string(log_depth, '|') INFO << "\x1B[94m[i]\x1B[34m: " << INF << "\033[0m\n\r"; std::cout.flush();
  100. #ifdef EXIT_ON_FAILURE
  101. #define FAILURE_TEST_EXIT std::exit(-1);
  102. #else
  103. #define FAILURE_TEST_EXIT
  104. #endif
  105. #define TEST(expression) \
  106. if(static_cast<bool>(expression)) { \
  107. std::cout << std::string(log_depth, '|') INFO << "\x1B[92m[✓]\x1B[32m: " << #expression << "\033[0m\n\r"; std::cout.flush(); \
  108. } else { \
  109. std::cout << std::string(log_depth, '|') INFO << "\x1B[97;41m[✗]\x1B[97;101m: " << #expression << "\033[0m\n\r"; std::cout.flush(); \
  110. __test_init.is_success = false; \
  111. std::cout.flush(); \
  112. FAILURE_TEST_EXIT \
  113. }
  114. #define TEST_LEGEND \
  115. std::cout << "Test legend:\n\r" \
  116. "\x1B[93m[r]\033[0m - running line of code\n\r" \
  117. "\033[107;30m[T]\033[0m - test announce\n\r" \
  118. "\x1B[94m[i]\033[0m - log\n\r" \
  119. "\x1B[92m[✓]\033[0m - passed test\n\r" \
  120. "\x1B[97;41m[✗]\033[0m - failed test\n\r"; \
  121. std::cout.flush();
  122. [[noreturn]] void __signal_handler(int signum);
  123. inline struct __TestInit {
  124. bool is_success = true;
  125. __TestInit() {
  126. signal(SIGILL, __signal_handler);
  127. signal(SIGFPE, __signal_handler);
  128. signal(SIGSEGV, __signal_handler);
  129. signal(SIGTERM, __signal_handler);
  130. signal(SIGABRT, __signal_handler);
  131. std::cout << "\033[102;30m+---------------------------------------------------------------------------+\033[0m\n\r"
  132. "\033[102;30m| Test started |\033[0m\n\r"
  133. "\033[102;30m+---------------------------------------------------------------------------+\033[0m\n\r";
  134. SEPARATOR
  135. std::cout << "OS: " << OS_TYPE << "\n\r"; std::cout.flush();
  136. SEPARATOR
  137. TEST_LEGEND
  138. }
  139. ~__TestInit() {
  140. SEPARATOR
  141. std::cout << "OS: " << OS_TYPE << "\n\r"; std::cout.flush();
  142. SEPARATOR
  143. TEST_LEGEND
  144. SEPARATOR
  145. if(is_success)
  146. std::cout << "\033[102;30m+---------------------------------------------------------------------------+\033[0m\n\r"
  147. "\033[102;30m| Test ended success! |\033[0m\n\r"
  148. "\033[102;30m+---------------------------------------------------------------------------+\033[0m\n\r";
  149. else
  150. std::cout << "\033[101;31m+---------------------------------------------------------------------------+\033[0m\n\r"
  151. "\033[101;31m| Test ended with error! |\033[0m\n\r"
  152. "\033[101;31m+---------------------------------------------------------------------------+\033[0m\n\r";
  153. std::cout.flush();
  154. }
  155. } __test_init;
  156. extern class RAIIPerfomanceTest {
  157. clock_t start_time;
  158. const char* msg;
  159. public:
  160. RAIIPerfomanceTest(const char* msg = "") : start_time(clock()), msg(msg) {}
  161. RAIIPerfomanceTest(const RAIIPerfomanceTest&) = delete;
  162. RAIIPerfomanceTest(RAIIPerfomanceTest&& other) : start_time(other.start_time), msg(other.msg) {}
  163. ~RAIIPerfomanceTest() {
  164. double time = double( clock() - start_time ) / (double)CLOCKS_PER_SEC;
  165. if(!start_time) return;
  166. std::cout << std::string(log_depth, '|') << msg << time << " second(s).\033[0m" << std::endl;
  167. std::cout.flush();
  168. }
  169. } __test_perf;
  170. #endif // TESTER_HPP