blob: be1e37e761b7cb372beb0b0c7325accb15a8a7fd [file] [log] [blame]
The Android Open Source Projectb80e2872009-03-03 19:29:30 -08001/* Miniature re-implementation of the "check" library.
Elliott Hughes72472942018-01-10 08:36:10 -08002
3 This is intended to support just enough of check to run the Expat
4 tests. This interface is based entirely on the portion of the
5 check library being used.
6 __ __ _
7 ___\ \/ /_ __ __ _| |_
8 / _ \\ /| '_ \ / _` | __|
9 | __// \| |_) | (_| | |_
10 \___/_/\_\ .__/ \__,_|\__|
11 |_| XML parser
12
13 Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
14 Copyright (c) 2000-2017 Expat development team
15 Licensed under the MIT license:
16
17 Permission is hereby granted, free of charge, to any person obtaining
18 a copy of this software and associated documentation files (the
19 "Software"), to deal in the Software without restriction, including
20 without limitation the rights to use, copy, modify, merge, publish,
21 distribute, sublicense, and/or sell copies of the Software, and to permit
22 persons to whom the Software is furnished to do so, subject to the
23 following conditions:
24
25 The above copyright notice and this permission notice shall be included
26 in all copies or substantial portions of the Software.
27
28 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
29 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
30 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
31 NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
32 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
33 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
34 USE OR OTHER DEALINGS IN THE SOFTWARE.
35*/
The Android Open Source Projectb80e2872009-03-03 19:29:30 -080036
37#include <stdio.h>
38#include <stdlib.h>
39#include <setjmp.h>
40#include <assert.h>
Elliott Hughes72472942018-01-10 08:36:10 -080041#include <string.h>
The Android Open Source Projectb80e2872009-03-03 19:29:30 -080042
Paul Duffinba34a0c2017-02-27 14:40:16 +000043#include "internal.h" /* for UNUSED_P only */
The Android Open Source Projectb80e2872009-03-03 19:29:30 -080044#include "minicheck.h"
45
46Suite *
Paul Duffinba34a0c2017-02-27 14:40:16 +000047suite_create(const char *name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -080048{
49 Suite *suite = (Suite *) calloc(1, sizeof(Suite));
50 if (suite != NULL) {
51 suite->name = name;
52 }
53 return suite;
54}
55
56TCase *
Paul Duffinba34a0c2017-02-27 14:40:16 +000057tcase_create(const char *name)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -080058{
59 TCase *tc = (TCase *) calloc(1, sizeof(TCase));
60 if (tc != NULL) {
61 tc->name = name;
62 }
63 return tc;
64}
65
66void
67suite_add_tcase(Suite *suite, TCase *tc)
68{
69 assert(suite != NULL);
70 assert(tc != NULL);
71 assert(tc->next_tcase == NULL);
72
73 tc->next_tcase = suite->tests;
74 suite->tests = tc;
75}
76
77void
78tcase_add_checked_fixture(TCase *tc,
79 tcase_setup_function setup,
80 tcase_teardown_function teardown)
81{
82 assert(tc != NULL);
83 tc->setup = setup;
84 tc->teardown = teardown;
85}
86
87void
88tcase_add_test(TCase *tc, tcase_test_function test)
89{
90 assert(tc != NULL);
91 if (tc->allocated == tc->ntests) {
92 int nalloc = tc->allocated + 100;
93 size_t new_size = sizeof(tcase_test_function) * nalloc;
94 tcase_test_function *new_tests = realloc(tc->tests, new_size);
95 assert(new_tests != NULL);
Elliott Hughes72472942018-01-10 08:36:10 -080096 tc->tests = new_tests;
The Android Open Source Projectb80e2872009-03-03 19:29:30 -080097 tc->allocated = nalloc;
98 }
99 tc->tests[tc->ntests] = test;
100 tc->ntests++;
101}
102
Elliott Hughes72472942018-01-10 08:36:10 -0800103static void
104tcase_free(TCase *tc)
105{
106 if (! tc) {
107 return;
108 }
109
110 free(tc->tests);
111 free(tc);
112}
113
114static void
115suite_free(Suite *suite)
116{
117 if (! suite) {
118 return;
119 }
120
121 while (suite->tests != NULL) {
122 TCase *next = suite->tests->next_tcase;
123 tcase_free(suite->tests);
124 suite->tests = next;
125 }
126 free(suite);
127}
128
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800129SRunner *
130srunner_create(Suite *suite)
131{
132 SRunner *runner = calloc(1, sizeof(SRunner));
133 if (runner != NULL) {
134 runner->suite = suite;
135 }
136 return runner;
137}
138
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800139static jmp_buf env;
140
141static char const *_check_current_function = NULL;
142static int _check_current_lineno = -1;
143static char const *_check_current_filename = NULL;
144
145void
146_check_set_test_info(char const *function, char const *filename, int lineno)
147{
148 _check_current_function = function;
149 _check_current_lineno = lineno;
150 _check_current_filename = filename;
151}
152
153
154static void
155add_failure(SRunner *runner, int verbosity)
156{
157 runner->nfailures++;
158 if (verbosity >= CK_VERBOSE) {
159 printf("%s:%d: %s\n", _check_current_filename,
160 _check_current_lineno, _check_current_function);
161 }
162}
163
164void
165srunner_run_all(SRunner *runner, int verbosity)
166{
167 Suite *suite;
168 TCase *tc;
169 assert(runner != NULL);
170 suite = runner->suite;
171 tc = suite->tests;
172 while (tc != NULL) {
173 int i;
174 for (i = 0; i < tc->ntests; ++i) {
175 runner->nchecks++;
176
177 if (tc->setup != NULL) {
178 /* setup */
179 if (setjmp(env)) {
180 add_failure(runner, verbosity);
181 continue;
182 }
183 tc->setup();
184 }
185 /* test */
186 if (setjmp(env)) {
187 add_failure(runner, verbosity);
188 continue;
189 }
190 (tc->tests[i])();
191
192 /* teardown */
193 if (tc->teardown != NULL) {
194 if (setjmp(env)) {
195 add_failure(runner, verbosity);
196 continue;
197 }
198 tc->teardown();
199 }
200 }
201 tc = tc->next_tcase;
202 }
203 if (verbosity) {
204 int passed = runner->nchecks - runner->nfailures;
205 double percentage = ((double) passed) / runner->nchecks;
206 int display = (int) (percentage * 100);
207 printf("%d%%: Checks: %d, Failed: %d\n",
208 display, runner->nchecks, runner->nfailures);
209 }
210}
211
212void
Paul Duffinba34a0c2017-02-27 14:40:16 +0000213_fail_unless(int UNUSED_P(condition), const char *UNUSED_P(file), int UNUSED_P(line), const char *msg)
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800214{
Elliott Hughesd07d5a72009-09-25 16:04:37 -0700215 /* Always print the error message so it isn't lost. In this case,
216 we have a failure, so there's no reason to be quiet about what
217 it is.
218 */
Elliott Hughes72472942018-01-10 08:36:10 -0800219 if (msg != NULL) {
220 const int has_newline = (msg[strlen(msg) - 1] == '\n');
221 fprintf(stderr, "ERROR: %s%s", msg, has_newline ? "" : "\n");
222 }
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800223 longjmp(env, 1);
224}
225
226int
227srunner_ntests_failed(SRunner *runner)
228{
229 assert(runner != NULL);
230 return runner->nfailures;
231}
232
233void
234srunner_free(SRunner *runner)
235{
Elliott Hughes72472942018-01-10 08:36:10 -0800236 if (! runner) {
237 return;
238 }
239
240 suite_free(runner->suite);
The Android Open Source Projectb80e2872009-03-03 19:29:30 -0800241 free(runner);
242}