libsheepy

C lib for handling text files, strings and json like data structure with an object oriented system
git clone https://spartatek.se/git/libsheepy.git
Log | Files | Refs | README | LICENSE

CuTest.c (10435B)


      1 #include <assert.h>
      2 #include <setjmp.h>
      3 #include <stdlib.h>
      4 #include <stdio.h>
      5 #include <string.h>
      6 #include <math.h>
      7 #include <inttypes.h>
      8 
      9 #include "CuTest.h"
     10 
     11 /*-------------------------------------------------------------------------*
     12  * CuStr
     13  *-------------------------------------------------------------------------*/
     14 
     15 char* CuStrAlloc(int size)
     16 {
     17 	char* newStr = (char*) malloc( sizeof(char) * (size) );
     18 	return newStr;
     19 }
     20 
     21 char* CuStrCopy(const char* old)
     22 {
     23 	int len = strlen(old);
     24 	char* newStr = CuStrAlloc(len + 1);
     25 	strcpy(newStr, old);
     26 	return newStr;
     27 }
     28 
     29 /*-------------------------------------------------------------------------*
     30  * CuString
     31  *-------------------------------------------------------------------------*/
     32 
     33 void CuStringInit(CuString* str)
     34 {
     35 	str->length = 0;
     36 	str->size = STRING_MAX;
     37 	str->buffer = (char*) malloc(sizeof(char) * str->size);
     38 	str->buffer[0] = '\0';
     39 }
     40 
     41 CuString* CuStringNew(void)
     42 {
     43 	CuString* str = (CuString*) malloc(sizeof(CuString));
     44 	str->length = 0;
     45 	str->size = STRING_MAX;
     46 	str->buffer = (char*) malloc(sizeof(char) * str->size);
     47 	str->buffer[0] = '\0';
     48 	return str;
     49 }
     50 
     51 void CuStringDelete(CuString *str)
     52 {
     53         if (!str) return;
     54         free(str->buffer);
     55         free(str);
     56 }
     57 
     58 void CuStringResize(CuString* str, int newSize)
     59 {
     60 	str->buffer = (char*) realloc(str->buffer, sizeof(char) * newSize);
     61 	str->size = newSize;
     62 }
     63 
     64 void CuStringAppend(CuString* str, const char* text)
     65 {
     66 	int length;
     67 
     68 	if (text == NULL) {
     69 		text = "NULL";
     70 	}
     71 
     72 	length = strlen(text);
     73 	if (str->length + length + 1 >= str->size)
     74 		CuStringResize(str, str->length + length + 1 + STRING_INC);
     75 	str->length += length;
     76 	strcat(str->buffer, text);
     77 }
     78 
     79 void CuStringAppendChar(CuString* str, char ch)
     80 {
     81 	char text[2];
     82 	text[0] = ch;
     83 	text[1] = '\0';
     84 	CuStringAppend(str, text);
     85 }
     86 
     87 void CuStringAppendFormat(CuString* str, const char* format, ...)
     88 {
     89 	va_list argp;
     90 	char buf[HUGE_STRING_LEN];
     91 	va_start(argp, format);
     92 	vsprintf(buf, format, argp);
     93 	va_end(argp);
     94 	CuStringAppend(str, buf);
     95 }
     96 
     97 void CuStringInsert(CuString* str, const char* text, int pos)
     98 {
     99 	int length = strlen(text);
    100 	if (pos > str->length)
    101 		pos = str->length;
    102 	if (str->length + length + 1 >= str->size)
    103 		CuStringResize(str, str->length + length + 1 + STRING_INC);
    104 	memmove(str->buffer + pos + length, str->buffer + pos, (str->length - pos) + 1);
    105 	str->length += length;
    106 	memcpy(str->buffer + pos, text, length);
    107 }
    108 
    109 /*-------------------------------------------------------------------------*
    110  * CuTest
    111  *-------------------------------------------------------------------------*/
    112 
    113 void CuTestInit(CuTest* t, const char* name, TestFunction function)
    114 {
    115 	t->name = CuStrCopy(name);
    116 	t->failed = 0;
    117 	t->ran = 0;
    118         t->message = NULL;
    119 	t->function = function;
    120 	t->jumpBuf = NULL;
    121 }
    122 
    123 CuTest* CuTestNew(const char* name, TestFunction function)
    124 {
    125 	CuTest* tc = CU_ALLOC(CuTest);
    126 	CuTestInit(tc, name, function);
    127 	return tc;
    128 }
    129 
    130 void CuTestDelete(CuTest *t)
    131 {
    132         if (!t) return;
    133         CuStringDelete(t->message);
    134         free(t->name);
    135         free(t);
    136 }
    137 
    138 void CuTestRun(CuTest* tc)
    139 {
    140 	jmp_buf buf;
    141 	tc->jumpBuf = &buf;
    142 	if (setjmp(buf) == 0)
    143 	{
    144 		tc->ran = 1;
    145 		(tc->function)(tc);
    146 	}
    147 	tc->jumpBuf = 0;
    148 }
    149 
    150 static void CuFailInternal(CuTest* tc, const char* file, int line, CuString* string)
    151 {
    152 	char buf[HUGE_STRING_LEN];
    153 
    154 	sprintf(buf, "%s:%d: ", file, line);
    155 	CuStringInsert(string, buf, 0);
    156 
    157 	tc->failed = 1;
    158         free(tc->message);
    159         tc->message = CuStringNew();
    160         CuStringAppend(tc->message, string->buffer);
    161 	if (tc->jumpBuf != 0) longjmp(*(tc->jumpBuf), 0);
    162 }
    163 
    164 void CuFail_Line(CuTest* tc, const char* file, int line, const char* message2, const char* message)
    165 {
    166 	CuString string;
    167 
    168 	CuStringInit(&string);
    169 	if (message2 != NULL)
    170 	{
    171 		CuStringAppend(&string, message2);
    172 		CuStringAppend(&string, ": ");
    173 	}
    174 	CuStringAppend(&string, message);
    175 	CuFailInternal(tc, file, line, &string);
    176 }
    177 
    178 void CuAssert_Line(CuTest* tc, const char* file, int line, const char* message, int condition)
    179 {
    180 	if (condition) return;
    181 	CuFail_Line(tc, file, line, NULL, message);
    182 }
    183 
    184 void CuAssertStrEquals_LineMsg(CuTest* tc, const char* file, int line, const char* message,
    185 	const char* expected, const char* actual)
    186 {
    187 	CuString string;
    188 	if ((expected == NULL && actual == NULL) ||
    189 	    (expected != NULL && actual != NULL &&
    190 	     strcmp(expected, actual) == 0))
    191 	{
    192 		return;
    193 	}
    194 
    195 	CuStringInit(&string);
    196 	if (message != NULL)
    197 	{
    198 		CuStringAppend(&string, message);
    199 		CuStringAppend(&string, ": ");
    200 	}
    201 	CuStringAppend(&string, "expected <");
    202 	CuStringAppend(&string, expected);
    203 	CuStringAppend(&string, "> but was <");
    204 	CuStringAppend(&string, actual);
    205 	CuStringAppend(&string, ">");
    206 	CuFailInternal(tc, file, line, &string);
    207 }
    208 
    209 void CuAssertDblEquals_LineMsg(CuTest* tc, const char* file, int line, const char* message,
    210 	double expected, double actual, double delta)
    211 {
    212 	char buf[STRING_MAX];
    213 	if (fabs(expected - actual) <= delta) return;
    214 	sprintf(buf, "expected <%f> but was <%f>", expected, actual);
    215 
    216 	CuFail_Line(tc, file, line, message, buf);
    217 }
    218 
    219 
    220 /*-------------------------------------------------------------------------*
    221  * CuSuite
    222  *-------------------------------------------------------------------------*/
    223 
    224 void CuSuiteInit(CuSuite* testSuite)
    225 {
    226 	testSuite->count = 0;
    227 	testSuite->failCount = 0;
    228         memset(testSuite->list, 0, sizeof(testSuite->list));
    229 }
    230 
    231 CuSuite* CuSuiteNew(void)
    232 {
    233 	CuSuite* testSuite = CU_ALLOC(CuSuite);
    234 	CuSuiteInit(testSuite);
    235 	return testSuite;
    236 }
    237 
    238 void CuSuiteDelete(CuSuite *testSuite)
    239 {
    240         unsigned int n;
    241         for (n=0; n < MAX_TEST_CASES; n++)
    242         {
    243                 if (testSuite->list[n])
    244                 {
    245                         CuTestDelete(testSuite->list[n]);
    246                 }
    247         }
    248         free(testSuite);
    249 
    250 }
    251 
    252 void CuSuiteAdd(CuSuite* testSuite, CuTest *testCase)
    253 {
    254 	assert(testSuite->count < MAX_TEST_CASES);
    255 	testSuite->list[testSuite->count] = testCase;
    256 	testSuite->count++;
    257 }
    258 
    259 void CuSuiteAddSuite(CuSuite* testSuite, CuSuite* testSuite2)
    260 {
    261 	int i;
    262 	for (i = 0 ; i < testSuite2->count ; ++i)
    263 	{
    264 		CuTest* testCase = testSuite2->list[i];
    265 		CuSuiteAdd(testSuite, testCase);
    266 	}
    267 }
    268 
    269 void CuSuiteRun(CuSuite* testSuite)
    270 {
    271 	int i;
    272 	for (i = 0 ; i < testSuite->count ; ++i)
    273 	{
    274 		CuTest* testCase = testSuite->list[i];
    275 		CuTestRun(testCase);
    276 		if (testCase->failed) { testSuite->failCount += 1; }
    277 	}
    278 }
    279 
    280 void CuSuiteSummary(CuSuite* testSuite, CuString* summary)
    281 {
    282 	int i;
    283 	for (i = 0 ; i < testSuite->count ; ++i)
    284 	{
    285 		CuTest* testCase = testSuite->list[i];
    286 		CuStringAppend(summary, testCase->failed ? "F" : ".");
    287 	}
    288 	CuStringAppend(summary, "\n\n");
    289 }
    290 
    291 void CuSuiteDetails(CuSuite* testSuite, CuString* details)
    292 {
    293 	int i;
    294 	int failCount = 0;
    295 
    296 	if (testSuite->failCount == 0)
    297 	{
    298 		int passCount = testSuite->count - testSuite->failCount;
    299 		const char* testWord = passCount == 1 ? "test" : "tests";
    300 		CuStringAppendFormat(details, "OK (%d %s)\n", passCount, testWord);
    301 	}
    302 	else
    303 	{
    304 		if (testSuite->failCount == 1)
    305 			CuStringAppend(details, "There was 1 failure:\n");
    306 		else
    307 			CuStringAppendFormat(details, "There were %d failures:\n", testSuite->failCount);
    308 
    309 		for (i = 0 ; i < testSuite->count ; ++i)
    310 		{
    311 			CuTest* testCase = testSuite->list[i];
    312 			if (testCase->failed)
    313 			{
    314 				failCount++;
    315 				CuStringAppendFormat(details, "%d) %s: %s\n",
    316 					failCount, testCase->name, testCase->message->buffer);
    317 			}
    318 		}
    319 		CuStringAppend(details, "\n!!!FAILURES!!!\n");
    320 
    321 		CuStringAppendFormat(details, "Runs: %d ",   testSuite->count);
    322 		CuStringAppendFormat(details, "Passes: %d ", testSuite->count - testSuite->failCount);
    323 		CuStringAppendFormat(details, "Fails: %d\n",  testSuite->failCount);
    324 	}
    325 }
    326 
    327 
    328 /*-------------------------------------------------------------------------*
    329  * CuTest changes by Remy Noulin
    330  *-------------------------------------------------------------------------*/
    331 
    332 
    333 void CuAssertStrNotEquals_LineMsg(CuTest* tc, const char* file, int line, const char* message,
    334 	const char* expected, const char* actual)
    335 {
    336 	CuString string;
    337 	if ((expected == NULL && actual == NULL) ||
    338 	    (expected != NULL && actual != NULL &&
    339 	     strcmp(expected, actual) == 0))
    340 	{
    341 		CuStringInit(&string);
    342 		if (message != NULL)
    343 		{
    344 			CuStringAppend(&string, message);
    345 			CuStringAppend(&string, ": ");
    346 		}
    347 		CuStringAppend(&string, "expected <");
    348 		CuStringAppend(&string, expected);
    349 		CuStringAppend(&string, "> not equal to <");
    350 		CuStringAppend(&string, actual);
    351 		CuStringAppend(&string, ">");
    352 		CuFailInternal(tc, file, line, &string);
    353 	}
    354 
    355 	return;
    356 }
    357 
    358 void CuAssertPtrEquals_LineMsg(CuTest* tc, const char* file, int line, const char* message,
    359 	const void* expected, const void* actual)
    360 {
    361 	char buf[STRING_MAX];
    362 	if (expected == actual) return;
    363 	sprintf(buf, "expected pointer <0x%p> but was <0x%p>", expected, actual);
    364 	CuFail_Line(tc, file, line, message, buf);
    365 }
    366 
    367 void CuAssertPtrNotEquals_LineMsg(CuTest* tc, const char* file, int line, const char* message,
    368 	const void* expected, const void* actual)
    369 {
    370 	char buf[STRING_MAX];
    371 	if (expected == actual)
    372 	{
    373 		sprintf(buf, "expected pointer <0x%p> not equal to <0x%p>", expected, actual);
    374 		CuFail_Line(tc, file, line, message, buf);
    375 		return;
    376 	}
    377 }
    378 
    379 void CuAssertUintEquals_LineMsg(CuTest* tc, const char* file, int line, const char* message,
    380 	uint64_t expected, uint64_t actual)
    381 {
    382 	char buf[STRING_MAX];
    383 	if (expected == actual) return;
    384 	sprintf(buf, "expected <%"PRIu64"> but was <%"PRIu64">", expected, actual);
    385 	CuFail_Line(tc, file, line, message, buf);
    386 }
    387 
    388 void CuAssertUintNotEquals_LineMsg(CuTest* tc, const char* file, int line, const char* message,
    389 	uint64_t expected, uint64_t actual)
    390 {
    391 	char buf[STRING_MAX];
    392 	if (expected == actual)
    393  	{
    394 		sprintf(buf, "expected <%"PRIu64"> not equal to <%"PRIu64">", expected, actual);
    395 		CuFail_Line(tc, file, line, message, buf);
    396 		return;
    397 	}
    398 }
    399 
    400 void CuAssertIntEquals_LineMsg(CuTest* tc, const char* file, int line, const char* message,
    401 	int64_t expected, int64_t actual)
    402 {
    403 	char buf[STRING_MAX];
    404 	if (expected == actual) return;
    405 	sprintf(buf, "expected <%"PRIi64"> but was <%"PRIi64">", expected, actual);
    406 	CuFail_Line(tc, file, line, message, buf);
    407 }
    408 
    409 void CuAssertIntNotEquals_LineMsg(CuTest* tc, const char* file, int line, const char* message,
    410 	int64_t expected, int64_t actual)
    411 {
    412 	char buf[STRING_MAX];
    413 	if (expected == actual)
    414 	{
    415 		sprintf(buf, "expected <%"PRIi64"> not equal to <%"PRIi64">", expected, actual);
    416 		CuFail_Line(tc, file, line, message, buf);
    417 		return;
    418 	}
    419 }
    420