--- /dev/null
+# fss-0001
+
+cmocka 1.*
--- /dev/null
+# 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 f_path
+
+version_major 0
+version_minor 5
+version_micro 9
+version_file micro
+version_target minor
+
+modes individual clang test
+modes_default individual
+
+build_compiler gcc
+build_compiler-clang clang
+build_indexer ar
+build_indexer_arguments rcs
+build_language c
+
+build_libraries -lc
+build_libraries-individual -lf_memory -lf_string
+
+build_sources_library path.c private-path.c path/common.c ../../tests/unit/c/mock-path.c
+
+build_sources_headers path.h path/common.h
+
+build_script yes
+build_shared yes
+build_static no
+
+path_headers fll/level_0
+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
+
+flags -O0 -z now -g -fdiagnostics-color=always -Wno-logical-not-parentheses -Wno-parentheses
+flags-clang -Wno-logical-op-parentheses
+flags-test -fstack-protector
+
+flags_library -fPIC
+
+# Inject mocks.
+flags -Wl,--wrap=chdir
+flags -Wl,--wrap=fchdir
+flags -Wl,--wrap=getcwd
+flags -Wl,--wrap=realpath
--- /dev/null
+# 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-f_path
+
+version_major 0
+version_minor 5
+version_micro 9
+version_file major
+version_target major
+
+modes individual clang test
+modes_default individual
+
+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_memory -lf_string -lf_type_array -lf_utf -lf_path
+
+build_sources_program test-path-change.c test-path-change_at.c test-path-current.c test-path-directory_cleanup.c test-path-is.c test-path-is_absolute.c test-path-is_relative.c test-path-is_relative_current.c test-path-real.c
+build_sources_program test-path.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
+
+defines -Ibuild/includes
+defines_static -Lbuild/libraries/static
+defines_shared -Lbuild/libraries/shared
+
+flags -O2 -z now -g -fdiagnostics-color=always -Wno-logical-not-parentheses -Wno-parentheses
+flags-clang -Wno-logical-op-parentheses
+flags-test -fstack-protector -Wall
+
+flags_program -fPIE
--- /dev/null
+# fss-0005 iki-0002
+
+settings:
+ load_build yes
+ fail exit
+
+ environment LD_LIBRARY_PATH
+
+main:
+ build settings-mocks
+ build settings-tests
+
+ operate ld_library_path
+
+ if exists build/programs/shared/test-f_path
+ shell build/programs/shared/test-f_path
+
+ if exists build/programs/static/test-f_path
+ shell build/programs/static/test-f_path
+
+ if not exists build/programs/shared/test-f_path
+ and not exists build/programs/static/test-f_path
+ 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
+
+ld_library_path:
+ if defined environment LD_LIBRARY_PATH
+ and defined parameter work
+ define LD_LIBRARY_PATH 'build/libraries/shared:parameter:"work:value"libraries/shared:define:"LD_LIBRARY_PATH"'
+
+ else
+ if defined environment LD_LIBRARY_PATH
+ define LD_LIBRARY_PATH 'build/libraries/shared:parameter:define:"LD_LIBRARY_PATH"'
+
+ else
+ if defined parameter work
+ define LD_LIBRARY_PATH 'build/libraries/shared:parameter:"work:value"libraries/shared'
+
+ else
+ define LD_LIBRARY_PATH build/libraries/shared
--- /dev/null
+#include "mock-path.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int __wrap_chdir(const char *path) {
+
+ const bool failure = mock_type(bool);
+
+ if (failure) {
+ errno = mock_type(int);
+
+ return -1;
+ }
+
+ return mock_type(int);
+}
+
+int __wrap_fchdir(int fd) {
+
+ const bool failure = mock_type(bool);
+
+ if (failure) {
+ errno = mock_type(int);
+
+ return -1;
+ }
+
+ return mock_type(int);
+}
+
+char *__wrap_getcwd(char *buf, size_t size) {
+
+ const bool failure = mock_type(bool);
+
+ if (failure) {
+ errno = mock_type(int);
+
+ return 0;
+ }
+
+ return mock_type(char *);
+}
+
+char *__wrap_realpath(const char *path, char *resolved_path) {
+
+ const bool failure = mock_type(bool);
+
+ if (failure) {
+ errno = mock_type(int);
+
+ return 0;
+ }
+
+ resolved_path = mock_type(char *);
+
+ return resolved_path;
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 0
+ *
+ * Project: Path
+ * API Version: 0.5
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the path project.
+ */
+#ifndef _MOCK__path_h
+#define _MOCK__path_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/path.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+const static int mock_errno_generic = 32767;
+
+extern int __wrap_chdir(const char *path);
+extern int __wrap_fchdir(int fd);
+extern char *__wrap_getcwd(char *buf, size_t size);
+extern char *__wrap_realpath(const char *path, char *resolved_path);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _MOCK__path_h
--- /dev/null
+#include "test-path.h"
+#include "test-path-change.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_path_change__fails(void **state) {
+
+ const f_string_static_t path = macro_f_string_static_t_initialize("test", 0, 4);
+
+ int errnos[] = {
+ EACCES,
+ EFAULT,
+ EIO,
+ ELOOP,
+ ENAMETOOLONG,
+ ENOENT,
+ ENOMEM,
+ ENOTDIR,
+ mock_errno_generic,
+ };
+
+ f_status_t statuss[] = {
+ F_access_denied,
+ F_buffer,
+ F_input_output,
+ F_loop,
+ F_name,
+ F_file_found_not,
+ F_memory_not,
+ F_directory,
+ F_failure,
+ };
+
+ for (int i = 0; i < 9; ++i) {
+
+ will_return(__wrap_chdir, true);
+ will_return(__wrap_chdir, errnos[i]);
+
+ const f_status_t status = f_path_change(path);
+
+ assert_int_equal(status, F_status_set_error(statuss[i]));
+ } // for
+}
+
+void test__f_path_change__works(void **state) {
+
+ const f_string_static_t path = macro_f_string_static_t_initialize("test", 0, 4);
+
+ {
+ will_return(__wrap_chdir, F_false);
+ will_return(__wrap_chdir, 0);
+
+ const f_status_t status = f_path_change(path);
+
+ assert_int_equal(status, F_none);
+ }
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 0
+ *
+ * Project: Path
+ * API Version: 0.5
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the path project.
+ */
+#ifndef _TEST__F_path_change_h
+#define _TEST__F_path_change_h
+
+/**
+ * Test that function fails.
+ *
+ * @see f_path_change()
+ */
+extern void test__f_path_change__fails(void **state);
+
+/**
+ * Test that function works.
+ *
+ * @see f_path_change()
+ */
+extern void test__f_path_change__works(void **state);
+
+#endif // _TEST__F_path_change_h
--- /dev/null
+#include "test-path.h"
+#include "test-path-change_at.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_path_change_at__fails(void **state) {
+
+ const int id = 1;
+
+ int errnos[] = {
+ EACCES,
+ EBADF,
+ EFAULT,
+ EIO,
+ ELOOP,
+ ENAMETOOLONG,
+ ENOENT,
+ ENOMEM,
+ ENOTDIR,
+ mock_errno_generic,
+ };
+
+ f_status_t statuss[] = {
+ F_access_denied,
+ F_directory_descriptor,
+ F_buffer,
+ F_input_output,
+ F_loop,
+ F_name,
+ F_file_found_not,
+ F_memory_not,
+ F_directory,
+ F_failure,
+ };
+
+ for (int i = 0; i < 10; ++i) {
+
+ will_return(__wrap_fchdir, true);
+ will_return(__wrap_fchdir, errnos[i]);
+
+ const f_status_t status = f_path_change_at(id);
+
+ assert_int_equal(status, F_status_set_error(statuss[i]));
+ } // for
+}
+
+void test__f_path_change_at__works(void **state) {
+
+ const int id = 1;
+
+ {
+ will_return(__wrap_fchdir, F_false);
+ will_return(__wrap_fchdir, 0);
+
+ const f_status_t status = f_path_change_at(id);
+
+ assert_int_equal(status, F_none);
+ }
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 0
+ *
+ * Project: Path
+ * API Version: 0.5
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the path project.
+ */
+#ifndef _TEST__F_path_change_at_h
+#define _TEST__F_path_change_at_h
+
+/**
+ * Test that function fails.
+ *
+ * @see f_path_change_at()
+ */
+extern void test__f_path_change_at__fails(void **state);
+
+/**
+ * Test that function works.
+ *
+ * @see f_path_change_at()
+ */
+extern void test__f_path_change_at__works(void **state);
+
+#endif // _TEST__F_path_change_at_h
--- /dev/null
+#include "test-path.h"
+#include "test-path-current.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_path_current__fails(void **state) {
+
+ f_string_dynamic_t destination = f_string_dynamic_t_initialize;
+
+ {
+ int errnos[] = {
+ EACCES,
+ EFAULT,
+ EINVAL,
+ ENAMETOOLONG,
+ ENOENT,
+ ENOMEM,
+ ERANGE,
+ mock_errno_generic,
+ };
+
+ f_status_t statuss[] = {
+ F_access_denied,
+ F_buffer,
+ F_parameter,
+ F_name,
+ F_file_found_not,
+ F_memory_not,
+ F_buffer_too_small,
+ F_failure,
+ };
+
+ for (int i = 0; i < 8; ++i) {
+
+ will_return(__wrap_getcwd, true);
+ will_return(__wrap_getcwd, errnos[i]);
+
+ const f_status_t status = f_path_current(F_false, &destination);
+
+ assert_int_equal(status, F_status_set_error(statuss[i]));
+ } // for
+ }
+
+ destination.used = 0;
+
+ {
+ int errnos[] = {
+ EACCES,
+ EINVAL,
+ EIO,
+ ELOOP,
+ ENAMETOOLONG,
+ ENOENT,
+ ENOMEM,
+ ENOTDIR,
+ mock_errno_generic,
+ };
+
+ f_status_t statuss[] = {
+ F_access_denied,
+ F_parameter,
+ F_input_output,
+ F_loop,
+ F_name,
+ F_file_found_not,
+ F_memory_not,
+ F_directory,
+ F_failure,
+ };
+
+ for (int i = 0; i < 9; ++i) {
+
+ will_return(__wrap_getcwd, false);
+ will_return(__wrap_getcwd, 0);
+
+ will_return(__wrap_realpath, true);
+ will_return(__wrap_realpath, errnos[i]);
+
+ const f_status_t status = f_path_current(F_true, &destination);
+
+ assert_int_equal(status, F_status_set_error(statuss[i]));
+ } // for
+ }
+
+ f_string_dynamic_resize(0, &destination);
+}
+
+#ifndef _di_level_0_parameter_checking_
+ void test__f_path_current__parameter_checking(void **state) {
+
+ {
+ const f_status_t status = f_path_current(F_false, 0);
+
+ assert_int_equal(F_status_set_fine(status), F_parameter);
+ }
+ }
+#endif // _di_level_0_parameter_checking_
+
+void test__f_path_current__works(void **state) {
+
+ const f_string_static_t path = macro_f_string_static_t_initialize("test", 0, 4);
+ const f_string_static_t path_real = macro_f_string_static_t_initialize("/test", 0, 5);
+
+ f_string_dynamic_t destination = f_string_dynamic_t_initialize;
+
+ {
+ will_return(__wrap_getcwd, F_false);
+ will_return(__wrap_getcwd, path.string);
+
+ const f_status_t status = f_path_current(F_false, &destination);
+
+ assert_int_equal(status, F_none);
+ assert_int_equal(destination.used, path.used);
+ assert_string_equal(destination.string, path.string);
+ }
+
+ destination.used = 0;
+
+ {
+ will_return(__wrap_getcwd, F_false);
+ will_return(__wrap_getcwd, path.string);
+
+ will_return(__wrap_realpath, F_false);
+ will_return(__wrap_realpath, path_real.string);
+
+ const f_status_t status = f_path_current(F_true, &destination);
+
+ assert_int_equal(status, F_none);
+ assert_int_equal(destination.used, path_real.used);
+ assert_string_equal(destination.string, path_real.string);
+ }
+
+ f_string_dynamic_resize(0, &destination);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 0
+ *
+ * Project: Path
+ * API Version: 0.5
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the path project.
+ */
+#ifndef _TEST__F_path_current_h
+#define _TEST__F_path_current_h
+
+/**
+ * Test that parameter checking works as expected.
+ *
+ * @see f_path_current()
+ */
+#ifndef _di_level_0_parameter_checking_
+ extern void test__f_path_current__parameter_checking(void **state);
+#endif // _di_level_0_parameter_checking_
+
+#endif // _TEST__F_path_current_h
--- /dev/null
+#include "test-path.h"
+#include "test-path-directory_cleanup.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_level_0_parameter_checking_
+ void test__f_path_directory_cleanup__parameter_checking(void **state) {
+
+ const f_string_static_t path = macro_f_string_static_t_initialize("test", 0, 4);
+
+ {
+ const f_status_t status = f_path_directory_cleanup(path, 0);
+
+ assert_int_equal(F_status_set_fine(status), F_parameter);
+ }
+ }
+#endif // _di_level_0_parameter_checking_
+
+void test__f_path_directory_cleanup__works(void **state) {
+
+ const f_string_static_t paths[] = {
+ macro_f_string_static_t_initialize("path", 0, 4),
+ macro_f_string_static_t_initialize("also path", 0, 9),
+ macro_f_string_static_t_initialize("", 0, 0),
+ macro_f_string_static_t_initialize("/", 0, 1),
+ macro_f_string_static_t_initialize("///", 0, 3),
+ macro_f_string_static_t_initialize("///path", 0, 7),
+ macro_f_string_static_t_initialize("///path////", 0, 11),
+ macro_f_string_static_t_initialize("///also////path", 0, 15),
+ macro_f_string_static_t_initialize("../", 0, 3),
+ macro_f_string_static_t_initialize("..///", 0, 3),
+ macro_f_string_static_t_initialize("..///path", 0, 9),
+ macro_f_string_static_t_initialize("..///path////", 0, 11),
+ macro_f_string_static_t_initialize("..///also////path", 0, 17),
+ macro_f_string_static_t_initialize("also///..//path", 0, 15),
+ };
+
+ const f_string_static_t expecteds[] = {
+ macro_f_string_static_t_initialize("path/", 0, 5),
+ macro_f_string_static_t_initialize("also path/", 0, 10),
+ macro_f_string_static_t_initialize("", 0, 0),
+ macro_f_string_static_t_initialize("/", 0, 1),
+ macro_f_string_static_t_initialize("/", 0, 1),
+ macro_f_string_static_t_initialize("/path/", 0, 6),
+ macro_f_string_static_t_initialize("/path/", 0, 6),
+ macro_f_string_static_t_initialize("/also/path/", 0, 11),
+ macro_f_string_static_t_initialize("../", 0, 3),
+ macro_f_string_static_t_initialize("../", 0, 3),
+ macro_f_string_static_t_initialize("../path/", 0, 8),
+ macro_f_string_static_t_initialize("../path/", 0, 8),
+ macro_f_string_static_t_initialize("../also/path/", 0, 13),
+ macro_f_string_static_t_initialize("also/../path/", 0, 13),
+ };
+
+ f_string_dynamic_t destination = f_string_dynamic_t_initialize;
+
+ for (f_array_length_t i = 0; i < 14; ++i, destination.used = 0) {
+
+ const f_status_t status = f_path_directory_cleanup(paths[i], &destination);
+
+ assert_int_equal(status, F_none);
+ assert_int_equal(destination.used, expecteds[i].used);
+
+ if (destination.used) {
+ assert_string_equal(destination.string, expecteds[i].string);
+
+ // Check that string is NULL terminated.
+ assert_true(destination.size > destination.used);
+ assert_int_equal(destination.string[destination.used], 0);
+ }
+
+ // De-allocate each pass to ensure that the NULL termination check is accurate.
+ f_string_dynamic_resize(0, &destination);
+ } // for
+
+ f_string_dynamic_resize(0, &destination);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 0
+ *
+ * Project: Path
+ * API Version: 0.5
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the path project.
+ */
+#ifndef _TEST__F_path_directory_cleanup_h
+#define _TEST__F_path_directory_cleanup_h
+
+/**
+ * Test that parameter checking works as expected.
+ *
+ * @see f_path_directory_cleanup()
+ */
+#ifndef _di_level_0_parameter_checking_
+ extern void test__f_path_directory_cleanup__parameter_checking(void **state);
+#endif // _di_level_0_parameter_checking_
+
+/**
+ * Test that function works.
+ *
+ * @see f_path_directory_cleanup()
+ */
+extern void test__f_path_directory_cleanup__works(void **state);
+
+#endif // _TEST__F_path_directory_cleanup_h
--- /dev/null
+#include "test-path.h"
+#include "test-path-is.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_path_is__returns_false(void **state) {
+
+ const f_string_static_t paths[] = {
+ macro_f_string_static_t_initialize("'false", 0, 6),
+ macro_f_string_static_t_initialize("false'", 0, 6),
+ macro_f_string_static_t_initialize("f a l s e", 0, 9),
+ macro_f_string_static_t_initialize("0+-12, false", 0, 12),
+ };
+
+ for (uint8_t i = 0; i < 4; ++i) {
+
+ const f_status_t status = f_path_is(paths[i]);
+
+ assert_int_equal(F_status_set_fine(status), F_false);
+ } // for
+}
+
+void test__f_path_is__returns_data_not(void **state) {
+
+ {
+ const f_status_t status = f_path_is(f_string_empty_s);
+
+ assert_int_equal(F_status_set_fine(status), F_data_not);
+ }
+}
+
+void test__f_path_is__returns_true(void **state) {
+
+ const f_string_static_t paths[] = {
+ macro_f_string_static_t_initialize("'true/", 0, 6),
+ macro_f_string_static_t_initialize("/true'", 0, 6),
+ macro_f_string_static_t_initialize("t /r u e", 0, 8),
+ macro_f_string_static_t_initialize("0+-12,/ true", 0, 12),
+ };
+
+ for (uint8_t i = 0; i < 4; ++i) {
+
+ const f_status_t status = f_path_is(paths[i]);
+
+ assert_int_equal(F_status_set_fine(status), F_true);
+ } // for
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 0
+ *
+ * Project: Path
+ * API Version: 0.5
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the path project.
+ */
+#ifndef _TEST__F_path_is_h
+#define _TEST__F_path_is_h
+
+/**
+ * Test that function returns F_false.
+ *
+ * @see f_path_is()
+ */
+extern void test__f_path_is__returns_false(void **state);
+
+/**
+ * Test that function returns F_data_not.
+ *
+ * @see f_path_is()
+ */
+extern void test__f_path_is__returns_data_not(void **state);
+
+/**
+ * Test that function returns F_true.
+ *
+ * @see f_path_is()
+ */
+extern void test__f_path_is__returns_true(void **state);
+
+#endif // _TEST__F_path_is_h
--- /dev/null
+#include "test-path.h"
+#include "test-path-is_absolute.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_path_is_absolute__returns_false(void **state) {
+
+ const f_string_static_t paths[] = {
+ macro_f_string_static_t_initialize("'fa/lse", 0, 7),
+ macro_f_string_static_t_initialize("false'/", 0, 7),
+ macro_f_string_static_t_initialize("f a l s e", 0, 9),
+ macro_f_string_static_t_initialize("0+-12,/ false", 0, 13),
+ };
+
+ for (uint8_t i = 0; i < 4; ++i) {
+
+ const f_status_t status = f_path_is_absolute(paths[i]);
+
+ assert_int_equal(F_status_set_fine(status), F_false);
+ } // for
+}
+
+void test__f_path_is_absolute__returns_data_not(void **state) {
+
+ {
+ const f_status_t status = f_path_is_absolute(f_string_empty_s);
+
+ assert_int_equal(F_status_set_fine(status), F_data_not);
+ }
+}
+
+void test__f_path_is_absolute__returns_true(void **state) {
+
+ const f_string_static_t paths[] = {
+ macro_f_string_static_t_initialize("/'true/", 0, 7),
+ macro_f_string_static_t_initialize("/true'", 0, 6),
+ macro_f_string_static_t_initialize("/t /r u e", 0, 9),
+ macro_f_string_static_t_initialize("/0+-12,/ true", 0, 13),
+ };
+
+ for (uint8_t i = 0; i < 4; ++i) {
+
+ const f_status_t status = f_path_is_absolute(paths[i]);
+
+ assert_int_equal(F_status_set_fine(status), F_true);
+ } // for
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 0
+ *
+ * Project: Path
+ * API Version: 0.5
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the path project.
+ */
+#ifndef _TEST__F_path_is_absolute_h
+#define _TEST__F_path_is_absolute_h
+
+/**
+ * Test that function returns F_false.
+ *
+ * @see f_path_is_absolute()
+ */
+extern void test__f_path_is_absolute__returns_false(void **state);
+
+/**
+ * Test that function returns F_data_not.
+ *
+ * @see f_path_is_absolute()
+ */
+extern void test__f_path_is_absolute__returns_data_not(void **state);
+
+/**
+ * Test that function returns F_true.
+ *
+ * @see f_path_is_absolute()
+ */
+extern void test__f_path_is_absolute__returns_true(void **state);
+
+#endif // _TEST__F_path_is_absolute_h
--- /dev/null
+#include "test-path.h"
+#include "test-path-is_relative.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_path_is_relative__returns_false(void **state) {
+
+ const f_string_static_t paths[] = {
+ macro_f_string_static_t_initialize("/'false", 0, 7),
+ macro_f_string_static_t_initialize("/false'", 0, 7),
+ macro_f_string_static_t_initialize("/f a l s e", 0, 10),
+ macro_f_string_static_t_initialize("/0+-12, false", 0, 13),
+ };
+
+ for (uint8_t i = 0; i < 4; ++i) {
+
+ const f_status_t status = f_path_is_relative(paths[i]);
+
+ assert_int_equal(F_status_set_fine(status), F_false);
+ } // for
+}
+
+void test__f_path_is_relative__returns_data_not(void **state) {
+
+ {
+ const f_status_t status = f_path_is_relative(f_string_empty_s);
+
+ assert_int_equal(F_status_set_fine(status), F_data_not);
+ }
+}
+
+void test__f_path_is_relative__returns_true(void **state) {
+
+ const f_string_static_t paths[] = {
+ macro_f_string_static_t_initialize("'true/", 0, 6),
+ macro_f_string_static_t_initialize("./true'", 0, 7),
+ macro_f_string_static_t_initialize("t /r u e", 0, 8),
+ macro_f_string_static_t_initialize("0+-12,/ true", 0, 12),
+ };
+
+ for (uint8_t i = 0; i < 4; ++i) {
+
+ const f_status_t status = f_path_is_relative(paths[i]);
+
+ assert_int_equal(F_status_set_fine(status), F_true);
+ } // for
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 0
+ *
+ * Project: Path
+ * API Version: 0.5
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the path project.
+ */
+#ifndef _TEST__F_path_is_relative_h
+#define _TEST__F_path_is_relative_h
+
+/**
+ * Test that function returns F_false.
+ *
+ * @see f_path_is_relative()
+ */
+extern void test__f_path_is_relative__returns_false(void **state);
+
+/**
+ * Test that function returns F_data_not.
+ *
+ * @see f_path_is_relative()
+ */
+extern void test__f_path_is_relative__returns_data_not(void **state);
+
+/**
+ * Test that function returns F_true.
+ *
+ * @see f_path_is_relative()
+ */
+extern void test__f_path_is_relative__returns_true(void **state);
+
+#endif // _TEST__F_path_is_relative_h
--- /dev/null
+#include "test-path.h"
+#include "test-path-is_relative_current.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_path_is_relative_current__returns_false(void **state) {
+
+ const f_string_static_t paths[] = {
+ macro_f_string_static_t_initialize("'false", 0, 6),
+ macro_f_string_static_t_initialize("false'", 0, 6),
+ macro_f_string_static_t_initialize("f a l s e", 0, 9),
+ macro_f_string_static_t_initialize("0+-12, false", 0, 12),
+ };
+
+ for (uint8_t i = 0; i < 4; ++i) {
+
+ const f_status_t status = f_path_is_relative_current(paths[i]);
+
+ assert_int_equal(F_status_set_fine(status), F_false);
+ } // for
+}
+
+void test__f_path_is_relative_current__returns_data_not(void **state) {
+
+ {
+ const f_status_t status = f_path_is_relative_current(f_string_empty_s);
+
+ assert_int_equal(F_status_set_fine(status), F_data_not);
+ }
+}
+
+void test__f_path_is_relative_current__returns_true(void **state) {
+
+ const f_string_static_t paths[] = {
+ macro_f_string_static_t_initialize("./'true/", 0, 8),
+ macro_f_string_static_t_initialize("../true'", 0, 8),
+ macro_f_string_static_t_initialize("./../t /r u e", 0, 13),
+ macro_f_string_static_t_initialize("./0+-12,/ true", 0, 14),
+ };
+
+ for (uint8_t i = 0; i < 4; ++i) {
+
+ const f_status_t status = f_path_is_relative_current(paths[i]);
+
+ assert_int_equal(F_status_set_fine(status), F_true);
+ } // for
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 0
+ *
+ * Project: Path
+ * API Version: 0.5
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the path project.
+ */
+#ifndef _TEST__F_path_is_relative_current_h
+#define _TEST__F_path_is_relative_current_h
+
+/**
+ * Test that function returns F_false.
+ *
+ * @see f_path_is_relative_current()
+ */
+extern void test__f_path_is_relative_current__returns_false(void **state);
+
+/**
+ * Test that function returns F_data_not.
+ *
+ * @see f_path_is_relative_current()
+ */
+extern void test__f_path_is_relative_current__returns_data_not(void **state);
+
+/**
+ * Test that function returns F_true.
+ *
+ * @see f_path_is_relative_current()
+ */
+extern void test__f_path_is_relative_current__returns_true(void **state);
+
+#endif // _TEST__F_path_is_relative_current_h
--- /dev/null
+#include "test-path.h"
+#include "test-path-real.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_path_real__fails(void **state) {
+
+ const f_string_static_t path = macro_f_string_static_t_initialize("test", 0, 4);
+
+ f_string_dynamic_t destination = f_string_dynamic_t_initialize;
+
+ int errnos[] = {
+ EACCES,
+ EINVAL,
+ EIO,
+ ELOOP,
+ ENAMETOOLONG,
+ ENOENT,
+ ENOMEM,
+ ENOTDIR,
+ mock_errno_generic,
+ };
+
+ f_status_t statuss[] = {
+ F_access_denied,
+ F_parameter,
+ F_input_output,
+ F_loop,
+ F_name,
+ F_file_found_not,
+ F_memory_not,
+ F_directory,
+ F_failure,
+ };
+
+ for (int i = 0; i < 9; ++i, destination.used = 0) {
+
+ will_return(__wrap_realpath, true);
+ will_return(__wrap_realpath, errnos[i]);
+
+ const f_status_t status = f_path_real(path, &destination);
+
+ assert_int_equal(status, F_status_set_error(statuss[i]));
+ } // for
+
+ f_string_dynamic_resize(0, &destination);
+}
+
+#ifndef _di_level_0_parameter_checking_
+ void test__f_path_real__parameter_checking(void **state) {
+
+ const f_string_static_t path = macro_f_string_static_t_initialize("test", 0, 4);
+
+ {
+ const f_status_t status = f_path_real(path, 0);
+
+ assert_int_equal(F_status_set_fine(status), F_parameter);
+ }
+ }
+#endif // _di_level_0_parameter_checking_
+
+void test__f_path_real__works(void **state) {
+
+ const f_string_static_t path = macro_f_string_static_t_initialize("test", 0, 4);
+ const f_string_static_t path_real = macro_f_string_static_t_initialize("/test", 0, 5);
+
+ f_string_dynamic_t destination = f_string_dynamic_t_initialize;
+
+ {
+ will_return(__wrap_realpath, F_false);
+ will_return(__wrap_realpath, path_real.string);
+
+ const f_status_t status = f_path_real(path, &destination);
+
+ assert_int_equal(status, F_none);
+ assert_int_equal(destination.used, path_real.used);
+ assert_string_equal(destination.string, path_real.string);
+ }
+
+ f_string_dynamic_resize(0, &destination);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 0
+ *
+ * Project: Path
+ * API Version: 0.5
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the path project.
+ */
+#ifndef _TEST__F_path_real_h
+#define _TEST__F_path_real_h
+
+/**
+ * Test that function fails.
+ *
+ * @see f_path_real()
+ */
+extern void test__f_path_real__fails(void **state);
+
+/**
+ * Test that parameter checking works as expected.
+ *
+ * @see f_path_real()
+ */
+#ifndef _di_level_0_parameter_checking_
+ extern void test__f_path_real__parameter_checking(void **state);
+#endif // _di_level_0_parameter_checking_
+
+/**
+ * Test that function works.
+ *
+ * @see f_path_real()
+ */
+extern void test__f_path_real__works(void **state);
+
+#endif // _TEST__F_path_real_h
--- /dev/null
+#include "test-path.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__f_path_change__fails),
+ cmocka_unit_test(test__f_path_change__works),
+
+ cmocka_unit_test(test__f_path_change_at__fails),
+ cmocka_unit_test(test__f_path_change_at__works),
+
+ // test__f_path_directory_cleanup__fails test isn't needed yet as f_string_dynamic_increase_by() aren't tested at this time.
+ cmocka_unit_test(test__f_path_directory_cleanup__works),
+
+ cmocka_unit_test(test__f_path_is__returns_false),
+ cmocka_unit_test(test__f_path_is__returns_data_not),
+ cmocka_unit_test(test__f_path_is__returns_true),
+
+ cmocka_unit_test(test__f_path_is_absolute__returns_false),
+ cmocka_unit_test(test__f_path_is_absolute__returns_data_not),
+ cmocka_unit_test(test__f_path_is_absolute__returns_true),
+
+ cmocka_unit_test(test__f_path_is_relative__returns_false),
+ cmocka_unit_test(test__f_path_is_relative__returns_data_not),
+ cmocka_unit_test(test__f_path_is_relative__returns_true),
+
+ cmocka_unit_test(test__f_path_is_relative_current__returns_false),
+ cmocka_unit_test(test__f_path_is_relative_current__returns_data_not),
+ cmocka_unit_test(test__f_path_is_relative_current__returns_true),
+
+ cmocka_unit_test(test__f_path_real__fails),
+ cmocka_unit_test(test__f_path_real__works),
+
+ #ifndef _di_level_0_parameter_checking_
+ // f_path_change() doesn't use parameter checking.
+ // f_path_change_at() doesn't use parameter checking.
+ cmocka_unit_test(test__f_path_current__parameter_checking),
+ cmocka_unit_test(test__f_path_directory_cleanup__parameter_checking),
+ // f_path_is() doesn't use parameter checking.
+ // f_path_is_absolute() doesn't use parameter checking.
+ // f_path_is_relative() doesn't use parameter checking.
+ // f_path_is_relative_current() doesn't use parameter checking.
+ cmocka_unit_test(test__f_path_real__parameter_checking),
+ #endif // _di_level_0_parameter_checking_
+ };
+
+ return cmocka_run_group_tests(tests, setup, setdown);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 0
+ *
+ * Project: Path
+ * API Version: 0.5
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the path project.
+ */
+#ifndef _TEST__F_path_h
+#define _TEST__F_path_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/path.h>
+
+// Mock includes.
+#include "mock-path.h"
+
+// Test includes.
+#include "test-path-change.h"
+#include "test-path-change_at.h"
+#include "test-path-current.h"
+#include "test-path-directory_cleanup.h"
+#include "test-path-is.h"
+#include "test-path-is_absolute.h"
+#include "test-path-is_relative.h"
+#include "test-path-is_relative_current.h"
+#include "test-path-real.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__F_path_h