#include <stdio.h>
#include <string.h>
#include <sc_assert.h>
#include <sc_mmgr.h>
#include <sc_error.h>
#include <unittest.h>
/* --------------------------------------------------------------------
* 定数定義
* --------------------------------------------------------------------
*/
/* assert エラー時に呼び出す最大関数登録数 */
#define UT_UNITTEST_FUNC_MAX (4096)
#define UT_OUTPUT stderr
/**
* テスト用関数リスト.
*/
typedef struct TestFuncEntry_ {
const char* funcName;
void (*testFunc)(void);
} TestFuncEntry;
/* プロトタイプ宣言 */
static void UT_cleanup(void);
static void UT_checkMemoryLeak(SC_MMgr* mmgr);
static void UT_checkMemoryError(SC_MMgr* mmgr);
/* テスト関数のリスト */
static TestFuncEntry testFuncs[UT_UNITTEST_FUNC_MAX];
static int testRunIndex = 0;
static int testRunSize = 0;
static int otherFuncSize = 0;
extern void UT_run_kscript_main(void);
/**
* 単体テスト実行。
*
* @param argc 引数の数
* @param argv コマンド引数
*/
int main(int argc, char* argv[])
{
UT_run_kscript_main();
UT_run();
return 0;
}
/**
* テスト用関数を追加します.
*
* @param testfunc テスト用関数
*/
void UT_add(const char* funcName, void (*testFunc)(void))
{
testFuncs[testRunSize + otherFuncSize].funcName = funcName;
testFuncs[testRunSize + otherFuncSize].testFunc = testFunc;
if (strcmp("OTHER", funcName) == 0)
{
otherFuncSize++;
}
else
{
testRunSize++;
}
}
/**
* 単体テストを実行します.
*/
void UT_run(void)
{
int i;
SC_setAssertOutput(UT_OUTPUT);
SC_assertAtExit(UT_cleanup);
testRunIndex = 0;
for (i = 0; i < (testRunSize + otherFuncSize); i++)
{
SC_MMgr_setHandler(NULL, NULL, UT_checkMemoryError);
if (strcmp("OTHER", testFuncs[i].funcName) != 0)
{
fprintf(UT_OUTPUT, "[No.%05d] %-50s\n",
(testRunIndex + 1), testFuncs[i].funcName);
testRunIndex++;
}
testFuncs[i].testFunc();
}
UT_cleanup();
}
/**
* 単体試験終了時に実行します.
*/
static
void UT_cleanup(void)
{
SC_MMgr_entries(UT_checkMemoryLeak);
fprintf(UT_OUTPUT, "run test case [ %d / %d ]\n",
testRunIndex, testRunSize);
}
/**
* メモリリークが発生していないかチェックします。
*/
static
void UT_checkMemoryLeak(SC_MMgr* mmgr)
{
fprintf(UT_OUTPUT, "%s:%08d (size = %08d byte) memory Leak\n",
mmgr->file,
mmgr->line,
mmgr->size);
}
static
void UT_checkMemoryError(SC_MMgr* mmgr)
{
const char* errorType;
int nowError = SC_getError();
int ret;
switch (nowError)
{
case SC_EINVAL: errorType = "memory duplicate free"; break;
case SC_ENOMEM: errorType = "memory allocate error"; break;
default: errorType = "other error";
}
/* メモリ管理部分 (tests/ut_scmmgr.c) のテストでは
* エラーの試験しているため、エラー出力対象外とする
*/
ret = strcmp("tests/ut_sc_mmgr.c", mmgr->file);
if (ret != 0)
{
fprintf(UT_OUTPUT, "%s:%08d (size = %08d byte) %s\n",
mmgr->file,
mmgr->line,
mmgr->size,
errorType);
}
}