#include #include #if defined(TEST_TARGET_csv) #include #include #include #else #include "init.h" #include "command.h" #include "unitt.h" #include "kern.h" #include "csv.h" #endif /************************************************************************************/ /************************************* Unit Test ************************************/ /************************************************************************************/ // #define EXIT_TEST extern uint64_t unitt_clock(void); static int test_0(void) { for (int i = 0; i < 100; i++) { if (0) { #if defined (EXIT_TEST) exit(0); #endif return UNITT_E_FAIL; } } return UNITT_E_OK; } static void unitt_task(void) { static UNITT_TCASE rand_tests[] = { UNITT_TCASE(test_0), // UNITT_TCASE(test_1), // UNITT_TCASE(test_2), }; static UNITT suites[] = { { "xxx suite", rand_tests, sizeof(rand_tests) / sizeof(rand_tests[0]) , unitt_clock }, }; UNITT_EXE(suites); } /************************************************************************************/ /************************************* Base Test ************************************/ /************************************************************************************/ #define READ_FILE "source/application/test/file/read.csv" #define WRITE_FILE "source/application/test/file/write.csv" static void test_create(void) { csv_t csv = NULL; csv = csv_create(3, 5, NULL); if (csv) { printf("csv_create success!!! %p\r\n", csv); } csv_delete(csv); } static void test_cell(void) { csv_t csv = NULL; csv = csv_create(3, 5, NULL); printf("csv_row %d\r\n", csv_row(csv)); printf("csv_col %d\r\n", csv_col(csv)); printf("csv_cell %d\r\n", csv_cell(csv)); csv_delete(csv); } static void test_set(void) { csv_t csv = NULL; unsigned int row = 0, col = 0; const char *array[3][5] = { {"ID", "Name", "Gender", "Age", "Height"}, {"20240107001", "ZhangSan", "Man", "18", "178"}, {"20240107002", "LiSi", "Woman", "24", "162"}, }; csv = csv_create(3, 5, array); row = csv_row(csv); col = csv_col(csv); printf("--- Before set:\r\n"); for (int i = 1; i <= row; i++) { for (int j = 1; j <= col; j++) { printf("%s,", csv_get_text(csv, i, j)); } printf("\r\n"); } csv_set_text(csv, 2, 4, "21"); csv_clean_text(csv, 3, 5); printf("--- After set:\r\n"); for (int i = 1; i <= row; i++) { for (int j = 1; j <= col; j++) { printf("%s,", csv_get_text(csv, i, j)); } printf("\r\n"); } csv_delete(csv); } static void test_for_each(void) { csv_t csv = NULL; unsigned int row = 0, col = 0; char *text = NULL; const char *array[3][5] = { {"ID", "Name", "Gender", "Age", "Height"}, {"20240107001", "ZhangSan", "Man", "18", "178"}, {"20240107002", "LiSi", "Woman", "24", "162"}, }; csv = csv_create(3, 5, array); csv_for_each(csv, row, col, text) { printf("[%u,%u]: %s\r\n", row, col, text); } csv_delete(csv); } static void test_op_ranks(void) { csv_t csv = NULL; unsigned int row = 0, col = 0; char *text = NULL; const char *array[3][5] = { {"ID", "Name", "Gender", "Age", "Height"}, {"20240107001", "ZhangSan", "Man", "18", "178"}, {"20240107002", "LiSi", "Woman", "24", "162"}, }; for (int i = 0; i < 9; i++) { printf("-------------------------------------\r\n"); csv = csv_create(3, 5, array); switch (i) { case 0: { printf("Before OP:\r\n"); } break; case 1: { printf("csv_insert_row:\r\n"); csv_insert_row(csv, 2, NULL, 0); } break; case 2: { printf("csv_insert_col:\r\n"); csv_insert_col(csv, 2, NULL, 0); } break; case 3: { printf("csv_delete_row:\r\n"); csv_delete_row(csv, 2); } break; case 4: { printf("csv_delete_col:\r\n"); csv_delete_col(csv, 2); } break; case 5: { printf("csv_move_row_to:\r\n"); csv_move_row_to(csv, 2, 3); } break; case 6: { printf("csv_move_col_to:\r\n"); csv_move_col_to(csv, 2, 3); } break; case 7: { printf("csv_copy_row_to:\r\n"); csv_copy_row_to(csv, 2, 3); } break; case 8: { printf("csv_copy_col_to:\r\n"); csv_copy_col_to(csv, 2, 3); } break; default: break; } text = csv_dumps(csv, NULL); if (text) { printf("%s\r\n", text); free(text); } else { printf("[ERROR] dumps fail!!!\r\n"); } csv_delete(csv); } } static void test_op_cells(void) { csv_t csv = NULL; unsigned int row = 0, col = 0; char *text = NULL; const char *array[3][5] = { {"11", "12", "13", "14", "15"}, {"21", "22", "23", "24", "25"}, {"31", "32", "33", "34", "35"}, }; for (int i = 0; i < 7; i++) { printf("-------------------------------------\r\n"); csv = csv_create(3, 5, array); switch (i) { case 0: { printf("Before OP:\r\n"); } break; case 1: { printf("csv_insert_cell[move down]:\r\n"); csv_insert_cell(csv, 2, 1, 1); } break; case 2: { printf("csv_insert_cell[move right]:\r\n"); csv_insert_cell(csv, 2, 1, 0); } break; case 3: { printf("csv_delete_cell[move up]:\r\n"); csv_delete_cell(csv, 2, 1, 1); } break; case 4: { printf("csv_delete_cell[move left]:\r\n"); csv_delete_cell(csv, 2, 1, 0); } break; case 5: { printf("csv_copy_cell_to:\r\n"); csv_copy_cell_to(csv, 2, 1, 3, 2); } break; case 6: { printf("csv_cut_cell_to:\r\n"); csv_cut_cell_to(csv, 2, 1, 3, 2); } break; default: break; } text = csv_dumps(csv, NULL); if (text) { printf("%s\r\n", text); free(text); } else { printf("[ERROR] dumps fail!!!\r\n"); } csv_delete(csv); } } static void test_find(void) { csv_t csv; unsigned int row = 0, col = 0; const char *array[3][5] = { {"ID", "Name", "Gender", "Age", "Height"}, {"20240107001", "ZhangSan", "Man", "18", "178"}, {"20240107002", "LiSi", "Woman", "24", "162"}, }; csv = csv_create(3, 5, array); if (!csv) { printf("create csv fail!\r\n"); return; } // while (csv_find(csv, "2", CSV_F_FLAG_MatchForward | CSV_F_FLAG_MatchByCol, &row, &col) == 1) while (csv_find(csv, "2", CSV_F_FLAG_Default, &row, &col) == 1) { printf("[%u, %u]: %s\r\n", row, col, csv_get_text(csv, row, col)); } csv_delete(csv); } static void test_duplicate(void) { csv_t csv; unsigned int row = 0, col = 0; char *text = NULL; const char *array[3][5] = { {"ID", "Name", "Gender", "Age", "Height"}, {"20240107001", "ZhangSan", "Man", "18", "178"}, {"20240107002", "LiSi", "Woman", "24", "162"}, }; csv = csv_create(3, 5, array); if (!csv) { printf("create csv fail!\r\n"); return; } csv_t dup = csv_duplicate(csv); csv_for_each(dup, row, col, text) { printf("[%u,%u]: %s\r\n", row, col, text); } csv_delete(dup); csv_delete(csv); } static void test_minify(void) { csv_t csv; unsigned int row = 0, col = 0; char *text = NULL; const char *array[3][5] = { {"ID", "Name", "Gender", "Age", "Height"}, {"20240107001", "ZhangSan", "Man", "18", "178"}, {"20240107002", "LiSi", "Woman", "24", "162"}, }; csv = csv_create(3, 5, array); if (!csv) { printf("create csv fail!\r\n"); return; } csv_clean_text(csv, 2, 2); csv_clean_text(csv, 2, 3); csv_clean_text(csv, 2, 4); csv_clean_text(csv, 2, 5); csv_minify(csv); text = csv_dumps(csv, NULL); if (text) { printf("%s\r\n", text); free(text); } else { printf("[ERROR] dumps fail!!!\r\n"); } csv_delete(csv); } static void test_to_array(void) { csv_t csv; unsigned int row = 0, col = 0; char *text = NULL; const char *array[3][5] = { {"ID", "Name", "Gender", "Age", "Height"}, {"20240107001", "ZhangSan", "Man", "18", "178"}, {"20240107002", "LiSi", "Woman", "24", "162"}, }; csv = csv_create(3, 5, array); if (!csv) { printf("create csv fail!\r\n"); return; } char *out[2][3]; csv_to_array(csv, 2, 2, out, 2, 3); printf("out: %s\r\n", out[1][2]); csv_delete(csv); } static void test_dump(void) { csv_t csv; const char *array[3][5] = { {"ID", "Name", "Gender", "Age", "Height"}, {"20240107001", "ZhangSan", "Man", "18", "178"}, {"20240107002", "LiSi", "Woman", "24", "162"}, }; char *out[2][3]; csv = csv_create(3, 5, array); if (!csv) { printf("create csv fail!\r\n"); return; } printf("File length %d.\r\n", csv_file_dump(csv, WRITE_FILE)); csv_delete(csv); } static void test_load(void) { csv_t csv; unsigned int row, col; int i, j; const char *text; int error; int line; int ecol; csv = csv_file_load(READ_FILE); if (!csv) { error = csv_error_info(&line, &ecol); printf("Load csv file fail! Error line %d column %d code %d.\r\n", line, ecol, error); return; } row = csv_row(csv); col = csv_col(csv); text = csv_get_text(csv, 1, 3); printf("len %d, %s\r\n", strlen(text), text); printf("row %d, col %d\r\n", row, col); for (i = 1; i <= row; i++) { for (j = 1; j <= col; j++) { text = csv_get_text(csv, i, j); if (text) { if (j != 1) printf(","); printf("%s", text); } } printf("\r\n"); } csv_delete(csv); } static void dump_demo(void) { csv_t csv; const char *array[3][5] = { {"ID", "Name", "Gender", "Age", "Height"}, {"20240107001", "ZhangSan", "Man", "18", "178"}, {"20240107002", "LiSi", "Woman", "24", "162"}, }; csv = csv_create(3, 5, array); if (!csv) { printf("create csv fail!\r\n"); return; } if (csv_file_dump(csv, "info.csv") < 0) { printf("csv dump fail!\r\n"); } else { printf("csv dump success!\r\n"); } csv_delete(csv); } static void load_demo(void) { csv_t csv; csv = csv_file_load("info.csv"); if (!csv) { printf("csv load fail!\r\n"); return; } unsigned int row, col; const char *text = NULL; csv_for_each(csv, row, col, text) { printf("[%u, %u]: %s\r\n", row, col, text); } csv_delete(csv); } static void test_base(void) { dump_demo(); load_demo(); } /************************************************************************************/ /************************************* Command ************************************/ /************************************************************************************/ static void usage(void) { printf( "Usage: csv [opt] [arg] ...\n" "\n" "options:\n" " -e Specifies the function to execute, the default is the test\n" " Test base function\n" " Unit test\n" " Test create and delete functions\n" " Test cell information functions\n" " Test set, get and clean functions\n" " Test `for each` method\n" " Test operate rows and cols functions\n" " Test operate cells functions\n" " Test find function\n" " Test duplicate function\n" " Test minify function\n" " Test to array function\n" " Test dump functions\n" " Test load functions\n" " -h Print help\n" " -v Print version\n" " -u [] Unit test period, unit ms, the default is 1000ms\n" "\n" ); } static int test(int argc, char *argv[]) { char *execute = NULL; int ut_period = 1000; /* reset getopt */ command_opt_init(); while (1) { int opt = command_getopt(argc, argv, "e:hvu::"); if (opt == -1) break; switch (opt) { case 'u' : if (command_optarg) ut_period = atoi(command_optarg); break; case 'e' : execute = command_optarg; break; case 'v' : printf("csv version %d.%d.%d\r\n", CSV_V_MAJOR, CSV_V_MINOR, CSV_V_PATCH); return 0; case '?': printf("Unknown option `%c`\r\n", command_optopt); return -1; case 'h' : default: usage(); return 0; } } if (execute) { if (!strcmp(execute, "base")) { test_base(); } else if (!strcmp(execute, "ut")) { #if defined(TEST_TARGET_csv) while (1) { unitt_task(); usleep(1000 * ut_period); } #else printf("create task %d\r\n", task_create(ut_period, unitt_task)); #endif } else if (!strcmp(execute, "create")) { test_create(); } else if (!strcmp(execute, "cell")) { test_cell(); } else if (!strcmp(execute, "set")) { test_set(); } else if (!strcmp(execute, "each")) { test_for_each(); } else if (!strcmp(execute, "opranks")) { test_op_ranks(); } else if (!strcmp(execute, "opcells")) { test_op_cells(); } else if (!strcmp(execute, "find")) { test_find(); } else if (!strcmp(execute, "dup")) { test_duplicate(); } else if (!strcmp(execute, "minify")) { test_minify(); } else if (!strcmp(execute, "array")) { test_to_array(); } else if (!strcmp(execute, "dump")) { test_dump(); } else if (!strcmp(execute, "load")) { test_load(); } } else { test_base(); } return 0; } /************************************************************************************/ /************************************ Test entry ************************************/ /************************************************************************************/ #if defined(TEST_TARGET_csv) int main(int argc, char *argv[]) { return test(argc, argv); } #else void test_csv(void) { command_export("csv", test); } init_export_app(test_csv); #endif