source: trunk/src/CuTest.c@ 51

Last change on this file since 51 was 17, checked in by katerina, 19 years ago

Optimized version of tiger algorithm, and basic ingredients for unit testing (part 1)

File size: 8.2 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
35#include "CuTest.h"
36
37/*-------------------------------------------------------------------------*
38 * CuStr
39 *-------------------------------------------------------------------------*/
40
41char* CuStrAlloc(int size)
42{
43 char* newStr = (char*) malloc( sizeof(char) * (size) );
44 return newStr;
45}
46
47char* CuStrCopy(const char* old)
48{
49 int len = strlen(old);
50 char* newStr = CuStrAlloc(len + 1);
51 strcpy(newStr, old);
52 return newStr;
53}
54
55/*-------------------------------------------------------------------------*
56 * CuString
57 *-------------------------------------------------------------------------*/
58
59void CuStringInit(CuString* str)
60{
61 str->length = 0;
62 str->size = STRING_MAX;
63 str->buffer = (char*) malloc(sizeof(char) * str->size);
64 str->buffer[0] = '\0';
65}
66
67CuString* CuStringNew(void)
68{
69 CuString* str = (CuString*) malloc(sizeof(CuString));
70 str->length = 0;
71 str->size = STRING_MAX;
72 str->buffer = (char*) malloc(sizeof(char) * str->size);
73 str->buffer[0] = '\0';
74 return str;
75}
76
77void CuStringResize(CuString* str, int newSize)
78{
79 str->buffer = (char*) realloc(str->buffer, sizeof(char) * newSize);
80 str->size = newSize;
81}
82
83void CuStringAppend(CuString* str, const char* text)
84{
85 int length;
86
87 if (text == NULL) {
88 text = "NULL";
89 }
90
91 length = strlen(text);
92 if (str->length + length + 1 >= str->size)
93 CuStringResize(str, str->length + length + 1 + STRING_INC);
94 str->length += length;
95 strcat(str->buffer, text);
96}
97
98void CuStringAppendChar(CuString* str, char ch)
99{
100 char text[2];
101 text[0] = ch;
102 text[1] = '\0';
103 CuStringAppend(str, text);
104}
105
106void CuStringAppendFormat(CuString* str, const char* format, ...)
107{
108 va_list argp;
109 char buf[HUGE_STRING_LEN];
110 va_start(argp, format);
111 vsprintf(buf, format, argp);
112 va_end(argp);
113 CuStringAppend(str, buf);
114}
115
116void CuStringInsert(CuString* str, const char* text, int pos)
117{
118 int length = strlen(text);
119 if (pos > str->length)
120 pos = str->length;
121 if (str->length + length + 1 >= str->size)
122 CuStringResize(str, str->length + length + 1 + STRING_INC);
123 memmove(str->buffer + pos + length, str->buffer + pos, (str->length - pos) + 1);
124 str->length += length;
125 memcpy(str->buffer + pos, text, length);
126}
127
128/*-------------------------------------------------------------------------*
129 * CuTest
130 *-------------------------------------------------------------------------*/
131
132void CuTestInit(CuTest* t, const char* name, TestFunction function)
133{
134 t->name = CuStrCopy(name);
135 t->failed = 0;
136 t->ran = 0;
137 t->message = NULL;
138 t->function = function;
139 t->jumpBuf = NULL;
140}
141
142CuTest* CuTestNew(const char* name, TestFunction function)
143{
144 CuTest* tc = CU_ALLOC(CuTest);
145 CuTestInit(tc, name, function);
146 return tc;
147}
148
149void CuTestRun(CuTest* tc)
150{
151 jmp_buf buf;
152 tc->jumpBuf = &buf;
153 if (setjmp(buf) == 0)
154 {
155 tc->ran = 1;
156 (tc->function)(tc);
157 }
158 tc->jumpBuf = 0;
159}
160
161static void CuFailInternal(CuTest* tc, const char* file, int line, CuString* string)
162{
163 char buf[HUGE_STRING_LEN];
164
165 sprintf(buf, "%s:%d: ", file, line);
166 CuStringInsert(string, buf, 0);
167
168 tc->failed = 1;
169 tc->message = string->buffer;
170 if (tc->jumpBuf != 0) longjmp(*(tc->jumpBuf), 0);
171}
172
173void CuFail_Line(CuTest* tc, const char* file, int line, const char* message2, const char* message)
174{
175 CuString string;
176
177 CuStringInit(&string);
178 if (message2 != NULL)
179 {
180 CuStringAppend(&string, message2);
181 CuStringAppend(&string, ": ");
182 }
183 CuStringAppend(&string, message);
184 CuFailInternal(tc, file, line, &string);
185}
186
187void CuAssert_Line(CuTest* tc, const char* file, int line, const char* message, int condition)
188{
189 if (condition) return;
190 CuFail_Line(tc, file, line, NULL, message);
191}
192
193void CuAssertStrEquals_LineMsg(CuTest* tc, const char* file, int line, const char* message,
194 const char* expected, const char* actual)
195{
196 CuString string;
197 if ((expected == NULL && actual == NULL) ||
198 (expected != NULL && actual != NULL &&
199 strcmp(expected, actual) == 0))
200 {
201 return;
202 }
203
204 CuStringInit(&string);
205 if (message != NULL)
206 {
207 CuStringAppend(&string, message);
208 CuStringAppend(&string, ": ");
209 }
210 CuStringAppend(&string, "expected <");
211 CuStringAppend(&string, expected);
212 CuStringAppend(&string, "> but was <");
213 CuStringAppend(&string, actual);
214 CuStringAppend(&string, ">");
215 CuFailInternal(tc, file, line, &string);
216}
217
218void CuAssertIntEquals_LineMsg(CuTest* tc, const char* file, int line, const char* message,
219 int expected, int actual)
220{
221 char buf[STRING_MAX];
222 if (expected == actual) return;
223 sprintf(buf, "expected <%d> but was <%d>", expected, actual);
224 CuFail_Line(tc, file, line, message, buf);
225}
226
227void CuAssertDblEquals_LineMsg(CuTest* tc, const char* file, int line, const char* message,
228 double expected, double actual, double delta)
229{
230 char buf[STRING_MAX];
231 if (fabs(expected - actual) <= delta) return;
232 sprintf(buf, "expected <%lf> but was <%lf>", expected, actual);
233 CuFail_Line(tc, file, line, message, buf);
234}
235
236void CuAssertPtrEquals_LineMsg(CuTest* tc, const char* file, int line, const char* message,
237 void* expected, void* actual)
238{
239 char buf[STRING_MAX];
240 if (expected == actual) return;
241 sprintf(buf, "expected pointer <0x%p> but was <0x%p>", expected, actual);
242 CuFail_Line(tc, file, line, message, buf);
243}
244
245
246/*-------------------------------------------------------------------------*
247 * CuSuite
248 *-------------------------------------------------------------------------*/
249
250void CuSuiteInit(CuSuite* testSuite)
251{
252 testSuite->count = 0;
253 testSuite->failCount = 0;
254}
255
256CuSuite* CuSuiteNew(void)
257{
258 CuSuite* testSuite = CU_ALLOC(CuSuite);
259 CuSuiteInit(testSuite);
260 return testSuite;
261}
262
263void CuSuiteAdd(CuSuite* testSuite, CuTest *testCase)
264{
265 assert(testSuite->count < MAX_TEST_CASES);
266 testSuite->list[testSuite->count] = testCase;
267 testSuite->count++;
268}
269
270void CuSuiteAddSuite(CuSuite* testSuite, CuSuite* testSuite2)
271{
272 int i;
273 for (i = 0 ; i < testSuite2->count ; ++i)
274 {
275 CuTest* testCase = testSuite2->list[i];
276 CuSuiteAdd(testSuite, testCase);
277 }
278}
279
280void CuSuiteRun(CuSuite* testSuite)
281{
282 int i;
283 for (i = 0 ; i < testSuite->count ; ++i)
284 {
285 CuTest* testCase = testSuite->list[i];
286 CuTestRun(testCase);
287 if (testCase->failed) { testSuite->failCount += 1; }
288 }
289}
290
291void CuSuiteSummary(CuSuite* testSuite, CuString* summary)
292{
293 int i;
294 for (i = 0 ; i < testSuite->count ; ++i)
295 {
296 CuTest* testCase = testSuite->list[i];
297 CuStringAppend(summary, testCase->failed ? "F" : ".");
298 }
299 CuStringAppend(summary, "\n\n");
300}
301
302void CuSuiteDetails(CuSuite* testSuite, CuString* details)
303{
304 int i;
305 int failCount = 0;
306
307 if (testSuite->failCount == 0)
308 {
309 int passCount = testSuite->count - testSuite->failCount;
310 const char* testWord = passCount == 1 ? "test" : "tests";
311 CuStringAppendFormat(details, "OK (%d %s)\n", passCount, testWord);
312 }
313 else
314 {
315 if (testSuite->failCount == 1)
316 CuStringAppend(details, "There was 1 failure:\n");
317 else
318 CuStringAppendFormat(details, "There were %d failures:\n", testSuite->failCount);
319
320 for (i = 0 ; i < testSuite->count ; ++i)
321 {
322 CuTest* testCase = testSuite->list[i];
323 if (testCase->failed)
324 {
325 failCount++;
326 CuStringAppendFormat(details, "%d) %s: %s\n",
327 failCount, testCase->name, testCase->message);
328 }
329 }
330 CuStringAppend(details, "\n!!!FAILURES!!!\n");
331
332 CuStringAppendFormat(details, "Runs: %d ", testSuite->count);
333 CuStringAppendFormat(details, "Passes: %d ", testSuite->count - testSuite->failCount);
334 CuStringAppendFormat(details, "Fails: %d\n", testSuite->failCount);
335 }
336}
Note: See TracBrowser for help on using the repository browser.