]> Kevux Git Server - fll/commitdiff
Feature: Add new function fl_directory_empty().
authorKevin Day <Kevin@kevux.org>
Fri, 17 Jan 2025 05:04:47 +0000 (23:04 -0600)
committerKevin Day <Kevin@kevux.org>
Sat, 18 Jan 2025 02:50:58 +0000 (20:50 -0600)
Simplify the process of determining if the directory is empty.
The entire list of directories do not need to be processed in this case.
Only check if the first child in the directory exists.

23 files changed:
level_0/f_directory/c/directory.c
level_0/f_directory/c/directory.h
level_0/f_directory/data/build/settings-mocks
level_0/f_directory/data/build/settings-tests
level_0/f_directory/tests/unit/c/mock-directory.c
level_0/f_directory/tests/unit/c/mock-directory.h
level_0/f_directory/tests/unit/c/test-directory-create.c
level_0/f_directory/tests/unit/c/test-directory-create_at.c
level_0/f_directory/tests/unit/c/test-directory-empty.c [new file with mode: 0644]
level_0/f_directory/tests/unit/c/test-directory-empty.h [new file with mode: 0644]
level_0/f_directory/tests/unit/c/test-directory-exists.c
level_0/f_directory/tests/unit/c/test-directory-exists_at.c
level_0/f_directory/tests/unit/c/test-directory-is.c
level_0/f_directory/tests/unit/c/test-directory-is_at.c
level_0/f_directory/tests/unit/c/test-directory-list.c
level_0/f_directory/tests/unit/c/test-directory-open.c
level_0/f_directory/tests/unit/c/test-directory-open_at.c
level_0/f_directory/tests/unit/c/test-directory-remove.c
level_0/f_directory/tests/unit/c/test-directory-remove_custom.c
level_0/f_directory/tests/unit/c/test-directory-touch.c
level_0/f_directory/tests/unit/c/test-directory-touch_at.c
level_0/f_directory/tests/unit/c/test-directory.c
level_0/f_directory/tests/unit/c/test-directory.h

index c996b24a001167b911ba49b3479136856332017d..87aa92cc7b03acc625c352e1ff234bfab9590165 100644 (file)
@@ -23,6 +23,63 @@ extern "C" {
   }
 #endif // _di_f_directory_create_at_
 
+#ifndef _di_f_directory_empty_
+  f_status_t f_directory_empty(const f_string_static_t path) {
+
+    if (!path.used) return F_data_not;
+
+    f_status_t status = F_true;
+
+    DIR *parent = opendir(path.string);
+
+    if (!parent) {
+      if (errno == ENOMEM) return F_status_set_error(F_memory_not);
+      if (errno == EMFILE) return F_status_set_error(F_file_descriptor_max);
+      if (errno == ENFILE) return F_status_set_error(F_file_open_max);
+      if (errno == ENOTDIR) return F_status_set_error(F_directory);
+      if (errno == ENOENT) return F_status_set_error(F_directory_found_not);
+      if (errno == EACCES) return F_status_set_error(F_access_denied);
+
+      return F_status_set_error(F_directory_open);
+    }
+
+    errno = 0;
+
+    // The '.' and '..' paths must not be counted, so check at most 3 dirents.
+    struct dirent * dir = readdir(parent);
+
+    if (dir) {
+      errno = 0;
+
+      if (!strncmp(f_directory_current_s.string, dir->d_name, f_directory_current_s.used + 1) || !strncmp(f_directory_back_s.string, dir->d_name, f_directory_back_s.used + 1)) {
+        dir = readdir(parent);
+
+        if (dir) {
+          errno = 0;
+
+          if (!strncmp(f_directory_current_s.string, dir->d_name, f_directory_current_s.used + 1) || !strncmp(f_directory_back_s.string, dir->d_name, f_directory_back_s.used + 1)) {
+            status = readdir(parent) ? F_false : F_true;
+          }
+          else {
+            status = F_false;
+          }
+        }
+      }
+      else {
+        status = F_false;
+      }
+    }
+
+    if (errno) {
+      status = errno == EBADF ? F_status_set_error(F_directory_descriptor) : F_status_set_error(F_directory_read);
+    }
+
+    closedir(parent);
+
+    return status;
+  }
+#endif // _di_f_directory_empty_
+
 #ifndef _di_f_directory_exists_
   f_status_t f_directory_exists(const f_string_static_t path) {
 
index a16f1546e5b401baa68358238380ca755c9e2b61..b1ea679638752202b30860a605e8a9f0003daed7 100644 (file)
@@ -116,6 +116,38 @@ extern "C" {
 #endif // _di_f_directory_create_at_
 
 /**
+ * For some given path, check to see if is a directory and if the directory is empty.
+ *
+ *
+ * @param path
+ *   Filesystem path to the directory.
+ *
+ * @return
+ *   F_okay on success.
+ *   F_data_not if source.used or destination.used is 0.
+ *
+ *   F_directory (with error bit) if the path is not a directory.
+ *   F_directory_descriptor (with error bit) for bad directory descriptor after opening the path.
+ *   F_directory_found_not (with error bit) if there is not file at the path.
+ *   F_directory_read (with error bit) if there is an error while reading the directory.
+ *   F_failure (with error bit) if failed to read directory information.
+ *   F_file_descriptor_max (with error bit) if max file descriptors is reached.
+ *   F_file_open_max (with error bit) too many open files.
+ *   F_memory_not (with error bit) on out of memory.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *
+ *   Errors (with error bit) from: f_file_stat_at().
+ *
+ * @see opendir()
+ * @see scandir()
+ *
+ * @see f_file_stat_at()
+ */
+#ifndef _di_f_directory_empty_
+  extern f_status_t f_directory_empty(const f_string_static_t path);
+#endif // _di_f_directory_empty_
+
+/**
  * Identify whether or not a file exists at the given path and if that file is a directory or a symlink to a directory.
  *
  * @param path
index 5ebb3d952571fb677a1235d5aad7158d1c12f2e2..e936bd41a724f26cb09e291fdc5fa827f3628e01 100644 (file)
@@ -71,12 +71,15 @@ flags -Wl,--wrap=f_memory_array_resize
 flags -Wl,--wrap=f_memory_arrays_adjust
 flags -Wl,--wrap=f_memory_arrays_resize
 flags -Wl,--wrap=alphasort
+flags -Wl,--wrap=closedir
 flags -Wl,--wrap=fstatat
 flags -Wl,--wrap=mkdir
 flags -Wl,--wrap=mkdirat
 flags -Wl,--wrap=nftw
 flags -Wl,--wrap=open
 flags -Wl,--wrap=openat
+flags -Wl,--wrap=opendir
+flags -Wl,--wrap=readdir
 flags -Wl,--wrap=remove
 flags -Wl,--wrap=scandir
 flags -Wl,--wrap=stat
index 9a63e9438b090c0f99fffd5c1344234ab9228bc6..4ac59c74022a415b200cd769e4428030d7b41df5 100644 (file)
@@ -25,7 +25,7 @@ build_language c
 build_libraries -lc -lcmocka
 build_libraries-individual -lf_memory -lf_string -lf_directory
 
-build_sources_program test-directory.c test-directory-create.c test-directory-create_at.c test-directory-exists.c test-directory-exists_at.c test-directory-is.c test-directory-is_at.c test-directory-list.c test-directory-open.c test-directory-open_at.c test-directory-remove.c test-directory-remove_custom.c test-directory-touch.c test-directory-touch_at.c
+build_sources_program test-directory.c test-directory-create.c test-directory-create_at.c test-directory-empty.c test-directory-exists.c test-directory-exists_at.c test-directory-is.c test-directory-is_at.c test-directory-list.c test-directory-open.c test-directory-open_at.c test-directory-remove.c test-directory-remove_custom.c test-directory-touch.c test-directory-touch_at.c
 build_sources_program test-directory-listings_destroy_callback.c test-directory-listings_delete_callback.c test-directory-listingss_destroy_callback.c test-directory-listingss_delete_callback.c
 build_sources_program test-directory-recurse_dos_destroy_callback.c test-directory-recurse_dos_delete_callback.c test-directory-recurse_doss_destroy_callback.c test-directory-recurse_doss_delete_callback.c
 build_sources_program test-directory-statuss_destroy_callback.c test-directory-statuss_delete_callback.c test-directory-statusss_destroy_callback.c test-directory-statusss_delete_callback.c
index 6c58d0b4a7b84ad982f2a0c976b7b0d870a75533..be1bde2843585107eb0b813d451f6365c92b7ad3 100644 (file)
@@ -77,6 +77,27 @@ f_status_t __wrap_f_memory_arrays_resize(const f_number_unsigned_t length, const
 
 int __wrap_alphasort(const struct dirent **a, const struct dirent **b) {
 
+  if (mock_unwrap) {
+    return __real_alphasort(a, b);
+  }
+
+  const bool failure = mock_type(bool);
+
+  if (failure) {
+    errno = mock_type(int);
+
+    return -1;
+  }
+
+  return mock_type(int);
+}
+
+int __wrap_closedir(DIR *dirp) {
+
+  if (mock_unwrap) {
+    return __real_closedir(dirp);
+  }
+
   const bool failure = mock_type(bool);
 
   if (failure) {
@@ -90,6 +111,10 @@ int __wrap_alphasort(const struct dirent **a, const struct dirent **b) {
 
 int __wrap_fstatat(int dirfd, const char *pathname, struct stat *statbuf, int flags) {
 
+  if (mock_unwrap) {
+    return __real_fstatat(dirfd, pathname, statbuf, flags);
+  }
+
   const bool failure = mock_type(bool);
 
   if (failure) {
@@ -119,6 +144,10 @@ int __wrap_fstatat(int dirfd, const char *pathname, struct stat *statbuf, int fl
 
 int __wrap_mkdir(const char *pathname, mode_t mode) {
 
+  if (mock_unwrap) {
+    return __real_mkdir(pathname, mode);
+  }
+
   const bool failure = mock_type(bool);
 
   if (failure) {
@@ -132,6 +161,10 @@ int __wrap_mkdir(const char *pathname, mode_t mode) {
 
 int __wrap_mkdirat(int dirfd, const char *pathname, mode_t mode) {
 
+  if (mock_unwrap) {
+    return __real_mkdirat(dirfd, pathname, mode);
+  }
+
   const bool failure = mock_type(bool);
 
   if (failure) {
@@ -145,6 +178,10 @@ int __wrap_mkdirat(int dirfd, const char *pathname, mode_t mode) {
 
 int __wrap_nftw(const char *dirpath, int (*fn) (const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf), int nopenfd, int flags) {
 
+  if (mock_unwrap) {
+    return __real_nftw(dirpath, fn, nopenfd, flags);
+  }
+
   const bool failure = mock_type(bool);
 
   if (failure) {
@@ -158,6 +195,10 @@ int __wrap_nftw(const char *dirpath, int (*fn) (const char *fpath, const struct
 
 int __wrap_open(const char *pathname, int flags) {
 
+  if (mock_unwrap) {
+    return __real_open(pathname, flags);
+  }
+
   const bool failure = mock_type(bool);
 
   if (failure) {
@@ -171,6 +212,10 @@ int __wrap_open(const char *pathname, int flags) {
 
 int __wrap_openat(int dirfd, const char *pathname, int flags) {
 
+  if (mock_unwrap) {
+    return __real_openat(dirfd, pathname, flags);
+  }
+
   const bool failure = mock_type(bool);
 
   if (failure) {
@@ -182,8 +227,46 @@ int __wrap_openat(int dirfd, const char *pathname, int flags) {
   return mock_type(int);
 }
 
+DIR *__wrap_opendir(const char *name) {
+
+  if (mock_unwrap) {
+    return __real_opendir(name);
+  }
+
+  const bool failure = mock_type(bool);
+
+  if (failure) {
+    errno = mock_type(int);
+
+    return 0;
+  }
+
+  return mock_type(DIR *);
+}
+
+struct dirent *__wrap_readdir(DIR *dirp) {
+
+  if (mock_unwrap) {
+    return __real_readdir(dirp);
+  }
+
+  const bool failure = mock_type(bool);
+
+  if (failure) {
+    errno = mock_type(int);
+
+    return 0;
+  }
+
+  return mock_type(struct dirent *);
+}
+
 int __wrap_remove(const char *pathname) {
 
+  if (mock_unwrap) {
+    return __real_remove(pathname);
+  }
+
   const bool failure = mock_type(bool);
 
   if (failure) {
@@ -197,6 +280,10 @@ int __wrap_remove(const char *pathname) {
 
 int __wrap_scandir(const char *dirp, struct dirent ***namelist, int (*filter)(const struct dirent *), int (*compar)(const struct dirent **, const struct dirent **)) {
 
+  if (mock_unwrap) {
+    return __real_scandir(dirp, namelist, filter, compar);
+  }
+
   const bool failure = mock_type(bool);
 
   if (failure) {
@@ -212,6 +299,10 @@ int __wrap_scandir(const char *dirp, struct dirent ***namelist, int (*filter)(co
 
 int __wrap_stat(const char *pathname, struct stat *statbuf) {
 
+  if (mock_unwrap) {
+    return __real_stat(pathname, statbuf);
+  }
+
   const bool failure = mock_type(bool);
 
   if (failure) {
@@ -241,6 +332,10 @@ int __wrap_stat(const char *pathname, struct stat *statbuf) {
 
 int __wrap_utimensat(int dirfd, const char *pathname, const struct timespec times[2], int flags) {
 
+  if (mock_unwrap) {
+    return __real_utimensat(dirfd, pathname, times, flags);
+  }
+
   const bool failure = mock_type(bool);
 
   if (failure) {
@@ -254,6 +349,10 @@ int __wrap_utimensat(int dirfd, const char *pathname, const struct timespec time
 
 int __wrap_versionsort(const struct dirent **a, const struct dirent **b) {
 
+  if (mock_unwrap) {
+    return __real_versionsort(a, b);
+  }
+
   const bool failure = mock_type(bool);
 
   if (failure) {
index e63aedb5b2378c6901828e31addd65e8068eefe3..72787e1f3907168ee6b5663a67710ece1e0a7616 100644 (file)
@@ -41,13 +41,32 @@ extern f_status_t __wrap_f_memory_array_resize(const f_number_unsigned_t length,
 extern f_status_t __wrap_f_memory_arrays_adjust(const f_number_unsigned_t length, const size_t width, void ** const array, f_number_unsigned_t * const used, f_number_unsigned_t * const size, f_status_t (*callback)(const f_number_unsigned_t start, const f_number_unsigned_t size, void * const array));
 extern f_status_t __wrap_f_memory_arrays_resize(const f_number_unsigned_t length, const size_t width, void ** const array, f_number_unsigned_t * const used, f_number_unsigned_t * const size, f_status_t (*callback)(const f_number_unsigned_t start, const f_number_unsigned_t size, void * const array));
 
+extern int __real_alphasort(const struct dirent **a, const struct dirent **b);
+extern int __real_closedir(DIR *dirp);
+extern int __real_fstatat(int dirfd, const char *pathname, struct stat *statbuf, int flags);
+extern int __real_mkdir(const char *pathname, mode_t mode);
+extern int __real_mkdirat(int dirfd, const char *pathname, mode_t mode);
+extern int __real_nftw(const char *dirpath, int (*fn) (const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf), int nopenfd, int flags);
+extern int __real_open(const char *pathname, int flags);
+extern int __real_openat(int dirfd, const char *pathname, int flags);
+extern DIR *__real_opendir(const char *name);
+extern struct dirent *__real_readdir(DIR *dirp);
+extern int __real_remove(const char *pathname);
+extern int __real_scandir(const char *dirp, struct dirent ***namelist, int (*filter)(const struct dirent *), int (*compar)(const struct dirent **, const struct dirent **));
+extern int __real_stat(const char *pathname, struct stat *statbuf);
+extern int __real_utimensat(int dirfd, const char *pathname, const struct timespec times[2], int flags);
+extern int __real_versionsort(const struct dirent **a, const struct dirent **b);
+
 extern int __wrap_alphasort(const struct dirent **a, const struct dirent **b);
+extern int __wrap_closedir(DIR *dirp);
 extern int __wrap_fstatat(int dirfd, const char *pathname, struct stat *statbuf, int flags);
 extern int __wrap_mkdir(const char *pathname, mode_t mode);
 extern int __wrap_mkdirat(int dirfd, const char *pathname, mode_t mode);
 extern int __wrap_nftw(const char *dirpath, int (*fn) (const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf), int nopenfd, int flags);
 extern int __wrap_open(const char *pathname, int flags);
 extern int __wrap_openat(int dirfd, const char *pathname, int flags);
+extern DIR *__wrap_opendir(const char *name);
+extern struct dirent *__wrap_readdir(DIR *dirp);
 extern int __wrap_remove(const char *pathname);
 extern int __wrap_scandir(const char *dirp, struct dirent ***namelist, int (*filter)(const struct dirent *), int (*compar)(const struct dirent **, const struct dirent **));
 extern int __wrap_stat(const char *pathname, struct stat *statbuf);
index c2a37ffb992cfd531d8725a7264b8c95efc39e32..4e82e35dbf4daedba948788761a5c521adda9306 100644 (file)
@@ -7,6 +7,9 @@ extern "C" {
 
 void test__f_directory_create__fails(void **state) {
 
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
   const f_string_static_t path = macro_f_string_static_t_initialize_1("test", 0, 4);
 
   int errnos[] = {
@@ -58,6 +61,9 @@ void test__f_directory_create__fails(void **state) {
 
 void test__f_directory_create__returns_data_not(void **state) {
 
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
   {
     const f_status_t status = f_directory_create(f_string_empty_s, 0);
 
@@ -67,6 +73,9 @@ void test__f_directory_create__returns_data_not(void **state) {
 
 void test__f_directory_create__works(void **state) {
 
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
   const f_string_static_t path = macro_f_string_static_t_initialize_1("test", 0, 4);
 
   {
index b3a49d42edba7921f40d263bb665088a1f572c2f..099a989c7155d61110971f5930926e188f509697 100644 (file)
@@ -7,6 +7,9 @@ extern "C" {
 
 void test__f_directory_create_at__fails(void **state) {
 
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
   const f_string_static_t path = macro_f_string_static_t_initialize_1("test", 0, 4);
 
   int errnos[] = {
@@ -60,6 +63,9 @@ void test__f_directory_create_at__fails(void **state) {
 
 void test__f_directory_create_at__returns_data_not(void **state) {
 
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
   {
     const f_status_t status = f_directory_create_at(0, f_string_empty_s, 0);
 
@@ -69,6 +75,9 @@ void test__f_directory_create_at__returns_data_not(void **state) {
 
 void test__f_directory_create_at__works(void **state) {
 
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
   const f_string_static_t path = macro_f_string_static_t_initialize_1("test", 0, 4);
 
   {
diff --git a/level_0/f_directory/tests/unit/c/test-directory-empty.c b/level_0/f_directory/tests/unit/c/test-directory-empty.c
new file mode 100644 (file)
index 0000000..01a7cbf
--- /dev/null
@@ -0,0 +1,237 @@
+#include "test-directory.h"
+#include "test-directory-empty.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_directory_empty__fails(void **state) {
+
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
+  {
+    int errnos[] = {
+      EACCES,
+      EMFILE,
+      ENFILE,
+      ENOTDIR,
+      ENOENT,
+      ENOMEM,
+      mock_errno_generic,
+    };
+
+    f_status_t statuss[] = {
+      F_status_set_error(F_access_denied),
+      F_status_set_error(F_file_descriptor_max),
+      F_status_set_error(F_file_open_max),
+      F_status_set_error(F_directory),
+      F_status_set_error(F_directory_found_not),
+      F_status_set_error(F_memory_not),
+      F_status_set_error(F_directory_open),
+    };
+
+    for (int i = 0; i < 7; ++i) {
+
+      will_return(__wrap_opendir, true);
+      will_return(__wrap_opendir, errnos[i]);
+
+      const f_status_t status = f_directory_empty(f_directory_current_s);
+
+      assert_int_equal(status, statuss[i]);
+    } // for
+  }
+
+  mock_unwrap = 1;
+  DIR *directory = opendir(f_directory_current_s.string);
+  mock_unwrap = 0;
+
+  int errnos[] = {
+    EBADF,
+    mock_errno_generic,
+  };
+
+  f_status_t statuss[] = {
+    F_status_set_error(F_directory_descriptor),
+    F_status_set_error(F_directory_read),
+  };
+
+  for (int i = 0; i < 2; ++i) {
+
+    will_return(__wrap_opendir, false);
+    will_return(__wrap_opendir, directory);
+    will_return(__wrap_readdir, true);
+    will_return(__wrap_readdir, errnos[i]);
+    will_return(__wrap_closedir, false);
+    will_return(__wrap_closedir, 0);
+
+    const f_status_t status = f_directory_empty(f_directory_current_s);
+
+    assert_int_equal(status, statuss[i]);
+  } // for
+
+  mock_unwrap = 1;
+  closedir(directory);
+}
+
+void test__f_directory_empty__returns_data_not(void **state) {
+
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
+  {
+    const f_status_t status = f_directory_empty(f_string_empty_s);
+
+    assert_int_equal(status, F_data_not);
+  }
+}
+
+void test__f_directory_empty__returns_false(void **state) {
+
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
+  const f_string_static_t path_other = macro_f_string_static_t_initialize_1("other", 0, 5);
+
+  // The "DIR" structure cannot be easily instantiated so just use a real call to PWD.
+  mock_unwrap = 1;
+  DIR *directory = opendir(f_directory_current_s.string);
+  mock_unwrap = 0;
+
+  struct dirent entity_1;
+  struct dirent entity_2;
+  struct dirent entity_3;
+
+  memset(&entity_1, 0, sizeof(struct dirent));
+  memset(&entity_2, 0, sizeof(struct dirent));
+  memset(&entity_3, 0, sizeof(struct dirent));
+
+  memcpy(entity_1.d_name, path_other.string, path_other.used + 1);
+
+  {
+    will_return(__wrap_opendir, false);
+    will_return(__wrap_opendir, directory);
+    will_return(__wrap_readdir, false);
+    will_return(__wrap_readdir, &entity_1);
+    will_return(__wrap_closedir, false);
+    will_return(__wrap_closedir, 0);
+
+    const f_status_t status = f_directory_empty(f_directory_current_s);
+
+    assert_int_equal(status, F_false);
+  }
+
+  memcpy(entity_1.d_name, f_directory_current_s.string, f_directory_current_s.used + 1);
+  memcpy(entity_2.d_name, path_other.string, path_other.used + 1);
+
+  {
+    will_return(__wrap_opendir, false);
+    will_return(__wrap_opendir, directory);
+    will_return(__wrap_readdir, false);
+    will_return(__wrap_readdir, &entity_1);
+    will_return(__wrap_readdir, false);
+    will_return(__wrap_readdir, &entity_2);
+    will_return(__wrap_closedir, false);
+    will_return(__wrap_closedir, 0);
+
+    const f_status_t status = f_directory_empty(f_directory_current_s);
+
+    assert_int_equal(status, F_false);
+  }
+
+  memcpy(entity_1.d_name, f_directory_current_s.string, f_directory_current_s.used + 1);
+  memcpy(entity_2.d_name, f_directory_back_s.string, f_directory_back_s.used + 1);
+  memcpy(entity_3.d_name, path_other.string, path_other.used + 1);
+
+  {
+    will_return(__wrap_opendir, false);
+    will_return(__wrap_opendir, directory);
+    will_return(__wrap_readdir, false);
+    will_return(__wrap_readdir, &entity_1);
+    will_return(__wrap_readdir, false);
+    will_return(__wrap_readdir, &entity_2);
+    will_return(__wrap_readdir, false);
+    will_return(__wrap_readdir, &entity_3);
+    will_return(__wrap_closedir, false);
+    will_return(__wrap_closedir, 0);
+
+    const f_status_t status = f_directory_empty(f_directory_current_s);
+
+    assert_int_equal(status, F_false);
+  }
+
+  mock_unwrap = 1;
+  closedir(directory);
+}
+
+void test__f_directory_empty__returns_true(void **state) {
+
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
+  // The "DIR" structure cannot be easily instantiated so just use a real call to PWD.
+  mock_unwrap = 1;
+  DIR *directory = opendir(f_directory_current_s.string);
+  mock_unwrap = 0;
+
+  struct dirent entity_1;
+  struct dirent entity_2;
+
+  memset(&entity_1, 0, sizeof(struct dirent));
+  memset(&entity_2, 0, sizeof(struct dirent));
+
+  memcpy(entity_1.d_name, f_directory_current_s.string, f_directory_current_s.used + 1);
+  memcpy(entity_2.d_name, f_directory_back_s.string, f_directory_back_s.used + 1);
+
+  {
+    will_return(__wrap_opendir, false);
+    will_return(__wrap_opendir, directory);
+    will_return(__wrap_readdir, false);
+    will_return(__wrap_readdir, 0);
+    will_return(__wrap_closedir, false);
+    will_return(__wrap_closedir, 0);
+
+    const f_status_t status = f_directory_empty(f_directory_current_s);
+
+    assert_int_equal(status, F_true);
+  }
+
+  {
+    will_return(__wrap_opendir, false);
+    will_return(__wrap_opendir, directory);
+    will_return(__wrap_readdir, false);
+    will_return(__wrap_readdir, &entity_1);
+    will_return(__wrap_readdir, false);
+    will_return(__wrap_readdir, 0);
+    will_return(__wrap_closedir, false);
+    will_return(__wrap_closedir, 0);
+
+    const f_status_t status = f_directory_empty(f_directory_current_s);
+
+    assert_int_equal(status, F_true);
+  }
+
+  {
+    will_return(__wrap_opendir, false);
+    will_return(__wrap_opendir, directory);
+    will_return(__wrap_readdir, false);
+    will_return(__wrap_readdir, &entity_1);
+    will_return(__wrap_readdir, false);
+    will_return(__wrap_readdir, &entity_2);
+    will_return(__wrap_readdir, false);
+    will_return(__wrap_readdir, 0);
+    will_return(__wrap_closedir, false);
+    will_return(__wrap_closedir, 0);
+
+    const f_status_t status = f_directory_empty(f_directory_current_s);
+
+    assert_int_equal(status, F_true);
+  }
+
+  mock_unwrap = 1;
+  closedir(directory);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_directory/tests/unit/c/test-directory-empty.h b/level_0/f_directory/tests/unit/c/test-directory-empty.h
new file mode 100644 (file)
index 0000000..51bfc60
--- /dev/null
@@ -0,0 +1,41 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Directory
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the directory project.
+ */
+#ifndef _TEST__F_directory_empty_h
+#define _TEST__F_directory_empty_h
+
+/**
+ * Test that function fails.
+ *
+ * @see f_directory_empty()
+ */
+extern void test__f_directory_empty__fails(void **state);
+
+/**
+ * Test that function works but the path is empty.
+ *
+ * @see f_directory_empty()
+ */
+extern void test__f_directory_empty__returns_data_not(void **state);
+
+/**
+ * Test that function works and returns F_false.
+ *
+ * @see f_directory_empty()
+ */
+extern void test__f_directory_empty__returns_false(void **state);
+
+/**
+ * Test that function works and returns F_true.
+ *
+ * @see f_directory_empty()
+ */
+extern void test__f_directory_empty__returns_true(void **state);
+
+#endif // _TEST__F_directory_empty_h
index a5e2803a698424856f4435edf948942b5b2677fd..e4a2ae5264aaa19132a19da533846747a69fb9e3 100644 (file)
@@ -7,6 +7,9 @@ extern "C" {
 
 void test__f_directory_exists__fails(void **state) {
 
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
   const f_string_static_t path = macro_f_string_static_t_initialize_1("test", 0, 4);
 
   int errnos[] = {
@@ -46,6 +49,9 @@ void test__f_directory_exists__fails(void **state) {
 
 void test__f_directory_exists__returns_data_not(void **state) {
 
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
   {
     const f_status_t status = f_directory_exists(f_string_empty_s);
 
@@ -55,6 +61,9 @@ void test__f_directory_exists__returns_data_not(void **state) {
 
 void test__f_directory_exists__returns_false(void **state) {
 
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
   const f_string_static_t path = macro_f_string_static_t_initialize_1("test", 0, 4);
 
   struct stat statistics;
@@ -74,6 +83,9 @@ void test__f_directory_exists__returns_false(void **state) {
 
 void test__f_directory_exists__returns_true(void **state) {
 
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
   const f_string_static_t path = macro_f_string_static_t_initialize_1("test", 0, 4);
 
   struct stat statistics;
index 26329f9399dd16a3c083a51096b86dead81d8d38..96bf75eab027d0a4634652189f2e22c5d2db2457 100644 (file)
@@ -7,6 +7,9 @@ extern "C" {
 
 void test__f_directory_exists_at__fails(void **state) {
 
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
   const f_string_static_t path = macro_f_string_static_t_initialize_1("test", 0, 4);
 
   int errnos[] = {
@@ -48,6 +51,9 @@ void test__f_directory_exists_at__fails(void **state) {
 
 void test__f_directory_exists_at__returns_data_not(void **state) {
 
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
   {
     const f_status_t status = f_directory_exists_at(0, f_string_empty_s, 0);
 
@@ -57,6 +63,9 @@ void test__f_directory_exists_at__returns_data_not(void **state) {
 
 void test__f_directory_exists_at__returns_false(void **state) {
 
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
   const f_string_static_t path = macro_f_string_static_t_initialize_1("test", 0, 4);
 
   struct stat statistics;
@@ -76,6 +85,9 @@ void test__f_directory_exists_at__returns_false(void **state) {
 
 void test__f_directory_exists_at__returns_true(void **state) {
 
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
   const f_string_static_t path = macro_f_string_static_t_initialize_1("test", 0, 4);
 
   struct stat statistics;
index 25efda81794e473723c01a41e43634c05b4c7554..55c1c43d6ff60a4baf9b5f78865d456f98412818 100644 (file)
@@ -7,6 +7,9 @@ extern "C" {
 
 void test__f_directory_is__fails(void **state) {
 
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
   const f_string_static_t path = macro_f_string_static_t_initialize_1("test", 0, 4);
 
   int errnos[] = {
@@ -46,6 +49,9 @@ void test__f_directory_is__fails(void **state) {
 
 void test__f_directory_is__returns_data_not(void **state) {
 
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
   {
     const f_status_t status = f_directory_is(f_string_empty_s);
 
@@ -55,6 +61,9 @@ void test__f_directory_is__returns_data_not(void **state) {
 
 void test__f_directory_is__returns_false(void **state) {
 
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
   const f_string_static_t path = macro_f_string_static_t_initialize_1("test", 0, 4);
 
   struct stat statistics;
@@ -74,6 +83,9 @@ void test__f_directory_is__returns_false(void **state) {
 
 void test__f_directory_is__returns_true(void **state) {
 
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
   const f_string_static_t path = macro_f_string_static_t_initialize_1("test", 0, 4);
 
   struct stat statistics;
index 3720d63907e7f7df842d755f20007f73c1cbc805..07ca5f9d80563c7236ffa9daef9ab627e0dfaae1 100644 (file)
@@ -7,6 +7,9 @@ extern "C" {
 
 void test__f_directory_is_at__fails(void **state) {
 
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
   const f_string_static_t path = macro_f_string_static_t_initialize_1("test", 0, 4);
 
   int errnos[] = {
@@ -48,6 +51,9 @@ void test__f_directory_is_at__fails(void **state) {
 
 void test__f_directory_is_at__returns_data_not(void **state) {
 
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
   {
     const f_status_t status = f_directory_is_at(0, f_string_empty_s, 0);
 
@@ -57,6 +63,9 @@ void test__f_directory_is_at__returns_data_not(void **state) {
 
 void test__f_directory_is_at__returns_false(void **state) {
 
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
   const f_string_static_t path = macro_f_string_static_t_initialize_1("test", 0, 4);
 
   struct stat statistics;
@@ -76,6 +85,9 @@ void test__f_directory_is_at__returns_false(void **state) {
 
 void test__f_directory_is_at__returns_true(void **state) {
 
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
   const f_string_static_t path = macro_f_string_static_t_initialize_1("test", 0, 4);
 
   struct stat statistics;
index 379747e5d466d9b37c57a5f6cca3ecca7f9623d2..12f68177708e7e21e7cd9a8608e0fc9275a20498 100644 (file)
@@ -7,6 +7,9 @@ extern "C" {
 
 void test__f_directory_list__fails(void **state) {
 
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
   const f_string_static_t path = macro_f_string_static_t_initialize_1("test", 0, 4);
 
   f_string_dynamics_t names = f_string_dynamics_t_initialize;
@@ -39,6 +42,9 @@ void test__f_directory_list__fails(void **state) {
 
 void test__f_directory_list__parameter_checking(void **state) {
 
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
   const f_string_static_t path = macro_f_string_static_t_initialize_1("test", 0, 4);
 
   {
@@ -50,6 +56,9 @@ void test__f_directory_list__parameter_checking(void **state) {
 
 void test__f_directory_list__returns_data_not(void **state) {
 
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
   f_string_dynamics_t names = f_string_dynamics_t_initialize;
 
   {
@@ -63,6 +72,9 @@ void test__f_directory_list__returns_data_not(void **state) {
 
 void test__f_directory_list__returns_directory_empty(void **state) {
 
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
   f_string_dynamics_t names = f_string_dynamics_t_initialize;
   const f_string_static_t path = macro_f_string_static_t_initialize_1("test", 0, 4);
 
@@ -86,6 +98,9 @@ void test__f_directory_list__returns_directory_empty(void **state) {
 
 void test__f_directory_list__works(void **state) {
 
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
   f_string_dynamics_t names = f_string_dynamics_t_initialize;
   const f_string_static_t path = macro_f_string_static_t_initialize_1("test", 0, 4);
 
index e81a6c66326dd521b4c7a926826e5f6f87e01323..df80165d42c34d27f94c53c314daf6d671d41441 100644 (file)
@@ -7,6 +7,9 @@ extern "C" {
 
 void test__f_directory_open__fails(void **state) {
 
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
   const f_string_static_t path = macro_f_string_static_t_initialize_1("test", 0, 4);
 
   int errnos[] = {
@@ -62,6 +65,9 @@ void test__f_directory_open__fails(void **state) {
 
 void test__f_directory_open__parameter_checking(void **state) {
 
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
   const f_string_static_t path = macro_f_string_static_t_initialize_1("test", 0, 4);
 
   {
@@ -73,6 +79,9 @@ void test__f_directory_open__parameter_checking(void **state) {
 
 void test__f_directory_open__returns_data_not(void **state) {
 
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
   {
     int id = 0;
 
@@ -84,6 +93,9 @@ void test__f_directory_open__returns_data_not(void **state) {
 
 void test__f_directory_open__works(void **state) {
 
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
   const f_string_static_t path = macro_f_string_static_t_initialize_1("test", 0, 4);
 
   {
index ed361927722f4f3bc47c42a4387e980eed4221be..7b38ed417051daafbbe5a32074bc8cce4860751e 100644 (file)
@@ -7,6 +7,9 @@ extern "C" {
 
 void test__f_directory_open_at__fails(void **state) {
 
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
   const int at = 1;
   const f_string_static_t path = macro_f_string_static_t_initialize_1("test", 0, 4);
 
@@ -65,6 +68,9 @@ void test__f_directory_open_at__fails(void **state) {
 
 void test__f_directory_open_at__parameter_checking(void **state) {
 
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
   const f_string_static_t path = macro_f_string_static_t_initialize_1("test", 0, 4);
 
   {
@@ -76,6 +82,9 @@ void test__f_directory_open_at__parameter_checking(void **state) {
 
 void test__f_directory_open_at__returns_data_not(void **state) {
 
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
   const int at = 1;
 
   {
@@ -89,6 +98,9 @@ void test__f_directory_open_at__returns_data_not(void **state) {
 
 void test__f_directory_open_at__works(void **state) {
 
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
   const int at = 1;
 
   const f_string_static_t path = macro_f_string_static_t_initialize_1("test", 0, 4);
index e919daca0b04a2a42abf4e062f984eceaf3e6f6b..1098475a0e58546bdcca627d7c87ce45e8745ab0 100644 (file)
@@ -7,6 +7,9 @@ extern "C" {
 
 void test__f_directory_remove__fails(void **state) {
 
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
   const f_string_static_t path = macro_f_string_static_t_initialize_1("test", 0, 4);
 
   int errnos[] = {
@@ -90,6 +93,9 @@ void test__f_directory_remove__fails(void **state) {
 
 void test__f_directory_remove__parameter_checking(void **state) {
 
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
   const f_string_static_t path = macro_f_string_static_t_initialize_1("test", 0, 4);
 
   {
@@ -101,6 +107,9 @@ void test__f_directory_remove__parameter_checking(void **state) {
 
 void test__f_directory_remove__returns_data_not(void **state) {
 
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
   {
     const f_status_t status = f_directory_remove(f_string_empty_s, 0, F_false);
 
@@ -110,6 +119,9 @@ void test__f_directory_remove__returns_data_not(void **state) {
 
 void test__f_directory_remove__works(void **state) {
 
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
   const f_string_static_t path = macro_f_string_static_t_initialize_1("test", 0, 4);
 
   {
index 3a4a54040da257f945d8faba22ff9d750fb65f07..de6724a629f8a6535cd1bbb20f7c6ce9a24efe0a 100644 (file)
@@ -7,6 +7,9 @@ extern "C" {
 
 void test__f_directory_remove_custom__fails(void **state) {
 
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
   const f_string_static_t path = macro_f_string_static_t_initialize_1("test", 0, 4);
 
   int errnos[] = {
@@ -90,6 +93,9 @@ void test__f_directory_remove_custom__fails(void **state) {
 
 void test__f_directory_remove_custom__parameter_checking(void **state) {
 
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
   const f_string_static_t path = macro_f_string_static_t_initialize_1("test", 0, 4);
 
   {
@@ -101,6 +107,9 @@ void test__f_directory_remove_custom__parameter_checking(void **state) {
 
 void test__f_directory_remove_custom__returns_data_not(void **state) {
 
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
   {
     const f_status_t status = f_directory_remove_custom(f_string_empty_s, 0, F_false, 0);
 
@@ -110,6 +119,9 @@ void test__f_directory_remove_custom__returns_data_not(void **state) {
 
 void test__f_directory_remove_custom__works(void **state) {
 
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
   const f_string_static_t path = macro_f_string_static_t_initialize_1("test", 0, 4);
 
   {
index 99bfd5255543af029dcee3d5733c4ad8df9beb06..58900a18ea70f1b8563bc3c407d0e352362cfe26 100644 (file)
@@ -7,6 +7,9 @@ extern "C" {
 
 void test__f_directory_touch__fails(void **state) {
 
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
   const f_string_static_t path = macro_f_string_static_t_initialize_1("test", 0, 4);
 
   {
@@ -147,6 +150,9 @@ void test__f_directory_touch__fails(void **state) {
 
 void test__f_directory_touch__returns_data_not(void **state) {
 
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
   {
     const f_status_t status = f_directory_touch(f_string_empty_s, 0);
 
@@ -156,6 +162,9 @@ void test__f_directory_touch__returns_data_not(void **state) {
 
 void test__f_directory_touch__works(void **state) {
 
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
   const f_string_static_t path = macro_f_string_static_t_initialize_1("test", 0, 4);
 
   {
index 4c9164ddbed4ce7f85cd05057d99e682d4076484..561e7ec33bcc2f0bc759bb95d82db94ddfc1bc50 100644 (file)
@@ -7,6 +7,9 @@ extern "C" {
 
 void test__f_directory_touch_at__fails(void **state) {
 
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
   const f_string_static_t path = macro_f_string_static_t_initialize_1("test", 0, 4);
 
   {
@@ -147,6 +150,9 @@ void test__f_directory_touch_at__fails(void **state) {
 
 void test__f_directory_touch_at__returns_data_not(void **state) {
 
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
   {
     const f_status_t status = f_directory_touch_at(1, f_string_empty_s, 0, 0);
 
@@ -156,6 +162,9 @@ void test__f_directory_touch_at__returns_data_not(void **state) {
 
 void test__f_directory_touch_at__works(void **state) {
 
+  mock_unwrap = 0;
+  mock_unwrap_f_memory = 1;
+
   const f_string_static_t path = macro_f_string_static_t_initialize_1("test", 0, 4);
 
   {
index 1a06c741a7b838b6b37e6efeee9e771365908d0d..ca0d8b7c68c31b3e67de53904ed469242dbf4fb9 100644 (file)
@@ -27,6 +27,11 @@ int main(void) {
     cmocka_unit_test(test__f_directory_create_at__returns_data_not),
     cmocka_unit_test(test__f_directory_create_at__works),
 
+    cmocka_unit_test(test__f_directory_empty__fails),
+    cmocka_unit_test(test__f_directory_empty__returns_data_not),
+    cmocka_unit_test(test__f_directory_empty__returns_false),
+    cmocka_unit_test(test__f_directory_empty__returns_true),
+
     cmocka_unit_test(test__f_directory_exists__fails),
     cmocka_unit_test(test__f_directory_exists__returns_data_not),
     cmocka_unit_test(test__f_directory_exists__returns_false),
index fef2ff474265bf19809edde1747c64700e1c5c98..c433dba4af8a468e4c6640afbc2e5d4050eeafb0 100644 (file)
@@ -28,6 +28,7 @@
 // Test includes.
 #include "test-directory-create.h"
 #include "test-directory-create_at.h"
+#include "test-directory-empty.h"
 #include "test-directory-exists.h"
 #include "test-directory-exists_at.h"
 #include "test-directory-is.h"