検証作成の補助 3 Cutterライブラリ
検証作成の補助 このセクションにあるシンボルは独自検証を作成することを補助します。

## 概要

    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)
    const char *        cut_append_diff                     (const char *message,
                                                             const char *from,
                                                             const char *to);
    #define             cut_set_expected                    (expected)
    #define             cut_set_actual                      (actual)
    const char *        cut_inspect_string_array            (const char **strings);
    cut_boolean         cut_equal_string                    (const char *string1,
                                                             const char *string2);
    cut_boolean         cut_equal_double                    (double double1,
                                                             double double2,
                                                             double error);
    #define             cut_equal_sockaddr                  (address1,
                                                             address2)
    #define             cut_inspect_sockaddr                (address)
    const char *        cut_get_test_directory              (void);
    const char *        cut_get_source_directory            (void);

## 説明

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

例:

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_pass

### 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

### 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_test_fail_va_list
cut_test_fail_va_list

### 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_RELATIVE_PATH

### cut_push_backtrace ()

    void                cut_push_backtrace                  (const char *expression);

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

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

expression :

  呼び出されたことを記録される式。

1.0.6から

cut_push_backtrace

### cut_pop_backtrace ()

    void                cut_pop_backtrace                   (void);

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

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

1.0.6から

cut_pop_backtrace

### 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

### 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から

cut_trace_with_info_expression

### cut_append_diff ()

    const char *        cut_append_diff                     (const char *message,
                                                             const char *from,
                                                             const char *to);

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

fromとtoのdiffを計算し、そのdiffをmessageに追加します。戻り値の文字列の所有者はCutterです。

message :

  diffが追加される文字列。

from :

  元の文字列。

to :

  修正された文字列。

戻り値 :

  fromとto間のdiff付きのmessage。必要なさそうなdiffであればmessageと同じ。開放しないでください。

1.0.3から

cut_append_diff
cut_append_diff

### cut_set_expected()

    #define             cut_set_expected(expected)

次の検証で使う詳細化した期待値オブジェクトを設定します。

期待値オブジェクトと実際値オブジェクトの両方が設定され、それらのdiffが必要な場合は自動的にdiffを生成します。

`cut_set_actual()`も見てください。

expected :

  期待値オブジェクトの詳細。

1.0.9から

cut_set_expected

### cut_set_actual()

    #define             cut_set_actual(actual)

次の検証で使う詳細化した実際値オブジェクトを設定します。

期待値オブジェクトと実際値オブジェクトの両方が設定され、それらのdiffが必要な場合は自動的にdiffを生成します。

`cut_set_expected()`も見てください。

actual :

  実測値オブジェクトの詳細。

1.0.9から

cut_set_actual

### cut_inspect_string_array ()

    const char *        cut_inspect_string_array            (const char **strings);

stringsを人が読みやすい文字列に整形します。整形された文字列の所有者はCutterです。

strings :

  整形される文字列の配列。

戻り値 :

  Cutterが所有する整形された文字列。解放しないで下さい。

cut_inspect_string_array

### cut_equal_string ()

    cut_boolean         cut_equal_string                    (const char *string1,
                                                             const char *string2);

string1とstring2を比較します。string1あるいはstring2、または両方が`NULL`でもかまいません。

string1 :

  文字列。

string2 :

  文字列。

戻り値 :

  string1とstring2が両方`NULL`、あるいは同じ内容の場合は`CUT_TRUE`、そうでない場合は`CUT_FALSE`。

1.0.5から

cut_equal_string

### cut_equal_double ()

    cut_boolean         cut_equal_double                    (double double1,
                                                             double double2,
                                                             double error);

double1とdouble2を誤差範囲errorで比較します。

double1 :

  浮動小数点値。

double2 :

  浮動小数点値。

error :

  誤差範囲を示す浮動小数点数。

戻り値 :

  |double1 - double2| <= errorなら`CUT_TRUE`、そうでなければ`CUT_FALSE`。

1.0.5から

cut_equal_double

### cut_equal_sockaddr()

    #define             cut_equal_sockaddr(address1, address2)

address1とaddress2を比較します。

この関数はCUT_DISABLE_SOCKET_SUPPORTを定義すると無効にできます。

address1 :

  ソケットアドレス。

address2 :

  ソケットアドレス。

戻り値 :

  sub_processが異常終了したときは`CUT_TRUE`、そうでない場合は`CUT_FALSE`。

1.1.1から

cut_equal_sockaddr

### cut_inspect_sockaddr()

    #define             cut_inspect_sockaddr(address)

addressを人が読みやすい文字列に整形します。整形された文字列の所有者はCutterです。

この関数はCUT_DISABLE_SOCKET_SUPPORTを定義すると無効にできます。

address :

  詳細化されるソケットアドレス。

戻り値 :

  Cutterが所有する整形されたソケットアドレス。解放しないで下さい。

1.1.1から

cut_inspect_sockaddr

### cut_get_test_directory ()

    const char *        cut_get_test_directory              (void);

コマンドラインで指定されたテストディレクトリ名を返します。

戻り値 :

  Cutterが所有する文字列。解放しないで下さい。

1.1.4から

cut_get_test_directory

### cut_get_source_directory ()

    const char *        cut_get_source_directory            (void);

コマンドラインで指定されたソースディレクトリ名を返します。

戻り値 :

  Cutterが所有する文字列。解放しないで下さい。

1.1.5から

cut_get_source_directory