source: trunk/src/CuTest.c@ 553

Last change on this file since 553 was 227, checked in by katerina, 16 years ago

Fix warnings with -fstack-check

File size: 8.5 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[2048];
123 va_start(argp, format);
124 vsnprintf(buf, sizeof(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[256];
177
178 snprintf(buf, sizeof(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#define SH_FABS(a) (((a) < 0) ? -(a) : (a))
245 if (SH_FABS(expected - actual) <= delta) return;
246 sprintf(buf, "expected <%lf> but was <%lf>", expected, actual);
247 CuFail_Line(tc, file, line, message, buf);
248}
249
250void CuAssertPtrEquals_LineMsg(CuTest* tc, const char* file, int line, const char* message,
251 void* expected, void* actual)
252{
253 char buf[STRING_MAX];
254 if (expected == actual) return;
255 sprintf(buf, "expected pointer <0x%p> but was <0x%p>", expected, actual);
256 CuFail_Line(tc, file, line, message, buf);
257}
258
259
260/*-------------------------------------------------------------------------*
261 * CuSuite
262 *-------------------------------------------------------------------------*/
263
264void CuSuiteInit(CuSuite* testSuite)
265{
266 testSuite->count = 0;
267 testSuite->failCount = 0;
268}
269
270CuSuite* CuSuiteNew(void)
271{
272 CuSuite* testSuite = CU_ALLOC(CuSuite);
273 CuSuiteInit(testSuite);
274 return testSuite;
275}
276
277void CuSuiteAdd(CuSuite* testSuite, CuTest *testCase)
278{
279 assert(testSuite->count < MAX_TEST_CASES);
280 testSuite->list[testSuite->count] = testCase;
281 testSuite->count++;
282}
283
284void CuSuiteAddSuite(CuSuite* testSuite, CuSuite* testSuite2)
285{
286 int i;
287 for (i = 0 ; i < testSuite2->count ; ++i)
288 {
289 CuTest* testCase = testSuite2->list[i];
290 CuSuiteAdd(testSuite, testCase);
291 }
292}
293
294void CuSuiteRun(CuSuite* testSuite)
295{
296 int i;
297 for (i = 0 ; i < testSuite->count ; ++i)
298 {
299 CuTest* testCase = testSuite->list[i];
300 CuTestRun(testCase);
301 if (testCase->failed) { testSuite->failCount += 1; }
302 }
303}
304
305void CuSuiteSummary(CuSuite* testSuite, CuString* summary)
306{
307 int i;
308 for (i = 0 ; i < testSuite->count ; ++i)
309 {
310 CuTest* testCase = testSuite->list[i];
311 CuStringAppend(summary, testCase->failed ? "F" : ".");
312 }
313 CuStringAppend(summary, "\n\n");
314}
315
316void CuSuiteDetails(CuSuite* testSuite, CuString* details)
317{
318 int i;
319 int failCount = 0;
320
321 if (testSuite->failCount == 0)
322 {
323 int passCount = testSuite->count - testSuite->failCount;
324 const char* testWord = passCount == 1 ? "test" : "tests";
325 CuStringAppendFormat(details, "OK (%d %s)\n", passCount, testWord);
326 }
327 else
328 {
329 if (testSuite->failCount == 1)
330 CuStringAppend(details, "There was 1 failure:\n");
331 else
332 CuStringAppendFormat(details, "There were %d failures:\n", testSuite->failCount);
333
334 for (i = 0 ; i < testSuite->count ; ++i)
335 {
336 CuTest* testCase = testSuite->list[i];
337 if (testCase->failed)
338 {
339 failCount++;
340 CuStringAppendFormat(details, "%d) %s: %s\n",
341 failCount, testCase->name, testCase->message);
342 }
343 }
344 CuStringAppend(details, "\n!!!FAILURES!!!\n");
345
346 CuStringAppendFormat(details, "Runs: %d ", testSuite->count);
347 CuStringAppendFormat(details, "Passes: %d ", testSuite->count - testSuite->failCount);
348 CuStringAppendFormat(details, "Fails: %d\n", testSuite->failCount);
349 }
350}
Note: See TracBrowser for help on using the repository browser.