From b4de032767f13d2b6cfa2063b67fc3a74f3b1670 Mon Sep 17 00:00:00 2001 From: JP Appel Date: Sat, 20 Jul 2024 18:24:56 -0400 Subject: added static target, first implementation of eztester --- Makefile | 17 ++++++++ README.md | 2 +- eztester.c | 128 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ eztester.h | 51 ++++++++++++++++++++++++ 4 files changed, 197 insertions(+), 1 deletion(-) create mode 100644 Makefile create mode 100644 eztester.c create mode 100644 eztester.h diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..018b920 --- /dev/null +++ b/Makefile @@ -0,0 +1,17 @@ +CC := gcc +CFLAGS := + +SRCS := eztester.c +OBJS := eztester.o eztester_debug.o +STATIC_LIBS := eztester.a eztester_debug.a + +all: $(STATIC_LIBS) + +eztester.o: eztester.c + $(CC) -c $(CFLAGS) -o $@ $< + +eztester_debug.o: eztester.c + $(CC) -c -ggdb $(CFLAGS) -o $@ $< + +%.a: %.o + ar rcs $@ $< diff --git a/README.md b/README.md index b375d48..df1a809 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ A barebones testing library for C ## TODO * [ ] makefile - * [ ] static library target + * [x] static library target * [ ] dynamic library target * [ ] header-only target * [ ] colorized output diff --git a/eztester.c b/eztester.c new file mode 100644 index 0000000..484c773 --- /dev/null +++ b/eztester.c @@ -0,0 +1,128 @@ +#include "eztester.h" +#include +#include +#include +#include +#include + +eztester_list *eztester_create_list(const size_t capacity) { + eztester_list *list = malloc(sizeof(eztester_list)); + if (!list) { + return NULL; + } + + list->length = 0; + + if (capacity == 0) { + list->tests = NULL; + list->capacity = 0; + return list; + } + + eztester_test *tests = malloc(capacity * sizeof(eztester_test)); + if (!tests) { + free(list); + return NULL; + } + + list->capacity = capacity; + return list; +} +void eztester_register(eztester_list *test_list, const eztester_test new_test) { + if (test_list->capacity == 0) { + test_list->capacity = 1; + } + if (test_list->capacity <= test_list->length + 1) { + test_list->capacity *= 2; + test_list->tests = + realloc(test_list->tests, test_list->capacity * sizeof(eztester_test)); + assert(test_list->tests); + } + + test_list->tests[test_list->length++] = new_test; +} + +void print_test_results(const size_t tests_run, const size_t tests_passed, + const size_t num_tests) { + const char *pass_str; + printf("--------\nRan %zu of %zu tests\n", tests_run, num_tests); + if (tests_run == num_tests && tests_run == tests_passed) { + printf("All tests passed :)\n"); + } else if (tests_run == num_tests && tests_passed == 0) { + printf("No test passsed :(\n"); + } else { + printf("%zu of %zu tests passed\n", tests_passed, tests_run); + } +} + +void eztester_run(eztester_list *test_list, eztester_behavior behavior) { + eztester_status status; + eztester_test test; + const size_t length = test_list->length; + size_t pass_count = 0; + + for (size_t i = 0; i < test_list->length; i++) { + test = test_list->tests[i]; + printf("[%03zu/%03zu] Testing: %s\n", i + 1, length, test.name); + fflush(stdout); + status = test.runner(); + + switch (status) { + case TEST_PASS: + printf("[%03zu/%03zu] %s Result: Pass\n", i + 1, length, test.name); + pass_count++; + break; + + case TEST_WARNING: + printf("[%03zu/%03zu] %s Result: Warning\n", i + 1, length, test.name); + if (behavior == EXIT_ON_WARNING) { + printf("Warning occured, Exitting\n"); + print_test_results(i + 1, pass_count, length); + exit(1); + } + break; + + case TEST_FAIL: + printf("[%03zu/%03zu] %s Result: Fail\n", i + 1, length, test.name); + if (behavior != CONTINUE_ALL) { + printf("Failure occured, Exitting\n"); + print_test_results(i + 1, pass_count, length); + exit(1); + } + break; + + case TEST_ERROR: + printf("[%03zu/%03zu] %s Result: Error\nFatal Error occured! Exiting\n", + i + 1, length, test.name); + print_test_results(i + 1, pass_count, length); + exit(1); + break; + } + } + print_test_results(length, pass_count, length); +} + +void eztester_test_print(const char *format, ...){ + va_list args; + va_start(args, format); + printf("> "); + vprintf(format, args); + printf("\n"); + va_end(args); +} + +void eztester_clear_list(eztester_list *test_list) { + free(test_list->tests); + test_list->length = 0; + test_list->capacity = 0; +} + +void eztester_destroy_list(eztester_list *test_list) { + eztester_clear_list(test_list); + free(test_list); +} + +eztester_status eztester_always_pass_test() { return TEST_PASS; } +eztester_status eztester_always_warn_test() { return TEST_WARNING; } +eztester_status eztester_always_fail_test() { return TEST_FAIL; } +eztester_status eztester_always_error_test() { return TEST_ERROR; } diff --git a/eztester.h b/eztester.h new file mode 100644 index 0000000..a8deb83 --- /dev/null +++ b/eztester.h @@ -0,0 +1,51 @@ +#pragma once + +#include +#include + +// possible results of a test +// error is always fatal +typedef enum { TEST_PASS, TEST_FAIL, TEST_WARNING, TEST_ERROR } eztester_status; + +typedef enum { EXIT_ON_WARNING, CONTINUE_ALL, EXIT_ON_FAIL } eztester_behavior; + +typedef eztester_status(eztester_runner)(); + +typedef struct { + eztester_runner *runner; + const char *name; +} eztester_test; + +typedef struct { + eztester_test *tests; + size_t length; + size_t capacity; +} eztester_list; + +eztester_list *eztester_create_list(const size_t capacity); +void eztester_register(eztester_list *test_list, const eztester_test new_test); +void eztester_run(eztester_list *test_list, const eztester_behavior behavior); +void eztester_clear_list(eztester_list *test_list); +void eztester_destroy_list(eztester_list *test_list); + +void eztester_test_print(const char *format, ...); + +/* Run a shell script found at file_path, it can read in from input and write to + * output + * + * Returns exit code of the command + * UNIMPLEMENTED! + */ +unsigned char ezteser_run_shell_script(const char *file_path, FILE *input, + FILE *output); + +// tests that always return an eztester_status + +// always return pass +eztester_status eztester_always_pass_test(); +// always return warning +eztester_status eztester_always_warn_test(); +// always return fail +eztester_status eztester_always_fail_test(); +// always return error +eztester_status eztester_always_error_test(); -- cgit v1.2.3