aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt6
-rw-r--r--tests/CMakeLists.txt22
-rw-r--r--tests/framework.h19
-rw-r--r--tests/test_errors.c11
-rw-r--r--tests/test_modes_filter_all.c89
-rw-r--r--tests/test_modes_filter_general.c86
6 files changed, 232 insertions, 1 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 096a49e..71de6df 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -7,6 +7,10 @@ set(LIB_SOURCES lib/cleanpath.c)
set(MAIN_SOURCES src/main.c)
set(INCLUDES include/cleanpath.h)
+include (CTest)
+enable_testing()
+add_subdirectory(tests)
+
add_library(cleanpath_static STATIC ${LIB_SOURCES})
set_target_properties(cleanpath_static PROPERTIES PUBLIC_HEADER ${INCLUDES})
set_target_properties(cleanpath_static PROPERTIES OUTPUT_NAME cleanpath)
@@ -30,4 +34,4 @@ install(TARGETS cleanpath
RUNTIME DESTINATION bin)
install(FILES ${CMAKE_SOURCE_DIR}/docs/man/cleanpath.1
- DESTINATION share/man/man1 COMPONENT doc) \ No newline at end of file
+ DESTINATION share/man/man1 COMPONENT doc)
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
new file mode 100644
index 0000000..4f23ecf
--- /dev/null
+++ b/tests/CMakeLists.txt
@@ -0,0 +1,22 @@
+include_directories(
+ ${CMAKE_SOURCE_DIR}/include
+ ${CMAKE_BINARY_DIR}/include
+)
+set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/tests)
+set(CTEST_BINARY_DIRECTORY ${PROJECT_BINARY_DIR}/tests)
+set(PROJECT_LIBS cleanpath_static)
+
+file(GLOB files "test_*.c")
+
+foreach(file ${files})
+ string(REGEX REPLACE "(^.*/|\\.[^.]*$)" "" file_without_ext ${file})
+ add_executable(${file_without_ext} ${file})
+ if(NOT(MSVC))
+ target_compile_options(${file_without_ext} PRIVATE -Wno-unused-parameter)
+ endif()
+ target_link_libraries(${file_without_ext} ${PROJECT_LIBS})
+ add_test(${file_without_ext} ${file_without_ext})
+ set_tests_properties(${file_without_ext}
+ PROPERTIES
+ TIMEOUT 120)
+endforeach()
diff --git a/tests/framework.h b/tests/framework.h
new file mode 100644
index 0000000..96ae3de
--- /dev/null
+++ b/tests/framework.h
@@ -0,0 +1,19 @@
+#ifndef CLEAN_PATH_FRAMEWORK_H
+#define CLEAN_PATH_FRAMEWORK_H
+
+#include <stdio.h>
+
+#define TEST_SEP ":"
+#define TEST_PATH "/opt/local/bin:/opt/local/sbin:/usr/local/bin:" \
+ "/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/Library/Apple/usr/bin"
+
+#define myassert(condition, ...) \
+ do { \
+ if (!(condition)) { \
+ fprintf(stderr, "%s:%d:%s :: ", __FILE__, __LINE__, __FUNCTION__); \
+ fprintf(stderr, __VA_ARGS__); \
+ return 1; \
+ } \
+ } while (0)
+
+#endif //CLEAN_PATH_FRAMEWORK_H
diff --git a/tests/test_errors.c b/tests/test_errors.c
new file mode 100644
index 0000000..f9d641f
--- /dev/null
+++ b/tests/test_errors.c
@@ -0,0 +1,11 @@
+#include "cleanpath.h"
+#include "framework.h"
+
+int main() {
+ struct CleanPath *path;
+ path = NULL;
+
+ //intentionally bad
+ myassert(cleanpath_init("good", NULL) == NULL, "cleanpath_init() returned non-NULL on NULL sep\n");
+ myassert(cleanpath_init(NULL, "good") == NULL, "cleanpath_init() returned non-NULL on NULL path\n");
+} \ No newline at end of file
diff --git a/tests/test_modes_filter_all.c b/tests/test_modes_filter_all.c
new file mode 100644
index 0000000..4f41dce
--- /dev/null
+++ b/tests/test_modes_filter_all.c
@@ -0,0 +1,89 @@
+#include <stdio.h>
+#include "cleanpath.h"
+#include "framework.h"
+
+#define MAX_MODE 3
+#define MAX_PART CLEANPATH_PART_MAX
+#define MAX_RECORD 255
+
+unsigned modes[MAX_MODE] = {
+ CLEANPATH_FILTER_EXACT,
+ CLEANPATH_FILTER_LOOSE,
+ CLEANPATH_FILTER_REGEX,
+};
+
+char *modes_str[MAX_MODE] = {
+ "exact",
+ "loose",
+ "regex",
+};
+
+const char *inputs[MAX_MODE][MAX_PART][MAX_RECORD] = {
+ { // Filter exact
+ "/opt/local/bin",
+ "/opt/local/sbin",
+ "/usr/local/bin",
+ "/usr/bin",
+ "/bin",
+ "/usr/sbin",
+ "/sbin",
+ "/opt/X11/bin",
+ "/Library/Apple/usr/bin",
+ NULL
+ },
+ { // Filter loose
+ "bin",
+ NULL
+ },
+ { // Filter regex
+ ".*",
+ NULL
+ },
+};
+
+struct TestResult {
+ size_t status;
+ size_t mode;
+ char *output;
+ char input[1024];
+ char sep[25];
+};
+
+int main() {
+ int status;
+ struct TestResult tr[MAX_MODE];
+
+ status = 0;
+ for (size_t mode = 0; mode < MAX_MODE; mode++) {
+ struct CleanPath *path;
+ strcpy(tr[mode].sep, TEST_SEP);
+ strcpy(tr[mode].input, TEST_PATH);
+ tr[mode].mode = mode;
+ tr[mode].status = 0;
+ tr[mode].output = NULL;
+
+ path = cleanpath_init(tr[mode].input, tr[mode].sep);
+ for (size_t part = 0; part < MAX_PART && inputs[mode][part] != NULL; part++) {
+ for (size_t record = 0; inputs[mode][part][record] != NULL; record++) {
+ cleanpath_filter(path, mode, inputs[mode][part][record]);
+ }
+ }
+ tr[mode].output = cleanpath_read(path);
+ tr[mode].status = strlen(tr[mode].output) == 0;
+ cleanpath_free(path);
+ }
+
+ for (size_t i = 0; i < MAX_MODE; i++) {
+ if (tr[i].status != 0) {
+ free(tr[i].output);
+ continue;
+ }
+ status++;
+ fprintf(stderr, "'%s' mode failed to filter elements from:\n'%s'\nRemainder:\n'%s'\n",
+ modes_str[tr[i].mode], tr[i].input, tr[i].output);
+ free(tr[i].output);
+ }
+
+ myassert(status == 0, "%d mode(s) failed", status);
+ return 0;
+} \ No newline at end of file
diff --git a/tests/test_modes_filter_general.c b/tests/test_modes_filter_general.c
new file mode 100644
index 0000000..e3a9cda
--- /dev/null
+++ b/tests/test_modes_filter_general.c
@@ -0,0 +1,86 @@
+#include "cleanpath.h"
+#include "framework.h"
+
+#define MAX_MODE 3
+#define MAX_PART CLEANPATH_PART_MAX
+#define MAX_RECORD 255
+
+unsigned modes[MAX_MODE] = {
+ CLEANPATH_FILTER_EXACT,
+ CLEANPATH_FILTER_LOOSE,
+ CLEANPATH_FILTER_REGEX,
+};
+
+char *modes_str[MAX_MODE] = {
+ "exact",
+ "loose",
+ "regex",
+};
+
+const char *inputs[MAX_MODE][MAX_PART][MAX_RECORD] = {
+ { // Filter exact
+ "/opt/local/bin",
+ "/opt/local/sbin",
+ "intentionally bad", // test non-existent pattern in string
+ NULL
+ },
+ { // Filter loose
+ "/opt/local",
+ "intentionally bad", // test non-existent pattern in string
+ NULL
+ },
+ { // Filter regex
+ "^/opt/local/.*",
+ "intentionally bad", // test non-existent pattern in string
+ "intentionally worse (", // cause total regex failure with unmatched parenthesis
+ NULL
+ },
+};
+const char *expected = "/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/Library/Apple/usr/bin";
+
+struct TestResult {
+ size_t status;
+ size_t mode;
+ char *output;
+ char input[1024];
+ char sep[25];
+};
+
+int main() {
+ int status;
+ struct TestResult tr[MAX_MODE];
+
+ status = 0;
+ for (size_t mode = 0; mode < MAX_MODE; mode++) {
+ struct CleanPath *path;
+ strcpy(tr[mode].sep, TEST_SEP);
+ strcpy(tr[mode].input, TEST_PATH);
+ tr[mode].mode = mode;
+ tr[mode].status = 0;
+ tr[mode].output = NULL;
+
+ path = cleanpath_init(tr[mode].input, tr[mode].sep);
+ for (size_t part = 0; part < MAX_PART && inputs[mode][part] != NULL; part++) {
+ for (size_t record = 0; inputs[mode][part][record] != NULL; record++) {
+ cleanpath_filter(path, mode, inputs[mode][part][record]);
+ }
+ }
+ tr[mode].output = cleanpath_read(path);
+ tr[mode].status = strcmp(tr[mode].output, expected);
+ cleanpath_free(path);
+ }
+
+ for (size_t i = 0; i < MAX_MODE; i++) {
+ if (tr[i].status == 0) {
+ free(tr[i].output);
+ continue;
+ }
+ status++;
+ fprintf(stderr, "'%s' mode failed to filter elements from:\n'%s'\nExpected:\n'%s'\nRemainder:\n'%s'\n\n",
+ modes_str[tr[i].mode], tr[i].input, expected, tr[i].output);
+ free(tr[i].output);
+ }
+
+ myassert(status == 0, "%d mode(s) failed", status);
+ return 0;
+} \ No newline at end of file