source: trunk/src/CuTest.c@ 150

Last change on this file since 150 was 137, checked in by rainer, 17 years ago

Fix compile errors.

File size: 8.4 KB
Line 
1/*******************
2
3LICENSE
4
5Copyright (c) 2003 Asim Jalis
6
7This software is provided 'as-is', without any express or implied
8warranty. In no event will the authors be held liable for any damages
9arising from the use of this software.
10
11Permission is granted to anyone to use this software for any purpose,
12including commercial applications, and to alter it and redistribute it
13freely, subject to the following restrictions:
14
151. The origin of this software must not be misrepresented; you must not
16claim that you wrote the original software. If you use this software in
17a product, an acknowledgment in the product documentation would be
18appreciated but is not required.
19
202. Altered source versions must be plainly marked as such, and must not
21be misrepresented as being the original software.
22
233. This notice may not be removed or altered from any source
24distribution.
25
26**********************/
27
28#include <assert.h>
29#include <setjmp.h>
30#include <stdlib.h>
31#include <stdio.h>
32#include <string.h>
33#include <math.h>
34#include <unistd.h>
35
36#include "CuTest.h"
37
38/*-------------------------------------------------------------------------*
39 * CuStr
40 *-------------------------------------------------------------------------*/
41
42char* CuStrAlloc(int size)
43{
44 char* newStr = (char*) malloc( sizeof(char) * (size) );
45 return newStr;
46}
47
48char* CuStrCopy(const char* old)
49{
50 int len = strlen(old);
51 char* newStr = CuStrAlloc(len + 1);
52 strcpy(newStr, old);
53 return newStr;
54}
55
56/*-------------------------------------------------------------------------*
57 * CuString
58 *-------------------------------------------------------------------------*/
59
60void CuStringInit(CuString* str)
61{
62 str->length = 0;
63 str->size = STRING_MAX;
64 str->buffer = (char*) malloc(sizeof(char) * str->size);
65 if (str->buffer)
66 str->buffer[0] = '\0';
67 else
68 {
69 perror("CuStringInit");
70 _exit (EXIT_FAILURE);
71 }
72}
73
74CuString* CuStringNew(void)
75{
76 CuString* str = (CuString*) malloc(sizeof(CuString));
77 str->length = 0;
78 str->size = STRING_MAX;
79 str->buffer = (char*) malloc(sizeof(char) * str->size);
80 if (str->buffer)
81 str->buffer[0] = '\0';
82 else
83 {
84 perror("CuStringNew");
85 _exit (EXIT_FAILURE);
86 }
87 return str;
88}
89
90void CuStringResize(CuString* str, int newSize)
91{
92 str->buffer = (char*) realloc(str->buffer, sizeof(char) * newSize);
93 str->size = newSize;
94}
95
96void CuStringAppend(CuString* str, const char* text)
97{
98 int length;
99
100 if (text == NULL) {
101 text = "NULL";
102 }
103
104 length = strlen(text);
105 if (str->length + length + 1 >= str->size)
106 CuStringResize(str, str->length + length + 1 + STRING_INC);
107 str->length += length;
108 strcat(str->buffer, text);
109}
110
111void CuStringAppendChar(CuString* str, char ch)
112{
113 char text[2];
114 text[0] = ch;
115 text[1] = '\0';
116 CuStringAppend(str, text);
117}
118
119void CuStringAppendFormat(CuString* str, const char* format, ...)
120{
121 va_list argp;
122 char buf[HUGE_STRING_LEN];
123 va_start(argp, format);
124 vsprintf(buf, format, argp);
125 va_end(argp);
126 CuStringAppend(str, buf);
127}
128
129void CuStringInsert(CuString* str, const char* text, int pos)
130{
131 int length = strlen(text);
132 if (pos > str->length)
133 pos = str->length;
134 if (str->length + length + 1 >= str->size)
135 CuStringResize(str, str->length + length + 1 + STRING_INC);
136 memmove(str->buffer + pos + length, str->buffer + pos, (str->length - pos) + 1);
137 str->length += length;
138 memcpy(str->buffer + pos, text, length);
139}
140
141/*-------------------------------------------------------------------------*
142 * CuTest
143 *-------------------------------------------------------------------------*/
144
145void CuTestInit(CuTest* t, const char* name, TestFunction function)
146{
147 t->name = CuStrCopy(name);
148 t->failed = 0;
149 t->ran = 0;
150 t->message = NULL;
151 t->function = function;
152 t->jumpBuf = NULL;
153}
154
155CuTest* CuTestNew(const char* name, TestFunction function)
156{
157 CuTest* tc = CU_ALLOC(CuTest);
158 CuTestInit(tc, name, function);
159 return tc;
160}
161
162void CuTestRun(CuTest* tc)
163{
164 jmp_buf buf;
165 tc->jumpBuf = &buf;
166 if (setjmp(buf) == 0)
167 {
168 tc->ran = 1;
169 (tc->function)(tc);
170 }
171 tc->jumpBuf = 0;
172}
173
174static void CuFailInternal(CuTest* tc, const char* file, int line, CuString* string)
175{
176 char buf[HUGE_STRING_LEN];
177
178 sprintf(buf, "%s:%d: ", file, line);
179 CuStringInsert(string, buf, 0);
180
181 tc->failed = 1;
182 tc->message = string->buffer;
183 if (tc->jumpBuf != 0) longjmp(*(tc->jumpBuf), 0);
184}
185
186void CuFail_Line(CuTest* tc, const char* file, int line, const char* message2, const char* message)
187{
188 CuString string;
189
190 CuStringInit(&string);
191 if (message2 != NULL)
192 {
193 CuStringAppend(&string, message2);
194 CuStringAppend(&string, ": ");
195 }
196 CuStringAppend(&string, message);
197 CuFailInternal(tc, file, line, &string);
198}
199
200void CuAssert_Line(CuTest* tc, const char* file, int line, const char* message, int condition)
201{
202 if (condition) return;
203 CuFail_Line(tc, file, line, NULL, message);
204}
205
206void CuAssertStrEquals_LineMsg(CuTest* tc, const char* file, int line, const char* message,
207 const char* expected, const char* actual)
208{
209 CuString string;
210 if ((expected == NULL && actual == NULL) ||
211 (expected != NULL && actual != NULL &&
212 strcmp(expected, actual) == 0))
213 {
214 return;
215 }
216
217 CuStringInit(&string);
218 if (message != NULL)
219 {
220 CuStringAppend(&string, message);
221 CuStringAppend(&string, ": ");
222 }
223 CuStringAppend(&string, "expected <");
224 CuStringAppend(&string, expected);
225 CuStringAppend(&string, "> but was <");
226 CuStringAppend(&string, actual);
227 CuStringAppend(&string, ">");
228 CuFailInternal(tc, file, line, &string);
229}
230
231void CuAssertIntEquals_LineMsg(CuTest* tc, const char* file, int line, const char* message,
232 int expected, int actual)
233{
234 char buf[STRING_MAX];
235 if (expected == actual) return;
236 sprintf(buf, "expected <%d> but was <%d>", expected, actual);
237 CuFail_Line(tc, file, line, message, buf);
238}
239
240void CuAssertDblEquals_LineMsg(CuTest* tc, const char* file, int line, const char* message,
241 double expected, double actual, double delta)
242{
243 char buf[STRING_MAX];
244 if (fabs(expected - actual) <= delta) return;
245 sprintf(buf, "expected <%lf> but was <%lf>", expected, actual);
246 CuFail_Line(tc, file, line, message, buf);
247}
248
249void CuAssertPtrEquals_LineMsg(CuTest* tc, const char* file, int line, const char* message,
250 void* expected, void* actual)
251{
252 char buf[STRING_MAX];
253 if (expected == actual) return;
254 sprintf(buf, "expected pointer <0x%p> but was <0x%p>", expected, actual);
255 CuFail_Line(tc, file, line, message, buf);
256}
257
258
259/*-------------------------------------------------------------------------*
260 * CuSuite
261 *-------------------------------------------------------------------------*/
262
263void CuSuiteInit(CuSuite* testSuite)
264{
265 testSuite->count = 0;
266 testSuite->failCount = 0;
267}
268
269CuSuite* CuSuiteNew(void)
270{
271 CuSuite* testSuite = CU_ALLOC(CuSuite);
272 CuSuiteInit(testSuite);
273 return testSuite;
274}
275
276void CuSuiteAdd(CuSuite* testSuite, CuTest *testCase)
277{
278 assert(testSuite->count < MAX_TEST_CASES);
279 testSuite->list[testSuite->count] = testCase;
280 testSuite->count++;
281}
282
283void CuSuiteAddSuite(CuSuite* testSuite, CuSuite* testSuite2)
284{
285 int i;
286 for (i = 0 ; i < testSuite2->count ; ++i)
287 {
288 CuTest* testCase = testSuite2->list[i];
289 CuSuiteAdd(testSuite, testCase);
290 }
291}
292
293void CuSuiteRun(CuSuite* testSuite)
294{
295 int i;
296 for (i = 0 ; i < testSuite->count ; ++i)
297 {
298 CuTest* testCase = testSuite->list[i];
299 CuTestRun(testCase);
300 if (testCase->failed) { testSuite->failCount += 1; }
301 }
302}
303
304void CuSuiteSummary(CuSuite* testSuite, CuString* summary)
305{
306 int i;
307 for (i = 0 ; i < testSuite->count ; ++i)
308 {
309 CuTest* testCase = testSuite->list[i];
310 CuStringAppend(summary, testCase->failed ? "F" : ".");
311 }
312 CuStringAppend(summary, "\n\n");
313}
314
315void CuSuiteDetails(CuSuite* testSuite, CuString* details)
316{
317 int i;
318 int failCount = 0;
319
320 if (testSuite->failCount == 0)
321 {
322 int passCount = testSuite->count - testSuite->failCount;
323 const char* testWord = passCount == 1 ? "test" : "tests";
324 CuStringAppendFormat(details, "OK (%d %s)\n", passCount, testWord);
325 }
326 else
327 {
328 if (testSuite->failCount == 1)
329 CuStringAppend(details, "There was 1 failure:\n");
330 else
331 CuStringAppendFormat(details, "There were %d failures:\n", testSuite->failCount);
332
333 for (i = 0 ; i < testSuite->count ; ++i)
334 {
335 CuTest* testCase = testSuite->list[i];
336 if (testCase->failed)
337 {
338 failCount++;
339 CuStringAppendFormat(details, "%d) %s: %s\n",
340 failCount, testCase->name, testCase->message);
341 }
342 }
343 CuStringAppend(details, "\n!!!FAILURES!!!\n");
344
345 CuStringAppendFormat(details, "Runs: %d ", testSuite->count);
346 CuStringAppendFormat(details, "Passes: %d ", testSuite->count - testSuite->failCount);
347 CuStringAppendFormat(details, "Fails: %d\n", testSuite->failCount);
348 }
349}
Note: See TracBrowser for help on using the repository browser.