-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathminiunit.h
More file actions
156 lines (137 loc) · 3.87 KB
/
miniunit.h
File metadata and controls
156 lines (137 loc) · 3.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
// miniunit
// ========
//
// Minimalistic unitets framework.
// Just one header file.
//
// Requirements
// ------------
//
// C++11
//
// Usage example
// -------------
//
// TEST(TEST1, "Test description for TEST1") {
// return true; // PASS
// }
//
// TEST(TEST2, "Test description for TEST2") {
// return false; // FAIL
// }
//
// // Custom test case
// class MyTestCase : public TestSuite::TestCase {
// public:
// MyTestCase(const char* name, const char* description)
// : TestSuite::TestCase(name, description) {
// // Setup action in constructor
// }
// ~MyTestCase() {
// // Tear down actions in destructor
// }
// bool test() {
// // Test body
// return true;
// };
// } MyTestCase_instance("TEST3", "Description for custom test case");
//
// int main(void) {
// bool result = TestSuite::run();
// std::cout << "Result: " << (result ? "PASS" : "FAIL") << std::endl;
// return (result ? 0 : 1);
// }
#ifndef MINIUNIT_H
#define MINIUNIT_H
#include <string>
#include <vector>
#include <iostream> // cout
#include <iomanip> // setw
namespace miniunit {
// Test suite controls test execution
class TestSuite {
public:
// Abstract test case
class TestCase {
public:
TestCase() {};
TestCase(const char* n, const char* d)
: name(n), description(d), skip(false) {
TestSuite::add(this);
};
virtual bool test() = 0;
virtual void setSkip(const char* r) {
skip = true;
reason = r;
};
std::string name;
std::string description;
bool skip;
std::string reason;
};
static TestSuite& get() {
static TestSuite testSuite;
return testSuite;
};
static void add(TestCase* test) {
get().tests.push_back(test);
};
static std::vector<TestCase*>& getTests() {
return get().tests;
};
static bool run(bool color = true) {
std::string pass = "PASS";
std::string fail = "FAIL";
std::string skip = "SKIP";
if (color) {
const std::string colorRed = "\x1b[31m";
const std::string colorGreen = "\x1b[32m";
const std::string colorYellow = "\x1b[33m";
const std::string colorReset = "\x1b[0m";
pass = colorGreen + pass + colorReset;
fail = colorRed + fail + colorReset;
skip = colorYellow + skip + colorReset;
}
size_t nameLen = 0;
for (auto t : getTests())
nameLen = (t->name.size() > nameLen ? t->name.size() : nameLen);
size_t descLen = 0;
for (auto t : getTests())
descLen = (t->description.size() > descLen ? t->description.size() : descLen);
bool allResults = true;
for (auto t : getTests()) {
std::cout << std::setw(nameLen + 4) << "[" + t->name + "] ";
std::cout << std::setw(descLen + 3) << t->description + " : ";
if (!t->skip) {
bool result = false;
std::string reason;
try {
result = t->test();
} catch (...) {
reason = "Exception!";
}
std::cout << (result ? pass : fail) << " " << reason << std::endl;
allResults = allResults && result;
} else {
std::cout << skip << " " << t->reason << std::endl;
}
}
return allResults;
};
private:
std::vector<TestCase*> tests;
};
// TEST macro to use when defining tests
#define TEST(name, description) \
class TEST_##name##_Test : \
public miniunit::TestSuite::TestCase { \
public: \
TEST_##name##_Test(const char* n, const char* d) \
: miniunit::TestSuite::TestCase(n, d) {} \
bool test(); \
} TEST_##name##_Test_instance(#name, description); \
bool TEST_##name##_Test::test()
// SKIP macro to define test as temporarily disabled
#define SKIP(name, reason) TEST_##name##_Test_instance.setSkip(reason)
}; // namespace miniunit
#endif // MINIUNIT_H