]> git.proxmox.com Git - libgit2.git/blob - tests/test_lib.c
Merge pull request #378 from kiryl/Wuninitialized
[libgit2.git] / tests / test_lib.c
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
8 #include "test_lib.h"
9
10 #define DO_ALLOC(TYPE) ((TYPE*) malloc(sizeof(TYPE)))
11 #define GIT_MAX_TEST_CASES 64
12
13 struct git_test {
14 char *name;
15 char *message;
16 char *failed_pos;
17 char *description;
18 char *error_message;
19
20 git_testfunc function;
21 unsigned failed:1, ran:1;
22 jmp_buf *jump;
23 };
24
25 struct git_testsuite {
26 char *name;
27 int count, fail_count;
28 git_test *list[GIT_MAX_TEST_CASES];
29 };
30
31 static void test_free(git_test *t)
32 {
33 if (t) {
34 free(t->name);
35 free(t->description);
36 free(t->failed_pos);
37 free(t->message);
38 free(t->error_message);
39 free(t);
40 }
41 }
42
43 static void test_run(git_test *tc)
44 {
45 jmp_buf buf;
46 tc->jump = &buf;
47
48 if (setjmp(buf) == 0) {
49 tc->ran = 1;
50 (tc->function)(tc);
51 }
52
53 tc->jump = 0;
54 }
55
56 static git_test *create_test(git_testfunc function)
57 {
58 git_test *t = DO_ALLOC(git_test);
59
60 memset(t, 0x0, sizeof(git_test));
61 t->function = function;
62
63 return t;
64 }
65
66 void git_test__init(git_test *t, const char *name, const char *description)
67 {
68 t->name = strdup(name);
69 t->description = strdup(description);
70 }
71
72
73 /*-------------------------------------------------------------------------*
74 * Public assert methods
75 *-------------------------------------------------------------------------*/
76
77 static void fail_test(git_test *tc, const char *file, int line, const char *message)
78 {
79 char buf[1024];
80 const char *last_error = git_lasterror();
81
82 snprintf(buf, 1024, "%s:%d", file, line);
83
84 tc->failed = 1;
85 tc->message = strdup(message);
86 tc->failed_pos = strdup(buf);
87
88 if (last_error)
89 tc->error_message = strdup(last_error);
90
91 if (tc->jump != 0)
92 longjmp(*(tc->jump), 0);
93 }
94
95 void git_test__fail(git_test *tc, const char *file, int line, const char *message)
96 {
97 fail_test(tc, file, line, message);
98 }
99
100 void git_test__assert(git_test *tc, const char *file, int line, const char *message, int condition)
101 {
102 if (condition == 0)
103 fail_test(tc, file, line, message);
104 }
105
106 void git_test__assert_pass(git_test *tc, const char *file, int line, const char *message, int ret_value)
107 {
108 if (ret_value < 0)
109 fail_test(tc, file, line, message);
110 }
111
112 /*-------------------------------------------------------------------------*
113 * Test Suite
114 *-------------------------------------------------------------------------*/
115
116 static void testsuite_init(git_testsuite *ts)
117 {
118 ts->count = 0;
119 ts->fail_count = 0;
120 memset(ts->list, 0, sizeof(ts->list));
121 }
122
123 git_testsuite *git_testsuite_new(const char *name)
124 {
125 git_testsuite *ts = DO_ALLOC(git_testsuite);
126 testsuite_init(ts);
127 ts->name = strdup(name);
128 return ts;
129 }
130
131 static void free_suite(git_testsuite *ts)
132 {
133 unsigned int n;
134
135 for (n = 0; n < GIT_MAX_TEST_CASES; n++)
136 if (ts->list[n])
137 test_free(ts->list[n]);
138
139 free(ts->name);
140 free(ts);
141 }
142
143 void git_testsuite_add(git_testsuite *ts, git_testfunc test)
144 {
145 assert(ts->count < GIT_MAX_TEST_CASES);
146 ts->list[ts->count++] = create_test(test);
147 }
148
149 static void print_details(git_testsuite *ts)
150 {
151 int i;
152 int failCount = 0;
153
154 if (ts->fail_count == 0) {
155 const char *testWord = ts->count == 1 ? "test" : "tests";
156 printf("OK (%d %s)\n", ts->count, testWord);
157 } else {
158 printf("Failed (%d failures):\n", ts->fail_count);
159
160 for (i = 0 ; i < ts->count ; ++i) {
161 git_test *tc = ts->list[i];
162 if (tc->failed) {
163 failCount++;
164 printf(" %d) \"%s\" [test %s @ %s]\n\t%s\n",
165 failCount, tc->description, tc->name, tc->failed_pos, tc->message);
166 if (tc->error_message)
167 printf("\tError: %s\n", tc->error_message);
168 }
169 }
170 }
171 }
172
173 int git_testsuite_run(git_testsuite *ts)
174 {
175 int i, fail_count;
176
177 printf("Suite \"%s\": ", ts->name);
178
179 for (i = 0 ; i < ts->count ; ++i) {
180 git_test *tc = ts->list[i];
181
182 test_run(tc);
183 if (tc->failed) {
184 ts->fail_count++;
185 putchar('F');
186 } else
187 putchar('.');
188
189 fflush(stdout);
190 }
191 printf("\n ");
192 print_details(ts);
193 fail_count = ts->fail_count;
194
195 free_suite(ts);
196 return fail_count;
197 }
198