]> granicus.if.org Git - libexpat/commitdiff
If the check library is not available, use an abbreviated implementation of
authorFred L. Drake, Jr. <fdrake@users.sourceforge.net>
Fri, 30 Apr 2004 03:18:11 +0000 (03:18 +0000)
committerFred L. Drake, Jr. <fdrake@users.sourceforge.net>
Fri, 30 Apr 2004 03:18:11 +0000 (03:18 +0000)
the check API.  This allows the unit and regression tests to be run on any
system without requiring an external package.

expat/Makefile.in
expat/README
expat/configure.in
expat/tests/chardata.c
expat/tests/minicheck.c [new file with mode: 0644]
expat/tests/minicheck.h [new file with mode: 0644]
expat/tests/runtests.c

index f85920c188f2bc9bae2886e4726780f48a7b4d5f..7994271784dd1b56faf3541dbfb0504829cddd90 100644 (file)
@@ -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 \
index 1e16f975f181b411f66996a47e911aafae6c51ac..6998da177488bc152999df9037527bfd37c6f0fc 100644 (file)
@@ -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
index 035cd4215957ca9f578c137dad9aa348b4b5735f..5da9d3c0757e8595aeca11b50e62828a296bff67 100644 (file)
@@ -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,
index 5736afc6d3b3b9c65517e4732ddcb5401f8c8551..5fb0299d88e0f7dfed4073248be3a512b1aa250c 100644 (file)
 #ifdef HAVE_CHECK_H
 #include <check.h>
 #else
-#error This test suite requires the 'check' unit test framework (http://check.sf.net/)
+#include "minicheck.h"
 #endif
 
 #include <assert.h>
-#include <check.h>
 #include <stdio.h>
 #include <string.h>
 
diff --git a/expat/tests/minicheck.c b/expat/tests/minicheck.c
new file mode 100644 (file)
index 0000000..6efd7c7
--- /dev/null
@@ -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 <stdlib.h>
+#include <setjmp.h>
+#include <assert.h>
+
+#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 (file)
index 0000000..6239fa3
--- /dev/null
@@ -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);
index 7df109a324e7c766b0279ce6bb204b2e9b1af13f..5c5d78452242f85c382d94f0e16168a8ee4d5939 100644 (file)
@@ -11,7 +11,7 @@
 #ifdef HAVE_CHECK_H
 #include <check.h>
 #else
-#error This test suite requires the 'check' unit test framework (http://check.sf.net/)
+#include "minicheck.h"
 #endif
 
 #include <assert.h>