## 検証作成の補助 検証作成の補助 — このセクションにあるシンボルは独自検証を作成することを補助します。 |

## 概要

    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)

## 説明

読みやすいテストを書くために独自の検証を作成する必要があるでしょう。このセクションのシンボルは独自の検証を作成を補助します。

例:

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

## 詳細

### cut_test_pass ()

    void                cut_test_pass                       (void);

検証をパスしたら`cut_test_pass()`を呼んでください。`cut_test_pass()`は検証数を増やします。

1.0.5から

### cut_test_fail ()

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

検証が失敗したら`cut_test_fail()`を呼んでください。`cut_test_fail()`は失敗数を増やし、現在のテストを中断します。

`system_message` : | テストフレームワーク指定の失敗メッセージ。
`...` : | 省略可能な整形文字列。以降のパラメータが整形文字列に挿入されます。（`printf()`と同じ。）このパラメータは0.1.6から非推奨となっています。代わりに`cut_set_message()`を使ってください。

1.0.5から

### cut_test_fail_va_list ()

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

### 警告

`cut_test_fail_va_list`はバージョン1.0.6から非推奨になりました。新しく書くコードでは使わないで下さい。代わりに`cut_test_fail()`を使ってください。

`cut_test_fail_va_list()`の動作については`cut_test_fail()`を見てください。`user_message_format`は可変長引数の1つ前の引数です。

例:

    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` : | テストフレームワーク指定の失敗メッセージ。
`user_message_format` : | ユーザ指定の失敗メッセージ。

1.0.5から

### CUT_RELATIVE_PATH

    #  define CUT_RELATIVE_PATH NULL

もし、テスト用の補助ライブラリを共有ライブラリとして使っている場合は、補助ライブラリのソースコード中またはビルドオプション（例: -DCUT_RELATIVE_PATH=\""sub/dir/"\"）でこのマクロを定義してください。もし、このパスが設定されていない場合は`cut_trace()`と`cut_trace_with_info_expression()`で正しいパスが得られません。

説明用のディレクト構成例です。

    --- core-lib/ --- XXX.c # コアライブラリ
     |             +- ...
     |             +- YYY.c
     +- util-lib/ --- AAA.c # 便利ライブラリ
     |             +- ...
     |             +- BBB.c
     |
     +- test/ --- core/ --- test-XXX.c # コアライブラリのテスト
               |         +- ...
               |         +- test-YYY.c
               +- util/ --- test-AAA.c # 便利ライブラリのテスト
               |         +- ...
               |         +- test-BBB.c
               +- lib/  --- my-assertions.c # テスト用補助ライブラリ
                         +- my-assertions.h # テスト中（
                         |                  # test/core/test-*.soと
                         |                  # test/util/test-*.soの中）
                         |                  # で共有ライブラリとして使われる
                         +- ...

      % cutter --source-directory=test test

上記の構成例では、test/lib/my-assertions.cでは`CUT_RELATIVE_PATH`を"lib"と定義しなければいけません。これは、--source-directoryコマンドラインオプションで指定した"test"ソースディレクトリからみてlib/ディレクトリにmy-assertions.cがあるからです。

コードとビルドオプションの例です。

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

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

1.0.6から

### cut_push_backtrace ()

    void                cut_push_backtrace                  (const char *expression);

`expression`と現在のソースの場所をバックトレーススタックにプッシュします。

通常は直接使う必要はありません。`cut_trace()`で十分です。

`expression` : | 呼び出されたことを記録される式。

1.0.6から

### cut_pop_backtrace ()

    void                cut_pop_backtrace                   (void);

バックトレーススタックからバックトレースをポップします。

通常は直接使う必要はありません。`cut_trace()`で十分です。

1.0.6から

### cut_trace()

    #define             cut_trace(expression)

現在のファイル名、行番号、関数名、`expression`を記憶し、`expression`内で検証が失敗した場合に表示します。`expression`の多くは関数呼び出しになるでしょう。

`expression`の戻り値を取得できないことに注意してください。

`cut_trace()`は以下の通りです。もし、cut_assert_not_null(object)が失敗したら、バックトレースには2行含まれます。cut_assert_not_null(object)とcreate_my_object("my-name")です。

例:

    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));
    }

テストを読みやすくするために`cut_trace()`を使ったマクロを書くかもしれません:

    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` : | 呼び出されたことを記録される式。

1.0.5から

### cut_trace_with_info_expression()

    #define             cut_trace_with_info_expression(expression, info_expression)

`cut_trace()`と`cut_trace_with_info_expression()`の違いは記録される式が`expression`と同じかどうかです。`cut_trace_with_info_expression()`はバックトレースの読みやすさのために`expression`から情報を隠したいときに便利です。

`cut_trace_with_info_expression()`の例です。cut_assert_not_null(object)が失敗すると以下の2行を含んだバックトレースが得られます:

- cut_assert_not_null(object)

- create_my_object_helper("my-name")ではなくcreate_my_object("my-name")

もし、`cut_trace_with_info_expression()`ではなく`cut_trace()`を使った場合はcreate_my_object_helper("my-name")になります。もし、create_my_object_helper("my-name")が得られたら以下のように混乱してしまうかもしれません。「create_my_object_helper("my-name")はどこからきたんだ？`test_my_object_name()`はcreate_my_object("my-name")は使っているけど、create_my_object_helper("my-name")は使っていないぞ。」

例:

    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` : | 呼び出されたことを記録される式。
`info_expression` : | 呼び出されたと記録される式。

1.0.5から