diff options
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | CMakeLists.txt | 10 | ||||
-rw-r--r-- | src/lily-test.h | 30 | ||||
-rw-r--r-- | src/test.c | 93 |
4 files changed, 135 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bdc5af0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*~ +build diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..379417a --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,10 @@ +cmake_minimum_required(VERSION 3.2) +project( + lily-test + VERSION 0.1.0 + DESCRIPTION "A super-simple single-header C test framework") + +add_executable(lily-metatest ${CMAKE_SOURCE_DIR}/src/test.c) +set_target_properties(lily-metatest PROPERTIES + C_STANDARD 99 + CMAKE_C_FLAGS "-Wall -Wextra -Werror -Wfatal-errors -Wpedantic") diff --git a/src/lily-test.h b/src/lily-test.h new file mode 100644 index 0000000..8ce0f41 --- /dev/null +++ b/src/lily-test.h @@ -0,0 +1,30 @@ +#ifndef LILY_TEST_H +#define LILY_TEST_H + +#define lily_test const char * + +struct lily_test_data_t { + int tests_run; + int tests_failed; +}; + +#define LILY_INIT() \ + struct lily_test_data_t lily_test_data = { 0, 0 }; + + +// helper macros to turn numerical constants into strings +#define STR_IMPL(x) #x +#define STR(X) STR_IMPL(x) + + +// assertion macros +#define lily_indent " " +#define lily_assert(statement, message) \ + do { \ + if (!(statement)) \ + return "" message \ + "\n" lily_indent " [" __FILE__ ":" STR(__LINE__) "]"; \ + } while(0) + + +#endif diff --git a/src/test.c b/src/test.c new file mode 100644 index 0000000..146f636 --- /dev/null +++ b/src/test.c @@ -0,0 +1,93 @@ +#include <stdio.h> +#include <stdbool.h> +#include <string.h> +#include <stdlib.h> + +#include "lily-test.h" + +LILY_INIT(); + +void run_test(const char *name, lily_test (*fp)()) +{ + printf("%s... ", name); + const char *result = fp(); + if (result != 0) { + printf("FAILED (%s)\n", result); + } + else + printf("OK\n"); +} + + +lily_test check_init() +{ + // should fail to compile if lily_test_data is undefined + if (lily_test_data.tests_run != 0) + return "tests_run is not equal to zero!"; + if (lily_test_data.tests_failed != 0) + return "tests_failed is not equal to zero!"; + return 0; +} + + +int get_message(char **destination, const char *source) +{ + const char *s = source; + size_t size = 0; + while (*s != '\n') { + if (*s == 0) + return false; + s++; + size++; + } + + *destination = malloc((size+1) * sizeof(char)); + strncpy(*destination, source, size); + (*destination)[size] = 0; + return true; +} + +#define assert_msg "message" + +lily_test wrap_assert(bool statement) +{ + lily_assert(statement, assert_msg); + return 0; +} + +lily_test check_assert() +{ + if (wrap_assert(true) != 0) + return "true assertion did not return 0!"; + + const char *result = wrap_assert(false); + + if (result == 0) + return "false assertion returned zero!"; + + char *message; + if (!get_message(&message, result)) + return "false assertion contained malformed message!"; + + if (strcmp(message, assert_msg) != 0) + return "false assertion message was not '" assert_msg "'!"; + free(message); + + return 0; +} + + +lily_test check_other_asserts() +{ + +} + + +int main() +{ + run_test("check LILY_INIT()", check_init); + run_test("check basic assertion", check_assert); + + printf("all tests finished.\n"); + return 0; +} |