Skip to content

Instantly share code, notes, and snippets.

@ksss
Created February 19, 2012 13:39
Show Gist options
  • Save ksss/1863883 to your computer and use it in GitHub Desktop.
Save ksss/1863883 to your computer and use it in GitHub Desktop.
cspec
/*
cspec.c
*/
#include <stdio.h>
#include <time.h>
#include "cspec.h"
#define false 0
#define true (!0)
/* private & global variables */
static struct _global {
int count; /* test counter */
int in_count; /* test counter in one case */
int red; /* error counter */
int in_red; /* error counter in one case */
} _g;
void _test_ok (void) {
_g.count++;
_g.in_count++;
printf("%d/%d test ok\r", _g.in_count - _g.in_red, _g.in_count);
}
void _test_ng (void) {
_g.count++;
_g.in_count++;
_g.red++;
_g.in_red++;
}
/*
runner
@func: function array
@length: function array length for loop
*/
void _test_run (int (**func)(), int length) {
clock_t start, stop;
time_t timer;
int i;
printf("test case %d\n", length);
time(&timer);
printf("%s\n", ctime(&timer));
start = clock();
for (i = 0; i < length; i++) {
_g.in_count = 0;
_g.in_red = 0;
(*func[i])();
printf("\n\n");
}
printf("*****************\n");
(_g.red)
? printf("* R E D *\n")
: printf("* G R E E N *\n");
printf("*****************\n");
stop = clock();
printf("all %d/%d test ok\n", _g.count - _g.red, _g.count);
printf("error = %d\n", _g.red);
printf("time = %fs\n", (double)(stop - start) / CLOCKS_PER_SEC);
}
void self_test(void) {
printf("*** self test ***\n");
ok(true);
ng(false);
ok(false == false);
ng(true == false);
ok((int)"");
ok(NULL == false);
ng(NULL != false);
ok(("" == NULL) == false);
ng(("" != NULL) == false);
ok(NULL == (void*) 0);
ng(NULL != (void*) 0);
ok((void*) 0 == (char*) 0);
ng((void*) 0 != (char*) 0);
eq("", "");
eq(NULL, NULL);
eq("abc", "abc");
eq("a\nb\nc", "a\nb\nc");
eq("漢字", "漢字");
ne("", NULL);
ne("test", "text");
}
/*
=use example
int case0 (void) {
ok(true == true);
ok(3 == 3);
ok('a' == 'a');
eq("aaa", "aaa");
...
}
//jump table for test case (variable)
int (*test_case[]) (void) = {
case0,
case1,
case2,
};
////// test main ////////
int main (void) {
test_run(test_case);
return 0;
}
=out
test case 4
Tue Dec 13 09:38:28 2011
*** self test ***
[ok]
19/19 test ok
[ok count / case count #print by case function]
[ng (example: ok('a', 'b'))]
runner.c:17 => 'a' != 'b'
[filename:line => arg1 != arg2]
18/19 test ok
...
*** test example ***
24/24 test ok
[all ok]
*****************
* G R E E N *
*****************
[ng]
*****************
* R E D *
*****************
all 115/115 test ok
error = 0
time = 0.000000s
=end
*/
/*
cspec.h
*/
#ifndef CSPEC_H
#define CSPEC_H 1
#if defined(__cplusplus)
extern "C" {
#endif
extern void _test_ok (void);
extern void _test_ng (void);
extern void _test_run (int (**)(), int);
extern void self_test (void);
/* s1 equal s2 ? (use strcmp) */
#define STR_EQUAL(s1, s2)\
(((s1) && (s2)) ? !strcmp((s1), (s2)) : ((s1) == (s2)))
/* target is true? or false? */
#define ok(s) do {\
if (s) {\
_test_ok();\
} else {\
printf("%s:%d => %s is false", __FILE__, __LINE__, #s);\
_test_ng();\
}\
} while (0)
#define ng(s) do {\
if (!(s)) {\
_test_ok();\
} else {\
printf("%s:%d => %s is false", __FILE__, __LINE__, #s);\
_test_ng();\
}\
} while (0)
/* check only string equal string */
#define eq(s, t) do {\
char *res_s = (char *) s; /* function run only onece */\
char *res_t = (char *) t;\
if ((int)STR_EQUAL(res_s, res_t)) {\
_test_ok();\
} else {\
printf("%s:%d => %s != %s", __FILE__, __LINE__, #s, #t);\
_test_ng();\
}\
} while (0)
#define ne(s, t) do {\
char *res_s = (char *) s;\
char *res_t = (char *) t;\
if ((int)!STR_EQUAL(res_s, res_t)) {\
_test_ok();\
} else {\
printf("%s:%d => %s != %s", __FILE__, __LINE__, #s, #t);\
_test_ng();\
}\
} while (0)
#define test_run(f)\
_test_run(f, sizeof(f) / sizeof(*f))
#if defined(__cplusplus)
} /* extern "C" { */
#endif
#endif /* CSPEC_H */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment