diff options
Diffstat (limited to 'tests/test_lib.c')
-rwxr-xr-x[-rw-r--r--] | tests/test_lib.c | 234 |
1 files changed, 159 insertions, 75 deletions
diff --git a/tests/test_lib.c b/tests/test_lib.c index 1ce3f92bf..3c3d7e5db 100644..100755 --- a/tests/test_lib.c +++ b/tests/test_lib.c @@ -1,95 +1,179 @@ -/* - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 2, - * as published by the Free Software Foundation. - * - * In addition to the permissions in the GNU General Public License, - * the authors give you unlimited permission to link the compiled - * version of this file into combinations with other programs, - * and to distribute those combinations without any restriction - * coming from the use of this file. (The General Public License - * restrictions do apply in other respects; for example, they cover - * modification of the file, and distribution when not linked into - * a combined executable.) - * - * This file is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#define GIT__NO_HIDE_MALLOC +#include <assert.h> +#include <setjmp.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <math.h> + #include "test_lib.h" -struct test_info { - struct test_info *next; - const char *test_name; - const char *file_name; - int line_no; +#define DO_ALLOC(TYPE) ((TYPE*) malloc(sizeof(TYPE))) +#define GIT_MAX_TEST_CASES 64 + +struct git_test { + char *name; + git_testfunc function; + int failed; + int ran; + const char *message; + jmp_buf *jump; +}; + +struct git_testsuite { + char *name; + int count, fail_count; + git_test *list[GIT_MAX_TEST_CASES]; }; -static int first_test = 1; -static struct test_info *current_test; +static void test_init(git_test *t, const char *name, git_testfunc function) +{ + t->name = strdup(name); + t->failed = 0; + t->ran = 0; + t->message = NULL; + t->function = function; + t->jump = NULL; +} + +static void test_free(git_test *t) +{ + if (t) { + free(t->name); + free(t); + } +} + +void test_run(git_test *tc) +{ + jmp_buf buf; + tc->jump = &buf; + + if (setjmp(buf) == 0) { + tc->ran = 1; + (tc->function)(tc); + } + + tc->jump = 0; +} + +git_test *git_test_new(const char *name, git_testfunc function) +{ + git_test *tc = DO_ALLOC(git_test); + test_init(tc, name, function); + return tc; +} + + +/*-------------------------------------------------------------------------* + * Public assert methods + *-------------------------------------------------------------------------*/ + +static void fail_test(git_test *tc, const char *file, int line, const char *message) +{ + char buf[1024]; + + snprintf(buf, 1024, "%s @ %s:%d", message, file, line); + + tc->failed = 1; + tc->message = strdup(buf); -static void show_test_result(const char *status) + if (tc->jump != 0) + longjmp(*(tc->jump), 0); +} + +void git_test__fail(git_test *tc, const char *file, int line, const char *message) { - fprintf(stderr, "* %-6s %5d: %s\n", - status, - current_test->line_no, - current_test->test_name); + fail_test(tc, file, line, message); } -void test_die(const char *fmt, ...) +void git_test__assert(git_test *tc, const char *file, int line, const char *message, int condition) { - va_list p; + if (condition == 0) + fail_test(tc, file, line, message); +} - if (current_test) - show_test_result("FAILED"); +/*-------------------------------------------------------------------------* + * Test Suite + *-------------------------------------------------------------------------*/ - va_start(p, fmt); - vfprintf(stderr, fmt, p); - va_end(p); - fputc('\n', stderr); - fflush(stderr); - exit(128); +static void testsuite_init(git_testsuite *ts) +{ + ts->count = 0; + ts->fail_count = 0; + memset(ts->list, 0, sizeof(ts->list)); +} + +git_testsuite *git_testsuite_new(const char *name) +{ + git_testsuite *ts = DO_ALLOC(git_testsuite); + testsuite_init(ts); + ts->name = strdup(name); + return ts; } -void test_begin( - const char *test_name, - const char *file_name, - int line_no) +void git_testsuite_free(git_testsuite *ts) { - struct test_info *i = malloc(sizeof(*i)); - if (!i) - test_die("cannot malloc memory"); - - i->test_name = test_name; - i->file_name = file_name; - i->line_no = line_no; - current_test = i; - - if (first_test) { - const char *name = strrchr(i->file_name, '/'); - if (name) - name = name + 1; - else - name = i->file_name; - fprintf(stderr, "*** %s ***\n", name); - first_test = 0; + unsigned int n; + + for (n = 0; n < GIT_MAX_TEST_CASES; n++) + if (ts->list[n]) + test_free(ts->list[n]); + + free(ts); +} + +void git_testsuite_add(git_testsuite *ts, git_test *tc) +{ + assert(ts->count < GIT_MAX_TEST_CASES); + ts->list[ts->count++] = tc; +} + +void git_testsuite_addsuite(git_testsuite *ts, git_testsuite *ts2) +{ + int i; + for (i = 0 ; i < ts2->count ; ++i) + git_testsuite_add(ts, ts2->list[i]); +} + + +static void print_details(git_testsuite *ts) +{ + int i; + int failCount = 0; + + if (ts->fail_count == 0) { + const char *testWord = ts->count == 1 ? "test" : "tests"; + printf("OK (%d %s)\n", ts->count, testWord); + } else { + printf("Failed (%d failures):\n", ts->fail_count); + + for (i = 0 ; i < ts->count ; ++i) { + git_test *tc = ts->list[i]; + if (tc->failed) { + failCount++; + printf(" %d) %s: %s\n", failCount, tc->name, tc->message); + } + } } } -void test_end(void) +void git_testsuite_run(git_testsuite *ts) { - if (!current_test) - test_die("BEGIN_TEST() not used before END_TEST"); + int i; + + printf("Suite \"%s\": ", ts->name); - show_test_result("ok"); - free(current_test); - current_test = NULL; + for (i = 0 ; i < ts->count ; ++i) { + git_test *tc = ts->list[i]; + + test_run(tc); + if (tc->failed) { + ts->fail_count++; + putchar('F'); + } else + putchar('.'); + } + printf("\n "); + print_details(ts); } + |