mirror of
				https://git.proxmox.com/git/libgit2
				synced 2025-11-04 04:38:58 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			199 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			199 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
#include <assert.h>
 | 
						|
#include <setjmp.h>
 | 
						|
#include <stdlib.h>
 | 
						|
#include <stdio.h>
 | 
						|
#include <string.h>
 | 
						|
#include <math.h>
 | 
						|
 | 
						|
#include "test_lib.h"
 | 
						|
 | 
						|
#define DO_ALLOC(TYPE) ((TYPE*) malloc(sizeof(TYPE)))
 | 
						|
#define GIT_MAX_TEST_CASES 64
 | 
						|
 | 
						|
struct git_test {
 | 
						|
	char *name;
 | 
						|
	char *message;
 | 
						|
	char *failed_pos;
 | 
						|
	char *description;
 | 
						|
	char *error_message;
 | 
						|
 | 
						|
	git_testfunc function;
 | 
						|
	unsigned failed:1, ran:1;
 | 
						|
	jmp_buf *jump;
 | 
						|
};
 | 
						|
 | 
						|
struct git_testsuite {
 | 
						|
	char *name;
 | 
						|
	int count, fail_count;
 | 
						|
	git_test *list[GIT_MAX_TEST_CASES];
 | 
						|
};
 | 
						|
 | 
						|
static void test_free(git_test *t)
 | 
						|
{
 | 
						|
	if (t) {
 | 
						|
		free(t->name);
 | 
						|
		free(t->description);
 | 
						|
		free(t->failed_pos);
 | 
						|
		free(t->message);
 | 
						|
		free(t->error_message);
 | 
						|
		free(t);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
static 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;
 | 
						|
}
 | 
						|
 | 
						|
static git_test *create_test(git_testfunc function)
 | 
						|
{
 | 
						|
	git_test *t = DO_ALLOC(git_test);
 | 
						|
 | 
						|
	memset(t, 0x0, sizeof(git_test));
 | 
						|
	t->function = function;
 | 
						|
 | 
						|
	return t;
 | 
						|
}
 | 
						|
 | 
						|
void git_test__init(git_test *t, const char *name, const char *description)
 | 
						|
{
 | 
						|
	t->name = strdup(name);
 | 
						|
	t->description = strdup(description);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------*
 | 
						|
 * Public assert methods
 | 
						|
 *-------------------------------------------------------------------------*/
 | 
						|
 | 
						|
static void fail_test(git_test *tc, const char *file, int line, const char *message)
 | 
						|
{
 | 
						|
	char buf[1024];
 | 
						|
	const char *last_error = git_lasterror();
 | 
						|
 | 
						|
	snprintf(buf, 1024, "%s:%d", file, line);
 | 
						|
 | 
						|
	tc->failed = 1;
 | 
						|
	tc->message = strdup(message);
 | 
						|
	tc->failed_pos = strdup(buf);
 | 
						|
 | 
						|
	if (last_error)
 | 
						|
		tc->error_message = strdup(last_error);
 | 
						|
 | 
						|
	if (tc->jump != 0)
 | 
						|
		longjmp(*(tc->jump), 0);
 | 
						|
}
 | 
						|
 | 
						|
void git_test__fail(git_test *tc, const char *file, int line, const char *message)
 | 
						|
{
 | 
						|
	fail_test(tc, file, line, message);
 | 
						|
}
 | 
						|
 | 
						|
void git_test__assert(git_test *tc, const char *file, int line, const char *message, int condition)
 | 
						|
{
 | 
						|
	if (condition == 0)
 | 
						|
		fail_test(tc, file, line, message);
 | 
						|
}
 | 
						|
 | 
						|
void git_test__assert_pass(git_test *tc, const char *file, int line, const char *message, int ret_value)
 | 
						|
{
 | 
						|
	if (ret_value < 0)
 | 
						|
		fail_test(tc, file, line, message);
 | 
						|
}
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------*
 | 
						|
 * Test Suite
 | 
						|
 *-------------------------------------------------------------------------*/
 | 
						|
 | 
						|
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;
 | 
						|
}
 | 
						|
 | 
						|
static void free_suite(git_testsuite *ts)
 | 
						|
{
 | 
						|
	unsigned int n;
 | 
						|
 | 
						|
	for (n = 0; n < GIT_MAX_TEST_CASES; n++)
 | 
						|
		if (ts->list[n])
 | 
						|
			test_free(ts->list[n]);
 | 
						|
 | 
						|
	free(ts->name);
 | 
						|
	free(ts);
 | 
						|
}
 | 
						|
 | 
						|
void git_testsuite_add(git_testsuite *ts, git_testfunc test)
 | 
						|
{
 | 
						|
	assert(ts->count < GIT_MAX_TEST_CASES);
 | 
						|
	ts->list[ts->count++] = create_test(test);
 | 
						|
}
 | 
						|
 | 
						|
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\" [test %s @ %s]\n\t%s\n",
 | 
						|
					failCount, tc->description, tc->name, tc->failed_pos, tc->message);
 | 
						|
				if (tc->error_message)
 | 
						|
					printf("\tError: %s\n", tc->error_message);
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
int git_testsuite_run(git_testsuite *ts)
 | 
						|
{
 | 
						|
	int i, fail_count;
 | 
						|
 | 
						|
	printf("Suite \"%s\": ", ts->name);
 | 
						|
 | 
						|
	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('.');
 | 
						|
 | 
						|
		fflush(stdout);
 | 
						|
	}
 | 
						|
	printf("\n  ");
 | 
						|
	print_details(ts);
 | 
						|
	fail_count = ts->fail_count;
 | 
						|
 | 
						|
	free_suite(ts);
 | 
						|
	return fail_count;
 | 
						|
}
 | 
						|
 |