1b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project/* Miniature re-implementation of the "check" library.
2b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project *
3b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project * This is intended to support just enough of check to run the Expat
4b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project * tests.  This interface is based entirely on the portion of the
5b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project * check library being used.
6b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project */
7b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project
8b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project#include <stdio.h>
9b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project#include <stdlib.h>
10b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project#include <setjmp.h>
11b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project#include <assert.h>
12b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project
13ba34a0c0eeed7538bd405826bf3ac25cecf71c90Paul Duffin#include "internal.h"  /* for UNUSED_P only */
14b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project#include "minicheck.h"
15b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project
16b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source ProjectSuite *
17ba34a0c0eeed7538bd405826bf3ac25cecf71c90Paul Duffinsuite_create(const char *name)
18b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project{
19b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    Suite *suite = (Suite *) calloc(1, sizeof(Suite));
20b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    if (suite != NULL) {
21b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project        suite->name = name;
22b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    }
23b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    return suite;
24b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project}
25b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project
26b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source ProjectTCase *
27ba34a0c0eeed7538bd405826bf3ac25cecf71c90Paul Duffintcase_create(const char *name)
28b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project{
29b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    TCase *tc = (TCase *) calloc(1, sizeof(TCase));
30b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    if (tc != NULL) {
31b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project        tc->name = name;
32b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    }
33b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    return tc;
34b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project}
35b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project
36b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Projectvoid
37b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Projectsuite_add_tcase(Suite *suite, TCase *tc)
38b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project{
39b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    assert(suite != NULL);
40b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    assert(tc != NULL);
41b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    assert(tc->next_tcase == NULL);
42b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project
43b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    tc->next_tcase = suite->tests;
44b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    suite->tests = tc;
45b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project}
46b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project
47b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Projectvoid
48b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Projecttcase_add_checked_fixture(TCase *tc,
49b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project                          tcase_setup_function setup,
50b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project                          tcase_teardown_function teardown)
51b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project{
52b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    assert(tc != NULL);
53b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    tc->setup = setup;
54b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    tc->teardown = teardown;
55b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project}
56b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project
57b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Projectvoid
58b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Projecttcase_add_test(TCase *tc, tcase_test_function test)
59b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project{
60b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    assert(tc != NULL);
61b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    if (tc->allocated == tc->ntests) {
62b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project        int nalloc = tc->allocated + 100;
63b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project        size_t new_size = sizeof(tcase_test_function) * nalloc;
64b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project        tcase_test_function *new_tests = realloc(tc->tests, new_size);
65b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project        assert(new_tests != NULL);
66b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project        if (new_tests != tc->tests) {
67b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project            free(tc->tests);
68b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project            tc->tests = new_tests;
69b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project        }
70b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project        tc->allocated = nalloc;
71b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    }
72b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    tc->tests[tc->ntests] = test;
73b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    tc->ntests++;
74b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project}
75b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project
76b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source ProjectSRunner *
77b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Projectsrunner_create(Suite *suite)
78b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project{
79b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    SRunner *runner = calloc(1, sizeof(SRunner));
80b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    if (runner != NULL) {
81b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project        runner->suite = suite;
82b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    }
83b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    return runner;
84b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project}
85b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project
86b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Projectstatic jmp_buf env;
87b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project
88b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Projectstatic char const *_check_current_function = NULL;
89b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Projectstatic int _check_current_lineno = -1;
90b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Projectstatic char const *_check_current_filename = NULL;
91b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project
92b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Projectvoid
93b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project_check_set_test_info(char const *function, char const *filename, int lineno)
94b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project{
95b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    _check_current_function = function;
96b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    _check_current_lineno = lineno;
97b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    _check_current_filename = filename;
98b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project}
99b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project
100b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project
101b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Projectstatic void
102b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Projectadd_failure(SRunner *runner, int verbosity)
103b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project{
104b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    runner->nfailures++;
105b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    if (verbosity >= CK_VERBOSE) {
106b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project        printf("%s:%d: %s\n", _check_current_filename,
107b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project               _check_current_lineno, _check_current_function);
108b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    }
109b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project}
110b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project
111b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Projectvoid
112b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Projectsrunner_run_all(SRunner *runner, int verbosity)
113b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project{
114b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    Suite *suite;
115b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    TCase *tc;
116b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    assert(runner != NULL);
117b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    suite = runner->suite;
118b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    tc = suite->tests;
119b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    while (tc != NULL) {
120b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project        int i;
121b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project        for (i = 0; i < tc->ntests; ++i) {
122b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project            runner->nchecks++;
123b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project
124b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project            if (tc->setup != NULL) {
125b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project                /* setup */
126b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project                if (setjmp(env)) {
127b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project                    add_failure(runner, verbosity);
128b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project                    continue;
129b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project                }
130b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project                tc->setup();
131b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project            }
132b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project            /* test */
133b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project            if (setjmp(env)) {
134b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project                add_failure(runner, verbosity);
135b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project                continue;
136b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project            }
137b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project            (tc->tests[i])();
138b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project
139b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project            /* teardown */
140b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project            if (tc->teardown != NULL) {
141b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project                if (setjmp(env)) {
142b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project                    add_failure(runner, verbosity);
143b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project                    continue;
144b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project                }
145b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project                tc->teardown();
146b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project            }
147b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project        }
148b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project        tc = tc->next_tcase;
149b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    }
150b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    if (verbosity) {
151b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project        int passed = runner->nchecks - runner->nfailures;
152b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project        double percentage = ((double) passed) / runner->nchecks;
153b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project        int display = (int) (percentage * 100);
154b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project        printf("%d%%: Checks: %d, Failed: %d\n",
155b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project               display, runner->nchecks, runner->nfailures);
156b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    }
157b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project}
158b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project
159b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Projectvoid
160ba34a0c0eeed7538bd405826bf3ac25cecf71c90Paul Duffin_fail_unless(int UNUSED_P(condition), const char *UNUSED_P(file), int UNUSED_P(line), const char *msg)
161b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project{
162d07d5a72938fd52415368c2320fc29575ae9a0c3Elliott Hughes    /* Always print the error message so it isn't lost.  In this case,
163d07d5a72938fd52415368c2320fc29575ae9a0c3Elliott Hughes       we have a failure, so there's no reason to be quiet about what
164d07d5a72938fd52415368c2320fc29575ae9a0c3Elliott Hughes       it is.
165d07d5a72938fd52415368c2320fc29575ae9a0c3Elliott Hughes    */
166d07d5a72938fd52415368c2320fc29575ae9a0c3Elliott Hughes    if (msg != NULL)
167d07d5a72938fd52415368c2320fc29575ae9a0c3Elliott Hughes        printf("%s", msg);
168b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    longjmp(env, 1);
169b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project}
170b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project
171b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Projectint
172b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Projectsrunner_ntests_failed(SRunner *runner)
173b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project{
174b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    assert(runner != NULL);
175b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    return runner->nfailures;
176b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project}
177b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project
178b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Projectvoid
179b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Projectsrunner_free(SRunner *runner)
180b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project{
181b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    free(runner->suite);
182b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project    free(runner);
183b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project}
184