-
Notifications
You must be signed in to change notification settings - Fork 0
/
Test.h
208 lines (174 loc) · 6.78 KB
/
Test.h
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
#ifndef TEST_H
#define TEST_H
// Test is a base class for all tests. It provides a command interface for
// running tests (run) as well as a data member for recording the name of
// the test.
//
// Tests are constructed using the TEST macro. TEST creates a subclass of
// Test and static instance of that subclass. If you look at the constructor
// for the Test class, you'll notice that it registers the created object
// with a global TestRegistry. These features combine to make test creation
// particularly easy.
#include <cmath>
#include <vector>
#include <sstream>
#include <string>
#include "TestResult.h"
#include "Failure.h"
class Test
{
public:
Test (const std::string& testName,
std::string fileName,
long lineNumber);
virtual ~Test();
const std::string& getFileName() const;
const long& getLineNumber() const;
const std::string& getName() const;
void run (TestResult& result);
virtual void runTest (TestResult& result) = 0;
private:
std::string myFileName;
long myLineNumber;
std::string myName;
};
#define TEST(name,classUnderTest)\
class classUnderTest##name##Test : public Test\
{ \
public: \
classUnderTest##name##Test () \
: \
Test ("TEST(" #name ", " #classUnderTest ")", \
__FILE__, __LINE__) {} \
void runTest (TestResult& rEsUlT_); \
} classUnderTest##name##Instance; \
void classUnderTest##name##Test::runTest (TestResult& rEsUlT_)
// Here is a collection of testing macros that can be used in the
// bodies of tests. CHECK tests a boolean expression and records
// a failure if the expression evaluates to false. CHECK_LONGS_EQUAL
// and CHECK_DOUBLES_EQUAL check_equal_compare longs and doubles respectively.
//
// To make this an industrial strength test harness, you should
// add equals macros for various low level types as you develop them.
// If, for instance, you have a daterange class, the ability to check_equal_compare
// them directly and print out their values in the test output is
// invaluable.
#define CHECK(condition) \
{\
if (!(condition)) { \
rEsUlT_.addFailure (Failure (#condition, __FILE__, __LINE__)); \
return; \
}\
}
#define CHECK_LONGS_EQUAL(expected,actual)\
{\
long _expected = (expected);\
long _actual = (actual);\
if (_expected != _actual) {\
std::ostringstream message; \
message << "expected '" << (_expected) << "' but was '" << (_actual) << "'"; \
rEsUlT_.addFailure (Failure (message.str(), __FILE__, __LINE__));\
return; \
}\
}
#define CHECK_DOUBLES_EQUAL(expected,actual,threshold)\
{\
double _expected = (expected);\
double _actual = (actual);\
if (fabs ((_expected)-(_actual)) > (threshold)) {\
std::ostringstream message; \
message << "expected '" << (_expected) << "' but was '" << (_actual) << "'"; \
rEsUlT_.addFailure (Failure (message.str(), __FILE__, __LINE__));\
return; \
}\
}
#define CHECK_FAIL(text) \
{\
rEsUlT_.addFailure (Failure ((text), __FILE__, __LINE__)); \
return; \
}
// The following check for equality.
//
// The things being check_equal_compared must have an ostream or wostream inserters.
//
// BEWARE: The arguments are evaluated more than once!
// If this is a problem then use CHECK instead.
// Use this when the things being check_equal_compared have a wostream inserter.
inline void compare(const wchar_t* const expected, const wchar_t* const actual, TestResult& result, const char* file, int line)
{
if (wcscmp((expected), (actual)) != 0) {
std::ostringstream message;
message << "expected '" << (expected) << "' but was '" << (actual) << "'";
result.addFailure (Failure (message.str(), file, line));
return;
}
}
template <typename T, typename U> void check_equal_wcompare(T expected, U actual, TestResult& result, const char* file, int line)
{
if (! ((expected) == (actual))) {
std::wostringstream message;
message << L"expected '" << (expected) << L"' but was '" << (actual) << L"'";
result.addFailure (Failure (message.str(), file, line));
return;
}
}
inline void check_equal_compare(const wchar_t* expected, const wchar_t* actual, TestResult& result, const char* file, int line)
{
compare(expected, actual, result, file, line);
}
inline void check_equal_compare(wchar_t* expected, wchar_t* actual, TestResult& result, const char* file, int line)
{
compare(expected, actual, result, file, line);
}
inline void check_equal_compare(const wchar_t* expected, wchar_t* actual, TestResult& result, const char* file, int line)
{
compare(expected, actual, result, file, line);
}
inline void check_equal_compare(wchar_t* expected, const wchar_t* actual, TestResult& result, const char* file, int line)
{
compare(expected, actual, result, file, line);
}
#define CHECK_WEQUAL(expected, actual)\
{\
check_equal_wcompare(expected, actual, rEsUlT_, __FILE__, __LINE__); \
}
// Use this when the things being check_equal_compared have an ostream inserter.
template <typename T, typename U> void check_equal_compare(T expected, U actual, TestResult& result, const char* file, int line)
{
if (! ((expected) == (actual))) {
std::ostringstream message;
message << "expected '" << (expected) << "' but was '" << (actual) << "'";
result.addFailure (Failure (message.str(), file, line));
return;
}
}
inline void compare(const char* expected, const char* actual, TestResult& result, const char* file, int line)
{
if (strcmp((expected), (actual)) != 0) {
std::ostringstream message;
message << "expected '" << (expected) << "' but was '" << (actual) << "'";
result.addFailure (Failure (message.str(), file, line));
return;
}
}
inline void check_equal_compare(const char* expected, const char* actual, TestResult& result, const char* file, int line)
{
compare(expected, actual, result, file, line);
}
inline void check_equal_compare(char* expected, char* actual, TestResult& result, const char* file, int line)
{
compare(expected, actual, result, file, line);
}
inline void check_equal_compare(const char* expected, char* actual, TestResult& result, const char* file, int line)
{
compare(expected, actual, result, file, line);
}
inline void check_equal_compare(char* expected, const char* actual, TestResult& result, const char* file, int line)
{
compare(expected, actual, result, file, line);
}
#define CHECK_EQUAL(expected, actual)\
{\
check_equal_compare(expected, actual, rEsUlT_, __FILE__, __LINE__); \
}
#endif