]> Kevux Git Server - fll/commitdiff
Feature: Add fl_iki_eki_read(), add unit tests, and update existing stand alone builds.
authorKevin Day <Kevin@kevux.org>
Sun, 24 Nov 2024 03:43:01 +0000 (21:43 -0600)
committerKevin Day <Kevin@kevux.org>
Sun, 24 Nov 2024 03:43:01 +0000 (21:43 -0600)
16 files changed:
build/stand_alone/fake.config.h
build/stand_alone/firewall.config.h
level_1/fl_iki/c/iki.c
level_1/fl_iki/c/iki.h
level_1/fl_iki/data/build/dependencies-tests [new file with mode: 0644]
level_1/fl_iki/data/build/settings-mocks [new file with mode: 0644]
level_1/fl_iki/data/build/settings-tests [new file with mode: 0644]
level_1/fl_iki/data/build/testfile [new file with mode: 0644]
level_1/fl_iki/tests/unit/c/mock-iki.c [new file with mode: 0644]
level_1/fl_iki/tests/unit/c/mock-iki.h [new file with mode: 0644]
level_1/fl_iki/tests/unit/c/test-iki-eki_read.c [new file with mode: 0644]
level_1/fl_iki/tests/unit/c/test-iki-eki_read.h [new file with mode: 0644]
level_1/fl_iki/tests/unit/c/test-iki-read.c [new file with mode: 0644]
level_1/fl_iki/tests/unit/c/test-iki-read.h [new file with mode: 0644]
level_1/fl_iki/tests/unit/c/test-iki.c [new file with mode: 0644]
level_1/fl_iki/tests/unit/c/test-iki.h [new file with mode: 0644]

index 872a65f9adb9b7b6dd4adab2d09e9b146dddd205..e53427206f41db8246450910b8ac838f4b3bed82 100644 (file)
 #define _di_f_iki_datass_destroy_callback_
 #define _di_f_iki_datass_t_
 //#define _di_f_iki_default_d_
-//#define _di_f_iki_eki_delete_
-//#define _di_f_iki_eki_destroy_
-//#define _di_f_iki_eki_read_
-//#define _di_f_iki_eki_t_
-//#define _di_f_iki_eki_write_
-//#define _di_f_iki_ekis_append_
-//#define _di_f_iki_ekis_append_all_
-//#define _di_f_iki_ekis_delete_callback_
-//#define _di_f_iki_ekis_destroy_callback_
-//#define _di_f_iki_ekis_t_
-//#define _di_f_iki_ekiss_append_
-//#define _di_f_iki_ekiss_append_all_
-//#define _di_f_iki_ekiss_delete_callback_
-//#define _di_f_iki_ekiss_destroy_callback_
-//#define _di_f_iki_ekiss_t_
+#define _di_f_iki_eki_delete_
+#define _di_f_iki_eki_destroy_
+#define _di_f_iki_eki_read_
+#define _di_f_iki_eki_t_
+#define _di_f_iki_eki_write_
+#define _di_f_iki_ekis_append_
+#define _di_f_iki_ekis_append_all_
+#define _di_f_iki_ekis_delete_callback_
+#define _di_f_iki_ekis_destroy_callback_
+#define _di_f_iki_ekis_t_
+#define _di_f_iki_ekiss_append_
+#define _di_f_iki_ekiss_append_all_
+#define _di_f_iki_ekiss_delete_callback_
+#define _di_f_iki_ekiss_destroy_callback_
+#define _di_f_iki_ekiss_t_
 #define _di_f_iki_object_is_
 #define _di_f_iki_object_partial_is_
 //#define _di_f_iki_read_
 #define _di_fl_fss_payload_header_map_
 #define _di_fl_fss_payload_header_maps_
 #define _di_fl_fss_payload_header_state_t_
+#define _di_fl_iki_eki_read_
 //#define _di_fl_iki_read_
 //#define _di_fl_path_canonical_
 //#define _di_fl_print_debug_s_
index 43869934c82096d804a29060d443b5b4c524c282..5926c4a1321e88b5f11c9739be6f4d539359e0ad 100644 (file)
 #define _di_fl_fss_payload_header_map_
 #define _di_fl_fss_payload_header_maps_
 #define _di_fl_fss_payload_header_state_t_
+#define _di_fl_iki_eki_read_
 #define _di_fl_iki_read_
 #define _di_fl_path_canonical_
 //#define _di_fl_print_debug_s_
index afa5c9c8661879c01fcfbd90facd4780d58d1519..feaa82a725611e84b252d7e3042d07586d7d0ed5 100644 (file)
@@ -4,6 +4,24 @@
 extern "C" {
 #endif
 
+#ifndef _di_fl_iki_eki_read_
+  void fl_iki_eki_read(f_string_static_t * const buffer, f_range_t * const range, f_iki_eki_t * const data, f_state_t * const state) {
+    #ifndef _di_level_1_parameter_checking_
+      if (!state) return;
+
+      if (!buffer || !range) {
+        state->status = F_status_set_error(F_parameter);
+
+        return;
+      }
+    #endif // _di_level_1_parameter_checking_
+
+    do {
+      f_iki_eki_read(buffer, range, data, state);
+    } while (F_status_is_error_not(state->status) && range->start <= range->stop && range->start < buffer->used);
+  }
+#endif // _di_fl_iki_eki_read_
+
 #ifndef _di_fl_iki_read_
   void fl_iki_read(f_string_static_t * const buffer, f_range_t * const range, f_iki_data_t * const data, f_state_t * const state) {
     #ifndef _di_level_1_parameter_checking_
@@ -18,9 +36,7 @@ extern "C" {
 
     do {
       f_iki_read(buffer, range, data, state);
-      if (F_status_is_error(state->status)) return;
-
-    } while (range->start <= range->stop && range->start < buffer->used);
+    } while (F_status_is_error_not(state->status) && range->start <= range->stop && range->start < buffer->used);
   }
 #endif // _di_fl_iki_read_
 
index 13c71ef3f8a2e3ad9e6a6be9c7925a613c7d6d09..056be16835eb6b01ba2a5f61abf45a53824d5ffb 100644 (file)
@@ -30,6 +30,37 @@ extern "C" {
 #endif
 
 /**
+ * Read all EKI Vocabulary and Content in the given range of the given buffer.
+ *
+ * This does not verify if any vocabulary name is known.
+ * This only finds complete vocabulary names and their respective content.
+ *
+ * @param buffer
+ *   The string to process.
+ * @param range
+ *   The start/stop location within the buffer to be processed.
+ *   The start location will be updated as the buffer is being processed.
+ *   The start location will represent where the read stopped on return.
+ *   A start location past the stop location or buffer used means that the entire range was processed.
+ * @param data
+ *   The EKI data.
+ * @param state
+ *   A state for providing flags and handling interrupts during long running operations.
+ *   This must not be NULL.
+ *
+ *   This alters state.status:
+ *     F_parameter (with error bit) if a parameter is invalid.
+ *
+ *     Success from: f_iki_eki_read().
+ *     Errors (with error bit) from: f_iki_eki_read().
+ *
+ * @see f_iki_eki_read()
+ */
+#ifndef _di_fl_iki_eki_read_
+  extern void fl_iki_eki_read(f_string_static_t * const buffer, f_range_t * const range, f_iki_eki_t * const data, f_state_t * const state);
+#endif // _di_fl_iki_eki_read_
+
+/**
  * Read all IKI Vocabulary and Content in the given range of the given buffer.
  *
  * This does not verify if any vocabulary name is known.
@@ -49,14 +80,6 @@ extern "C" {
  *   This must not be NULL.
  *
  *   This alters state.status:
- *     F_okay on success and an IKI vocabulary name was found.
- *     F_okay_stop on success and an IKI vocabulary name was found and stop point was reached.
- *     F_okay_eos on success and an IKI vocabulary name was found and end of string was reached.
- *     F_complete_not_utf_eos on success and EOS was reached, but at an incomplete UTF-8 sequence.
- *     F_complete_not_utf_stop on success and stop point was reached, but at an incomplete UTF-8 sequence.
- *     F_data_not_eos on success and EOS was reached, but there were no IKI vocabularie names found.
- *     F_data_not_stop on success and stop point was reached, but there were no IKI vocabularie names found.
- *
  *     F_parameter (with error bit) if a parameter is invalid.
  *
  *     Success from: f_iki_read().
diff --git a/level_1/fl_iki/data/build/dependencies-tests b/level_1/fl_iki/data/build/dependencies-tests
new file mode 100644 (file)
index 0000000..dea3179
--- /dev/null
@@ -0,0 +1,3 @@
+# fss-0001
+
+cmocka 1.*
diff --git a/level_1/fl_iki/data/build/settings-mocks b/level_1/fl_iki/data/build/settings-mocks
new file mode 100644 (file)
index 0000000..561d053
--- /dev/null
@@ -0,0 +1,72 @@
+# fss-0001
+#
+# Build the project with appropriate mocks linked in via the dynamic linker's "--wrap" functionality.
+#
+# The -Wl,--wrap does not work across shared files.
+# Therefore, this file is a work-around to inject the mocks into the library for testing purposes.
+# This should exactly match the "settings" file, except for the additional "-Wl,--wrap" parts and the additional mock source file.
+#
+# The flags -o0 must be passed to prevent the compiler from optimizing away any functions being mocked (which results in the mock not happening and a real function being called).
+# Alternatively, figure out which optimization that is disabled by -o0 and have that specific optimization disabled.
+#
+
+build_name fl_iki
+
+version_major 0
+version_minor 7
+version_micro 0
+version_file micro
+version_target minor
+
+modes individual clang gcc gcc_13 test coverage
+modes_default individual test gcc
+
+build_compiler gcc
+build_compiler-clang clang
+build_indexer ar
+build_indexer_arguments rcs
+build_language c
+
+build_libraries -lc
+build_libraries-individual -lf_iki -lf_memory -lf_string -lf_type_array -lf_utf
+
+build_sources_library iki.c
+build_sources_library ../../tests/unit/c/mock-iki.c
+
+build_sources_headers iki.h
+
+build_script yes
+build_shared yes
+build_static no
+
+path_headers fll/level_1
+path_library_script script
+path_library_shared shared
+path_library_static static
+
+has_path_standard yes
+preserve_path_headers yes
+
+search_exclusive yes
+search_shared yes
+search_static yes
+
+environment PATH LD_LIBRARY_PATH
+environment LANG LC_ALL LC_COLLATE LC_CTYPE LC_FASTMSG LC_MESSAGES LC_MONETARY LC_NUMERIC LC_TIME LOCPATH NLSPATH
+
+#defines -D_pthread_attr_unsupported_ -D_pthread_sigqueue_unsupported_
+defines -D_pthread_sigqueue_unsupported_
+
+flags -O0 -g -fdiagnostics-color=always -Wno-logical-not-parentheses -Wno-parentheses -Wno-missing-braces
+flags -fstack-clash-protection -fno-delete-null-pointer-checks
+flags -Wl,-z,nodlopen -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now
+flags-clang -Wno-logical-op-parentheses
+flags-coverage --coverage -fprofile-abs-path -fprofile-dir=build/coverage/
+flags-gcc_13 -fstrict-flex-arrays=3
+flags-test -fstack-protector-strong -Wall
+
+flags_library -fPIC
+
+# Inject mocks.
+flags -Wl,--wrap=f_iki_eki_read
+flags -Wl,--wrap=f_iki_read
diff --git a/level_1/fl_iki/data/build/settings-tests b/level_1/fl_iki/data/build/settings-tests
new file mode 100644 (file)
index 0000000..fedd595
--- /dev/null
@@ -0,0 +1,61 @@
+# fss-0001
+#
+# Builds a program that is links to the generated library and is executed to perform tests.
+#
+# Memory leaks in the test program can be checked for by running valgrind with this executable.
+#
+
+build_name test-fl_iki
+
+version_major 0
+version_minor 6
+version_micro 4
+version_file micro
+version_target minor
+
+modes individual clang gcc gcc_13 test coverage
+modes_default individual test gcc
+
+build_compiler gcc
+build_compiler-clang clang
+build_indexer ar
+build_indexer_arguments rcs
+build_language c
+
+build_libraries -lc -lcmocka
+build_libraries-individual -lf_iki -lf_memory -lf_string -lf_type_array -lf_utf -lfl_iki
+
+build_sources_program test-iki-eki_read.c test-iki-read.c
+
+build_sources_program test-iki.c
+
+build_script no
+build_shared yes
+build_static no
+
+path_headers tests/unit/c
+path_sources tests/unit/c
+
+has_path_standard no
+preserve_path_headers yes
+
+search_exclusive yes
+search_shared yes
+search_static yes
+
+environment PATH LD_LIBRARY_PATH
+environment LANG LC_ALL LC_COLLATE LC_CTYPE LC_FASTMSG LC_MESSAGES LC_MONETARY LC_NUMERIC LC_TIME LOCPATH NLSPATH
+
+defines -Ibuild/includes
+defines_static -Lbuild/libraries/static
+defines_shared -Lbuild/libraries/shared
+
+flags -O2 -g -fdiagnostics-color=always -Wno-logical-not-parentheses -Wno-parentheses -Wno-missing-braces
+flags -fstack-clash-protection -fno-delete-null-pointer-checks
+flags -Wl,-z,nodlopen -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now
+flags-clang -Wno-logical-op-parentheses
+flags-coverage -O0 --coverage -fprofile-abs-path -fprofile-dir=build/coverage/
+flags-gcc_13 -fstrict-flex-arrays=3
+flags-test -fstack-protector-strong -Wall
+
+flags_program -fPIE
diff --git a/level_1/fl_iki/data/build/testfile b/level_1/fl_iki/data/build/testfile
new file mode 100644 (file)
index 0000000..5480340
--- /dev/null
@@ -0,0 +1,63 @@
+# fss-0005 iki-0002
+
+settings:
+  load_build yes
+  fail exit
+
+  environment PATH LD_LIBRARY_PATH
+  environment LANG LC_ALL LC_COLLATE LC_CTYPE LC_FASTMSG LC_MESSAGES LC_MONETARY LC_NUMERIC LC_TIME LOCPATH NLSPATH
+  environment CMOCKA_XML_FILE CMOCKA_MESSAGE_OUTPUT CMOCKA_TEST_ABORT
+
+  # Cmocka is not fully thread-safe, set this to "1" to have cmocka call abort() on a test failure.
+  #define CMOCKA_TEST_ABORT 1
+
+  # One of: STDOUT, SUBUNIT, TAP, or XML.
+  #define CMOCKA_MESSAGE_OUTPUT STDOUT
+
+  # When in "XML" output mode, output to this file rather than stdout.
+  #define CMOCKA_XML_FILE ./out.xml
+
+main:
+  build settings-mocks individual test
+  build settings-tests individual test
+
+  operate build_path
+  operate ld_library_path
+
+  if exist parameter:"build_path"programs/shared/test-fl_iki
+    shell parameter:"build_path"programs/shared/test-fl_iki
+
+  if exist parameter:"build_path"programs/static/test-fl_iki
+    shell parameter:"build_path"programs/static/test-fl_iki
+
+  if not exist parameter:"build_path"programs/shared/test-fl_iki
+  and not exist parameter:"build_path"programs/static/test-fl_iki
+    operate not_created
+
+not_created:
+  print
+  print 'context:"error"Failed to test due to being unable to find either a shared or static test binary to perform tests. context:"reset"'
+
+  exit failure
+
+build_path:
+  parameter build_path build/
+
+  if parameter build:value
+    parameter build_path parameter:"build:value"
+
+ld_library_path:
+  if define LD_LIBRARY_PATH
+  and parameter work:value
+    define LD_LIBRARY_PATH 'parameter:"build_path"libraries/shared:parameter:"work:value"libraries/shared:define:"LD_LIBRARY_PATH"'
+
+  else
+  if define LD_LIBRARY_PATH
+    define LD_LIBRARY_PATH 'parameter:"build_path"libraries/shared:define:"LD_LIBRARY_PATH"'
+
+  else
+  if parameter work:value
+    define LD_LIBRARY_PATH 'parameter:"build_path"libraries/shared:parameter:"work:value"libraries/shared'
+
+  else
+    define LD_LIBRARY_PATH 'parameter:"build_path"libraries/shared'
diff --git a/level_1/fl_iki/tests/unit/c/mock-iki.c b/level_1/fl_iki/tests/unit/c/mock-iki.c
new file mode 100644 (file)
index 0000000..cb5b86b
--- /dev/null
@@ -0,0 +1,53 @@
+#include "mock-iki.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void __wrap_f_iki_eki_read(f_string_static_t * const buffer, f_range_t * const range, f_iki_eki_t * const data, f_state_t * const state) {
+
+  if (!state) return;
+
+  if (!buffer || !range || !data || !state) {
+    state->status = F_status_set_error(F_parameter_not);
+
+    return;
+  }
+
+  const bool failure = mock_type(bool);
+
+  if (failure) {
+    state->status = mock_type(f_status_t);
+
+    return;
+  }
+
+  range->start = mock_type(f_number_unsigned_t);
+  state->status = mock_type(f_status_t);
+}
+
+void __wrap_f_iki_read(f_string_static_t * const buffer, f_range_t * const range, f_iki_data_t * const data, f_state_t * const state) {
+
+  if (!state) return;
+
+  if (!buffer || !range || !data || !state) {
+    state->status = F_status_set_error(F_parameter_not);
+
+    return;
+  }
+
+  const bool failure = mock_type(bool);
+
+  if (failure) {
+    state->status = mock_type(f_status_t);
+
+    return;
+  }
+
+  range->start = mock_type(f_number_unsigned_t);
+  state->status = mock_type(f_status_t);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_1/fl_iki/tests/unit/c/mock-iki.h b/level_1/fl_iki/tests/unit/c/mock-iki.h
new file mode 100644 (file)
index 0000000..28b66c6
--- /dev/null
@@ -0,0 +1,38 @@
+/**
+ * FLL - Level 1
+ *
+ * Project: Abstruse
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the iki project.
+ */
+#ifndef _MOCK__iki_h
+#define _MOCK__iki_h
+
+// Libc includes.
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <stdint.h>
+
+// cmocka includes.
+#include <cmocka.h>
+
+// FLL-0 includes.
+#include <fll/level_0/iki.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+const static int mock_errno_generic = 32767;
+
+extern void __wrap_f_iki_eki_read(f_string_static_t * const buffer, f_range_t * const range, f_iki_eki_t * const data, f_state_t * const state);
+extern void __wrap_f_iki_read(f_string_static_t * const buffer, f_range_t * const range, f_iki_data_t * const data, f_state_t * const state);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _MOCK__iki_h
diff --git a/level_1/fl_iki/tests/unit/c/test-iki-eki_read.c b/level_1/fl_iki/tests/unit/c/test-iki-eki_read.c
new file mode 100644 (file)
index 0000000..91f965a
--- /dev/null
@@ -0,0 +1,88 @@
+#include "test-iki.h"
+#include "test-iki-eki_read.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__fl_iki_eki_read__parameter_checking(void **state) {
+
+  f_string_static_t buffer = f_string_static_t_initialize;
+  f_range_t range = f_range_t_initialize;
+  f_iki_eki_t data = f_iki_eki_t_initialize;
+  f_state_t the_state = f_state_t_initialize;
+
+  // The data parameter is not directly accessed by fl_iki_eki_read(), and so there is no parameter checking for that parameter.
+
+  {
+    fl_iki_eki_read(0, 0, 0, &the_state);
+
+    assert_int_equal(F_status_set_fine(the_state.status), F_parameter);
+  }
+
+  {
+    fl_iki_eki_read(&buffer, 0, 0, &the_state);
+
+    assert_int_equal(F_status_set_fine(the_state.status), F_parameter);
+  }
+
+  {
+    fl_iki_eki_read(&buffer, 0, &data, &the_state);
+
+    assert_int_equal(F_status_set_fine(the_state.status), F_parameter);
+  }
+
+  {
+    fl_iki_eki_read(&buffer, 0, &data, &the_state);
+
+    assert_int_equal(F_status_set_fine(the_state.status), F_parameter);
+  }
+
+  {
+    fl_iki_eki_read(0, &range, 0, &the_state);
+
+    assert_int_equal(F_status_set_fine(the_state.status), F_parameter);
+  }
+
+  {
+    fl_iki_eki_read(0, &range, &data, &the_state);
+
+    assert_int_equal(F_status_set_fine(the_state.status), F_parameter);
+  }
+}
+
+void test__fl_iki_eki_read__works(void **state) {
+
+  f_string_static_t buffer = f_string_static_t_initialize;
+  f_range_t range = f_range_t_initialize;
+  f_iki_eki_t data = f_iki_eki_t_initialize;
+  f_state_t the_state = f_state_t_initialize;
+
+  {
+    the_state.status = F_false;
+    range.start = 0;
+    range.stop = 2;
+    buffer.used = 10;
+
+    will_return(__wrap_f_iki_eki_read, false);
+    will_return(__wrap_f_iki_eki_read, 1);
+    will_return(__wrap_f_iki_eki_read, F_okay);
+
+    will_return(__wrap_f_iki_eki_read, false);
+    will_return(__wrap_f_iki_eki_read, 2);
+    will_return(__wrap_f_iki_eki_read, F_okay);
+
+    will_return(__wrap_f_iki_eki_read, false);
+    will_return(__wrap_f_iki_eki_read, 3);
+    will_return(__wrap_f_iki_eki_read, F_okay_stop);
+
+    fl_iki_eki_read(&buffer, &range, &data, &the_state);
+
+    assert_int_equal(the_state.status, F_okay_stop);
+    assert_int_equal(range.start, range.stop + 1);
+  }
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_1/fl_iki/tests/unit/c/test-iki-eki_read.h b/level_1/fl_iki/tests/unit/c/test-iki-eki_read.h
new file mode 100644 (file)
index 0000000..fd390a1
--- /dev/null
@@ -0,0 +1,27 @@
+/**
+ * FLL - Level 1
+ *
+ * Project: Status
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the iki project.
+ */
+#ifndef _TEST__FL_iki_eki_read_h
+#define _TEST__FL_iki_eki_read_h
+
+/**
+ * Test that parameter checking works as expected.
+ *
+ * @see fl_iki_eki_read()
+ */
+extern void test__fl_iki_eki_read__parameter_checking(void **state);
+
+/**
+ * Test that function works.
+ *
+ * @see fl_iki_eki_read()
+ */
+extern void test__fl_iki_eki_read__works(void **state);
+
+#endif // _TEST__FL_iki_eki_read_h
diff --git a/level_1/fl_iki/tests/unit/c/test-iki-read.c b/level_1/fl_iki/tests/unit/c/test-iki-read.c
new file mode 100644 (file)
index 0000000..fd160a8
--- /dev/null
@@ -0,0 +1,88 @@
+#include "test-iki.h"
+#include "test-iki-read.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__fl_iki_read__parameter_checking(void **state) {
+
+  f_string_static_t buffer = f_string_static_t_initialize;
+  f_range_t range = f_range_t_initialize;
+  f_iki_data_t data = f_iki_data_t_initialize;
+  f_state_t the_state = f_state_t_initialize;
+
+  // The data parameter is not directly accessed by fl_iki_read(), and so there is no parameter checking for that parameter.
+
+  {
+    fl_iki_read(0, 0, 0, &the_state);
+
+    assert_int_equal(F_status_set_fine(the_state.status), F_parameter);
+  }
+
+  {
+    fl_iki_read(&buffer, 0, 0, &the_state);
+
+    assert_int_equal(F_status_set_fine(the_state.status), F_parameter);
+  }
+
+  {
+    fl_iki_read(&buffer, 0, &data, &the_state);
+
+    assert_int_equal(F_status_set_fine(the_state.status), F_parameter);
+  }
+
+  {
+    fl_iki_read(&buffer, 0, &data, &the_state);
+
+    assert_int_equal(F_status_set_fine(the_state.status), F_parameter);
+  }
+
+  {
+    fl_iki_read(0, &range, 0, &the_state);
+
+    assert_int_equal(F_status_set_fine(the_state.status), F_parameter);
+  }
+
+  {
+    fl_iki_read(0, &range, &data, &the_state);
+
+    assert_int_equal(F_status_set_fine(the_state.status), F_parameter);
+  }
+}
+
+void test__fl_iki_read__works(void **state) {
+
+  f_string_static_t buffer = f_string_static_t_initialize;
+  f_range_t range = f_range_t_initialize;
+  f_iki_data_t data = f_iki_data_t_initialize;
+  f_state_t the_state = f_state_t_initialize;
+
+  {
+    the_state.status = F_false;
+    range.start = 0;
+    range.stop = 2;
+    buffer.used = 10;
+
+    will_return(__wrap_f_iki_read, false);
+    will_return(__wrap_f_iki_read, 1);
+    will_return(__wrap_f_iki_read, F_okay);
+
+    will_return(__wrap_f_iki_read, false);
+    will_return(__wrap_f_iki_read, 2);
+    will_return(__wrap_f_iki_read, F_okay);
+
+    will_return(__wrap_f_iki_read, false);
+    will_return(__wrap_f_iki_read, 3);
+    will_return(__wrap_f_iki_read, F_okay_stop);
+
+    fl_iki_read(&buffer, &range, &data, &the_state);
+
+    assert_int_equal(the_state.status, F_okay_stop);
+    assert_int_equal(range.start, range.stop + 1);
+  }
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_1/fl_iki/tests/unit/c/test-iki-read.h b/level_1/fl_iki/tests/unit/c/test-iki-read.h
new file mode 100644 (file)
index 0000000..e340c5b
--- /dev/null
@@ -0,0 +1,27 @@
+/**
+ * FLL - Level 1
+ *
+ * Project: Status
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the iki project.
+ */
+#ifndef _TEST__FL_iki_read_h
+#define _TEST__FL_iki_read_h
+
+/**
+ * Test that parameter checking works as expected.
+ *
+ * @see fl_iki_read()
+ */
+extern void test__fl_iki_read__parameter_checking(void **state);
+
+/**
+ * Test that function works.
+ *
+ * @see fl_iki_read()
+ */
+extern void test__fl_iki_read__works(void **state);
+
+#endif // _TEST__FL_iki_read_h
diff --git a/level_1/fl_iki/tests/unit/c/test-iki.c b/level_1/fl_iki/tests/unit/c/test-iki.c
new file mode 100644 (file)
index 0000000..1b24b9f
--- /dev/null
@@ -0,0 +1,38 @@
+#include "test-iki.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int setup(void **state) {
+
+  return 0;
+}
+
+int setdown(void **state) {
+
+  errno = 0;
+
+  return 0;
+}
+
+int main(void) {
+
+  const struct CMUnitTest tests[] = {
+
+    cmocka_unit_test(test__fl_iki_eki_read__works),
+
+    cmocka_unit_test(test__fl_iki_read__works),
+
+    #ifndef _di_level_0_parameter_checking_
+      cmocka_unit_test(test__fl_iki_eki_read__parameter_checking),
+      cmocka_unit_test(test__fl_iki_read__parameter_checking),
+    #endif // _di_level_0_parameter_checking_
+  };
+
+  return cmocka_run_group_tests(tests, setup, setdown);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_1/fl_iki/tests/unit/c/test-iki.h b/level_1/fl_iki/tests/unit/c/test-iki.h
new file mode 100644 (file)
index 0000000..7f7c92f
--- /dev/null
@@ -0,0 +1,73 @@
+/**
+ * FLL - Level 1
+ *
+ * Project: Status
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the iki project.
+ */
+#ifndef _TEST__FL_iki_h
+#define _TEST__FL_iki_h
+
+// Libc includes.
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <stdint.h>
+
+// cmocka includes.
+#include <cmocka.h>
+
+// FLL-1 includes.
+#include <fll/level_1/iki.h>
+
+// Mock includes.
+#include "mock-iki.h"
+
+// Test includes.
+#include "test-iki-eki_read.h"
+#include "test-iki-read.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Perform any setup operations.
+ *
+ * @param state
+ *   The test state.
+ *
+ * @return
+ *   The status of this function, where 0 means success.
+ */
+extern int setup(void **state);
+
+/**
+ * Peform any setdown operations.
+ *
+ * @param state
+ *   The test state.
+ *
+ * @return
+ *   The status of this function, where 0 means success.
+ */
+extern int setdown(void **state);
+
+/**
+ * Run all tests.
+ *
+ * @return
+ *   The final result of the tests.
+ *
+ * @see cmocka_run_group_tests()
+ * @see cmocka_unit_test()
+ */
+extern int main(void);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _TEST__FL_iki_h