-S option implemented: works only on the given strand (still not implemented for...
[matrix_rider.git] / CuTest.c
blobf952193871d9281dcc6b94f06f12002ad5a58b99
1 #include <assert.h>
2 #include <setjmp.h>
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <string.h>
6 #include <math.h>
8 #include "CuTest.h"
10 /*-------------------------------------------------------------------------*
11 * CuStr
12 *-------------------------------------------------------------------------*/
14 char *CuStrAlloc(int size)
16 char *newStr = (char *)malloc(sizeof(char) * (size));
17 return newStr;
20 char *CuStrCopy(const char *old)
22 int len = strlen(old);
23 char *newStr = CuStrAlloc(len + 1);
24 strcpy(newStr, old);
25 return newStr;
28 /*-------------------------------------------------------------------------*
29 * CuString
30 *-------------------------------------------------------------------------*/
32 void CuStringInit(CuString * str)
34 str->length = 0;
35 str->size = STRING_MAX;
36 str->buffer = (char *)malloc(sizeof(char) * str->size);
37 str->buffer[0] = '\0';
40 CuString *CuStringNew(void)
42 CuString *str = (CuString *) malloc(sizeof(CuString));
43 str->length = 0;
44 str->size = STRING_MAX;
45 str->buffer = (char *)malloc(sizeof(char) * str->size);
46 str->buffer[0] = '\0';
47 return str;
50 void CuStringResize(CuString * str, int newSize)
52 str->buffer = (char *)realloc(str->buffer, sizeof(char) * newSize);
53 str->size = newSize;
56 void CuStringAppend(CuString * str, const char *text)
58 int length;
60 if (text == NULL) {
61 text = "NULL";
64 length = strlen(text);
65 if (str->length + length + 1 >= str->size)
66 CuStringResize(str, str->length + length + 1 + STRING_INC);
67 str->length += length;
68 strcat(str->buffer, text);
71 void CuStringAppendChar(CuString * str, char ch)
73 char text[2];
74 text[0] = ch;
75 text[1] = '\0';
76 CuStringAppend(str, text);
79 void CuStringAppendFormat(CuString * str, const char *format, ...)
81 va_list argp;
82 char buf[HUGE_STRING_LEN];
83 va_start(argp, format);
84 vsprintf(buf, format, argp);
85 va_end(argp);
86 CuStringAppend(str, buf);
89 void CuStringInsert(CuString * str, const char *text, int pos)
91 int length = strlen(text);
92 if (pos > str->length)
93 pos = str->length;
94 if (str->length + length + 1 >= str->size)
95 CuStringResize(str, str->length + length + 1 + STRING_INC);
96 memmove(str->buffer + pos + length, str->buffer + pos,
97 (str->length - pos) + 1);
98 str->length += length;
99 memcpy(str->buffer + pos, text, length);
102 /*-------------------------------------------------------------------------*
103 * CuTest
104 *-------------------------------------------------------------------------*/
106 void CuTestInit(CuTest * t, const char *name, TestFunction function)
108 t->name = CuStrCopy(name);
109 t->failed = 0;
110 t->ran = 0;
111 t->message = NULL;
112 t->function = function;
113 t->jumpBuf = NULL;
116 CuTest *CuTestNew(const char *name, TestFunction function)
118 CuTest *tc = CU_ALLOC(CuTest);
119 CuTestInit(tc, name, function);
120 return tc;
123 void CuTestRun(CuTest * tc)
125 jmp_buf buf;
126 tc->jumpBuf = &buf;
127 if (setjmp(buf) == 0) {
128 tc->ran = 1;
129 (tc->function) (tc);
131 tc->jumpBuf = 0;
134 static void CuFailInternal(CuTest * tc, const char *file, int line,
135 CuString * string)
137 char buf[HUGE_STRING_LEN];
139 sprintf(buf, "%s:%d: ", file, line);
140 CuStringInsert(string, buf, 0);
142 tc->failed = 1;
143 tc->message = string->buffer;
144 if (tc->jumpBuf != 0)
145 longjmp(*(tc->jumpBuf), 0);
148 void CuFail_Line(CuTest * tc, const char *file, int line, const char *message2,
149 const char *message)
151 CuString string;
153 CuStringInit(&string);
154 if (message2 != NULL) {
155 CuStringAppend(&string, message2);
156 CuStringAppend(&string, ": ");
158 CuStringAppend(&string, message);
159 CuFailInternal(tc, file, line, &string);
162 void CuAssert_Line(CuTest * tc, const char *file, int line, const char *message,
163 int condition)
165 if (condition)
166 return;
167 CuFail_Line(tc, file, line, NULL, message);
170 void CuAssertStrEquals_LineMsg(CuTest * tc, const char *file, int line,
171 const char *message, const char *expected,
172 const char *actual)
174 CuString string;
175 if ((expected == NULL && actual == NULL) ||
176 (expected != NULL && actual != NULL &&
177 strcmp(expected, actual) == 0)) {
178 return;
181 CuStringInit(&string);
182 if (message != NULL) {
183 CuStringAppend(&string, message);
184 CuStringAppend(&string, ": ");
186 CuStringAppend(&string, "expected <");
187 CuStringAppend(&string, expected);
188 CuStringAppend(&string, "> but was <");
189 CuStringAppend(&string, actual);
190 CuStringAppend(&string, ">");
191 CuFailInternal(tc, file, line, &string);
194 void CuAssertIntEquals_LineMsg(CuTest * tc, const char *file, int line,
195 const char *message, int expected, int actual)
197 char buf[STRING_MAX];
198 if (expected == actual)
199 return;
200 sprintf(buf, "expected <%d> but was <%d>", expected, actual);
201 CuFail_Line(tc, file, line, message, buf);
204 void CuAssertDblEquals_LineMsg(CuTest * tc, const char *file, int line,
205 const char *message, double expected,
206 double actual, double delta)
208 char buf[STRING_MAX];
209 if (fabs(expected - actual) <= delta)
210 return;
211 sprintf(buf, "expected <%lf> but was <%lf>", expected, actual);
212 CuFail_Line(tc, file, line, message, buf);
215 void CuAssertPtrEquals_LineMsg(CuTest * tc, const char *file, int line,
216 const char *message, void *expected,
217 void *actual)
219 char buf[STRING_MAX];
220 if (expected == actual)
221 return;
222 sprintf(buf, "expected pointer <0x%p> but was <0x%p>", expected,
223 actual);
224 CuFail_Line(tc, file, line, message, buf);
227 /*-------------------------------------------------------------------------*
228 * CuSuite
229 *-------------------------------------------------------------------------*/
231 void CuSuiteInit(CuSuite * testSuite)
233 testSuite->count = 0;
234 testSuite->failCount = 0;
237 CuSuite *CuSuiteNew(void)
239 CuSuite *testSuite = CU_ALLOC(CuSuite);
240 CuSuiteInit(testSuite);
241 return testSuite;
244 void CuSuiteAdd(CuSuite * testSuite, CuTest * testCase)
246 assert(testSuite->count < MAX_TEST_CASES);
247 testSuite->list[testSuite->count] = testCase;
248 testSuite->count++;
251 void CuSuiteAddSuite(CuSuite * testSuite, CuSuite * testSuite2)
253 int i;
254 for (i = 0; i < testSuite2->count; ++i) {
255 CuTest *testCase = testSuite2->list[i];
256 CuSuiteAdd(testSuite, testCase);
260 void CuSuiteRun(CuSuite * testSuite)
262 int i;
263 for (i = 0; i < testSuite->count; ++i) {
264 CuTest *testCase = testSuite->list[i];
265 CuTestRun(testCase);
266 if (testCase->failed) {
267 testSuite->failCount += 1;
272 void CuSuiteSummary(CuSuite * testSuite, CuString * summary)
274 int i;
275 for (i = 0; i < testSuite->count; ++i) {
276 CuTest *testCase = testSuite->list[i];
277 CuStringAppend(summary, testCase->failed ? "F" : ".");
279 CuStringAppend(summary, "\n\n");
282 void CuSuiteDetails(CuSuite * testSuite, CuString * details)
284 int i;
285 int failCount = 0;
287 if (testSuite->failCount == 0) {
288 int passCount = testSuite->count - testSuite->failCount;
289 const char *testWord = passCount == 1 ? "test" : "tests";
290 CuStringAppendFormat(details, "OK (%d %s)\n", passCount,
291 testWord);
292 } else {
293 if (testSuite->failCount == 1)
294 CuStringAppend(details, "There was 1 failure:\n");
295 else
296 CuStringAppendFormat(details,
297 "There were %d failures:\n",
298 testSuite->failCount);
300 for (i = 0; i < testSuite->count; ++i) {
301 CuTest *testCase = testSuite->list[i];
302 if (testCase->failed) {
303 failCount++;
304 CuStringAppendFormat(details, "%d) %s: %s\n",
305 failCount, testCase->name,
306 testCase->message);
309 CuStringAppend(details, "\n!!!FAILURES!!!\n");
311 CuStringAppendFormat(details, "Runs: %d ", testSuite->count);
312 CuStringAppendFormat(details, "Passes: %d ",
313 testSuite->count - testSuite->failCount);
314 CuStringAppendFormat(details, "Fails: %d\n",
315 testSuite->failCount);