From 6c74793931c41aaf38759fd2a72a3f9f19e845f6 Mon Sep 17 00:00:00 2001 From: jf-home Date: Fri, 30 Aug 2024 01:45:15 +0800 Subject: [PATCH] =?UTF-8?q?list=E5=8D=95=E6=B5=8B=E5=8F=8A=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E7=BB=93=E6=9E=84=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 3rdparty/unicstl-unity/src/unity_config.h | 2 +- demo/demo.c | 10 +- include/list.h | 10 +- run.bat | 2 +- src/list.c | 16 +- test/test.c | 10 +- test/test.h | 6 +- test/test_list.c | 490 ++++++++++++++++++++++ test/test_queue.c | 1 - test/test_stack.c | 4 +- 10 files changed, 526 insertions(+), 25 deletions(-) create mode 100644 test/test_list.c diff --git a/3rdparty/unicstl-unity/src/unity_config.h b/3rdparty/unicstl-unity/src/unity_config.h index 4ed416d..6d5e8c8 100644 --- a/3rdparty/unicstl-unity/src/unity_config.h +++ b/3rdparty/unicstl-unity/src/unity_config.h @@ -2,7 +2,7 @@ #ifndef _UNITY_CONFIG_H_ #define _UNITY_CONFIG_H_ -#define UNITY_OUTPUT_COLOR 1 +// #define UNITY_OUTPUT_COLOR 1 #define UNITY_USE_FLUSH_STDOUT 1 #define UNITY_INCLUDE_PRINT_FORMATTED 1 // support TEST_PRINTF diff --git a/demo/demo.c b/demo/demo.c index b1519cf..74af719 100644 --- a/demo/demo.c +++ b/demo/demo.c @@ -58,12 +58,12 @@ int main() printf("----- unicstl demo -----\n"); // while (1) { - // demo_list(); - // demo_stack(); - // demo_deque(); demo_queue(); - // demo_tree(); - // demo_heap(); + demo_stack(); + demo_list(); + demo_deque(); + demo_tree(); + demo_heap(); } printf("----- unicstl ok -----\n"); diff --git a/include/list.h b/include/list.h index db10f9f..9e09c82 100644 --- a/include/list.h +++ b/include/list.h @@ -30,8 +30,6 @@ struct _list int (*index)(struct _list* self, void* obj); // Return first index of obj. Return -1 if the obj is not present. bool (*remove)(struct _list* self, void *obj); // Remove first occurrence of obj. - bool (*clear)(struct _list* self); // Remove all items from list. - bool (*get)(struct _list* self, int index, void* obj); // 根据索引,获取对象 bool (*set)(struct _list* self, int index, void* obj); // 根据索引,修改对象 @@ -39,6 +37,11 @@ struct _list uint32_t(*size)(struct _list* self); bool (*empty)(struct _list* self); + // clear and free node + bool (*clear)(struct _list* self); + void (*destory)(struct _list* self); + + // sort bool (*reverse)(struct _list* self); // Reverse *IN PLACE*. @@ -50,9 +53,6 @@ struct _list */ bool (*sort)(struct _list* self, uint8_t reserve, int (*compare)(void* obj, void* obj2)); - // free - void (*destory)(struct _list* self); - // print void (*print)(struct _list* self); void (*print_obj)(void* obj); diff --git a/run.bat b/run.bat index e2ee338..e15252c 100644 --- a/run.bat +++ b/run.bat @@ -1 +1 @@ -start /b /wait build/release/bin/test.exe +start /b /wait build/release/bin/demo.exe diff --git a/src/list.c b/src/list.c index 6002c52..9095055 100644 --- a/src/list.c +++ b/src/list.c @@ -182,6 +182,12 @@ void list_print(struct _list* self) bool list_init2(struct _list* list, uint32_t obj_size, uint32_t capacity) { assert(list != NULL); + assert(obj_size > 0); + assert(capacity > 0); + if(list == NULL || obj_size == 0 || capacity == 0) + { + return false; + } // 1. set attr list->_obj_size = obj_size; @@ -222,10 +228,14 @@ list_t list_new(void) void list_free(list_t* list) { - if(*list != NULL) + assert(list != NULL); + if(list != NULL && *list != NULL) { - (*list)->destory(*list); + if((*list)->destory != NULL) + { + (*list)->destory(*list); + } free(*list); + *list = NULL; } - *list = NULL; } diff --git a/test/test.c b/test/test.c index 20e3027..4ebb5f9 100644 --- a/test/test.c +++ b/test/test.c @@ -60,8 +60,9 @@ void print_str(void* obj) // -------------------------------------------------- void setUp(void) { + // before each test static uint32_t item_cnt = 1; - printf("[%4d] ", item_cnt); + printf("# %d. ", item_cnt); item_cnt+=1; } @@ -70,13 +71,16 @@ void tearDown(void) // after each test } +#define TEST_ADD(name) printf("\n----- " #name " -----\n"); name(); + int main(int argc, char const *argv[]) { printf("----- Unicstl Unit Test -----\n"); UNITY_BEGIN(); - test_queue(); - test_stack(); + TEST_ADD(test_queue); + TEST_ADD(test_stack); + TEST_ADD(test_list); return UNITY_END(); } diff --git a/test/test.h b/test/test.h index bd6b685..a8ec0db 100644 --- a/test/test.h +++ b/test/test.h @@ -41,10 +41,10 @@ void print_str(void* obj); * @brief test function * */ -void test_list(void); -void test_stack(void); -void test_deque(void); void test_queue(void); +void test_stack(void); +void test_list(void); +void test_deque(void); void test_tree(void); void test_heap(void); diff --git a/test/test_list.c b/test/test_list.c new file mode 100644 index 0000000..4ec9c85 --- /dev/null +++ b/test/test_list.c @@ -0,0 +1,490 @@ +/** + * @file test_list.c + * @author wenjf (Orig5826@163.com) + * @brief + * @version 0.1 + * @date 2024-08-30 + * + * @copyright Copyright (c) 2024 + * + */ +#include "test.h" + +static void test_list_init2(void) +{ + struct _list list; + // ------------------------------ +#ifdef NDEBUG + TEST_ASSERT_FALSE(list_init2(NULL, sizeof(int), 1)); + TEST_ASSERT_FALSE(list_init2(&list, 0, 1)); + TEST_ASSERT_FALSE(list_init2(&list, sizeof(int), 0)); +#endif + TEST_ASSERT_TRUE(list_init2(&list, sizeof(int), 1)); + list.destory(&list); +} + +static void test_list_new(void) +{ + list_t list = NULL; + list = list_new(); + list_free(&list); + + // ------------------------------ + list = list_new(); + TEST_ASSERT_NOT_NULL(list); + +#ifdef NDEBUG + TEST_ASSERT_FALSE(list_init2(NULL, sizeof(int), 1)); + TEST_ASSERT_FALSE(list_init2(list, 0, 1)); + TEST_ASSERT_FALSE(list_init2(list, sizeof(int), 0)); +#endif + TEST_ASSERT_TRUE(list_init2(list, sizeof(int), 1)); + list_free(&list); + + TEST_ASSERT_NULL(list); + list_free(&list); // list_free(NULL); +} + +#if 0 + +static void test_list_push(void) +{ + int temp = 0; + int data[] = { 1,2,3,4,5,6,7,8,9,10 }; + uint32_t len = sizeof(data) / sizeof(data[0]); + uint32_t i = 0; + + list_t list = NULL; + + // ------------------------------ + list = list_new(); + list_init2(list, sizeof(int)); + TEST_ASSERT_TRUE(list->empty(list)); + for(i = 0; i < len; i++) + { + TEST_ASSERT_TRUE(list->push(list, &data[i])); + TEST_ASSERT_EQUAL_INT(i + 1, list->size(list)); + + TEST_ASSERT_TRUE(list->peek(list, &temp)); + TEST_ASSERT_EQUAL_INT(data[i], temp); + + TEST_ASSERT_FALSE(list->empty(list)); + } + list_free(&list); + + // ------------------------------ + list = list_new(); + list_init2(list, sizeof(int), len); + TEST_ASSERT_TRUE(list->empty(list)); + for(i = 0; i < len; i++) + { + TEST_ASSERT_TRUE(list->push(list, &data[i])); + TEST_ASSERT_EQUAL_INT(i + 1, list->size(list)); + + TEST_ASSERT_TRUE(list->peek(list, &temp)); + TEST_ASSERT_EQUAL_INT(data[i], temp); + + TEST_ASSERT_FALSE(list->empty(list)); + } + list_free(&list); + + // ------------------------------ + // if capacity is less than data len + list = list_new(); + list_init2(list, sizeof(int), len - 2); + for(i = 0; i < len; i++) + { + TEST_ASSERT_TRUE(list->push(list, &data[i])); + TEST_ASSERT_EQUAL_INT(i + 1, list->size(list)); + } + list_free(&list); +} + +static void test_list_pop(void) +{ + int temp = 0; + int data[] = { 1,2,3,4,5,6,7,8,9,10 }; + uint32_t len = sizeof(data) / sizeof(data[0]); + uint32_t i = 0; + + list_t list = NULL; + + // ------------------------------ + list = list_new(); + list_init2(list, sizeof(int)); + for(i = 0; i < len; i++) + { + list->push(list, &data[i]); + } + for (i = 0; i < len; i++) + { + TEST_ASSERT_TRUE(list->peek(list, &temp)); + TEST_ASSERT_EQUAL_INT(data[list->size(list) - 1], temp); + + TEST_ASSERT_TRUE(list->pop(list, &temp)); + + if (!list->empty(list)) + { + TEST_ASSERT_TRUE(list->peek(list, &temp)); + TEST_ASSERT_EQUAL_INT(data[list->size(list) - 1], temp); + } + else + { + TEST_ASSERT_FALSE(list->peek(list, &temp)); + } + } + TEST_ASSERT_TRUE(list->empty(list)); + TEST_ASSERT_FALSE(list->pop(list, &temp)); + list_free(&list); + + // ------------------------------ + list = list_new(); + list_init2(list, sizeof(int), len); + for(i = 0; i < len; i++) + { + list->push(list, &data[i]); + } + for (i = 0; i < len; i++) + { + TEST_ASSERT_TRUE(list->peek(list, &temp)); + TEST_ASSERT_EQUAL_INT(data[list->size(list) - 1], temp); + + TEST_ASSERT_TRUE(list->pop(list, &temp)); + + if (!list->empty(list)) + { + TEST_ASSERT_TRUE(list->peek(list, &temp)); + TEST_ASSERT_EQUAL_INT(data[list->size(list) - 1], temp); + } + else + { + TEST_ASSERT_FALSE(list->peek(list, &temp)); + } + } + TEST_ASSERT_TRUE(list->empty(list)); + TEST_ASSERT_FALSE(list->pop(list, &temp)); + list_free(&list); + + // ------------------------------ + // if capacity is less than data len + list = list_new(); + list_init2(list, sizeof(int), len - 2); + for(i = 0; i < len; i++) + { + TEST_ASSERT_TRUE(list->push(list, &data[i])); + TEST_ASSERT_EQUAL_INT(i + 1, list->size(list)); + } + uint32_t capacity = list->capacity(list); + for (i = 0; i < len; i++) + { + if (!list->empty(list)) + { + TEST_ASSERT_TRUE(list->pop(list, &temp)); + } + else + { + TEST_ASSERT_FALSE(list->pop(list, &temp)); + } + + if (!list->empty(list)) + { + TEST_ASSERT_TRUE(list->peek(list, &temp)); + TEST_ASSERT_EQUAL_INT(data[list->size(list) - 1], temp); + } + else + { + TEST_ASSERT_FALSE(list->pop(list, &temp)); + TEST_ASSERT_FALSE(list->peek(list, &temp)); + } + } + list_free(&list); +} + +static void test_list_clear(void) +{ + int temp = 0; + int data[] = { 1,2,3,4,5,6,7,8,9,10 }; + uint32_t len = sizeof(data) / sizeof(data[0]); + uint32_t i = 0; + + list_t list = NULL; + + // ------------------------------ + list = list_new(); + list_init2(list, sizeof(int)); + for(i = 0; i < len; i++) + { + list->push(list, &data[i]); + } + TEST_ASSERT_TRUE(list->clear(list)); + for(i = 0; i < len; i++) + { + list->push(list, &data[i]); + } + TEST_ASSERT_FALSE(list->empty(list)); + TEST_ASSERT_TRUE(list->clear(list)); + TEST_ASSERT_TRUE(list->empty(list)); + TEST_ASSERT_TRUE(list->clear(list)); + list_free(&list); + + // ------------------------------ + list = list_new(); + list_init2(list, sizeof(int), len); + TEST_ASSERT_TRUE(list->clear(list)); + for(i = 0; i < len; i++) + { + list->push(list, &data[i]); + } + TEST_ASSERT_FALSE(list->empty(list)); + TEST_ASSERT_TRUE(list->clear(list)); + TEST_ASSERT_TRUE(list->empty(list)); + TEST_ASSERT_TRUE(list->clear(list)); + list_free(&list); +} + +static void test_list_num(void) +{ + uint32_t i = 0; + int data[] = { 1,2,3,4,5,6,7,8,9,10 }; + int temp = 0; + uint32_t len = sizeof(data) / sizeof(data[0]); + + list_t list = NULL; + list = list_new(); + TEST_ASSERT_NOT_NULL(list); + + TEST_ASSERT_TRUE(list_init2(list, sizeof(int))); + list->print_obj = print_num; + + TEST_ASSERT_FALSE(list->peek(list, &temp)); + TEST_ASSERT_TRUE(list->clear(list)); + for (i = 0; i < len; i++) + { + TEST_ASSERT_TRUE(list->push(list, &data[i])); + TEST_ASSERT_EQUAL_INT(i + 1, list->size(list)); + + TEST_ASSERT_TRUE(list->peek(list, &temp)); + TEST_ASSERT_EQUAL_INT(data[i], temp); + } + + TEST_ASSERT_FALSE(list->empty(list)); + TEST_ASSERT_TRUE(list->clear(list)); + TEST_ASSERT_TRUE(list->empty(list)); + for (i = 0; i < len; i++) + { + TEST_ASSERT_TRUE(list->push(list, &data[i])); + } + + for (i = 0; i < len; i++) + { + TEST_ASSERT_TRUE(list->peek(list, &temp)); + TEST_ASSERT_EQUAL_INT(data[list->size(list) - 1], temp); + + TEST_ASSERT_TRUE(list->pop(list, &temp)); + + if (!list->empty(list)) + { + TEST_ASSERT_TRUE(list->peek(list, &temp)); + TEST_ASSERT_EQUAL_INT(data[list->size(list) - 1], temp); + } + } + TEST_ASSERT_TRUE(list->empty(list)); + TEST_ASSERT_FALSE(list->pop(list, &temp)); + + list_free(&list); + TEST_ASSERT_NULL(list); +} + +static void test_list_struct(void) +{ + uint32_t i = 0; + struct _student data[] = { + {"zhao", 1001}, {"qian", 1002}, {"sun", 1003}, {"li", 1004}, + "zhou", 1005, "wu", 1006, "zheng", 1007, "wang", 1008, + }; + struct _student temp; + uint32_t len = sizeof(data) / sizeof(data[0]) - 1; + + list_t list = list_new(); + TEST_ASSERT_NOT_NULL(list); + + list_init2(list, sizeof(struct _student)); + list->print_obj = print_struct; + + TEST_ASSERT_FALSE(list->peek(list, &temp)); + TEST_ASSERT_TRUE(list->clear(list)); + for (i = 0; i < len; i++) + { + TEST_ASSERT_TRUE(list->push(list, &data[i])); + TEST_ASSERT_EQUAL_INT(i + 1, list->size(list)); + + TEST_ASSERT_TRUE(list->peek(list, &temp)); + TEST_ASSERT_EQUAL_INT(data[i].id, temp.id); + TEST_ASSERT_EQUAL_STRING(data[i].name, temp.name); + } + + TEST_ASSERT_FALSE(list->empty(list)); + TEST_ASSERT_TRUE(list->clear(list)); + TEST_ASSERT_TRUE(list->empty(list)); + for (i = 0; i < len; i++) + { + TEST_ASSERT_TRUE(list->push(list, &data[i])); + } + + for(i = 0; i < len; i++) + { + TEST_ASSERT_TRUE(list->peek(list, &temp)); + TEST_ASSERT_EQUAL_INT(data[list->size(list) - 1].id, temp.id); + TEST_ASSERT_EQUAL_STRING(data[list->size(list) - 1].name, temp.name); + + TEST_ASSERT_TRUE(list->pop(list, &temp)); + + if (!list->empty(list)) + { + TEST_ASSERT_TRUE(list->peek(list, &temp)); + TEST_ASSERT_EQUAL_INT(data[list->size(list) - 1].id, temp.id); + TEST_ASSERT_EQUAL_STRING(data[list->size(list) - 1].name, temp.name); + } + } + TEST_ASSERT_TRUE(list->empty(list)); + TEST_ASSERT_FALSE(list->pop(list, &temp)); + list_free(&list); + TEST_ASSERT_NULL(list); +} + + +static void test_list2_num(void) +{ + uint32_t i = 0; + int data[] = { 1,2,3,4,5,6,7,8,9,10 }; + int temp = 0; + uint32_t len = sizeof(data) / sizeof(data[0]); + uint32_t capacity = len; + + list_t list = NULL; + list = list_new(); + TEST_ASSERT_NOT_NULL(list); + + TEST_ASSERT_TRUE(list_init2(list, sizeof(int), capacity)); + list->print_obj = print_num; + + TEST_ASSERT_FALSE(list->peek(list, &temp)); + TEST_ASSERT_TRUE(list->clear(list)); + for (i = 0; i < len; i++) + { + TEST_ASSERT_TRUE(list->push(list, &data[i])); + TEST_ASSERT_EQUAL_INT(i + 1, list->size(list)); + + TEST_ASSERT_TRUE(list->peek(list, &temp)); + TEST_ASSERT_EQUAL_INT(data[i], temp); + } + + TEST_ASSERT_FALSE(list->empty(list)); + TEST_ASSERT_TRUE(list->clear(list)); + TEST_ASSERT_TRUE(list->empty(list)); + for (i = 0; i < len; i++) + { + TEST_ASSERT_TRUE(list->push(list, &data[i])); + } + + for (i = 0; i < len; i++) + { + TEST_ASSERT_TRUE(list->peek(list, &temp)); + TEST_ASSERT_EQUAL_INT(data[list->size(list) - 1], temp); + + TEST_ASSERT_TRUE(list->pop(list, &temp)); + + if (!list->empty(list)) + { + TEST_ASSERT_TRUE(list->peek(list, &temp)); + TEST_ASSERT_EQUAL_INT(data[list->size(list) - 1], temp); + } + } + TEST_ASSERT_TRUE(list->empty(list)); + TEST_ASSERT_FALSE(list->pop(list, &temp)); + + list_free(&list); + TEST_ASSERT_NULL(list); +} + +static void test_list2_struct(void) +{ + uint32_t i = 0; + struct _student data[] = { + {"zhao", 1001}, {"qian", 1002}, {"sun", 1003}, {"li", 1004}, + "zhou", 1005, "wu", 1006, "zheng", 1007, "wang", 1008, + }; + struct _student temp; + uint32_t len = sizeof(data) / sizeof(data[0]) - 1; + uint32_t capacity = len - 2; + + list_t list = NULL; + list = list_new(); + TEST_ASSERT_NOT_NULL(list); + + TEST_ASSERT_TRUE(list_init2(list, sizeof(struct _student), capacity)); + list->print_obj = print_struct; + + TEST_ASSERT_FALSE(list->peek(list, &temp)); + TEST_ASSERT_TRUE(list->empty(list)); + for (i = 0; i < len; i++) + { + TEST_ASSERT_TRUE(list->push(list, &data[i])); + TEST_ASSERT_EQUAL_INT(i + 1, list->size(list)); + + TEST_ASSERT_TRUE(list->peek(list, &temp)); + TEST_ASSERT_EQUAL_INT(data[list->size(list) - 1].id, temp.id); + TEST_ASSERT_EQUAL_STRING(data[list->size(list) - 1].name, temp.name); + } + + TEST_ASSERT_FALSE(list->empty(list)); + TEST_ASSERT_TRUE(list->clear(list)); + TEST_ASSERT_TRUE(list->empty(list)); + for (i = 0; i < len; i++) + { + TEST_ASSERT_TRUE(list->push(list, &data[i])); + TEST_ASSERT_EQUAL_INT(i + 1, list->size(list)); + } + + for(i = 0; i < len; i++) + { + if (!list->empty(list)) + { + TEST_ASSERT_TRUE(list->pop(list, &temp)); + } + else + { + TEST_ASSERT_FALSE(list->pop(list, &temp)); + } + + if (!list->empty(list)) + { + TEST_ASSERT_TRUE(list->peek(list, &temp)); + TEST_ASSERT_EQUAL_INT(data[list->size(list) - 1].id, temp.id); + TEST_ASSERT_EQUAL_STRING(data[list->size(list) - 1].name, temp.name); + } + else + { + TEST_ASSERT_FALSE(list->peek(list, &temp)); + } + } + list_free(&list); + TEST_ASSERT_NULL(list); +} + +#endif + +void test_list(void) +{ + RUN_TEST(test_list_init2); + RUN_TEST(test_list_new); + // RUN_TEST(test_list_push); + // RUN_TEST(test_list_pop); + // RUN_TEST(test_list_clear); + + // RUN_TEST(test_list_num); + // RUN_TEST(test_list_struct); + + // RUN_TEST(test_list2_num); + // RUN_TEST(test_list2_struct); +} diff --git a/test/test_queue.c b/test/test_queue.c index 6182cb4..3d44f88 100644 --- a/test/test_queue.c +++ b/test/test_queue.c @@ -633,7 +633,6 @@ static void test_queue2_struct(void) void test_queue(void) { - // TEST_MESSAGE("----- test_queue -----"); RUN_TEST(test_queue_init); RUN_TEST(test_queue_new); RUN_TEST(test_queue_push); diff --git a/test/test_stack.c b/test/test_stack.c index 056399a..4f09e86 100644 --- a/test/test_stack.c +++ b/test/test_stack.c @@ -383,7 +383,7 @@ static void test_stack2_num(void) stack_t stack = NULL; stack = stack_new(); TEST_ASSERT_NOT_NULL(stack); - + TEST_ASSERT_TRUE(stack_init2(stack, sizeof(int), capacity)); stack->print_obj = print_num; @@ -493,8 +493,6 @@ static void test_stack2_struct(void) void test_stack(void) { - RUN_TEST(test_stack_num); - RUN_TEST(test_stack_init); RUN_TEST(test_stack_new); RUN_TEST(test_stack_push);