TAP (Test Anything Protocol) ============================== .. warning:: *This file must be included before (or instead of) ``ymo_assert.h``.* .. c:macro:: YMO_TAP_STREAM_OUT Output stream for TAP results. .. code-block:: c :caption: Definition #define YMO_TAP_STREAM_OUT stdout .. c:macro:: YMO_TAP_STATUS_PASS Value to return from passing unit tests. (**NOTE**: :c:macro:`YMO_TAP_PASS` is preferred) .. code-block:: c :caption: Definition #define YMO_TAP_STATUS_PASS 0 .. c:macro:: YMO_TAP_STATUS_FAIL Value to return from failing unit tests (any non-zero value will work — ``errno`` is always a safe bet). (**NOTE**: :c:macro:`YMO_TAP_FAIL` is preferred) .. code-block:: c :caption: Definition #define YMO_TAP_STATUS_FAIL 1 This module overrides :c:macro:`ymo_assert_test_fail` to return :c:macro:`YMO_TAP_STATUS_FAIL`. The assertion conditional will be reported as test output, e.g.: .. code-block:: c int x = 1; int y = 2; ymo_assert(x == y); Will result in: .. code-block:: not ok 1 - assertion failed! assertion: x == y location: my_source.c:test_my_test:3 The override (included in ymo_tap.h!) looks like this: .. c:macro:: YMO_TAP_PASS Pass a unit test with the given message. .. code-block:: c :caption: Definition #define YMO_TAP_PASS(msg) \ fprintf(YMO_TAP_STREAM_OUT, "ok %zu - %s\n", \ tap_test_num, msg); \ return YMO_TAP_STATUS_PASS .. c:macro:: YMO_TAP_FAIL Pass a unit test with the given message. .. code-block:: c :caption: Definition #define YMO_TAP_FAIL(msg) \ fprintf(YMO_TAP_STREAM_OUT, "not ok %zu - %s\n", \ tap_test_num, msg); \ return YMO_TAP_STATUS_FAIL .. c:type:: ymo_tap_test_fn_t Individual unit test signature. .. code-block:: c :caption: Definition typedef int (*ymo_tap_test_fn_t)(void); .. c:type:: ymo_tap_test_t Struct used to represent individual unit tests. .. code-block:: c :caption: Definition typedef struct ymo_tap_test ymo_tap_test_t; .. c:type:: ymo_tap_setup_fn_t Test setup/teardown callback signature. .. code-block:: c :caption: Definition typedef int (*ymo_tap_setup_fn_t)(void); .. c:macro:: YMO_TAP_NO_INIT Pass as the first argument to :c:macro:`YMO_TAP_TEST` if no setup/teardown callbacks are required. .. code-block:: c :caption: Definition #define YMO_TAP_NO_INIT() NULL, NULL, NULL .. c:macro:: YMO_TAP_TEST_FN Macro used to pass a :c:type:`ymo_test_fn_t` as an argument to :c:func:`ymo_tap_run` or :c:macro:`YMO_TAP_RUN`. .. code-block:: c :caption: Definition #define YMO_TAP_TEST_FN(fn) \ ((ymo_tap_test_t) { .name = #fn, .test_fn = fn }) .. c:macro:: YMO_TAP_TEST_END Macro used to terminate the list of arguments to :c:func:`ymo_tap_run` or :c:macro:`YMO_TAP_RUN`. .. code-block:: c :caption: Definition #define YMO_TAP_TEST_END() \ ((ymo_tap_test_t) { .name = NULL, .test_fn = NULL }) .. c:function:: int ymo_tap_run( ymo_tap_setup_fn_t setup_suite, ymo_tap_setup_fn_t setup_test, ymo_tap_setup_fn_t cleanup, ...); :param ymo_tap_test_fn_t: an initialization function to run before each test (may be ``NULL``) :param ...: a `NULL` terminated list of :c:type:`ymo_tap_test_t`. :returns: zero on success; non-zero on failure .. c:macro:: YMO_TAP_RUN .. c:macro::YMO_TAP_RUN(...) Define a ``main`` function which invokes ::c:func:`ymo_tap_run` with the input arguments. .. code-block:: c :caption: Definition #define YMO_TAP_RUN(...) \ int main(int argc, char** argv) { \ ymo_tap_exec = argv[0]; \ ymo_log_init(); \ return ymo_tap_run(__VA_ARGS__); \ }