From eeb92b56ce69e0fc0a62ff03ee174f1d0865ae6a Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Sat, 31 Oct 2026 19:29:27 -0500 Subject: [PATCH] Update: Add unit tests for f_fss_count_slash(). Also fix problem where if `range.start` is greater than `buffer.used` then the it should return `F_data_not`. This adds to the feature commit 622ab506f56468c9699d2ae546434bdb07a4749c. --- level_0/f_fss/c/fss.c | 2 +- level_0/f_fss/c/fss.h | 2 + level_0/f_fss/data/build/settings-tests | 2 +- .../f_fss/tests/unit/c/test-fss-count_slash.c | 195 ++++++++++++++++++ .../f_fss/tests/unit/c/test-fss-count_slash.h | 34 +++ level_0/f_fss/tests/unit/c/test-fss.c | 3 + level_0/f_fss/tests/unit/c/test-fss.h | 1 + 7 files changed, 237 insertions(+), 2 deletions(-) create mode 100644 level_0/f_fss/tests/unit/c/test-fss-count_slash.c create mode 100644 level_0/f_fss/tests/unit/c/test-fss-count_slash.h diff --git a/level_0/f_fss/c/fss.c b/level_0/f_fss/c/fss.c index 9c208a54b..81d12beaa 100644 --- a/level_0/f_fss/c/fss.c +++ b/level_0/f_fss/c/fss.c @@ -153,7 +153,7 @@ extern "C" { } #endif // _di_level_0_parameter_checking_ - if (!buffer.used) { + if (!buffer.used || range->start > buffer.used) { state->status = F_data_not; return; diff --git a/level_0/f_fss/c/fss.h b/level_0/f_fss/c/fss.h index 79ee2963f..011ef85e6 100644 --- a/level_0/f_fss/c/fss.h +++ b/level_0/f_fss/c/fss.h @@ -173,6 +173,8 @@ extern "C" { * * This does not initialize count, instead it only performs addition to line. * + * This skips past (ignores) NULL (f_fss_placeholder_s). + * * @param buffer * The string to process. * @param range diff --git a/level_0/f_fss/data/build/settings-tests b/level_0/f_fss/data/build/settings-tests index fb9145026..5fd828c9b 100644 --- a/level_0/f_fss/data/build/settings-tests +++ b/level_0/f_fss/data/build/settings-tests @@ -25,7 +25,7 @@ build_language c build_libraries -lc -lcmocka build_libraries-individual -lf_memory -lf_string -lf_type_array -lf_utf -lf_fss -build_sources_program test-fss-apply_delimit.c test-fss-apply_delimit_range.c test-fss-count_lines.c test-fss-count_lines_range.c test-fss-fail_utf.c test-fss-fail_utf_to_false.c test-fss-is_combining.c test-fss-is_graph.c test-fss-is_space.c test-fss-is_zero_width.c test-fss-seek_to_eol.c test-fss-skip_past_combining_joiner.c test-fss-skip_past_delimit.c test-fss-skip_past_space.c test-fss-skip_past_space_previous.c +build_sources_program test-fss-apply_delimit.c test-fss-apply_delimit_range.c test-fss-count_lines.c test-fss-count_lines_range.c test-fss-count_slash.c test-fss-fail_utf.c test-fss-fail_utf_to_false.c test-fss-is_combining.c test-fss-is_graph.c test-fss-is_space.c test-fss-is_zero_width.c test-fss-seek_to_eol.c test-fss-skip_past_combining_joiner.c test-fss-skip_past_delimit.c test-fss-skip_past_space.c test-fss-skip_past_space_previous.c build_sources_program test-fss-item_delete.c test-fss-item_destroy.c build_sources_program test-fss-items_delete_callback.c test-fss-items_destroy_callback.c test-fss-itemss_delete_callback.c test-fss-itemss_destroy_callback.c build_sources_program test-fss-named_delete.c test-fss-named_destroy.c diff --git a/level_0/f_fss/tests/unit/c/test-fss-count_slash.c b/level_0/f_fss/tests/unit/c/test-fss-count_slash.c new file mode 100644 index 000000000..c69105cdc --- /dev/null +++ b/level_0/f_fss/tests/unit/c/test-fss-count_slash.c @@ -0,0 +1,195 @@ +#include "test-fss.h" +#include "test-fss-count_slash.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void test__f_fss_count_slash__parameter_checking(void **state) { + + const f_string_static_t test = macro_f_string_static_t_initialize_1("test", 4, 0); + + f_number_unsigned_t count = 0; + f_range_t range = f_range_t_initialize; + f_state_t state_data = f_state_t_initialize; + + { + f_fss_count_slash(test, 0, 0, &state_data); + + assert_int_equal(state_data.status, F_status_set_error(F_parameter)); + } + + { + f_fss_count_slash(test, &range, 0, &state_data); + + assert_int_equal(state_data.status, F_status_set_error(F_parameter)); + } + + { + f_fss_count_slash(test, 0, &count, &state_data); + + assert_int_equal(state_data.status, F_status_set_error(F_parameter)); + } +} + +void test__f_fss_count_slash__returns_data_not(void **state) { + + f_state_t state_data = f_state_t_initialize; + f_number_unsigned_t count = 0; + f_range_t range = f_range_t_initialize; + + { + f_fss_count_slash(f_string_empty_s, &range, &count, &state_data); + + assert_int_equal(state_data.status, F_data_not); + } +} + +void test__f_fss_count_slash__works(void **state) { + + const f_string_static_t buffers[] = { + macro_f_string_static_t_initialize_3("F_data_not", 0), + macro_f_string_static_t_initialize_3("none", 4), + macro_f_string_static_t_initialize_3("\\1", 2), + macro_f_string_static_t_initialize_3("\\\\two", 5), + macro_f_string_static_t_initialize_3("\\\\\\three", 8), + macro_f_string_static_t_initialize_3("\\⸙\n", 5), + macro_f_string_static_t_initialize_3("\\\\全全", 8), + macro_f_string_static_t_initialize_3("after\\", 6), + macro_f_string_static_t_initialize_3("e\\lse", 5), + macro_f_string_static_t_initialize_3("\\\0null", 6), + macro_f_string_static_t_initialize_3("\0\\null", 6), + macro_f_string_static_t_initialize_3("\\\0\\null", 7), + macro_f_string_static_t_initialize_3("\\\0\0\\null", 8), + macro_f_string_static_t_initialize_3("\\\\", 2), + macro_f_string_static_t_initialize_3("\\\\", 2), + macro_f_string_static_t_initialize_3("F_data_not", 10), + macro_f_string_static_t_initialize_3("\\́", 4), // Slash followed by U+0301. + macro_f_string_static_t_initialize_3("\\⁠J", 5), // Slash followed by U+2060 then "J". + macro_f_string_static_t_initialize_3("\\\\́", 5), // Two slashes followed by U+0301. + macro_f_string_static_t_initialize_3("\\\\⁠J", 6), // Two slashes followed by U+2060 then "J". + }; + + const f_number_unsigned_t counts[] = { + 0, // "F_data_not" + 0, // "none" + 1, // "\\1" + 2, // "\\\\two" + 3, // "\\\\\\three" + 1, // "\\⸙\n" + 2, // "\\\\全全" + 0, // "after\\" + 0, // "e\\lse" + 1, // "\\\0null" + 1, // "\0\\null" + 2, // "\\\0\\null" + 2, // "\\\0\0\\null" + 2, // "\\\\" + 1, // "\\\\" + 0, // "F_data_not" + 0, // "\\́" + 0, // "\\⁠J" + 1, // "\\\\́" + 1, // "\\\\⁠J" + }; + + const f_range_t ranges[] = { + macro_f_range_t_initialize_1(0, buffers[0].used), // "F_data_not" + macro_f_range_t_initialize_1(0, buffers[1].used), // "none" + macro_f_range_t_initialize_1(0, buffers[2].used), // "\\1" + macro_f_range_t_initialize_1(0, buffers[3].used), // "\\\\two" + macro_f_range_t_initialize_1(0, buffers[4].used), // "\\\\\\three" + macro_f_range_t_initialize_1(0, buffers[5].used), // "\\⸙\n" + macro_f_range_t_initialize_1(0, buffers[6].used), // "\\\\全全" + macro_f_range_t_initialize_1(0, buffers[7].used), // "after\\" + macro_f_range_t_initialize_1(0, buffers[8].used), // "e\\lse" + macro_f_range_t_initialize_1(0, buffers[9].used), // "\\\0null" + macro_f_range_t_initialize_1(0, buffers[10].used), // "\0\\null" + macro_f_range_t_initialize_1(0, buffers[11].used), // "\\\0\\null" + macro_f_range_t_initialize_1(0, buffers[12].used), // "\\\0\0\\null" + macro_f_range_t_initialize_1(0, buffers[13].used), // "\\" + macro_f_range_t_initialize_1(0, 0), // "\\" + macro_f_range_t_initialize_1(buffers[15].used + 1, 0), // "F_data_not" + macro_f_range_t_initialize_1(0, buffers[16].used), // "\\́" + macro_f_range_t_initialize_1(0, buffers[17].used), // "\\⁠J" + macro_f_range_t_initialize_1(0, buffers[18].used), // "\\\\́" + macro_f_range_t_initialize_1(0, buffers[19].used), // "\\\\⁠J" + }; + + const f_status_t statuss[] = { + F_data_not, // "F_data_not" + F_okay, // "none" + F_okay, // "\\1" + F_okay, // "\\\\two" + F_okay, // "\\\\\\three" + F_okay, // "\\⸙\n" + F_okay, // "\\\\全全" + F_okay, // "after\\" + F_okay, // "e\\lse" + F_okay, // "\\\0null" + F_okay, // "\0\\null" + F_okay, // "\\\0\\null" + F_okay, // "\\\0\0\\null" + F_okay_eos, // "\\" + F_okay_stop, // "\\" + F_data_not, // "F_data_not" + F_combarudoo, // "\\́" + F_bound, // "\\⁠J" + F_combarudoo, // "\\\\́" + F_bound, // "\\\\⁠J" + }; + + const f_number_unsigned_t starts[] = { + 0, // "F_data_not" + 0, // "none" + 1, // "\\1" + 2, // "\\\\two" + 3, // "\\\\\\three" + 1, // "\\⸙\n" + 2, // "\\\\全全" + 0, // "after\\" + 0, // "e\\lse" + 2, // "\\\0null" + 2, // "\0\\null" + 3, // "\\\0\\null" + 4, // "\\\0\0\\null" + 2, // "\\" + 1, // "\\" + buffers[15].used + 1, // "F_data_not" + 4, // "\\́" + 4, // "\\⁠J" + 5, // "\\\\́" + 5, // "\\\\⁠J" + }; + + for (uint8_t i = 0; i < 20; ++i) { + + f_state_t state_data = f_state_t_initialize; + f_range_t range = ranges[i]; + f_number_unsigned_t count = 0; + + f_fss_count_slash(buffers[i], &range, &count, &state_data); + + if (state_data.status != statuss[i]) { + printf("[ -------> ] --- [01] Failure with f_fss_count_slash(), with line %u '%s', status = %u, expecting %u.\n", i, buffers[i].string, state_data.status, statuss[i]); + } + + assert_int_equal(state_data.status, statuss[i]); + + if (count != counts[i]) { + printf("[ -------> ] --- [02] Failure with f_fss_count_slash(), with line %u '%s', count = %lu, expecting %lu.\n", i, buffers[i].string, count, counts[i]); + } + + assert_int_equal(count, counts[i]); + + if (range.start != starts[i]) { + printf("[ -------> ] --- [03] Failure with f_fss_count_slash(), with line %u '%s', range.start = %lu, expecting %lu.\n", i, buffers[i].string, range.start, starts[i]); + } + + assert_int_equal(range.start, starts[i]); + } // for +} + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_fss/tests/unit/c/test-fss-count_slash.h b/level_0/f_fss/tests/unit/c/test-fss-count_slash.h new file mode 100644 index 000000000..7a6891db0 --- /dev/null +++ b/level_0/f_fss/tests/unit/c/test-fss-count_slash.h @@ -0,0 +1,34 @@ +/** + * FLL - Level 0 + * + * Project: FSS + * API Version: 0.8 + * Licenses: clarified_1_0_or_later-lgpl_2_1_or_later + * + * Test count lines in the fss project. + */ +#ifndef _TEST__F_fss__count_slash +#define _TEST__F_fss__count_slash + +/** + * Test that the function correctly fails on invalid parameter. + * + * @see f_fss_count_slash() + */ +extern void test__f_fss_count_slash__parameter_checking(void **state); + +/** + * Test that the function returns F_data_not. + * + * @see f_fss_count_slash() + */ +extern void test__f_fss_count_slash__returns_data_not(void **state); + +/** + * Test that the function works. + * + * @see f_fss_count_slash() + */ +extern void test__f_fss_count_slash__works(void **state); + +#endif // _TEST__F_fss__count_slash diff --git a/level_0/f_fss/tests/unit/c/test-fss.c b/level_0/f_fss/tests/unit/c/test-fss.c index 823e15ab2..baf089c42 100644 --- a/level_0/f_fss/tests/unit/c/test-fss.c +++ b/level_0/f_fss/tests/unit/c/test-fss.c @@ -23,6 +23,7 @@ int main(void) { cmocka_unit_test(test__f_fss_apply_delimit_range__returns_data_not), cmocka_unit_test(test__f_fss_count_lines__returns_data_not), cmocka_unit_test(test__f_fss_count_lines_range__returns_data_not), + cmocka_unit_test(test__f_fss_count_slash__returns_data_not), cmocka_unit_test(test__f_fss_seek_to_eol__returns_data_not), cmocka_unit_test(test__f_fss_skip_past_combining_joiner__returns_data_not), cmocka_unit_test(test__f_fss_skip_past_delimit__returns_data_not), @@ -33,6 +34,7 @@ int main(void) { cmocka_unit_test(test__f_fss_apply_delimit_range__works), cmocka_unit_test(test__f_fss_count_lines__works), cmocka_unit_test(test__f_fss_count_lines_range__works), + cmocka_unit_test(test__f_fss_count_slash__works), cmocka_unit_test(test__f_fss_is_combining__works), cmocka_unit_test(test__f_fss_is_graph__works), cmocka_unit_test(test__f_fss_is_space__works), @@ -149,6 +151,7 @@ int main(void) { cmocka_unit_test(test__f_fss_apply_delimit_range__parameter_checking), cmocka_unit_test(test__f_fss_count_lines__parameter_checking), cmocka_unit_test(test__f_fss_count_lines_range__parameter_checking), + cmocka_unit_test(test__f_fss_count_slash__parameter_checking), // f_fss_fail_utf() doesn't use parameter checking. // f_fss_fail_utf_false() doesn't use parameter checking. // f_fss_is_combining() doesn't use parameter checking. diff --git a/level_0/f_fss/tests/unit/c/test-fss.h b/level_0/f_fss/tests/unit/c/test-fss.h index 451ac6fe5..575e777ad 100644 --- a/level_0/f_fss/tests/unit/c/test-fss.h +++ b/level_0/f_fss/tests/unit/c/test-fss.h @@ -30,6 +30,7 @@ #include "test-fss-apply_delimit_range.h" #include "test-fss-count_lines.h" #include "test-fss-count_lines_range.h" +#include "test-fss-count_slash.h" #include "test-fss-fail_utf.h" #include "test-fss-fail_utf_to_false.h" #include "test-fss-is_combining.h" -- 2.52.0