xref: /freebsd/contrib/expat/tests/minicheck.c (revision 220ed979dec58fe7c868d7b64de3cd46b27312e9)
1220ed979SColeman Kane /* Miniature re-implementation of the "check" library.
2220ed979SColeman Kane  *
3220ed979SColeman Kane  * This is intended to support just enough of check to run the Expat
4220ed979SColeman Kane  * tests.  This interface is based entirely on the portion of the
5220ed979SColeman Kane  * check library being used.
6220ed979SColeman Kane  */
7220ed979SColeman Kane 
8220ed979SColeman Kane #include <stdio.h>
9220ed979SColeman Kane #include <stdlib.h>
10220ed979SColeman Kane #include <setjmp.h>
11220ed979SColeman Kane #include <assert.h>
12220ed979SColeman Kane 
13220ed979SColeman Kane #include "minicheck.h"
14220ed979SColeman Kane 
15220ed979SColeman Kane Suite *
16220ed979SColeman Kane suite_create(char *name)
17220ed979SColeman Kane {
18220ed979SColeman Kane     Suite *suite = (Suite *) calloc(1, sizeof(Suite));
19220ed979SColeman Kane     if (suite != NULL) {
20220ed979SColeman Kane         suite->name = name;
21220ed979SColeman Kane     }
22220ed979SColeman Kane     return suite;
23220ed979SColeman Kane }
24220ed979SColeman Kane 
25220ed979SColeman Kane TCase *
26220ed979SColeman Kane tcase_create(char *name)
27220ed979SColeman Kane {
28220ed979SColeman Kane     TCase *tc = (TCase *) calloc(1, sizeof(TCase));
29220ed979SColeman Kane     if (tc != NULL) {
30220ed979SColeman Kane         tc->name = name;
31220ed979SColeman Kane     }
32220ed979SColeman Kane     return tc;
33220ed979SColeman Kane }
34220ed979SColeman Kane 
35220ed979SColeman Kane void
36220ed979SColeman Kane suite_add_tcase(Suite *suite, TCase *tc)
37220ed979SColeman Kane {
38220ed979SColeman Kane     assert(suite != NULL);
39220ed979SColeman Kane     assert(tc != NULL);
40220ed979SColeman Kane     assert(tc->next_tcase == NULL);
41220ed979SColeman Kane 
42220ed979SColeman Kane     tc->next_tcase = suite->tests;
43220ed979SColeman Kane     suite->tests = tc;
44220ed979SColeman Kane }
45220ed979SColeman Kane 
46220ed979SColeman Kane void
47220ed979SColeman Kane tcase_add_checked_fixture(TCase *tc,
48220ed979SColeman Kane                           tcase_setup_function setup,
49220ed979SColeman Kane                           tcase_teardown_function teardown)
50220ed979SColeman Kane {
51220ed979SColeman Kane     assert(tc != NULL);
52220ed979SColeman Kane     tc->setup = setup;
53220ed979SColeman Kane     tc->teardown = teardown;
54220ed979SColeman Kane }
55220ed979SColeman Kane 
56220ed979SColeman Kane void
57220ed979SColeman Kane tcase_add_test(TCase *tc, tcase_test_function test)
58220ed979SColeman Kane {
59220ed979SColeman Kane     assert(tc != NULL);
60220ed979SColeman Kane     if (tc->allocated == tc->ntests) {
61220ed979SColeman Kane         int nalloc = tc->allocated + 100;
62220ed979SColeman Kane         size_t new_size = sizeof(tcase_test_function) * nalloc;
63220ed979SColeman Kane         tcase_test_function *new_tests = realloc(tc->tests, new_size);
64220ed979SColeman Kane         assert(new_tests != NULL);
65220ed979SColeman Kane         if (new_tests != tc->tests) {
66220ed979SColeman Kane             free(tc->tests);
67220ed979SColeman Kane             tc->tests = new_tests;
68220ed979SColeman Kane         }
69220ed979SColeman Kane         tc->allocated = nalloc;
70220ed979SColeman Kane     }
71220ed979SColeman Kane     tc->tests[tc->ntests] = test;
72220ed979SColeman Kane     tc->ntests++;
73220ed979SColeman Kane }
74220ed979SColeman Kane 
75220ed979SColeman Kane SRunner *
76220ed979SColeman Kane srunner_create(Suite *suite)
77220ed979SColeman Kane {
78220ed979SColeman Kane     SRunner *runner = calloc(1, sizeof(SRunner));
79220ed979SColeman Kane     if (runner != NULL) {
80220ed979SColeman Kane         runner->suite = suite;
81220ed979SColeman Kane     }
82220ed979SColeman Kane     return runner;
83220ed979SColeman Kane }
84220ed979SColeman Kane 
85220ed979SColeman Kane static jmp_buf env;
86220ed979SColeman Kane 
87220ed979SColeman Kane static char const *_check_current_function = NULL;
88220ed979SColeman Kane static int _check_current_lineno = -1;
89220ed979SColeman Kane static char const *_check_current_filename = NULL;
90220ed979SColeman Kane 
91220ed979SColeman Kane void
92220ed979SColeman Kane _check_set_test_info(char const *function, char const *filename, int lineno)
93220ed979SColeman Kane {
94220ed979SColeman Kane     _check_current_function = function;
95220ed979SColeman Kane     _check_current_lineno = lineno;
96220ed979SColeman Kane     _check_current_filename = filename;
97220ed979SColeman Kane }
98220ed979SColeman Kane 
99220ed979SColeman Kane 
100220ed979SColeman Kane static void
101220ed979SColeman Kane add_failure(SRunner *runner, int verbosity)
102220ed979SColeman Kane {
103220ed979SColeman Kane     runner->nfailures++;
104220ed979SColeman Kane     if (verbosity >= CK_VERBOSE) {
105220ed979SColeman Kane         printf("%s:%d: %s\n", _check_current_filename,
106220ed979SColeman Kane                _check_current_lineno, _check_current_function);
107220ed979SColeman Kane     }
108220ed979SColeman Kane }
109220ed979SColeman Kane 
110220ed979SColeman Kane void
111220ed979SColeman Kane srunner_run_all(SRunner *runner, int verbosity)
112220ed979SColeman Kane {
113220ed979SColeman Kane     Suite *suite;
114220ed979SColeman Kane     TCase *tc;
115220ed979SColeman Kane     assert(runner != NULL);
116220ed979SColeman Kane     suite = runner->suite;
117220ed979SColeman Kane     tc = suite->tests;
118220ed979SColeman Kane     while (tc != NULL) {
119220ed979SColeman Kane         int i;
120220ed979SColeman Kane         for (i = 0; i < tc->ntests; ++i) {
121220ed979SColeman Kane             runner->nchecks++;
122220ed979SColeman Kane 
123220ed979SColeman Kane             if (tc->setup != NULL) {
124220ed979SColeman Kane                 /* setup */
125220ed979SColeman Kane                 if (setjmp(env)) {
126220ed979SColeman Kane                     add_failure(runner, verbosity);
127220ed979SColeman Kane                     continue;
128220ed979SColeman Kane                 }
129220ed979SColeman Kane                 tc->setup();
130220ed979SColeman Kane             }
131220ed979SColeman Kane             /* test */
132220ed979SColeman Kane             if (setjmp(env)) {
133220ed979SColeman Kane                 add_failure(runner, verbosity);
134220ed979SColeman Kane                 continue;
135220ed979SColeman Kane             }
136220ed979SColeman Kane             (tc->tests[i])();
137220ed979SColeman Kane 
138220ed979SColeman Kane             /* teardown */
139220ed979SColeman Kane             if (tc->teardown != NULL) {
140220ed979SColeman Kane                 if (setjmp(env)) {
141220ed979SColeman Kane                     add_failure(runner, verbosity);
142220ed979SColeman Kane                     continue;
143220ed979SColeman Kane                 }
144220ed979SColeman Kane                 tc->teardown();
145220ed979SColeman Kane             }
146220ed979SColeman Kane         }
147220ed979SColeman Kane         tc = tc->next_tcase;
148220ed979SColeman Kane     }
149220ed979SColeman Kane     if (verbosity) {
150220ed979SColeman Kane         int passed = runner->nchecks - runner->nfailures;
151220ed979SColeman Kane         double percentage = ((double) passed) / runner->nchecks;
152220ed979SColeman Kane         int display = (int) (percentage * 100);
153220ed979SColeman Kane         printf("%d%%: Checks: %d, Failed: %d\n",
154220ed979SColeman Kane                display, runner->nchecks, runner->nfailures);
155220ed979SColeman Kane     }
156220ed979SColeman Kane }
157220ed979SColeman Kane 
158220ed979SColeman Kane void
159220ed979SColeman Kane _fail_unless(int condition, const char *file, int line, char *msg)
160220ed979SColeman Kane {
161220ed979SColeman Kane     /* Always print the error message so it isn't lost.  In this case,
162220ed979SColeman Kane        we have a failure, so there's no reason to be quiet about what
163220ed979SColeman Kane        it is.
164220ed979SColeman Kane     */
165220ed979SColeman Kane     if (msg != NULL)
166220ed979SColeman Kane         printf("%s", msg);
167220ed979SColeman Kane     longjmp(env, 1);
168220ed979SColeman Kane }
169220ed979SColeman Kane 
170220ed979SColeman Kane int
171220ed979SColeman Kane srunner_ntests_failed(SRunner *runner)
172220ed979SColeman Kane {
173220ed979SColeman Kane     assert(runner != NULL);
174220ed979SColeman Kane     return runner->nfailures;
175220ed979SColeman Kane }
176220ed979SColeman Kane 
177220ed979SColeman Kane void
178220ed979SColeman Kane srunner_free(SRunner *runner)
179220ed979SColeman Kane {
180220ed979SColeman Kane     free(runner->suite);
181220ed979SColeman Kane     free(runner);
182220ed979SColeman Kane }
183