From d1df594ca280e86b7218e9cd8e57af5984b307c3 Mon Sep 17 00:00:00 2001 From: "Fred L. Drake, Jr." Date: Fri, 30 Apr 2004 03:18:11 +0000 Subject: [PATCH] If the check library is not available, use an abbreviated implementation of the check API. This allows the unit and regression tests to be run on any system without requiring an external package. --- expat/Makefile.in | 5 +- expat/README | 8 +- expat/configure.in | 5 ++ expat/tests/chardata.c | 3 +- expat/tests/minicheck.c | 163 ++++++++++++++++++++++++++++++++++++++++ expat/tests/minicheck.h | 70 +++++++++++++++++ expat/tests/runtests.c | 2 +- 7 files changed, 247 insertions(+), 9 deletions(-) create mode 100644 expat/tests/minicheck.c create mode 100644 expat/tests/minicheck.h diff --git a/expat/Makefile.in b/expat/Makefile.in index f85920c1..79942717 100644 --- a/expat/Makefile.in +++ b/expat/Makefile.in @@ -146,9 +146,10 @@ examples/outline: examples/outline.o $(LIBRARY) $(LINK_EXE) $< $(LIBRARY) tests/chardata.o: tests/chardata.c tests/chardata.h +tests/minicheck.o: tests/minicheck.c tests/minicheck.h tests/runtests.o: tests/runtests.c tests/chardata.h -tests/runtests: tests/runtests.o tests/chardata.o $(LIBRARY) - $(LINK_EXE) $^ -lcheck +tests/runtests: tests/runtests.o tests/chardata.o @MINICHECK_OBJECT@ $(LIBRARY) + $(LINK_EXE) $^ @CHECK_LIBRARY@ tests/xmlts.zip: wget --output-document=tests/xmlts.zip \ diff --git a/expat/README b/expat/README index 1e16f975..6998da17 100644 --- a/expat/README +++ b/expat/README @@ -92,12 +92,12 @@ you're using ksh or bash, use this command to build: PATH=/usr/ccs/bin:$PATH make -The unit and regression tests for Expat require the "check" library on +The unit and regression tests for Expat can use the "check" library on Unix; more information is available at http://check.sourceforge.net/, and downloadable packages are available from the library's project -page on SourceForge: http://sourceforge.net/projects/check/. You do -not need to install the check library to build and use Expat, only to -build and run Expat's test suite. +page on SourceForge: http://sourceforge.net/projects/check/. If the +check library is not available, a greatly abbreviated implementation +of the check API is used. When using Expat with a project using autoconf for configuration, you can use the probing macro in conftools/expat.m4 to determine how to diff --git a/expat/configure.in b/expat/configure.in index 035cd421..5da9d3c0 100644 --- a/expat/configure.in +++ b/expat/configure.in @@ -104,7 +104,12 @@ fi AC_SUBST(FILEMAP) dnl Only needed for regression tests: +AC_SUBST(MINICHECK_OBJECT) +AC_SUBST(CHECK_LIBRARY) AC_CHECK_HEADERS(check.h) +AC_CHECK_HEADER(check.h, + CHECK_LIBRARY=-lcheck, + MINICHECK_OBJECT=tests/minicheck.o) dnl Some basic configuration: AC_DEFINE([XML_NS], 1, diff --git a/expat/tests/chardata.c b/expat/tests/chardata.c index 5736afc6..5fb0299d 100644 --- a/expat/tests/chardata.c +++ b/expat/tests/chardata.c @@ -10,11 +10,10 @@ #ifdef HAVE_CHECK_H #include #else -#error This test suite requires the 'check' unit test framework (http://check.sf.net/) +#include "minicheck.h" #endif #include -#include #include #include diff --git a/expat/tests/minicheck.c b/expat/tests/minicheck.c new file mode 100644 index 00000000..6efd7c7b --- /dev/null +++ b/expat/tests/minicheck.c @@ -0,0 +1,163 @@ +/* Miniature re-implementation of the "check" library. + * + * This is intended to support just enough of check to run the Expat + * tests. This interface is based entirely on the portion of the + * check library being used. + */ + +#include +#include +#include + +#include "minicheck.h" + +Suite * +suite_create(char *name) +{ + Suite *suite = (Suite *) calloc(1, sizeof(Suite)); + if (suite != NULL) { + suite->name = name; + } + return suite; +} + +TCase * +tcase_create(char *name) +{ + TCase *tc = (TCase *) calloc(1, sizeof(TCase)); + if (tc != NULL) { + tc->name = name; + } + return tc; +} + +void +suite_add_tcase(Suite *suite, TCase *tc) +{ + assert(suite != NULL); + assert(tc != NULL); + assert(tc->next_tcase == NULL); + + tc->next_tcase = suite->tests; + suite->tests = tc; +} + +void +tcase_add_checked_fixture(TCase *tc, + tcase_setup_function setup, + tcase_teardown_function teardown) +{ + assert(tc != NULL); + tc->setup = setup; + tc->teardown = teardown; +} + +void +tcase_add_test(TCase *tc, tcase_test_function test) +{ + assert(tc != NULL); + if (tc->allocated == tc->ntests) { + int nalloc = tc->allocated + 100; + size_t new_size = sizeof(tcase_test_function) * nalloc; + tcase_test_function *new_tests = realloc(tc->tests, new_size); + assert(new_tests != NULL); + if (new_tests != tc->tests) { + free(tc->tests); + tc->tests = new_tests; + } + tc->allocated = nalloc; + } + tc->tests[tc->ntests] = test; + tc->ntests++; +} + +SRunner * +srunner_create(Suite *suite) +{ + SRunner *runner = calloc(1, sizeof(SRunner)); + if (runner != NULL) { + runner->suite = suite; + } + return runner; +} + +void +srunner_set_fork_status(SRunner *runner, int status) +{ + /* We ignore this. */ +} + +static jmp_buf env; + +void +srunner_run_all(SRunner *runner, int verbosity) +{ + Suite *suite; + TCase *tc; + assert(runner != NULL); + suite = runner->suite; + tc = suite->tests; + while (tc != NULL) { + int i; + for (i = 0; i < tc->ntests; ++i) { + runner->nchecks++; + + if (tc->setup != NULL) { + /* setup */ + if (setjmp(env)) { + runner->nfailures++; + continue; + } + tc->setup(); + } + /* test */ + if (setjmp(env)) { + runner->nfailures++; + continue; + } + (tc->tests[i])(); + + /* teardown */ + if (tc->teardown != NULL) { + if (setjmp(env)) { + runner->nfailures++; + continue; + } + tc->teardown(); + } + } + tc = tc->next_tcase; + } + if (verbosity) { + int passed = runner->nchecks - runner->nfailures; + double percentage = ((double) passed) / runner->nchecks; + int display = (int) (percentage * 100); + printf("%d%%: Checks: %d, Failed: %d\n", + display, runner->nchecks, runner->nfailures); + } +} + +void +_fail_unless(int condition, char *const file, int line, char *msg) +{ + longjmp(env, 1); +} + +int +srunner_ntests_failed(SRunner *runner) +{ + assert(runner != NULL); + return runner->nfailures; +} + +void +srunner_free(SRunner *runner) +{ + free(runner); +} + +void +suite_free(Suite *suite) +{ + free(suite); +} diff --git a/expat/tests/minicheck.h b/expat/tests/minicheck.h new file mode 100644 index 00000000..6239fa33 --- /dev/null +++ b/expat/tests/minicheck.h @@ -0,0 +1,70 @@ +/* Miniature re-implementation of the "check" library. + * + * This is intended to support just enough of check to run the Expat + * tests. This interface is based entirely on the portion of the + * check library being used. + * + * This is *source* compatible, but not necessary *link* compatible. + */ + +#define CK_NOFORK 0 +#define CK_FORK 1 + +#define CK_SILENT 0 +#define CK_NORMAL 1 +#define CK_VERBOSE 2 + +#define START_TEST(testname) static void testname(void) { +#define END_TEST } + +#define fail(msg) _fail_unless(0, __FILE__, __LINE__, msg) + +typedef void (*tcase_setup_function)(void); +typedef void (*tcase_teardown_function)(void); +typedef void (*tcase_test_function)(void); + +typedef struct SRunner SRunner; +typedef struct Suite Suite; +typedef struct TCase TCase; + +struct SRunner { + Suite *suite; + int forking; + int nchecks; + int nfailures; +}; + +struct Suite { + char *name; + TCase *tests; +}; + +struct TCase { + char *name; + tcase_setup_function setup; + tcase_teardown_function teardown; + tcase_test_function *tests; + int ntests; + int allocated; + TCase *next_tcase; +}; + + +/* + * Prototypes for the actual implementation. + */ + +void _fail_unless(int condition, char *const file, int line, char *msg); +Suite *suite_create(char *name); +TCase *tcase_create(char *name); +void suite_add_tcase(Suite *suite, TCase *tc); +void tcase_add_checked_fixture(TCase *, + tcase_setup_function, + tcase_teardown_function); +void tcase_add_test(TCase *tc, tcase_test_function test); +SRunner *srunner_create(Suite *suite); +void srunner_set_fork_status(SRunner *runner, int forking); +void srunner_run_all(SRunner *runner, int verbosity); +int srunner_ntests_failed(SRunner *runner); +void srunner_free(SRunner *runner); +void suite_free(Suite *suite); diff --git a/expat/tests/runtests.c b/expat/tests/runtests.c index 7df109a3..5c5d7845 100644 --- a/expat/tests/runtests.c +++ b/expat/tests/runtests.c @@ -11,7 +11,7 @@ #ifdef HAVE_CHECK_H #include #else -#error This test suite requires the 'check' unit test framework (http://check.sf.net/) +#include "minicheck.h" #endif #include -- 2.40.0