summaryrefslogtreecommitdiff
path: root/c
diff options
context:
space:
mode:
authorRobert Collins <robertc@robertcollins.net>2006-04-15 15:19:59 +1000
committerRobert Collins <robertc@robertcollins.net>2006-04-15 15:19:59 +1000
commit96bf18f88a718e2751d13c1aa3725e18f1223b77 (patch)
tree8d7eddf533277240da9b6067efd7e8f55955705d /c
parentff4fc243402f5b1da14aa20c8208ff882b43a6f7 (diff)
downloadsubunit-96bf18f88a718e2751d13c1aa3725e18f1223b77.tar.gz
Finish C child bindings.
Diffstat (limited to 'c')
-rw-r--r--c/include/subunit/child.h31
-rw-r--r--c/lib/child.c39
-rw-r--r--c/tests/test_child.c86
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)
{