Test.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. #include "Test.h"
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include "core/Logger.h"
  6. typedef struct {
  7. char* file;
  8. int tests;
  9. int successTests;
  10. } Result;
  11. static Result* results = nullptr;
  12. static size_t resultsIndex = 0;
  13. static size_t resultsCapacity = 0;
  14. static Result* getResult(const char* file) {
  15. for(size_t i = 0; i < resultsIndex; i++) {
  16. Result* r = results + i;
  17. if(strcmp(r->file, file) == 0) {
  18. return r;
  19. }
  20. }
  21. while(resultsIndex >= resultsCapacity) {
  22. size_t newCapacity = resultsCapacity == 0 ? 8 : resultsCapacity * 2;
  23. results = realloc(results, newCapacity * sizeof(Result));
  24. if(results == nullptr) {
  25. printf("realloc failure in '%s' at '%d'\n", __FILE__, __LINE__);
  26. exit(1);
  27. }
  28. resultsCapacity = newCapacity;
  29. }
  30. Result* r = results + (resultsIndex++);
  31. r->file = strdup(file);
  32. r->successTests = 0;
  33. r->tests = 0;
  34. return r;
  35. }
  36. void coreFinalizeTests(void) {
  37. for(size_t i = 0; i < resultsIndex; i++) {
  38. Result* r = results + i;
  39. bool c = r->successTests == r->tests;
  40. fputs(c ? CORE_TERMINAL_GREEN : CORE_TERMINAL_RED, stdout);
  41. printf("%s - %d / %d tests succeeded", r->file, r->successTests,
  42. r->tests);
  43. puts(CORE_TERMINAL_RESET);
  44. free(r->file);
  45. }
  46. free(results);
  47. results = nullptr;
  48. resultsIndex = 0;
  49. resultsCapacity = 0;
  50. }
  51. static bool addToResult(const char* file, bool comparison) {
  52. Result* r = getResult(file);
  53. r->tests++;
  54. if(comparison) {
  55. r->successTests++;
  56. return true;
  57. }
  58. return false;
  59. }
  60. #define CORE_TEST_SUCCESS(result) \
  61. file = coreGetShortFileName(file); \
  62. if(addToResult(file, result)) { \
  63. return true; \
  64. }
  65. #define CORE_TEST_NAMED_COMPARE(name, type, format) \
  66. bool coreTest##name(CORE_TEST_ARGS, type wanted, type actual) { \
  67. CORE_TEST_SUCCESS(wanted == actual) \
  68. fputs(CORE_TERMINAL_RED, stdout); \
  69. printf("%s:%d - expected '" format "' got '" format "'", file, line, \
  70. wanted, actual); \
  71. puts(CORE_TERMINAL_RESET); \
  72. return false; \
  73. }
  74. CORE_TEST_NAMED_COMPARE(Int, int, "%d")
  75. CORE_TEST_NAMED_COMPARE(I64, i64, "%ld")
  76. CORE_TEST_NAMED_COMPARE(U64, u64, "%lu")
  77. CORE_TEST_NAMED_COMPARE(Size, size_t, "%zu")
  78. CORE_TEST_NAMED_COMPARE(Bool, bool, "%d")
  79. bool coreTestString(CORE_TEST_ARGS, const char* wanted, const char* actual) {
  80. CORE_TEST_SUCCESS(strcmp(wanted, actual) == 0);
  81. fputs(CORE_TERMINAL_RED, stdout);
  82. printf("%s:%d - expected '%s' got '%s'", file, line, wanted, actual);
  83. puts(CORE_TERMINAL_RESET);
  84. return false;
  85. }
  86. bool coreTestFloat(CORE_TEST_ARGS, float wanted, float actual, float error) {
  87. float diff = wanted - actual;
  88. diff = diff < 0.0f ? -diff : diff;
  89. CORE_TEST_SUCCESS(diff <= error);
  90. fputs(CORE_TERMINAL_RED, stdout);
  91. printf("%s:%d - expected '%.3f' got '%.3f'", file, line, (double)wanted,
  92. (double)actual);
  93. puts(CORE_TERMINAL_RESET);
  94. return false;
  95. }
  96. bool coreTestNull(CORE_TEST_ARGS, const void* actual) {
  97. CORE_TEST_SUCCESS(actual == nullptr);
  98. fputs(CORE_TERMINAL_RED, stdout);
  99. printf("%s:%d - expected null", file, line);
  100. puts(CORE_TERMINAL_RESET);
  101. return false;
  102. }
  103. bool coreTestNotNull(CORE_TEST_ARGS, const void* actual) {
  104. CORE_TEST_SUCCESS(actual != nullptr);
  105. fputs(CORE_TERMINAL_RED, stdout);
  106. printf("%s:%d - expected valid pointer", file, line);
  107. puts(CORE_TERMINAL_RESET);
  108. return false;
  109. }
  110. bool coreTestVectorN(CORE_TEST_ARGS, const float* wanted, const float* actual,
  111. size_t n) {
  112. for(size_t i = 0; i < n; i++) {
  113. if(!coreTestFloat(file, line, wanted[i], actual[i], 0.01f)) {
  114. return false;
  115. }
  116. }
  117. return true;
  118. }
  119. bool coreTestIntVectorN(CORE_TEST_ARGS, const int* wanted, const int* actual,
  120. size_t n) {
  121. for(size_t i = 0; i < n; i++) {
  122. if(!coreTestInt(file, line, wanted[i], actual[i])) {
  123. return false;
  124. }
  125. }
  126. return true;
  127. }