## Assertion writing helper Assertion writing helper — Symbols in this section help you writing your own assertions. |

## Synopsis

    void                cut_test_pass                       (void);
    void                cut_test_fail                       (const char *system_message,
                                                             ...);
    void                cut_test_fail_va_list               (const char *system_message,
                                                             const char *user_message_format);
    #define             CUT_RELATIVE_PATH
    void                cut_push_backtrace                  (const char *expression);
    void                cut_pop_backtrace                   (void);
    #define             cut_trace                           (expression)
    #define             cut_trace_with_info_expression      (expression, info_expression)

## Description

You will need to write your own assertions for writing easy to read test. Symbols in this section help you writing your own assertions.

e.g.:

my-assertions.h:

    #ifndef __MY_ASSERTIONS_H__
    #define __MY_ASSERTIONS_H__

    #include <cutter.h>

    #ifdef __cplusplus
    extern "C" {
    #endif

    #define my_assert_equal_int(expected, actual)                    \
        cut_trace_with_info_expression(                              \
            my_assert_equal_int_helper((expected), (actual),         \
                                       # expected, # actual),        \
            my_assert_equal_int(expected, actual, __VA_ARGS__))

    void my_assert_equal_int_help (long expected,
                                   long actual,
                                   const char *expression_expected,
                                   const char *expression_actual);

    #ifdef __cplusplus
    }
    #endif

    #endif

my-assertions.c:

    #include "my-assertions.h"

    void
    my_assert_equal_int_helper (long expected,
                                long actual,
                                const char *expression_expected,
                                const char *expression_actual)
    {
        if (expected == actual) {
            cut_test_pass();
        } else {
            cut_test_fail(cut_take_printf("<%s == %s>\n"
                                          "expected: <%ld>\n"
                                          "  actual: <%ld>",
                                          expression_expected,
                                          expression_actual,
                                          expected, actual));
        }
    }

Makefile.am:

    AM_CFLAGS = $(CUTTER_CFLAGS)
    LIBS = $(CUTTER_LIBS)
    noinst_LTLIBRARIES = libmy-assertions.la
    libmy_assertions_la_SOURCES = my-assertions.c my-assertions.h
    AM_LDFLAGS = -module -rpath $(libdir) -avoid-version -no-undefined

## Details

### cut_test_pass ()

    void                cut_test_pass                       (void);

Call `cut_test_pass()` if an assertion is passed. `cut_test_pass()` counts up n-assertions.

Since 1.0.5

### cut_test_fail ()

    void                cut_test_fail                       (const char *system_message,
                                                             ...);

Call `cut_test_fail()` if an assertion is failed. `cut_test_fail()` counts up n-failures and terminate the current test.

`system_message` : | a failure message from testing system.
`...` : | optional format string, followed by parameters to insert into the format string. (as with `printf()`) This is deprecated since 0.1.6. Use `cut_set_message()` instead.

Since 1.0.5

### cut_test_fail_va_list ()

    void                cut_test_fail_va_list               (const char *system_message,
                                                             const char *user_message_format);

### Warning

`cut_test_fail_va_list` has been deprecated since version 1.0.6 and should not be used in newly-written code. Use `cut_test_fail()` instead.

See `cut_test_fail()` for `cut_test_fail_va_list()`'s behavior. `user_message_format` is the prior variable of variable length arguments.

e.g.:

    void
    my_assert(cut_boolean result,
              const gchar *user_message_format,
              ...)
    {
        if (result) {
            cut_test_pass();
        } else {
            cut_test_fail_va_list("Fail!", user_message_format);
        }
    }

`system_message` : | a failure message from testing system.
`user_message_format` : | a failure message from user.

Since 1.0.5

### CUT_RELATIVE_PATH

    #  define CUT_RELATIVE_PATH NULL

Define this macro in a source code or build option (e.g. -DCUT_RELATIVE_PATH=\""sub/dir/"\") if the source code is built as shared library and used it as helper library of your test. If this path isn't set, you can't get correct path from `cut_trace()` and `cut_trace_with_info_expression()`.

Here is an example structure for explain:

    --- core-lib/ --- XXX.c # Your core library
     |             +- ...
     |             +- YYY.c
     +- util-lib/ --- AAA.c # Your utility library
     |             +- ...
     |             +- BBB.c
     |
     +- test/ --- core/ --- test-XXX.c # Tests for your core library
               |         +- ...
               |         +- test-YYY.c
               +- util/ --- test-AAA.c # Tests for your utility library
               |         +- ...
               |         +- test-BBB.c
               +- lib/  --- my-assertions.c # Your library of tests.
                         +- my-assertions.h # This library will be used
                         |                  # as shared library of your
                         |                  # tests (test/core/test-*.so
                         |                  # and test/util/test-*.so)
                         +- ...

      % cutter --source-directory=test test

In the above example structure, you need to define `CUT_RELATIVE_PATH` as "lib" in test/lib/my-assertions.c because my-assertions.c is in lib/ directory from source directory "test" specified by command line option --source-directory.

Here are example code and build option:

    test/lib/my-assertions.c:
      #define CUT_RELATIVE_PATH "lib"
      #include <cutter.h>

    build option:
      % gcc -DCUT_RELATIVE_PATH="\"lib\"" ...

Since 1.0.6

### cut_push_backtrace ()

    void                cut_push_backtrace                  (const char *expression);

Pushes `expression` and the current source place to the backtrace stack.

Normally, you don't need to use it directory. `cut_trace()` is enough.

`expression` : | an expression to be traced.

Since 1.0.6

### cut_pop_backtrace ()

    void                cut_pop_backtrace                   (void);

Pops a backtrace from the backtrace stack.

Normally, you don't need to use it directory. `cut_trace()` is enough.

Since 1.0.6

### cut_trace()

    #define             cut_trace(expression)

Mark the current file, line, function and `expression` and show it when assertion is failed in `expression`. Most of `expression` will be function call.

Note that you can't get return value of `expression`.

Here is an example of `cut_trace()`. If cut_assert_not_null(object) is failed, you will get a backtrace that contains two line; cut_assert_not_null(object) and create_my_object("my-name").

e.g.:

    static MyObject *object;

    static void
    create_my_object(const char *name)
    {
        object = my_object_new(name);
        cut_assert_not_null(object);
    }

    void
    test_my_object_name(void)
    {
        cut_trace(create_my_object("my-name"));
        cut_assert_equal_string("my-name",
                                my_object_get_name(object));
    }

You will use `cut_trace()` with macro for test readability:

    static MyObject *object;

    static void
    create_my_object_helper(const char *name)
    {
        object = my_object_new(name);
        cut_assert_not_null(object);
    }

    #define create_my_object(...)                        \
        cut_trace(create_my_object_helper(__VA_ARGS__))

    void
    test_my_object_name(void)
    {
        create_my_object("my-name");
        cut_assert_equal_string("my-name",
                                my_object_get_name(object));
    }

`expression` : | an expression to be traced.

Since 1.0.5

### cut_trace_with_info_expression()

    #define             cut_trace_with_info_expression(expression, info_expression)

It's difference between `cut_trace()` and `cut_trace_with_info_expression()` that traced expression is the same expression as `expression` or not. `cut_trace_with_info_expression()` is useful when you want to hide some information in `expression` for backtrace readability.

Here is an example of `cut_trace_with_info_expression()`. If cut_assert_not_null(object) is failed, you will get a backtrace that contains two line:

- cut_assert_not_null(object)

- create_my_object("my-name") not create_my_object_helper("my-name")

If you use `cut_trace()` instead of `cut_trace_with_info_expression()`, you will get create_my_object_helper("my-name"). You may be confused about 'Where is create_my_object_helper("my-name") from? `test_my_object_name()` uses create_my_object("my-name") but does not use create_my_object_helper("my-name").'.

e.g.:

    static MyObject *object;

    static void
    create_my_object_helper(const char *name)
    {
        object = my_object_new(name);
        cut_assert_not_null(object);
    }

    #define create_my_object(...)                        \
        cut_trace_with_info_expression(                  \
            create_my_object_helper(__VA_ARGS__),        \
            create_my_object(__VA_ARGS__))

    void
    test_my_object_name(void)
    {
        create_my_object("my-name");
        cut_assert_equal_string("my-name",
                                my_object_get_name(object));
    }

`expression` : | an expression to be traced.
`info_expression` : | a traced expression.

Since 1.0.5