CuTest.c

00001 #include <assert.h>
00002 #include <setjmp.h>
00003 #include <stdlib.h>
00004 #include <stdio.h>
00005 #include <string.h>
00006 #include <math.h>
00007 
00008 #include "CuTest.h"
00009 
00010 /*-------------------------------------------------------------------------*
00011  * CuStr
00012  *-------------------------------------------------------------------------*/
00013 
00014 char* CuStrAlloc(int size)
00015 {
00016     char* newStr = (char*) malloc( sizeof(char) * (size) );
00017     return newStr;
00018 }
00019 
00020 char* CuStrCopy(const char* old)
00021 {
00022     int len = strlen(old);
00023     char* newStr = CuStrAlloc(len + 1);
00024     strcpy(newStr, old);
00025     return newStr;
00026 }
00027 
00028 /*-------------------------------------------------------------------------*
00029  * CuString
00030  *-------------------------------------------------------------------------*/
00031 
00032 void CuStringInit(CuString* str)
00033 {
00034     str->length = 0;
00035     str->size = STRING_MAX;
00036     str->buffer = (char*) malloc(sizeof(char) * str->size);
00037     str->buffer[0] = '\0';
00038 }
00039 
00040 CuString* CuStringNew(void)
00041 {
00042     CuString* str = (CuString*) malloc(sizeof(CuString));
00043     str->length = 0;
00044     str->size = STRING_MAX;
00045     str->buffer = (char*) malloc(sizeof(char) * str->size);
00046     str->buffer[0] = '\0';
00047     return str;
00048 }
00049 
00050 void CuStringResize(CuString* str, int newSize)
00051 {
00052     str->buffer = (char*) realloc(str->buffer, sizeof(char) * newSize);
00053     str->size = newSize;
00054 }
00055 
00056 void CuStringAppend(CuString* str, const char* text)
00057 {
00058     int length;
00059 
00060     if (text == NULL) {
00061         text = "NULL";
00062     }
00063 
00064     length = strlen(text);
00065     if (str->length + length + 1 >= str->size)
00066         CuStringResize(str, str->length + length + 1 + STRING_INC);
00067     str->length += length;
00068     strcat(str->buffer, text);
00069 }
00070 
00071 void CuStringAppendChar(CuString* str, char ch)
00072 {
00073     char text[2];
00074     text[0] = ch;
00075     text[1] = '\0';
00076     CuStringAppend(str, text);
00077 }
00078 
00079 void CuStringAppendFormat(CuString* str, const char* format, ...)
00080 {
00081     va_list argp;
00082     char buf[HUGE_STRING_LEN];
00083     va_start(argp, format);
00084     vsprintf(buf, format, argp);
00085     va_end(argp);
00086     CuStringAppend(str, buf);
00087 }
00088 
00089 void CuStringInsert(CuString* str, const char* text, int pos)
00090 {
00091     int length = strlen(text);
00092     if (pos > str->length)
00093         pos = str->length;
00094     if (str->length + length + 1 >= str->size)
00095         CuStringResize(str, str->length + length + 1 + STRING_INC);
00096     memmove(str->buffer + pos + length, str->buffer + pos, (str->length - pos) + 1);
00097     str->length += length;
00098     memcpy(str->buffer + pos, text, length);
00099 }
00100 
00101 /*-------------------------------------------------------------------------*
00102  * CuTest
00103  *-------------------------------------------------------------------------*/
00104 
00105 void CuTestInit(CuTest* t, const char* name, TestFunction function)
00106 {
00107     t->name = CuStrCopy(name);
00108     t->failed = 0;
00109     t->ran = 0;
00110     t->message = NULL;
00111     t->function = function;
00112     t->jumpBuf = NULL;
00113 }
00114 
00115 CuTest* CuTestNew(const char* name, TestFunction function)
00116 {
00117     CuTest* tc = CU_ALLOC(CuTest);
00118     CuTestInit(tc, name, function);
00119     return tc;
00120 }
00121 
00122 void CuTestRun(CuTest* tc)
00123 {
00124     jmp_buf buf;
00125     tc->jumpBuf = &buf;
00126     if (setjmp(buf) == 0)
00127     {
00128         tc->ran = 1;
00129         (tc->function)(tc);
00130     }
00131     tc->jumpBuf = 0;
00132 }
00133 
00134 static void CuFailInternal(CuTest* tc, const char* file, int line, CuString* string)
00135 {
00136     char buf[HUGE_STRING_LEN];
00137 
00138     sprintf(buf, "%s:%d: ", file, line);
00139     CuStringInsert(string, buf, 0);
00140 
00141     tc->failed = 1;
00142     tc->message = string->buffer;
00143     if (tc->jumpBuf != 0) longjmp(*(tc->jumpBuf), 0);
00144 }
00145 
00146 void CuFail_Line(CuTest* tc, const char* file, int line, const char* message2, const char* message)
00147 {
00148     CuString string;
00149 
00150     CuStringInit(&string);
00151     if (message2 != NULL) 
00152     {
00153         CuStringAppend(&string, message2);
00154         CuStringAppend(&string, ": ");
00155     }
00156     CuStringAppend(&string, message);
00157     CuFailInternal(tc, file, line, &string);
00158 }
00159 
00160 void CuAssert_Line(CuTest* tc, const char* file, int line, const char* message, int condition)
00161 {
00162     if (condition) return;
00163     CuFail_Line(tc, file, line, NULL, message);
00164 }
00165 
00166 void CuAssertStrEquals_LineMsg(CuTest* tc, const char* file, int line, const char* message, 
00167     const char* expected, const char* actual)
00168 {
00169     CuString string;
00170     if ((expected == NULL && actual == NULL) ||
00171         (expected != NULL && actual != NULL &&
00172          strcmp(expected, actual) == 0))
00173     {
00174         return;
00175     }
00176 
00177     CuStringInit(&string);
00178     if (message != NULL) 
00179     {
00180         CuStringAppend(&string, message);
00181         CuStringAppend(&string, ": ");
00182     }
00183     CuStringAppend(&string, "expected <");
00184     CuStringAppend(&string, expected);
00185     CuStringAppend(&string, "> but was <");
00186     CuStringAppend(&string, actual);
00187     CuStringAppend(&string, ">");
00188     CuFailInternal(tc, file, line, &string);
00189 }
00190 
00191 void CuAssertIntEquals_LineMsg(CuTest* tc, const char* file, int line, const char* message, 
00192     int expected, int actual)
00193 {
00194     char buf[STRING_MAX];
00195     if (expected == actual) return;
00196     sprintf(buf, "expected <%d> but was <%d>", expected, actual);
00197     CuFail_Line(tc, file, line, message, buf);
00198 }
00199 
00200 void CuAssertDblEquals_LineMsg(CuTest* tc, const char* file, int line, const char* message, 
00201     double expected, double actual, double delta)
00202 {
00203     char buf[STRING_MAX];
00204     if (fabs(expected - actual) <= delta) return;
00205     sprintf(buf, "expected <%lf> but was <%lf>", expected, actual);
00206     CuFail_Line(tc, file, line, message, buf);
00207 }
00208 
00209 void CuAssertPtrEquals_LineMsg(CuTest* tc, const char* file, int line, const char* message, 
00210     void* expected, void* actual)
00211 {
00212     char buf[STRING_MAX];
00213     if (expected == actual) return;
00214     sprintf(buf, "expected pointer <0x%p> but was <0x%p>", expected, actual);
00215     CuFail_Line(tc, file, line, message, buf);
00216 }
00217 
00218 
00219 /*-------------------------------------------------------------------------*
00220  * CuSuite
00221  *-------------------------------------------------------------------------*/
00222 
00223 void CuSuiteInit(CuSuite* testSuite)
00224 {
00225     testSuite->count = 0;
00226     testSuite->failCount = 0;
00227 }
00228 
00229 CuSuite* CuSuiteNew(void)
00230 {
00231     CuSuite* testSuite = CU_ALLOC(CuSuite);
00232     CuSuiteInit(testSuite);
00233     return testSuite;
00234 }
00235 
00236 void CuSuiteAdd(CuSuite* testSuite, CuTest *testCase)
00237 {
00238     assert(testSuite->count < MAX_TEST_CASES);
00239     testSuite->list[testSuite->count] = testCase;
00240     testSuite->count++;
00241 }
00242 
00243 void CuSuiteAddSuite(CuSuite* testSuite, CuSuite* testSuite2)
00244 {
00245     int i;
00246     for (i = 0 ; i < testSuite2->count ; ++i)
00247     {
00248         CuTest* testCase = testSuite2->list[i];
00249         CuSuiteAdd(testSuite, testCase);
00250     }
00251 }
00252 
00253 void CuSuiteRun(CuSuite* testSuite)
00254 {
00255     int i;
00256     for (i = 0 ; i < testSuite->count ; ++i)
00257     {
00258         CuTest* testCase = testSuite->list[i];
00259         CuTestRun(testCase);
00260         if (testCase->failed) { testSuite->failCount += 1; }
00261     }
00262 }
00263 
00264 void CuSuiteSummary(CuSuite* testSuite, CuString* summary)
00265 {
00266     int i;
00267     for (i = 0 ; i < testSuite->count ; ++i)
00268     {
00269         CuTest* testCase = testSuite->list[i];
00270         CuStringAppend(summary, testCase->failed ? "F" : ".");
00271     }
00272     CuStringAppend(summary, "\n\n");
00273 }
00274 
00275 void CuSuiteDetails(CuSuite* testSuite, CuString* details)
00276 {
00277     int i;
00278     int failCount = 0;
00279 
00280     if (testSuite->failCount == 0)
00281     {
00282         int passCount = testSuite->count - testSuite->failCount;
00283         const char* testWord = passCount == 1 ? "test" : "tests";
00284         CuStringAppendFormat(details, "OK (%d %s)\n", passCount, testWord);
00285     }
00286     else
00287     {
00288         if (testSuite->failCount == 1)
00289             CuStringAppend(details, "There was 1 failure:\n");
00290         else
00291             CuStringAppendFormat(details, "There were %d failures:\n", testSuite->failCount);
00292 
00293         for (i = 0 ; i < testSuite->count ; ++i)
00294         {
00295             CuTest* testCase = testSuite->list[i];
00296             if (testCase->failed)
00297             {
00298                 failCount++;
00299                 CuStringAppendFormat(details, "%d) %s: %s\n",
00300                     failCount, testCase->name, testCase->message);
00301             }
00302         }
00303         CuStringAppend(details, "\n!!!FAILURES!!!\n");
00304 
00305         CuStringAppendFormat(details, "Runs: %d ",   testSuite->count);
00306         CuStringAppendFormat(details, "Passes: %d ", testSuite->count - testSuite->failCount);
00307         CuStringAppendFormat(details, "Fails: %d\n",  testSuite->failCount);
00308     }
00309 }

Generated on Mon Oct 18 07:40:47 2010 for Python-on-a-chip by  doxygen 1.5.9