]> Kevux Git Server - fll/commitdiff
Update: Add unit tests for f_fss_count_slash().
authorKevin Day <Kevin@kevux.org>
Sun, 1 Nov 2026 00:29:27 +0000 (19:29 -0500)
committerKevin Day <Kevin@kevux.org>
Sun, 1 Nov 2026 00:40:47 +0000 (19:40 -0500)
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
level_0/f_fss/c/fss.h
level_0/f_fss/data/build/settings-tests
level_0/f_fss/tests/unit/c/test-fss-count_slash.c [new file with mode: 0644]
level_0/f_fss/tests/unit/c/test-fss-count_slash.h [new file with mode: 0644]
level_0/f_fss/tests/unit/c/test-fss.c
level_0/f_fss/tests/unit/c/test-fss.h

index 9c208a5..81d12be 100644 (file)
@@ -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;
index 79ee296..011ef85 100644 (file)
@@ -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
index fb91450..5fd828c 100644 (file)
@@ -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 (file)
index 0000000..c69105c
--- /dev/null
@@ -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 (file)
index 0000000..7a6891d
--- /dev/null
@@ -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
index 823e15a..baf089c 100644 (file)
@@ -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.
index 451ac6f..575e777 100644 (file)
@@ -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"