#include <stdio.h> #include <string.h> #include <kc.h> #include <kc_ut.h> #include <kc_assert.h> #include <kc_map.h> #include <kc_memory.h> #include "ut.h" // プロトタイプ宣言 static void test_map_new(void); static void test_map_put(void); static void test_map_remove(void); static void test_map_entries(void); static void test_map_malloc_error(void); /** * KcMap 単体テストスイート */ void suite_map(void) { KcUt *ut = KcUt_get_instance(); ut->add(ut, UT_TESTCASE, "map new/delete", test_map_new); ut->add(ut, UT_TESTCASE, "map put/get", test_map_put); ut->add(ut, UT_TESTCASE, "map remove", test_map_remove); ut->add(ut, UT_TESTCASE, "map entries", test_map_entries); ut->add(ut, UT_TESTCASE, "map malloc error", test_map_malloc_error); } /** * Map 生成/破棄。 * * @process KcMap_new を実行する。。 * @result KcMap が生成されること。 * * @process KcMap_delete にて Map を破棄する。 * @result Map が破棄されること。 */ static void test_map_new(void) { KcMap *map = KcMap_new(0); assert_not_null(map); KcMap_delete(map); map = KcMap_new(65538); assert_not_null(map); KcMap_delete(map); // map にデータが残った状態での削除 map = KcMap_new(10); assert_not_null(map); map->put(map, "key1", "value1", 7); KcMap_delete(map); } /** * Map への追加/取得。 */ static void test_map_put(void) { KcMap *map = KcMap_new(5); assert_not_null(map); const char *keys[] = { "key1", "key2", "key3", "key4", "key5", "key6", "key7", "key8", "key9", "key10", "key11", "key12", "key13", "key14", "key15"}; const char *vals[] = { "val1", "val2", "val3", "val4", "val5", "val6", "val7", "val8", "val9", "val10", "val11", "val12", "val13", "val14", "val15"}; char *res; for (int i = 0; i < (int)(sizeof(keys) / sizeof(const char *)); i++) { res = (char *)map->put(map, keys[i], vals[i], strlen(vals[i]) + 1); assert_equals(vals[i], (const char *)res); } // 値取得 for (int i = 0; i < (int)(sizeof(keys) / sizeof(const char *)); i++) { size_t size; const char *value = (const char *)map->get(map, keys[i], &size); assert_equals(vals[i], value); } // 存在しないキーの値取得 void *ptr = map->get(map, "ABC", NULL); assert_null(ptr); // キー上書き登録 res = (char *)map->put(map, "key10", "abcdefg", strlen("abcdefg") + 1); assert_equals("abcdefg", (const char *)res); res = (char *)map->get(map, "key10", NULL); assert_equals("abcdefg", (const char *)res); KcMap_delete(map); } /** * Map からの削除/サイズ確認。 */ static void test_map_remove(void) { KcMap *map = KcMap_new(3); assert_not_null(map); const char *keys[] = { "key1", "key2", "key3", "key4", "key5", "key6", "key7", "key8", "key9", "key10", "key11", "key12", "key13", "key14", "key15"}; const char *vals[] = { "val1", "val2", "val3", "val4", "val5", "val6", "val7", "val8", "val9", "val10", "val11", "val12", "val13", "val14", "val15"}; char *res; for (int i = 0; i < (int)(sizeof(keys) / sizeof(const char *)); i++) { res = (char *)map->put(map, keys[i], vals[i], strlen(vals[i]) + 1); assert_equals(vals[i], (const char *)res); } int size_counter = 14; map->remove(map, "key15"); size_t size = map->size(map); assert_equals(size_counter, size); size_counter--; res = (char *)map->get(map, "key15", NULL); assert_null(res); map->remove(map, "key7"); size = map->size(map); assert_equals(size_counter, size); size_counter--; res = (char *)map->get(map, "key7", NULL); assert_null(res); map->remove(map, "key13"); size = map->size(map); assert_equals(size_counter, size); size_counter--; res = (char *)map->get(map, "key13", NULL); assert_null(res); map->remove(map, "key1"); size = map->size(map); assert_equals(size_counter, size); size_counter--; res = (char *)map->get(map, "key1", NULL); assert_null(res); map->remove(map, "key2"); size = map->size(map); assert_equals(size_counter, size); size_counter--; res = (char *)map->get(map, "key2", NULL); assert_null(res); map->remove(map, "key3"); size = map->size(map); assert_equals(size_counter, size); size_counter--; res = (char *)map->get(map, "key3", NULL); assert_null(res); // 存在しないキー削除 map->remove(map, "abc"); size = map->size(map); assert_equals(9, size); KcMap_delete(map); // パターン2 map = KcMap_new(3); assert_not_null(map); size_counter = 3; for (int i = 0; i < size_counter; i++) { res = (char *)map->put(map, keys[i], vals[i], strlen(vals[i]) + 1); assert_equals(vals[i], (const char *)res); } size_counter--; map->remove(map, "key1"); size = map->size(map); assert_equals(size_counter, size); size_counter--; res = (char *)map->get(map, "key1", NULL); assert_null(res); map->remove(map, "key2"); size = map->size(map); assert_equals(size_counter, size); size_counter--; res = (char *)map->get(map, "key2", NULL); assert_null(res); map->remove(map, "key3"); size = map->size(map); assert_equals(size_counter, size); size_counter--; res = (char *)map->get(map, "key3", NULL); assert_null(res); KcMap_delete(map); } // エントリ typedef struct UserData_ { int value; } UserData; static bool test_map_entries_handler(const char *key, const void *val, size_t size, void *args) { UserData *user_data = (UserData *)args; user_data->value--; printf("key=%-5s, value=%-5s, size=%zu\n", key, (const char *)val, size); return (user_data->value >= 0); } /** * Map エントリ取得 */ static void test_map_entries(void) { KcMap *map = KcMap_new(5); assert_not_null(map); const char *keys[] = { "key1", "key2", "key3", "key4", "key5", "key6", "key7", "key8", "key9", "key10", "key11", "key12", "key13", "key14", "key15"}; const char *vals[] = { "val1", "val2", "val3", "val4", "val5", "val6", "val7", "val8", "val9", "val10", "val11", "val12", "val13", "val14", "val15"}; char *res; for (int i = 0; i < (int)(sizeof(keys) / sizeof(const char *)); i++) { res = (char *)map->put(map, keys[i], vals[i], strlen(vals[i]) + 1); assert_equals(vals[i], (const char *)res); } // entries UserData args = { .value = 10000}; map->entries(map, test_map_entries_handler, &args); // entries [途中中断] UserData args2 = { .value = 5}; map->entries(map, test_map_entries_handler, &args2); KcMap_delete(map); } /** * メモリ確保失敗 */ static void test_map_malloc_error(void) { // 生成時失敗 ut_alloc_control(0) { KcMap *map = KcMap_new(5); assert_null(map); } // put 時失敗 KcMap *map = KcMap_new(5); const char *keys[] = { "key1", "key2", "key3", "key4", "key5", "key6", "key7", "key8", "key9", "key10", "key11", "key12", "key13", "key14", "key15"}; const char *vals[] = { "val1", "val2", "val3", "val4", "val5", "val6", "val7", "val8", "val9", "val10", "val11", "val12", "val13", "val14", "val15"}; char *res; for (int i = 0; i < (int)(sizeof(keys) / sizeof(const char *)); i++) { res = (char *)map->put(map, keys[i], vals[i], strlen(vals[i]) + 1); assert_equals(vals[i], (const char *)res); } ut_alloc_control(0) { res = (char *)map->put(map, "abc", "def", 4); assert_null(res); } KcMap_delete(map); }