From cb7fc88118cefd6756e1ae7aab83891d887cfb4c Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Mon, 22 Jan 2024 21:42:07 -0600 Subject: [PATCH] Progress: Add "works" unit test for basic object read and basic content read. My goal is to get to writing the payload tests but getting these other unit tests figured out first will make that process easier. These "works" unit tests are intended to be very simple at this time. There are no checks for comments. The NULL data is not checked, partially due to the use of getline() and string comparison. --- level_1/fl_fss/data/build/settings-tests | 2 +- .../fl_fss/data/tests/contents/basic-all_read.txt | 39 ++++++ .../fl_fss/data/tests/objects/basic-all_read.txt | 39 ++++++ .../fl_fss/data/tests/strings/basic-all_read.txt | 39 ++++++ level_1/fl_fss/tests/unit/c/data-fss.c | 21 ++++ level_1/fl_fss/tests/unit/c/data-fss.h | 82 ++++++++++++ .../tests/unit/c/test-fss-basic_content_read.c | 137 +++++++++++++++++++++ .../tests/unit/c/test-fss-basic_content_read.h | 8 ++ .../tests/unit/c/test-fss-basic_object_read.c | 112 +++++++++++++++++ .../tests/unit/c/test-fss-basic_object_read.h | 8 ++ level_1/fl_fss/tests/unit/c/test-fss.c | 3 + level_1/fl_fss/tests/unit/c/test-fss.h | 4 + 12 files changed, 493 insertions(+), 1 deletion(-) create mode 100644 level_1/fl_fss/data/tests/contents/basic-all_read.txt create mode 100644 level_1/fl_fss/data/tests/objects/basic-all_read.txt create mode 100644 level_1/fl_fss/data/tests/strings/basic-all_read.txt create mode 100644 level_1/fl_fss/tests/unit/c/data-fss.c create mode 100644 level_1/fl_fss/tests/unit/c/data-fss.h diff --git a/level_1/fl_fss/data/build/settings-tests b/level_1/fl_fss/data/build/settings-tests index 2e49e56..3e5d6e2 100644 --- a/level_1/fl_fss/data/build/settings-tests +++ b/level_1/fl_fss/data/build/settings-tests @@ -32,7 +32,7 @@ build_sources_program test-fss-extended_content_read.c test-fss-extended_content build_sources_program test-fss-extended_list_content_read.c test-fss-extended_list_content_write.c test-fss-extended_list_object_read.c test-fss-extended_list_object_write.c build_sources_program test-fss-payload_header_map.c -build_sources_program test-fss.c +build_sources_program test-fss.c data-fss.c build_script no build_shared yes diff --git a/level_1/fl_fss/data/tests/contents/basic-all_read.txt b/level_1/fl_fss/data/tests/contents/basic-all_read.txt new file mode 100644 index 0000000..b9f0d78 --- /dev/null +++ b/level_1/fl_fss/data/tests/contents/basic-all_read.txt @@ -0,0 +1,39 @@ +b c d +b c d +b c d +a b c +b c +d +b c d +b c d +" b c d +d +d +c d +b c d + +c d +{ +c d + +b c d +Ȁ b c d +"Ȁ" b c d +" Ȁ " b c d +" Ȁ " b `c d` +b c d +b c d +b c d +c d' e +c d" e +c d` e +c d' e +c d" e +c d` e +b c d e +b c d e ' +b c d +b c +c d +b c d +b c d diff --git a/level_1/fl_fss/data/tests/objects/basic-all_read.txt b/level_1/fl_fss/data/tests/objects/basic-all_read.txt new file mode 100644 index 0000000..1194a09 --- /dev/null +++ b/level_1/fl_fss/data/tests/objects/basic-all_read.txt @@ -0,0 +1,39 @@ +a +a +a +. +.a +a b c +"a +a" +a +a b" c +a b` c +a b +a: +a: +b +a +b +} +Ȁ +Ȃ +Ȃ +Ȃ +Ȃ +Ȁ Ƞ +Ȁ Ƞ +Ȁ Ƞ +'A b +"A b +`A b +A b' +A b" +A b` +a +a +a +a +a +a +a diff --git a/level_1/fl_fss/data/tests/strings/basic-all_read.txt b/level_1/fl_fss/data/tests/strings/basic-all_read.txt new file mode 100644 index 0000000..bf11853 --- /dev/null +++ b/level_1/fl_fss/data/tests/strings/basic-all_read.txt @@ -0,0 +1,39 @@ +a b c d + a b c d + a b c d +. a b c +.a b c +"a b c" d +\"a b c d +a" b c d +a " b c d +'a b" c' d +'a b` c' d +`a b` c d +a: b c d +a: + b c d +a { + b c d +} +Ȁ b c d +Ȃ Ȁ b c d +Ȃ "Ȁ" b c d +Ȃ " Ȁ " b c d +Ȃ " Ȁ " b `c d` +`Ȁ Ƞ` b c d +"Ȁ Ƞ" b c d +'Ȁ Ƞ' b c d +''A b' c d' e +""A b" c d" e +``A b` c d` e +'A b'' c d' e +"A b"" c d" e +`A b`` c d` e +a b c d e +a b c d e ' + a b c d +a b c + a c d +a b c d +a b c d diff --git a/level_1/fl_fss/tests/unit/c/data-fss.c b/level_1/fl_fss/tests/unit/c/data-fss.c new file mode 100644 index 0000000..ca1601d --- /dev/null +++ b/level_1/fl_fss/tests/unit/c/data-fss.c @@ -0,0 +1,21 @@ +#include "data-fss.h" + +#ifdef __cplusplus +extern "C" { +#endif + +FILE *data__contents_file_open__basic_all_read(void) { + return fopen("./data/tests/contents/basic-all_read.txt", "r"); +} + +FILE *data__objects_file_open__basic_all_read(void) { + return fopen("./data/tests/objects/basic-all_read.txt", "r"); +} + +FILE *data__strings_file_open__basic_all_read(void) { + return fopen("./data/tests/strings/basic-all_read.txt", "r"); +} + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_1/fl_fss/tests/unit/c/data-fss.h b/level_1/fl_fss/tests/unit/c/data-fss.h new file mode 100644 index 0000000..6a7446a --- /dev/null +++ b/level_1/fl_fss/tests/unit/c/data-fss.h @@ -0,0 +1,82 @@ +/** + * FLL - Level 1 + * + * Project: FSS + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * Data for the fss project tests. + */ +#ifndef _DATA__FL_fss_h +#define _DATA__FL_fss_h + +// Libc includes. +#include +#include +#include + +// FLL-0 includes. + +// FLL-1 includes. +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Open the "FSS basic" contents file. + * + * This assumes the following: + * - The file path is relative to the current working directory (tests are run from project root). + * - The file path is "data/tests/contents/basic-all_read.txt". + * + * @return + * Non-zero on success. + * 0 on failure. + * + * @see fopen() + */ +extern FILE *data__contents_file_open__basic_all_read(void); + +/** + * Open the "FSS basic" objects file. + * + * This assumes the following: + * - The file path is relative to the current working directory (tests are run from project root). + * - The file path is "data/tests/objects/basic-all_read.txt". + * + * @return + * Non-zero on success. + * 0 on failure. + * + * @see fopen() + */ +extern FILE *data__objects_file_open__basic_all_read(void); + +/** + * Open the "fss basic" strings file. + * + * This assumes the following: + * - The file path is relative to the current working directory (tests are run from project root). + * - The file path is "data/tests/strings/basic-all_read.txt". + * + * @return + * Non-zero on success. + * 0 on failure. + * + * @see fopen() + */ +extern FILE *data__strings_file_open__basic_all_read(void); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _DATA__FL_fss_h diff --git a/level_1/fl_fss/tests/unit/c/test-fss-basic_content_read.c b/level_1/fl_fss/tests/unit/c/test-fss-basic_content_read.c index abcd011..dec2333 100644 --- a/level_1/fl_fss/tests/unit/c/test-fss-basic_content_read.c +++ b/level_1/fl_fss/tests/unit/c/test-fss-basic_content_read.c @@ -85,6 +85,143 @@ void test__fl_fss_basic_content_read__returns_data_not(void **void_state) { } } +void test__fl_fss_basic_content_read__works(void **void_state) { + + { + // Note: These files are required to have the same number of lines and each line should probably be at max 255 characters. + FILE *file_strings = data__strings_file_open__basic_all_read(); + FILE *file_contents = data__contents_file_open__basic_all_read(); + + assert_non_null(file_strings); + assert_non_null(file_contents); + + size_t max = 0; + char *line_string = 0; + char *line_content = 0; + ssize_t result = 0; + + f_string_static_t buffer_string = f_string_static_t_initialize; + f_string_static_t buffer_content = f_string_static_t_initialize; + + f_state_t state = f_state_t_initialize; + f_range_t range = f_range_t_initialize; + f_range_t found_object = f_range_t_initialize; + f_ranges_t found = f_ranges_t_initialize; + uint8_t quote = 0; + f_number_unsigneds_t delimits = f_number_unsigneds_t_initialize; + f_string_dynamic_t result_string = f_string_dynamic_t_initialize; + f_string_dynamic_t delimit_string = f_string_dynamic_t_initialize; + f_status_t status_object = F_okay; + + for (;;) { + + max = 255; + + result = getline(&line_string, &max, file_strings); + if (result == -1) break; + + buffer_string.string = line_string; + buffer_string.used = (f_number_unsigned_t) result; + buffer_string.size = buffer_string.used; + + max = 255; + + result = getline(&line_content, &max, file_contents); + assert_return_code(result, 0); + + buffer_content.string = line_content; + buffer_content.used = (f_number_unsigned_t) result; + buffer_content.size = buffer_content.used; + + // The newline is copied by getline(), and so remove that newline before comparing. + buffer_content.string[--buffer_content.used] = 0; + + state.status = F_none; + range.start = 0; + range.stop = buffer_string.used - 1; + found_object.start = 1; + found_object.stop = 0; + + fl_fss_basic_object_read(buffer_string, &range, &found_object, "e, &delimits, &state); + + assert_true(state.status == F_fss_found_object || state.status == F_fss_found_object_content_not); + + status_object = state.status; + state.status = F_none; + + fl_fss_basic_content_read(buffer_string, &range, &found, &delimits, &state); + + if (status_object == F_fss_found_object) { + assert_int_equal(state.status, F_fss_found_content); + } + else { + assert_int_equal(state.status, F_data_not); + } + + if (state.status == F_fss_found_content) { + assert_true(found.used); + + { + const f_status_t status = f_string_dynamic_append(buffer_string, &delimit_string); + assert_int_equal(status, F_okay); + } + + state.status = F_none; + + f_fss_apply_delimit(delimits, &delimit_string, &state); + assert_int_equal(state.status, F_okay); + + { + const f_status_t status = f_string_dynamic_partial_append_nulless(delimit_string, found.array[0], &result_string); + assert_true(status == F_okay || status == F_data_not_eos); + } + + { + const f_status_t status = f_string_dynamic_terminate_after(&result_string); + assert_int_equal(status, F_okay); + } + + assert_string_equal(result_string.string, line_content); + } + else { + assert_true(!found.used); + } + + if (line_string) free(line_string); + if (line_content) free(line_content); + if (result_string.string) free(result_string.string); + if (delimit_string.string) free(delimit_string.string); + if (delimits.array) free(delimits.array); + if (found.array) free(found.array); + + line_string = 0; + line_content = 0; + result_string.string = 0; + result_string.used = 0; + result_string.size = 0; + delimit_string.string = 0; + delimit_string.used = 0; + delimit_string.size = 0; + delimits.array = 0; + delimits.used = 0; + delimits.size = 0; + found.array = 0; + found.used = 0; + found.size = 0; + } // for + + if (file_strings) fclose(file_strings); + if (file_contents) fclose(file_contents); + + if (delimits.array) free(delimits.array); + if (found.array) free(found.array); + if (line_string) free(line_string); + if (line_content) free(line_content); + if (result_string.string) free(result_string.string); + if (delimit_string.string) free(delimit_string.string); + } +} + #ifdef __cplusplus } // extern "C" #endif diff --git a/level_1/fl_fss/tests/unit/c/test-fss-basic_content_read.h b/level_1/fl_fss/tests/unit/c/test-fss-basic_content_read.h index ccc1bde..be4c584 100644 --- a/level_1/fl_fss/tests/unit/c/test-fss-basic_content_read.h +++ b/level_1/fl_fss/tests/unit/c/test-fss-basic_content_read.h @@ -24,4 +24,12 @@ extern void test__fl_fss_basic_content_read__parameter_checking(void **state); */ extern void test__fl_fss_basic_content_read__returns_data_not(void **state); + +/** + * Test that the function works. + * + * @see fl_fss_basic_content_read() + */ +extern void test__fl_fss_basic_content_read__works(void **state); + #endif // _TEST__FL_fss_basic_content_read_h diff --git a/level_1/fl_fss/tests/unit/c/test-fss-basic_object_read.c b/level_1/fl_fss/tests/unit/c/test-fss-basic_object_read.c index 704270b..f0f1fb1 100644 --- a/level_1/fl_fss/tests/unit/c/test-fss-basic_object_read.c +++ b/level_1/fl_fss/tests/unit/c/test-fss-basic_object_read.c @@ -135,6 +135,118 @@ void test__fl_fss_basic_object_read__returns_data_not(void **void_state) { } } +void test__fl_fss_basic_object_read__works(void **void_state) { + + { + // Note: These files are required to have the same number of lines and each line should probably be at max 255 characters. + FILE *file_strings = data__strings_file_open__basic_all_read(); + FILE *file_objects = data__objects_file_open__basic_all_read(); + + assert_non_null(file_strings); + assert_non_null(file_objects); + + size_t max = 0; + char *line_string = 0; + char *line_object = 0; + ssize_t result = 0; + + f_string_static_t buffer_string = f_string_static_t_initialize; + f_string_static_t buffer_object = f_string_static_t_initialize; + + f_state_t state = f_state_t_initialize; + f_range_t range = f_range_t_initialize; + f_range_t found = f_range_t_initialize; + uint8_t quote = 0; + f_number_unsigneds_t delimits = f_number_unsigneds_t_initialize; + f_string_dynamic_t result_string = f_string_dynamic_t_initialize; + f_string_dynamic_t delimit_string = f_string_dynamic_t_initialize; + + for (;;) { + + max = 255; + + result = getline(&line_string, &max, file_strings); + if (result == -1) break; + + buffer_string.string = line_string; + buffer_string.used = (f_number_unsigned_t) result; + buffer_string.size = buffer_string.used; + + max = 255; + + result = getline(&line_object, &max, file_objects); + assert_return_code(result, 0); + + buffer_object.string = line_object; + buffer_object.used = (f_number_unsigned_t) result; + buffer_object.size = buffer_object.used; + + // The newline is copied by getline(), and so remove that newline before comparing. + buffer_object.string[--buffer_object.used] = 0; + + state.status = F_none; + range.start = 0; + range.stop = buffer_string.used - 1; + found.start = 1; + found.stop = 0; + + fl_fss_basic_object_read(buffer_string, &range, &found, "e, &delimits, &state); + + assert_true(state.status == F_fss_found_object || state.status == F_fss_found_object_content_not); + assert_true(found.start <= found.stop); + + { + const f_status_t status = f_string_dynamic_append(buffer_string, &delimit_string); + assert_int_equal(status, F_okay); + } + + state.status = F_none; + + f_fss_apply_delimit(delimits, &delimit_string, &state); + assert_int_equal(state.status, F_okay); + + { + const f_status_t status = f_string_dynamic_partial_append_nulless(delimit_string, found, &result_string); + assert_true(status == F_okay || status == F_data_not_eos); + } + + { + const f_status_t status = f_string_dynamic_terminate_after(&result_string); + assert_int_equal(status, F_okay); + } + + assert_string_equal(result_string.string, line_object); + + if (line_string) free(line_string); + if (line_object) free(line_object); + if (result_string.string) free(result_string.string); + if (delimit_string.string) free(delimit_string.string); + if (delimits.array) free(delimits.array); + + line_string = 0; + line_object = 0; + result_string.string = 0; + result_string.used = 0; + result_string.size = 0; + delimit_string.string = 0; + delimit_string.used = 0; + delimit_string.size = 0; + delimits.array = 0; + delimits.used = 0; + delimits.size = 0; + } // for + + if (file_strings) fclose(file_strings); + if (file_objects) fclose(file_objects); + + if (delimits.array) free(delimits.array); + if (line_string) free(line_string); + if (line_object) free(line_object); + if (result_string.string) free(result_string.string); + if (delimit_string.string) free(delimit_string.string); + } +} + #ifdef __cplusplus } // extern "C" #endif diff --git a/level_1/fl_fss/tests/unit/c/test-fss-basic_object_read.h b/level_1/fl_fss/tests/unit/c/test-fss-basic_object_read.h index 59800a5..feeaee0 100644 --- a/level_1/fl_fss/tests/unit/c/test-fss-basic_object_read.h +++ b/level_1/fl_fss/tests/unit/c/test-fss-basic_object_read.h @@ -24,4 +24,12 @@ extern void test__fl_fss_basic_object_read__parameter_checking(void **state); */ extern void test__fl_fss_basic_object_read__returns_data_not(void **state); + +/** + * Test that the function works. + * + * @see fl_fss_basic_object_read() + */ +extern void test__fl_fss_basic_object_read__works(void **state); + #endif // _TEST__FL_fss_basic_object_read_h diff --git a/level_1/fl_fss/tests/unit/c/test-fss.c b/level_1/fl_fss/tests/unit/c/test-fss.c index 70e132b..505c554 100644 --- a/level_1/fl_fss/tests/unit/c/test-fss.c +++ b/level_1/fl_fss/tests/unit/c/test-fss.c @@ -24,6 +24,9 @@ int main(void) { cmocka_unit_test(test__fl_fss_basic_object_read__returns_data_not), cmocka_unit_test(test__fl_fss_basic_object_write__returns_data_not), + cmocka_unit_test(test__fl_fss_basic_content_read__works), + cmocka_unit_test(test__fl_fss_basic_object_read__works), + cmocka_unit_test(test__fl_fss_basic_list_content_read__returns_data_not), cmocka_unit_test(test__fl_fss_basic_list_content_write__returns_data_not), cmocka_unit_test(test__fl_fss_basic_list_object_read__returns_data_not), diff --git a/level_1/fl_fss/tests/unit/c/test-fss.h b/level_1/fl_fss/tests/unit/c/test-fss.h index c1342d7..17c1941 100644 --- a/level_1/fl_fss/tests/unit/c/test-fss.h +++ b/level_1/fl_fss/tests/unit/c/test-fss.h @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -33,6 +34,9 @@ // Mock includes. //#include "mock-fss.h" +// Data includes. +#include "data-fss.h" + // Test includes. #include "test-fss-basic_content_read.h" #include "test-fss-basic_content_write.h" -- 1.8.3.1