diff options
author | Robert Collins <robertc@robertcollins.net> | 2006-04-15 15:19:59 +1000 |
---|---|---|
committer | Robert Collins <robertc@robertcollins.net> | 2006-04-15 15:19:59 +1000 |
commit | 96bf18f88a718e2751d13c1aa3725e18f1223b77 (patch) | |
tree | 8d7eddf533277240da9b6067efd7e8f55955705d /c | |
parent | ff4fc243402f5b1da14aa20c8208ff882b43a6f7 (diff) | |
download | subunit-96bf18f88a718e2751d13c1aa3725e18f1223b77.tar.gz |
Finish C child bindings.
Diffstat (limited to 'c')
-rw-r--r-- | c/include/subunit/child.h | 31 | ||||
-rw-r--r-- | c/lib/child.c | 39 | ||||
-rw-r--r-- | c/tests/test_child.c | 86 |
3 files changed, 149 insertions, 7 deletions
diff --git a/c/include/subunit/child.h b/c/include/subunit/child.h index e850c95..52801f5 100644 --- a/c/include/subunit/child.h +++ b/c/include/subunit/child.h @@ -26,3 +26,34 @@ * @name: test case name */ extern void subunit_test_start(char const * const name); + + +/** + * subunit_test_pass: + * + * Report that a test has passed. + * @name: test case name + */ +extern void subunit_test_pass(char const * const name); + + +/** + * subunit_test_fail: + * + * Report that a test has failed. + * @name: test case name + * @error: a string describing the error. + */ +extern void subunit_test_fail(char const * const name, char const * const error); + + +/** + * subunit_test_error: + * + * Report that a test has errored. An error is an unintentional failure - i.e. + * a segfault rather than a failed assertion. + * @name: test case name + * @error: a string describing the error. + */ +extern void subunit_test_error(char const * const name, + char const * const error); diff --git a/c/lib/child.c b/c/lib/child.c index afae611..302c50f 100644 --- a/c/lib/child.c +++ b/c/lib/child.c @@ -19,11 +19,48 @@ **/ #include <stdio.h> +#include <string.h> + +/* these functions all flush to ensure that the test runner knows the action + * that has been taken even if the subsequent test etc takes a long time or + * never completes (i.e. a segfault). + */ void subunit_test_start(char const * const name) { fprintf(stdout, "test: %s\n", name); - /* flush to ensure that the test runner knows we have started. */ + fflush(stdout); +} + + +void +subunit_test_pass(char const * const name) +{ + fprintf(stdout, "success: %s\n", name); + fflush(stdout); +} + + +void +subunit_test_fail(char const * const name, char const * const error) +{ + fprintf(stdout, "failure: %s [\n", name); + fprintf(stdout, "%s", error); + if (error[strlen(error) - 1] != '\n') + fprintf(stdout, "\n"); + fprintf(stdout, "]\n"); + fflush(stdout); +} + + +void +subunit_test_error(char const * const name, char const * const error) +{ + fprintf(stdout, "error: %s [\n", name); + fprintf(stdout, "%s", error); + if (error[strlen(error) - 1] != '\n') + fprintf(stdout, "\n"); + fprintf(stdout, "]\n"); fflush(stdout); } diff --git a/c/tests/test_child.c b/c/tests/test_child.c index e3a3d54..3dcd10d 100644 --- a/c/tests/test_child.c +++ b/c/tests/test_child.c @@ -24,7 +24,15 @@ #include "subunit/child.h" -START_TEST (test_start) +/** + * Helper function to capture stdout, run some call, and check what + * was written. + * @expected the expected stdout content + * @function the function to call. + **/ +static void +test_stdout_function(char const * expected, + void (*function)(void)) { /* test that the start function emits a correct test: line. */ int bytecount; @@ -50,7 +58,7 @@ START_TEST (test_start) /* yes this can block. Its a test case with < 100 bytes of output. * DEAL. */ - subunit_test_start("test case"); + function(); /* restore stdout now */ if (dup2(old_stdout, 1) != 1) { close(old_stdout); @@ -73,22 +81,88 @@ START_TEST (test_start) /* and we dont need the read side any more */ fail_if(close(new_stdout[0]), "Failed to close write side of socketpair."); /* compare with expected outcome */ -#define EXPECTED "test: test case\n" - fail_if(strcmp(EXPECTED, buffer), "Did not get expected output [%s], got [%s]", EXPECTED, buffer); -#undef EXPECTED + fail_if(strcmp(expected, buffer), "Did not get expected output [%s], got [%s]", expected, buffer); +} + + +static void +call_test_start(void) +{ + subunit_test_start("test case"); +} + + +START_TEST (test_start) +{ + test_stdout_function("test: test case\n", call_test_start); } END_TEST -Suite *child_suite(void) +static void +call_test_pass(void) +{ + subunit_test_pass("test case"); +} + + +START_TEST (test_pass) +{ + test_stdout_function("success: test case\n", call_test_pass); +} +END_TEST + + +static void +call_test_fail(void) +{ + subunit_test_fail("test case", "Multiple lines\n of error\n"); +} + + +START_TEST (test_fail) +{ + test_stdout_function("failure: test case [\n" + "Multiple lines\n" + " of error\n" + "]\n", + call_test_fail); +} +END_TEST + + +static void +call_test_error(void) +{ + subunit_test_error("test case", "Multiple lines\n of output\n"); +} + + +START_TEST (error) +{ + test_stdout_function("failure: test case [\n" + "Multiple lines\n" + " of output\n" + "]\n", + call_test_error); +} +END_TEST + + + +Suite * +child_suite(void) { Suite *s = suite_create("subunit_child"); TCase *tc_core = tcase_create("Core"); suite_add_tcase (s, tc_core); tcase_add_test (tc_core, test_start); + tcase_add_test (tc_core, test_pass); + tcase_add_test (tc_core, test_fail); return s; } + int main(void) { |