Test.hpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. #ifndef CORE_TEST_HPP
  2. #define CORE_TEST_HPP
  3. #include "core/data/HashMap.hpp"
  4. #include "core/math/Vector.hpp"
  5. #include "core/utils/Logger.hpp"
  6. namespace Core::Test {
  7. namespace Internal {
  8. struct Result final {
  9. int tests = 0;
  10. int successTests = 0;
  11. };
  12. using FileName = String32<256>;
  13. extern HashMap<FileName, Result> results;
  14. void warn(const char* file, int line, Error e);
  15. template<typename T>
  16. bool check(const char* file, int line, const T& wanted, const T& actual,
  17. bool c) {
  18. file = Logger::getFileName(file);
  19. Error e = Error::NONE;
  20. FileName fileName;
  21. if(checkError(e, fileName.append(file))) {
  22. warn(file, line, e);
  23. return false;
  24. }
  25. Result* result = results.search(fileName);
  26. if(result == nullptr &&
  27. checkError(e, results.tryEmplace(result, fileName))) {
  28. warn(file, line, e);
  29. return false;
  30. }
  31. result->tests++;
  32. if(c) {
  33. result->successTests++;
  34. return true;
  35. }
  36. Core::Logger::log(Core::Logger::COLOR_RED,
  37. "#:# - expected '#' got '#'", fileName, line,
  38. wanted, actual);
  39. return false;
  40. }
  41. template<typename T>
  42. bool checkEqual(const char* file, int line, const T& wanted,
  43. const T& actual) {
  44. return check(file, line, wanted, actual, wanted == actual);
  45. }
  46. template<typename A, typename B>
  47. bool checkString(const char* file, int line, const A& wanted,
  48. const B& actual) {
  49. Error e = Error::NONE;
  50. String32<2048> a;
  51. if(checkError(e, a.append(wanted))) {
  52. warn(file, line, e);
  53. return false;
  54. }
  55. String32<2048> b;
  56. if(checkError(e, b.append(actual))) {
  57. warn(file, line, e);
  58. return false;
  59. }
  60. return checkEqual(file, line, a, b);
  61. }
  62. bool checkFloat(const char* file, int line, float wanted, float actual,
  63. float error);
  64. template<int N, typename T>
  65. bool checkVector(const char* file, int line,
  66. const Core::Vector<N, T>& wanted,
  67. const Core::Vector<N, T>& actual, float error) {
  68. bool result = true;
  69. for(int i = 0; i < N; i++) {
  70. result &= checkFloat(file, line, static_cast<float>(wanted[i]),
  71. static_cast<float>(actual[i]), error);
  72. }
  73. return result;
  74. }
  75. }
  76. void finalize();
  77. }
  78. #define CORE_TEST_EQUAL(wanted, actual) \
  79. Core::Test::Internal::checkEqual<Core::RemoveReference<decltype(actual)>>( \
  80. __FILE__, __LINE__, wanted, actual)
  81. #define CORE_TEST_STRING(wanted, actual) \
  82. Core::Test::Internal::checkString(__FILE__, __LINE__, wanted, actual)
  83. #define CORE_TEST_FALSE(actual) CORE_TEST_EQUAL(false, actual)
  84. #define CORE_TEST_TRUE(actual) CORE_TEST_EQUAL(true, actual)
  85. #define CORE_TEST_ERROR(actual) CORE_TEST_EQUAL(Core::Error::NONE, actual)
  86. #define CORE_TEST_NULL(actual) CORE_TEST_EQUAL(true, actual == nullptr)
  87. // double check to make the null check clear for the compiler
  88. #define CORE_TEST_NOT_NULL(actual) \
  89. (CORE_TEST_EQUAL(true, (actual) != nullptr) && (actual) != nullptr)
  90. #define CORE_TEST_FLOAT(wanted, actual, error) \
  91. Core::Test::Internal::checkFloat(__FILE__, __LINE__, wanted, actual, error)
  92. #define CORE_TEST_VECTOR(wanted, actual) \
  93. Core::Test::Internal::checkVector(__FILE__, __LINE__, wanted, actual, \
  94. 0.0001f)
  95. #endif