FuncDoodle
Loading...
Searching...
No Matches
Test.h
Go to the documentation of this file.
1
18
19#pragma once
20
21#ifdef FUNCDOODLE_BUILD_IMTESTS
22#include "imgui_te_engine.h"
23#include "imgui_te_ui.h"
24#endif
25
26#include <atomic>
27#include <cstring>
28#include <iostream>
29#include <string>
30#include <vector>
31
32#ifdef FUNCDOODLE_BUILD_TESTS
33int FuncDoodle_RunTests();
34#endif
35
36#ifdef _MSC_VER
38#define CURRENT_FUNC __FUNCTION__
39#else
42#define CURRENT_FUNC __func__
43#endif
44
45#ifdef FUNCDOODLE_BUILD_IMTESTS
46int FuncDoodle_RegisterImTests();
47extern ImGuiTestEngine* s_TestEngine;
48#endif
49
50namespace FuncDoodle {
51
59 inline std::string Repeat(std::string_view s, size_t n) {
60 std::string out;
61 out.reserve(s.size() * n);
62 while (n--)
63 out += s;
64 return out;
65 }
66
71 struct TestResult {
72 std::string condition;
73 std::string message;
74 bool passed;
75 };
76
85 public:
93 static TestRegistry instance;
94 return instance;
95 }
96
101 const char* name, int passed, int total, int failed) {
102 m_Results.push_back({name, passed, total, failed});
103 }
104
111 int total_tests = 0;
112 int total_passed = 0;
113 int total_failed = 0;
114
115 for (const auto& r : m_Results) {
116 total_tests += r.total;
117 total_passed += r.passed;
118 total_failed += r.failed;
119 }
120
121 double percentage = total_tests > 0
122 ? (double)total_passed / total_tests * 100.0
123 : 0.0;
124
125 std::string percent_str = std::to_string(percentage);
126
127 std::cout << total_passed << ' '
128 << total_tests << ' '
129 << percentage << '\n';
130
131 std::cout << "\n";
132 std::cout << "╔" << Repeat("═", 62) << "╗\n";
133 std::cout << "║ TEST SUMMARY "
134 " ║\n";
135 std::cout << "╠" << Repeat("═", 62) << "╣\n";
136
137 std::cout << "║ Total: " << total_tests
138 << std::string(
139 48 - std::to_string(total_tests).length(), ' ')
140 << " ║\n";
141
142 std::cout << "║ \033[32mPassed: " << total_passed << "\033[0m"
143 << std::string(
144 47 - std::to_string(total_passed).length(), ' ')
145 << " ║\n";
146
147 std::cout << "║ \033[31mFailed: " << total_failed << "\033[0m"
148 << std::string(
149 47 - std::to_string(total_failed).length(), ' ')
150 << " ║\n";
151
152 std::string color =
153 (percentage == 100.0)
154 ? "\033[32m"
155 : (percentage >= 80.0 ? "\033[33m" : "\033[31m");
156
157 std::cout << "║ " << color << "Success: " << percent_str
158 << "%\033[0m"
159 << std::string(46 - percent_str.length(), ' ')
160 << " ║\n";
161
162 std::cout << "╚" << Repeat("═", 62) << "╝\n";
163 }
164
165 private:
166 struct ScopeResult {
167 const char* name;
169 };
170
171 std::vector<ScopeResult> m_Results;
172 };
173
180 class TestScope {
181 public:
188 explicit TestScope(const char* name) : m_Name(name) {}
189
195 m_Name.c_str(), m_Passed, m_Total, m_Failed);
196
197 std::cout << "\n";
198 std::cout << "╔" << Repeat("═", 62) << "╗\n";
199 std::cout << "║ \033[1m" << m_Name << "\033[0m"
200 << std::string(60 - m_Name.length(), ' ') << "║\n";
201 std::cout << "╠" << Repeat("═", 62) << "╣\n";
202
203 if (m_Failed == 0) {
204 std::cout << "║ \033[32m[PASS]\033[0m " << m_Passed << "/"
205 << m_Total << " passed"
206 << std::string(45 -
207 std::to_string(m_Passed).length() -
208 std::to_string(m_Total).length(),
209 ' ')
210 << "║\n";
211 } else {
212 std::cout << "║ \033[32m[PASS]\033[0m " << m_Passed << "/"
213 << m_Total << " passed"
214 << std::string(44 -
215 std::to_string(m_Passed).length() -
216 std::to_string(m_Total).length(),
217 ' ')
218 << "║\n";
219
220 std::cout << "║ \033[31m[FAIL]\033[0m " << m_Failed
221 << " failed"
222 << std::string(
223 47 - std::to_string(m_Failed).length(), ' ')
224 << "║\n";
225 }
226
227 std::cout << "╚" << Repeat("═", 62) << "╝\n";
228 }
229
233 void Check(bool cond, const char* condStr, const char* msg = "") {
234 m_Total++;
235 if (cond)
236 m_Passed++;
237 else {
238 m_Failed++;
239 m_Results.push_back({condStr, msg ? msg : "", false});
240 }
241 }
242
243 private:
244 std::string m_Name;
245 int m_Total = 0, m_Passed = 0, m_Failed = 0;
246 std::vector<TestResult> m_Results;
247 };
248
249} // namespace FuncDoodle
250
251// ================= MACROS =================
252
257#define TEST_SCOPE(name) FuncDoodle::TestScope _test_scope(name)
258
263#define CHECK(cond, msg) _test_scope.Check(cond, #cond, msg)
268#define CHECK_EQ(a, b, msg) _test_scope.Check((a) == (b), #a " == " #b, msg)
273#define CHECK_NE(a, b, msg) _test_scope.Check((a) != (b), #a " != " #b, msg)
278#define CHECK_LT(a, b, msg) _test_scope.Check((a) < (b), #a " < " #b, msg)
284#define CHECK_LE(a, b, msg) _test_scope.Check((a) <= (b), #a " <= " #b, msg)
289#define CHECK_GT(a, b, msg) _test_scope.Check((a) > (b), #a " > " #b, msg)
295#define CHECK_GE(a, b, msg) _test_scope.Check((a) >= (b), #a " >= " #b, msg)
300#define CHECK_NULL(ptr, msg) \
301 _test_scope.Check((ptr) == nullptr, #ptr " == nullptr", msg)
302
306#define CHECK_NOT_NULL(ptr, msg) \
307 _test_scope.Check((ptr) != nullptr, #ptr " != nullptr", msg)
Global singleton collecting test scope results.
Definition Test.h:84
static TestRegistry & Instance()
Returns the global test registry singleton.
Definition Test.h:92
std::vector< ScopeResult > m_Results
Definition Test.h:171
void RegisterScope(const char *name, int passed, int total, int failed)
Registers a completed test scope.
Definition Test.h:100
void PrintSummary()
Prints a full summary of all executed tests.
Definition Test.h:110
std::vector< TestResult > m_Results
Definition Test.h:246
int m_Passed
Definition Test.h:245
int m_Failed
Definition Test.h:245
~TestScope()
Finalizes and prints test scope results.
Definition Test.h:193
std::string m_Name
Definition Test.h:244
void Check(bool cond, const char *condStr, const char *msg="")
Evaluates a test condition.
Definition Test.h:233
TestScope(const char *name)
Creates a named test scope.
Definition Test.h:188
int m_Total
Definition Test.h:245
The FuncDoodle C++ namespace.
Definition Common.h:12
std::string Repeat(std::string_view s, size_t n)
Repeats a string N times.
Definition Test.h:59
int total
Definition Test.h:168
const char * name
Definition Test.h:167
int failed
Definition Test.h:168
int passed
Definition Test.h:168
Represents a single failed or recorded test assertion.
Definition Test.h:71
std::string message
Optional failure message.
Definition Test.h:73
bool passed
Whether the test passed.
Definition Test.h:74
std::string condition
Stringified test condition.
Definition Test.h:72