From 835e1fcd131c63ee2b3b647e327b33a3bfb369e3 Mon Sep 17 00:00:00 2001 From: Mitya Selivanov Date: Sat, 2 Sep 2023 20:59:29 +0200 Subject: [Linux] Change build system; Remove CMake --- .gitignore | 2 - CMakeLists.txt | 223 -------------------- TODO | 11 +- build.c | 247 ----------------------- build_and_test.sh | 11 + config.cmake.in | 8 - gen_cmake.c | 200 ------------------ source/CMakeLists.txt | 6 - source/kit/CMakeLists.txt | 27 --- source/kit/_static.c | 14 ++ source/kit/allocator.h | 4 + source/kit/array_ref.h | 18 +- source/kit/async_function.h | 4 + source/kit/atomic.h | 8 +- source/kit/bigint.h | 1 + source/kit/input_buffer.c | 10 +- source/kit/input_stream.c | 10 +- source/kit/mersenne_twister_64.h | 4 + source/kit/move_back.h | 4 + source/kit/mutex.h | 5 +- source/kit/secure_random.h | 5 +- source/kit/sha256.h | 4 + source/kit/sockets.h | 4 + source/kit/status.h | 2 +- source/kit/string_ref.h | 1 + source/kit/thread.h | 5 +- source/kit/types.h | 17 ++ source/kit_test/CMakeLists.txt | 7 - source/kit_test/_static.c | 3 + source/kit_test/bench.c | 39 +--- source/kit_test/bench.h | 1 + source/kit_test/shared.inl.h | 38 ++++ source/kit_test/test.c | 38 +--- source/kit_test/test.h | 4 + source/test/CMakeLists.txt | 2 - source/test/programs/CMakeLists.txt | 49 ----- source/test/programs/cpp_example.cpp | 13 -- source/test/programs/signals.cpp | 29 --- source/test/programs/too_many_assertions.c | 13 -- source/test/programs/too_many_tests.c | 14 -- source/test/unittests/CMakeLists.txt | 8 - source/test/unittests/array_ref.test.c | 65 ------ source/test/unittests/async_function.test.c | 132 ------------ source/test/unittests/atomic.test.c | 218 -------------------- source/test/unittests/bigint.test.c | 108 ---------- source/test/unittests/condition_variable.test.c | 84 -------- source/test/unittests/dynamic_array.test.c | 174 ---------------- source/test/unittests/file.test.c | 220 -------------------- source/test/unittests/foo.bench.c | 41 ---- source/test/unittests/input_buffer.test.c | 105 ---------- source/test/unittests/input_stream.test.c | 23 --- source/test/unittests/lower_bound.test.c | 178 ---------------- source/test/unittests/main.test.c | 9 - source/test/unittests/mersenne_twister_64.test.c | 38 ---- source/test/unittests/move_back.test.c | 148 -------------- source/test/unittests/mutex.test.c | 79 -------- source/test/unittests/secure_random.test.c | 24 --- source/test/unittests/sha256.test.c | 42 ---- source/test/unittests/string_ref.test.c | 23 --- source/test/unittests/test_duration.test.c | 20 -- source/test/unittests/thread.test.c | 91 --------- source/tests/_static.c | 55 +++++ source/tests/array_ref.test.c | 65 ++++++ source/tests/async_function.test.c | 132 ++++++++++++ source/tests/atomic.test.c | 218 ++++++++++++++++++++ source/tests/bench.test.c | 41 ++++ source/tests/bigint.test.c | 108 ++++++++++ source/tests/condition_variable.test.c | 84 ++++++++ source/tests/cpp.cpp | 13 ++ source/tests/dynamic_array.test.c | 174 ++++++++++++++++ source/tests/file.test.c | 220 ++++++++++++++++++++ source/tests/input_buffer.test.c | 105 ++++++++++ source/tests/input_stream.test.c | 23 +++ source/tests/lower_bound.test.c | 178 ++++++++++++++++ source/tests/main.test.c | 9 + source/tests/mersenne_twister_64.test.c | 38 ++++ source/tests/move_back.test.c | 148 ++++++++++++++ source/tests/mutex.test.c | 79 ++++++++ source/tests/secure_random.test.c | 24 +++ source/tests/sha256.test.c | 42 ++++ source/tests/signals.cpp | 29 +++ source/tests/string_ref.test.c | 23 +++ source/tests/test_duration.test.c | 19 ++ source/tests/thread.test.c | 91 +++++++++ source/tests/too_many_assertions.c | 13 ++ source/tests/too_many_tests.c | 14 ++ 86 files changed, 2112 insertions(+), 2768 deletions(-) delete mode 100644 CMakeLists.txt delete mode 100644 build.c create mode 100644 build_and_test.sh delete mode 100644 config.cmake.in delete mode 100644 gen_cmake.c delete mode 100644 source/CMakeLists.txt delete mode 100644 source/kit/CMakeLists.txt create mode 100644 source/kit/_static.c create mode 100644 source/kit/types.h delete mode 100644 source/kit_test/CMakeLists.txt create mode 100644 source/kit_test/_static.c create mode 100644 source/kit_test/shared.inl.h delete mode 100644 source/test/CMakeLists.txt delete mode 100644 source/test/programs/CMakeLists.txt delete mode 100644 source/test/programs/cpp_example.cpp delete mode 100644 source/test/programs/signals.cpp delete mode 100644 source/test/programs/too_many_assertions.c delete mode 100644 source/test/programs/too_many_tests.c delete mode 100644 source/test/unittests/CMakeLists.txt delete mode 100644 source/test/unittests/array_ref.test.c delete mode 100644 source/test/unittests/async_function.test.c delete mode 100644 source/test/unittests/atomic.test.c delete mode 100644 source/test/unittests/bigint.test.c delete mode 100644 source/test/unittests/condition_variable.test.c delete mode 100644 source/test/unittests/dynamic_array.test.c delete mode 100644 source/test/unittests/file.test.c delete mode 100644 source/test/unittests/foo.bench.c delete mode 100644 source/test/unittests/input_buffer.test.c delete mode 100644 source/test/unittests/input_stream.test.c delete mode 100644 source/test/unittests/lower_bound.test.c delete mode 100644 source/test/unittests/main.test.c delete mode 100644 source/test/unittests/mersenne_twister_64.test.c delete mode 100644 source/test/unittests/move_back.test.c delete mode 100644 source/test/unittests/mutex.test.c delete mode 100644 source/test/unittests/secure_random.test.c delete mode 100644 source/test/unittests/sha256.test.c delete mode 100644 source/test/unittests/string_ref.test.c delete mode 100644 source/test/unittests/test_duration.test.c delete mode 100644 source/test/unittests/thread.test.c create mode 100644 source/tests/_static.c create mode 100644 source/tests/array_ref.test.c create mode 100644 source/tests/async_function.test.c create mode 100644 source/tests/atomic.test.c create mode 100644 source/tests/bench.test.c create mode 100644 source/tests/bigint.test.c create mode 100644 source/tests/condition_variable.test.c create mode 100644 source/tests/cpp.cpp create mode 100644 source/tests/dynamic_array.test.c create mode 100644 source/tests/file.test.c create mode 100644 source/tests/input_buffer.test.c create mode 100644 source/tests/input_stream.test.c create mode 100644 source/tests/lower_bound.test.c create mode 100644 source/tests/main.test.c create mode 100644 source/tests/mersenne_twister_64.test.c create mode 100644 source/tests/move_back.test.c create mode 100644 source/tests/mutex.test.c create mode 100644 source/tests/secure_random.test.c create mode 100644 source/tests/sha256.test.c create mode 100644 source/tests/signals.cpp create mode 100644 source/tests/string_ref.test.c create mode 100644 source/tests/test_duration.test.c create mode 100644 source/tests/thread.test.c create mode 100644 source/tests/too_many_assertions.c create mode 100644 source/tests/too_many_tests.c diff --git a/.gitignore b/.gitignore index 6b8717a..b846915 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,3 @@ /*build*/ *.swp gen_inl -gen_cmake -build_c diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index b199e4d..0000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,223 +0,0 @@ -cmake_minimum_required(VERSION 3.16) - -set(CMAKE_EXPORT_COMPILE_COMMANDS ON CACHE BOOL "" FORCE) - -if(NOT DEFINED CMAKE_BUILD_PARALLEL_LEVEL) - set(CMAKE_BUILD_PARALLEL_LEVEL 4 CACHE STRING "" FORCE) -endif() - -option(KIT_DISABLE_SYSTEM_MALLOC "Disable system memory allocator" OFF) -option(KIT_DISABLE_SYSTEM_THREADS "Disable system threads" OFF) -option(KIT_ENABLE_CUSTOM_ALLOC_DISPATCH "Enable custom allocator dispatch" OFF) -option(KIT_ENABLE_CUSTOM_ASYNC_FUNCTION_DISPATCH "Enable custom async function dispatch" OFF) -option(KIT_ENABLE_TESTING "Enable testing" ON) - -project( - kit - VERSION 0.1.1 - DESCRIPTION "A collection of C libraries" - LANGUAGES C) - -add_library(kit STATIC) -add_library(kit::kit ALIAS kit) -target_include_directories( - kit INTERFACE - $) -if(WIN32) - target_link_libraries(kit PUBLIC Shlwapi) -endif() - -if(CMAKE_C_COMPILER_ID MATCHES "GNU|Clang") - target_compile_options(kit PUBLIC -pedantic -Wall -Werror) -endif() - -include(CheckCSourceRuns) - -check_c_source_runs( - " - __attribute__((weak)) int foo(); - int main() { return 0; } - " - KIT_HAVE_FUNC_ATTRIBUTE_WEAK -) - -set(CMAKE_REQUIRED_LIBRARIES_BACK_ ${CMAKE_REQUIRED_LIBRARIES}) -set(CMAKE_REQUIRED_LIBRARIES "pthread") -check_c_source_runs( - " - #define _GNU_SOURCE - #include - int main() { - pthread_mutexattr_t attr; - pthread_mutexattr_init(&attr); - pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); - return 0; - } - " - KIT_HAVE_PTHREAD_MUTEXATTR_SETTYPE -) -set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES_BACK_}) -unset(CMAKE_REQUIRED_LIBRARIES_BACK_) - -check_c_source_runs( - " - #include - int main() { - return 0; - } - " - KIT_HAVE_PTHREAD -) - -check_c_source_runs( - " - #include - int main() { - return 0; - } - " - KIT_HAVE_WINDOWS -) - -check_c_source_runs( - " - #include - int main() { - void *p = malloc(10); - free(p); - return 0; - } - " - KIT_HAVE_MALLOC -) - -if(NOT KIT_HAVE_PTHREAD AND NOT KIT_HAVE_WINDOWS) - set(KIT_DISABLE_SYSTEM_THREADS ON) -endif() - -if(NOT KIT_HAVE_MALLOC) - set(KIT_DISABLE_SYSTEM_MALLOC ON) -endif() - -if(KIT_HAVE_FUNC_ATTRIBUTE_WEAK) - target_compile_definitions(kit PUBLIC KIT_HAVE_FUNC_ATTRIBUTE_WEAK) -endif() - -if(KIT_HAVE_PTHREAD_MUTEXATTR_SETTYPE) - target_compile_definitions(kit PUBLIC KIT_HAVE_PTHREAD_MUTEXATTR_SETTYPE) -endif() - -if(KIT_DISABLE_SYSTEM_MALLOC) - target_compile_definitions(kit PUBLIC KIT_DISABLE_SYSTEM_MALLOC) -endif() - -if(KIT_DISABLE_SYSTEM_THREADS) - target_compile_definitions(kit PUBLIC KIT_DISABLE_SYSTEM_THREADS) -endif() - -if(KIT_ENABLE_CUSTOM_ALLOC_DISPATCH) - target_compile_definitions(kit PUBLIC KIT_ENABLE_CUSTOM_ALLOC_DISPATCH) -endif() - -if(KIT_ENABLE_CUSTOM_ASYNC_FUNCTION_DISPATCH) - target_compile_definitions(kit PUBLIC KIT_ENABLE_CUSTOM_ASYNC_FUNCTION_DISPATCH) -endif() - -if(NOT KIT_DISABLE_SYSTEM_THREADS) - find_package(Threads REQUIRED) - target_link_libraries(kit PUBLIC Threads::Threads) -endif() - -add_library(kit_test STATIC) -add_library(kit::kit_test ALIAS kit_test) -target_include_directories( - kit_test INTERFACE - $) - -enable_testing() - -if(KIT_ENABLE_TESTING) - add_executable(kit_test_suite) - add_executable(kit::kit_test_suite ALIAS kit_test_suite) - target_link_libraries(kit_test_suite PRIVATE kit kit_test) - - if(CMAKE_C_COMPILER_ID MATCHES "GNU|Clang") - target_compile_options( - kit PUBLIC - -fsanitize=undefined,address - --coverage -O0 -g) - target_link_options( - kit PUBLIC - -fsanitize=undefined,address - --coverage) - endif() - - add_test( - NAME kit_unittests - COMMAND kit_test_suite --no-carriage-return) - set_tests_properties( - kit_unittests - PROPERTIES - TIMEOUT "120") -endif() - -add_subdirectory(source) - -include(GNUInstallDirs) - -file( - GLOB_RECURSE headers_ - RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/source/kit - ${CMAKE_CURRENT_SOURCE_DIR}/source/kit/*.h) - -foreach(path_ ${headers_}) - get_filename_component(dir_ "${path_}" DIRECTORY) - - install( - FILES ${CMAKE_CURRENT_SOURCE_DIR}/source/kit/${path_} - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/kit/${dir_}) -endforeach() - -unset(headers_) -unset(path_) -unset(dir_) - -install( - TARGETS kit kit_test - EXPORT kit-targets - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} - INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) - -install( - EXPORT kit-targets - FILE kit-targets.cmake - NAMESPACE ${PROJECT_NAME}:: - DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}") - -export( - EXPORT kit-targets - FILE "${CMAKE_CURRENT_BINARY_DIR}/cmake/kit-targets.cmake" - NAMESPACE ${PROJECT_NAME}::) - -include(CMakePackageConfigHelpers) - -string(TOLOWER ${PROJECT_NAME} project_lower_) - -configure_package_config_file( - ${CMAKE_CURRENT_SOURCE_DIR}/config.cmake.in - "${CMAKE_CURRENT_BINARY_DIR}/${project_lower_}-config.cmake" - INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}) - -write_basic_package_version_file( - "${CMAKE_CURRENT_BINARY_DIR}/${project_lower_}-config-version.cmake" - VERSION "${PROJECT_VERSION}" - COMPATIBILITY AnyNewerVersion) - -install( - FILES - "${CMAKE_CURRENT_BINARY_DIR}/${project_lower_}-config.cmake" - "${CMAKE_CURRENT_BINARY_DIR}/${project_lower_}-config-version.cmake" - DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}) - -unset(project_lower_) diff --git a/TODO b/TODO index 127f597..f4c6115 100644 --- a/TODO +++ b/TODO @@ -1,11 +1,10 @@ To-Do +- Code + - Remove "const" - Cryptography - hmac_sha256 https://github.com/h5p9sl/hmac_sha256 - ecdh https://github.com/kokke/tiny-ECDH-c -- Build system - - build.c - - Remove CMake scripts - Allocators - Memory pool - Memory stack @@ -14,6 +13,10 @@ To-Do - Terminal - File and memory mapping - Inter-process transfer - - SDL boilerplate + - Graphics boilerplate + - X11 (Linux) + - Win32 (Windows) + - Cocoa (macOS) + - Emscripten (WebAssembly) - Add sockets tests diff --git a/build.c b/build.c deleted file mode 100644 index f9c0f95..0000000 --- a/build.c +++ /dev/null @@ -1,247 +0,0 @@ -#if 0 -gcc -fsanitize=address,undefined,leak build.c -o build_c && ./build_c -exit -#endif - -/********************************************************************* - * * - * KIT Library * - * * - *********************************************************************/ - -// Just paste the Kit library code here. - -#include "include/kit.inl.h" - -/********************************************************************* - * * - * BUILD_C * - * * - * Experimental pure C build system. * - * Work in progress. * - * * - *********************************************************************/ - -#include - -#define DL PATH_DELIM - -enum { MAX_STR = 4096, MAX_DEPENDENCIES = 100, MAX_UNITS = 400 }; - -typedef DA(ptrdiff_t) index_array_t; - -typedef enum { UNIT_NONE, UNIT_HEADER, UNIT_SOURCE } unit_type_t; - -typedef struct { - string_t path; - unit_type_t type; - index_array_t dependencies; -} unit_t; - -typedef DA(unit_t) unit_array_t; - -unit_array_t units; - -kit_allocator_t ALLOC; - -int is_header(str_t file) { - ptrdiff_t const n = file.size; - return n > 2 && file.values[n - 2] == '.' && - file.values[n - 1] == 'h'; -} - -int is_source(str_t file) { - ptrdiff_t const n = file.size; - return n > 2 && file.values[n - 2] == '.' && - file.values[n - 1] == 'c'; -} - -unit_type_t unit_type(str_t file) { - if (is_header(file)) - return UNIT_HEADER; - if (is_source(file)) - return UNIT_SOURCE; - return UNIT_NONE; -} - -void enum_sources(str_t folder) { - path_list_t const list = file_enum_folder(folder, ALLOC); - - for (ptrdiff_t i = 0; i < list.files.size; i++) { - str_t item = WRAP_STR(list.files.values[i]); - string_t file = path_join(folder, item, ALLOC); - path_type_t type = path_type(WRAP_STR(file)); - unit_type_t utype = unit_type(WRAP_STR(file)); - - switch (type) { - case PATH_FILE: - if (utype != UNIT_NONE) { - unit_t unit = { .path = file, .type = utype }; - DA_INIT(unit.dependencies, 0, ALLOC); - DA_APPEND(units, unit); - } else - DA_DESTROY(file); - break; - - case PATH_FOLDER: enum_sources(WRAP_STR(file)); - default: DA_DESTROY(file); - } - } - - path_list_destroy(list); -} - -void skip_comment(FILE *f) { - char c = fgetc(f); - if (c != '/' && c != '*') - return; - if (c == '/') - while (c != '\n') { - c = fgetc(f); - if (c == '\\') - fgetc(f); - } - else - while (c != '*') { - c = fgetc(f); - if (c == '*' && fgetc(f) == '/') - break; - } -} - -typedef struct { - int ok; - int is_local; - string_t path; -} include_t; - -include_t parse_include(FILE *f) { - include_t result = { .ok = 0 }; - char c = ' '; - while (c == ' ') c = fgetc(f); - if (c != '#') - return result; - c = ' '; - while (c == ' ') c = fgetc(f); - if (c != 'i') - return result; - char s[] = "nclude"; - for (int i = 0; i + 1 < sizeof s; i++) - if (fgetc(f) != s[i]) - return result; - c = ' '; - while (c == ' ') c = fgetc(f); - if (c != '"' && c != '<') - return result; - if (c == '"') - result.is_local = 1; - else - result.is_local = 0; - DA_INIT(result.path, 1, ALLOC); - for (;;) { - char z = fgetc(f); - if (c == '"' && z == '"') - break; - if (c == '<' && z == '>') - break; - if (z == '\n' || z == '\r' || z == '\0') { - DA_DESTROY(result.path); - return result; - } - result.path.values[result.path.size - 1] = z; - DA_RESIZE(result.path, result.path.size + 1); - } - DA_RESIZE(result.path, result.path.size - 1); - if (result.path.size == 0) { - DA_DESTROY(result.path); - return result; - } - c = ' '; - while (c == ' ') c = fgetc(f); - if (c != '\n' && c != '\r') { - DA_DESTROY(result.path); - return result; - } - result.ok = 1; - return result; -} - -str_t base_path(str_t path) { - ptrdiff_t n = 0; - while (path_index(path, n).size != 0) n++; - return path_take(path, n - 2); -} - -void parse_unit(unit_t *u) { - FILE *f = fopen(BS(u->path), "rt"); - if (f == NULL) { - printf("Can't read %s\n", BS(u->path)); - return; - } - - str_t base = base_path(WRAP_STR(u->path)); - - while (!feof(f)) { - char c = fgetc(f); - switch (c) { - case '/': skip_comment(f); break; - case '\n': { - include_t inc = parse_include(f); - if (inc.ok) { - if (inc.is_local) { - string_t temp = path_join(base, WRAP_STR(inc.path), - ALLOC); - string_t inc_path = path_norm(WRAP_STR(temp), ALLOC); - for (ptrdiff_t i = 0; i < units.size; i++) - if (AR_EQUAL(units.values[i].path, inc_path)) { - ptrdiff_t k = u->dependencies.size; - DA_RESIZE(u->dependencies, k + 1); - u->dependencies.values[k] = i; - break; - } - DA_DESTROY(temp); - DA_DESTROY(inc_path); - } - DA_DESTROY(inc.path); - } - } break; - default:; - } - } - - fclose(f); -} - -void parse_units(void) { - for (ptrdiff_t i = 0; i < units.size; i++) - parse_unit(units.values + i); -} - -int main(int argc, char **argv) { - ALLOC = kit_alloc_default(); - DA_INIT(units, 0, ALLOC); - - enum_sources(SZ("." DL "src")); - enum_sources(SZ("." DL "source")); - parse_units(); - - for (ptrdiff_t i = 0; i < units.size; i++) { - unit_t *u = units.values + i; - if (u->type == UNIT_HEADER) - printf("[ Header ] "); - else - printf("[ Source ] "); - printf("%s\n", BS(u->path)); - for (ptrdiff_t j = 0; j < u->dependencies.size; j++) - printf(" -> %s\n", - BS(units.values[u->dependencies.values[j]].path)); - } - - for (ptrdiff_t i = 0; i < units.size; i++) { - DA_DESTROY(units.values[i].path); - DA_DESTROY(units.values[i].dependencies); - } - DA_DESTROY(units); - - return 0; -} diff --git a/build_and_test.sh b/build_and_test.sh new file mode 100644 index 0000000..e78ef2d --- /dev/null +++ b/build_and_test.sh @@ -0,0 +1,11 @@ +if [ ! -d "build" ]; then + mkdir build +fi + +gcc -c -o "build/kit.o" "source/kit/_static.c" +ar rcs "build/libkit.a" "build/kit.o" + +gcc -c -o "build/kit_test.o" "source/kit_test/_static.c" +ar rcs "build/libkit_test.a" "build/kit_test.o" + +gcc -o "build/kit_test_suite" "source/tests/_static.c" -Lbuild -lkit -lkit_test diff --git a/config.cmake.in b/config.cmake.in deleted file mode 100644 index d2f3c05..0000000 --- a/config.cmake.in +++ /dev/null @@ -1,8 +0,0 @@ -@PACKAGE_INIT@ - -if(NOT @KIT_DISABLE_SYSTEM_THREADS@) - include(CMakeFindDependencyMacro) - find_dependency(Threads) -endif() - -include("${CMAKE_CURRENT_LIST_DIR}/kit-targets.cmake") diff --git a/gen_cmake.c b/gen_cmake.c deleted file mode 100644 index cfb4f24..0000000 --- a/gen_cmake.c +++ /dev/null @@ -1,200 +0,0 @@ -#if 0 -gcc -fsanitize=address,undefined,leak gen_cmake.c -o gen_cmake && ./gen_cmake -exit -#endif - -#include "include/kit.inl.h" - -#include - -kit_allocator_t ALLOC; - -typedef struct { - kit_status_t status; - int have_cmakelists; -} gen_result_t; - -int is_header(str_t const file) { - return file.size > 2 && file.values[file.size - 2] == '.' && - file.values[file.size - 1] == 'h'; -} - -int is_source(str_t const file) { - return file.size > 2 && file.values[file.size - 2] == '.' && - file.values[file.size - 1] == 'c'; -} - -gen_result_t gen_cmakelists_for(str_t const target, - str_t const folder) { - gen_result_t result = { KIT_OK, 0 }; - - path_list_t const list = file_enum_folder(folder, ALLOC); - - if (list.status != KIT_OK) { - printf("Error: file_enum_folder failed with code %d.\n", - list.status); - result.status = list.status; - return result; - } - - int have_headers = 0; - int have_sources = 0; - int have_folders = 0; - - FILE *out = NULL; - - string_t cmakelists_path = path_join(folder, SZ("CMakeLists.txt"), - ALLOC); - - DA_APPEND(cmakelists_path, '\0'); - - if (cmakelists_path.size == 0 || - cmakelists_path.values[cmakelists_path.size - 1] != '\0') { - result.status = KIT_ERROR_BAD_ALLOC; - result.have_cmakelists = 0; - DA_DESTROY(cmakelists_path); - path_list_destroy(list); - return result; - } - -#define OPEN_CMAKELISTS \ - do { \ - if (out == NULL) { \ - out = fopen(cmakelists_path.values, "wt"); \ - if (out == NULL) { \ - result.status = 101; \ - result.have_cmakelists = 0; \ - DA_DESTROY(cmakelists_path); \ - path_list_destroy(list); \ - return result; \ - } \ - } \ - } while (0) - -#define CHECK_TYPE(type_) \ - string_t const full_path_ = path_join(folder, WRAP_STR(item), \ - ALLOC); \ - int check_ = path_type(WRAP_STR(full_path_)) == (type_); \ - DA_DESTROY(full_path_); \ - if (!check_) \ - continue - - for (ptrdiff_t i = 0; i < list.files.size; i++) { - str_t const item = WRAP_STR(list.files.values[i]); - - CHECK_TYPE(PATH_FILE); - - if (!is_header(item)) - continue; - - OPEN_CMAKELISTS; - - if (!have_headers) - fprintf(out, "target_sources(\n %*s\n PUBLIC", - (int) target.size, BS(target)); - - fprintf( - out, - "\n $", - (int) item.size, BS(item)); - - have_headers = 1; - } - - ptrdiff_t const LINE_LIMIT = 80; - ptrdiff_t line_length = LINE_LIMIT; - - for (ptrdiff_t i = 0; i < list.files.size; i++) { - str_t const item = WRAP_STR(list.files.values[i]); - - CHECK_TYPE(PATH_FILE); - - if (!is_source(item)) - continue; - - OPEN_CMAKELISTS; - - if (!have_headers && !have_sources) - fprintf(out, "target_sources(\n %*s\n PRIVATE", - (int) target.size, BS(target)); - else if (!have_sources) - fprintf(out, "\n PRIVATE"); - - if (line_length + item.size > LINE_LIMIT) { - fprintf(out, "\n "); - line_length = 5; - } - - fprintf(out, " %*s", (int) item.size, BS(item)); - line_length += 1 + item.size; - - have_sources = 1; - } - - if (have_headers || have_sources) - fprintf(out, ")\n"); - - for (ptrdiff_t i = 0; i < list.files.size; i++) { - str_t const item = WRAP_STR(list.files.values[i]); - - CHECK_TYPE(PATH_FOLDER); - - string_t const subfolder = path_join(folder, item, ALLOC); - gen_result_t const r = gen_cmakelists_for(target, - WRAP_STR(subfolder)); - DA_DESTROY(subfolder); - if (r.status != KIT_OK) { - result.status = r.status; - break; - } - - if (!r.have_cmakelists) - continue; - - OPEN_CMAKELISTS; - - if (have_headers || have_sources) - fprintf(out, "\n"); - - fprintf(out, "add_subdirectory(%*s)\n", (int) item.size, - BS(item)); - - have_folders = 1; - } - - if (out != NULL) - fclose(out); - - DA_DESTROY(cmakelists_path); - path_list_destroy(list); - - if (result.status == KIT_OK) - result.have_cmakelists = have_headers || have_sources || - have_folders; - - if (!result.have_cmakelists && out != NULL) - file_remove(WRAP_STR(cmakelists_path)); - - return result; -} - -int main(int argc, char **argv) { - ALLOC = kit_alloc_default(); - - str_t const targets[] = { SZ("kit"), SZ("kit_test"), - SZ("kit_test_suite") }; - - str_t const folders[] = { - SZ("." PATH_DELIM "source" PATH_DELIM "kit"), - SZ("." PATH_DELIM "source" PATH_DELIM "kit_test"), - SZ("." PATH_DELIM "source" PATH_DELIM "test/unittests") - }; - - int ok = 1; - - for (ptrdiff_t i = 0; i < sizeof folders / sizeof *folders; i++) - ok = ok && - gen_cmakelists_for(targets[i], folders[i]).status == KIT_OK; - - return ok ? 0 : 1; -} diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt deleted file mode 100644 index 1444b6a..0000000 --- a/source/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -add_subdirectory(kit) -add_subdirectory(kit_test) - -if(KIT_ENABLE_TESTING) - add_subdirectory(test) -endif() diff --git a/source/kit/CMakeLists.txt b/source/kit/CMakeLists.txt deleted file mode 100644 index 2e89133..0000000 --- a/source/kit/CMakeLists.txt +++ /dev/null @@ -1,27 +0,0 @@ -target_sources( - kit - PUBLIC - $ - $ - $ - $ - $ - $ - $ - $ - $ - $ - $ - $ - $ - $ - $ - $ - $ - $ - $ - $ - PRIVATE - input_buffer.c secure_random.c sha256.c thread.posix.c atomic.win32.c - condition_variable.c thread.win32.c input_stream.c file.c allocator.c - array_ref.c dynamic_array.c mutex.c mersenne_twister_64.c) diff --git a/source/kit/_static.c b/source/kit/_static.c new file mode 100644 index 0000000..f098ab1 --- /dev/null +++ b/source/kit/_static.c @@ -0,0 +1,14 @@ +#include "allocator.c" +#include "array_ref.c" +#include "atomic.win32.c" +#include "condition_variable.c" +#include "dynamic_array.c" +#include "file.c" +#include "input_buffer.c" +#include "input_stream.c" +#include "mersenne_twister_64.c" +#include "mutex.c" +#include "secure_random.c" +#include "sha256.c" +#include "thread.posix.c" +#include "thread.win32.c" diff --git a/source/kit/allocator.h b/source/kit/allocator.h index 7b73b20..f6dc62d 100644 --- a/source/kit/allocator.h +++ b/source/kit/allocator.h @@ -1,6 +1,10 @@ #ifndef KIT_ALLOCATOR_H #define KIT_ALLOCATOR_H +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif + #include #ifdef __cplusplus diff --git a/source/kit/array_ref.h b/source/kit/array_ref.h index 39f1e8b..c893b49 100644 --- a/source/kit/array_ref.h +++ b/source/kit/array_ref.h @@ -1,6 +1,10 @@ #ifndef KIT_ARRAY_REF_H #define KIT_ARRAY_REF_H +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif + #include #include @@ -21,15 +25,15 @@ int kit_ar_compare(ptrdiff_t left_element_size, ptrdiff_t left_size, void const *right_data, kit_ar_compare_fn compare); #define KIT_AR_MUT(type_) \ - struct { \ - ptrdiff_t size; \ - type_ *values; \ + struct { \ + ptrdiff_t size; \ + type_ *values; \ } -#define KIT_AR(type_) \ - struct { \ - ptrdiff_t size; \ - type_ const *values; \ +#define KIT_AR(type_) \ + struct { \ + ptrdiff_t size; \ + type_ const *values; \ } #define KIT_AR_MUT_WRAP(name_, element_type_, array_) \ diff --git a/source/kit/async_function.h b/source/kit/async_function.h index 45e1089..f7a04e7 100644 --- a/source/kit/async_function.h +++ b/source/kit/async_function.h @@ -1,6 +1,10 @@ #ifndef KIT_ASYNC_FUNCTION_H #define KIT_ASYNC_FUNCTION_H +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif + #include #include diff --git a/source/kit/atomic.h b/source/kit/atomic.h index 23962a2..4d56def 100644 --- a/source/kit/atomic.h +++ b/source/kit/atomic.h @@ -1,8 +1,8 @@ #ifndef KIT_ATOMIC_H #define KIT_ATOMIC_H -#ifdef __cplusplus -extern "C" { +#ifndef _GNU_SOURCE +# define _GNU_SOURCE #endif #include @@ -16,6 +16,10 @@ extern "C" { # define KIT_ATOMIC(type_) type_ volatile +# ifdef __cplusplus +extern "C" { +# endif + enum { memory_order_relaxed, memory_order_consume, diff --git a/source/kit/bigint.h b/source/kit/bigint.h index b302c22..c948b57 100644 --- a/source/kit/bigint.h +++ b/source/kit/bigint.h @@ -2,6 +2,7 @@ #define KIT_BIGINT_H #include "string_ref.h" + #include #include diff --git a/source/kit/input_buffer.c b/source/kit/input_buffer.c index 1ea9e94..c59031f 100644 --- a/source/kit/input_buffer.c +++ b/source/kit/input_buffer.c @@ -67,16 +67,12 @@ static void buf_adjust(void *p, ptrdiff_t size) { } } -static ptrdiff_t min(ptrdiff_t a, ptrdiff_t b) { - if (a < b) - return a; - return b; -} - static ptrdiff_t buf_read(void *p, ptrdiff_t offset, kit_out_str_t destination) { internal_buffer_t *buf = (internal_buffer_t *) p; - ptrdiff_t n = min(destination.size, buf->data.size - offset); + ptrdiff_t n = destination.size < buf->data.size - offset + ? destination.size + : buf->data.size - offset; memcpy(destination.values, buf->data.values + offset, n); return n; } diff --git a/source/kit/input_stream.c b/source/kit/input_stream.c index df31c1d..7d8476b 100644 --- a/source/kit/input_stream.c +++ b/source/kit/input_stream.c @@ -20,17 +20,13 @@ static int check_type(void *state, ptrdiff_t type) { return basic != NULL && basic->type == type; } -static ptrdiff_t min(ptrdiff_t a, ptrdiff_t b) { - if (a < b) - return a; - return b; -} - static ptrdiff_t read_str(void *state, kit_out_str_t destination) { if (!check_type(state, input_stream_str)) return 0; kit_is_state_str_t *str = (kit_is_state_str_t *) state; - ptrdiff_t size = min(destination.size, str->string.size); + ptrdiff_t size = destination.size < str->string.size + ? destination.size + : str->string.size; memcpy(destination.values, str->string.values, size); str->string.values += size; str->string.size -= size; diff --git a/source/kit/mersenne_twister_64.h b/source/kit/mersenne_twister_64.h index f351194..548aea4 100644 --- a/source/kit/mersenne_twister_64.h +++ b/source/kit/mersenne_twister_64.h @@ -1,6 +1,10 @@ #ifndef KIT_MERSENNE_TWISTER_64_H #define KIT_MERSENNE_TWISTER_64_H +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif + #include #include diff --git a/source/kit/move_back.h b/source/kit/move_back.h index 6eee4cf..0927321 100644 --- a/source/kit/move_back.h +++ b/source/kit/move_back.h @@ -1,6 +1,10 @@ #ifndef KIT_MOVE_BACK_H #define KIT_MOVE_BACK_H +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif + #include #ifdef __cplusplus diff --git a/source/kit/mutex.h b/source/kit/mutex.h index 7816301..919d92a 100644 --- a/source/kit/mutex.h +++ b/source/kit/mutex.h @@ -2,9 +2,12 @@ #define KIT_MUTEX_H #ifndef KIT_DISABLE_SYSTEM_THREADS +# ifndef _GNU_SOURCE +# define _GNU_SOURCE +# endif + # include "thread_defs.h" -# define _GNU_SOURCE # include # if !defined(_WIN32) || defined(__CYGWIN__) diff --git a/source/kit/secure_random.h b/source/kit/secure_random.h index e7a80c2..21399b7 100644 --- a/source/kit/secure_random.h +++ b/source/kit/secure_random.h @@ -1,9 +1,12 @@ #ifndef KIT_SECURE_RANDOM_H #define KIT_SECURE_RANDOM_H +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif + #include "status.h" -#define _GNU_SOURCE #include #include diff --git a/source/kit/sha256.h b/source/kit/sha256.h index 806bff3..ce74ed9 100644 --- a/source/kit/sha256.h +++ b/source/kit/sha256.h @@ -1,6 +1,10 @@ #ifndef KIT_SHA256_H #define KIT_SHA256_H +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif + #include #include diff --git a/source/kit/sockets.h b/source/kit/sockets.h index 8afcee6..87e37e6 100644 --- a/source/kit/sockets.h +++ b/source/kit/sockets.h @@ -1,6 +1,10 @@ #ifndef KIT_SOCKETS_H #define KIT_SOCKETS_H +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif + #include "status.h" #ifndef KIT_DISABLE_SYSTEM_SOCKETS diff --git a/source/kit/status.h b/source/kit/status.h index 0e23151..e689c5f 100644 --- a/source/kit/status.h +++ b/source/kit/status.h @@ -18,7 +18,7 @@ enum { KIT_ERROR_SOCKET_CONTROL_FAILED }; -typedef int kit_status_t; +typedef signed int kit_status_t; #ifdef __cplusplus } diff --git a/source/kit/string_ref.h b/source/kit/string_ref.h index a5ad5c1..8cf1970 100644 --- a/source/kit/string_ref.h +++ b/source/kit/string_ref.h @@ -2,6 +2,7 @@ #define KIT_STRING_REF_H #include "array_ref.h" + #include #ifdef __cplusplus diff --git a/source/kit/thread.h b/source/kit/thread.h index e8fb7e8..92e6a5d 100644 --- a/source/kit/thread.h +++ b/source/kit/thread.h @@ -2,9 +2,12 @@ #define KIT_THREAD_H #ifndef KIT_DISABLE_SYSTEM_THREADS +# ifndef _GNU_SOURCE +# define _GNU_SOURCE +# endif + # include "thread_defs.h" -# define _GNU_SOURCE # include # include diff --git a/source/kit/types.h b/source/kit/types.h new file mode 100644 index 0000000..0251b75 --- /dev/null +++ b/source/kit/types.h @@ -0,0 +1,17 @@ +#ifndef KIT_TYPES_H +#define KIT_TYPES_H + +typedef signed char i8; +typedef signed short i16; +typedef signed int i32; +typedef signed long long i64; + +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned int u32; +typedef unsigned long long u64; + +typedef float f32; +typedef double f64; + +#endif diff --git a/source/kit_test/CMakeLists.txt b/source/kit_test/CMakeLists.txt deleted file mode 100644 index 56aa9a4..0000000 --- a/source/kit_test/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -target_sources( - kit_test - PUBLIC - $ - $ - PRIVATE - test.c bench.c) diff --git a/source/kit_test/_static.c b/source/kit_test/_static.c new file mode 100644 index 0000000..036b397 --- /dev/null +++ b/source/kit_test/_static.c @@ -0,0 +1,3 @@ +#include "test.c" + +#include "bench.c" diff --git a/source/kit_test/bench.c b/source/kit_test/bench.c index 9d439c3..dcf7249 100644 --- a/source/kit_test/bench.c +++ b/source/kit_test/bench.c @@ -1,12 +1,6 @@ #include "bench.h" -#define _GNU_SOURCE -#include -#include -#include -#include -#include -#include +#include "shared.inl.h" kit_benchs_list_t kit_benchs_list = { 0 }; @@ -57,17 +51,6 @@ static void bench_end(int i) { kit_benchs_list.v[i].duration_nsec[n] = sec * 1000000000 + nsec; } -enum { white, blue, light, yellow, red, green }; - -static char const *const color_codes[] = { - [white] = "\x1b[38m", [blue] = "\x1b[34m", [light] = "\x1b[37m", - [yellow] = "\x1b[33m", [red] = "\x1b[31m", [green] = "\x1b[32m" -}; - -static int print_color(int c) { - return printf("%s", color_codes[c]); -} - void kit_bench_register(char const *name, char const *file, kit_bench_run_fn fn) { int n = kit_benchs_list.size++; @@ -84,23 +67,11 @@ void kit_bench_register(char const *name, char const *file, static jmp_buf kit_bench_restore_execution; -static int const signums[] = { SIGINT, SIGILL, SIGABRT, - SIGFPE, SIGSEGV, SIGTERM }; - -static char const *const signames[] = { - [SIGINT] = "Interactive attention signal", - [SIGILL] = "Illegal instruction", - [SIGABRT] = "Abnormal termination", - [SIGFPE] = "Erroneous arithmetic operation", - [SIGSEGV] = "Invalid access to storage", - [SIGTERM] = "Termination request" -}; - -static void handle_signal(int signum) { +static void kit_bench_handle_signal(int signum) { longjmp(kit_bench_restore_execution, signum); } -static void setup_signals() { +static void kit_bench_setup_signals() { int i; for (i = 0; i < sizeof signums / sizeof *signums; i++) { @@ -110,7 +81,7 @@ static void setup_signals() { #else struct sigaction action; memset(&action, 0, sizeof action); - action.sa_handler = handle_signal; + action.sa_handler = kit_bench_handle_signal; sigaction(signums[i], &action, NULL); #endif @@ -151,7 +122,7 @@ int kit_run_benchmarks(int argc, char **argv) { char const *specific_bench = NULL; - setup_signals(); + kit_bench_setup_signals(); for (int i = 0; i < argc; i++) if (strcmp("--no-term-color", argv[i]) == 0) diff --git a/source/kit_test/bench.h b/source/kit_test/bench.h index f3d71b8..dd86c17 100644 --- a/source/kit_test/bench.h +++ b/source/kit_test/bench.h @@ -6,6 +6,7 @@ extern "C" { #endif #include "test.h" + #include #ifndef KIT_TEST_FILE diff --git a/source/kit_test/shared.inl.h b/source/kit_test/shared.inl.h new file mode 100644 index 0000000..e31c9f3 --- /dev/null +++ b/source/kit_test/shared.inl.h @@ -0,0 +1,38 @@ +#ifndef KIT_TEST_SHARED_INL_H +#define KIT_TEST_SHARED_INL_H + +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif + +#include +#include +#include +#include +#include +#include + +enum { white, blue, light, yellow, red, green }; + +static char const *const color_codes[] = { + [white] = "\x1b[38m", [blue] = "\x1b[34m", [light] = "\x1b[37m", + [yellow] = "\x1b[33m", [red] = "\x1b[31m", [green] = "\x1b[32m" +}; + +static int print_color(int c) { + return printf("%s", color_codes[c]); +} + +static int const signums[] = { SIGINT, SIGILL, SIGABRT, + SIGFPE, SIGSEGV, SIGTERM }; + +static char const *const signames[] = { + [SIGINT] = "Interactive attention signal", + [SIGILL] = "Illegal instruction", + [SIGABRT] = "Abnormal termination", + [SIGFPE] = "Erroneous arithmetic operation", + [SIGSEGV] = "Invalid access to storage", + [SIGTERM] = "Termination request" +}; + +#endif diff --git a/source/kit_test/test.c b/source/kit_test/test.c index d1e048c..034d1e7 100644 --- a/source/kit_test/test.c +++ b/source/kit_test/test.c @@ -1,11 +1,6 @@ #include "test.h" -#define _GNU_SOURCE -#include -#include -#include -#include -#include +#include "shared.inl.h" kit_tests_list_t kit_tests_list = { 0 }; @@ -30,17 +25,6 @@ static long long sec_to_ms(long long sec) { return 1000 * sec; } -enum { white, blue, light, yellow, red, green }; - -static char const *const color_codes[] = { - [white] = "\x1b[38m", [blue] = "\x1b[34m", [light] = "\x1b[37m", - [yellow] = "\x1b[33m", [red] = "\x1b[31m", [green] = "\x1b[32m" -}; - -static int print_color(int c) { - return printf("%s", color_codes[c]); -} - void kit_test_register(char const *name, char const *file, kit_test_run_fn fn) { int n = kit_tests_list.size++; @@ -54,23 +38,11 @@ void kit_test_register(char const *name, char const *file, static jmp_buf kit_test_restore_execution; -static int const signums[] = { SIGINT, SIGILL, SIGABRT, - SIGFPE, SIGSEGV, SIGTERM }; - -static char const *const signames[] = { - [SIGINT] = "Interactive attention signal", - [SIGILL] = "Illegal instruction", - [SIGABRT] = "Abnormal termination", - [SIGFPE] = "Erroneous arithmetic operation", - [SIGSEGV] = "Invalid access to storage", - [SIGTERM] = "Termination request" -}; - -static void handle_signal(int signum) { +static void kit_test_handle_signal(int signum) { longjmp(kit_test_restore_execution, signum); } -static void setup_signals() { +static void kit_test_setup_signals() { int i; for (i = 0; i < sizeof signums / sizeof *signums; i++) { @@ -80,7 +52,7 @@ static void setup_signals() { #else struct sigaction action; memset(&action, 0, sizeof action); - action.sa_handler = handle_signal; + action.sa_handler = kit_test_handle_signal; sigaction(signums[i], &action, NULL); #endif @@ -113,7 +85,7 @@ int kit_run_tests(int argc, char **argv) { char const *specific_test = NULL; - setup_signals(); + kit_test_setup_signals(); for (i = 0; i < argc; i++) if (strcmp("--no-term-color", argv[i]) == 0) diff --git a/source/kit_test/test.h b/source/kit_test/test.h index 8732366..6584cbe 100644 --- a/source/kit_test/test.h +++ b/source/kit_test/test.h @@ -5,6 +5,10 @@ extern "C" { #endif +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif + #include #ifndef KIT_TEST_FILE diff --git a/source/test/CMakeLists.txt b/source/test/CMakeLists.txt deleted file mode 100644 index 4435be1..0000000 --- a/source/test/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -add_subdirectory(unittests) -add_subdirectory(programs) diff --git a/source/test/programs/CMakeLists.txt b/source/test/programs/CMakeLists.txt deleted file mode 100644 index 81332cf..0000000 --- a/source/test/programs/CMakeLists.txt +++ /dev/null @@ -1,49 +0,0 @@ -project( - ${KIT_PROJECT}_test_programs - VERSION 0.1.1 - DESCRIPTION "Kit test programs" - LANGUAGES C CXX) - -if(KIT_ENABLE_TESTING) - add_executable(too_many_tests too_many_tests.c) - target_link_libraries(too_many_tests kit_test) - add_test( - NAME too_many_tests_test - COMMAND too_many_tests --quiet) - set_tests_properties( - too_many_tests_test - PROPERTIES - TIMEOUT "15") - - add_executable(too_many_assertions too_many_assertions.c) - target_link_libraries(too_many_assertions kit_test) - add_test( - NAME too_many_assertions_test - COMMAND too_many_assertions --quiet) - set_tests_properties( - too_many_assertions_test - PROPERTIES - TIMEOUT "15") - - add_executable(cpp_example cpp_example.cpp) - target_link_libraries(cpp_example kit_test) - add_test( - NAME cpp_example_test - COMMAND cpp_example --quiet) - set_tests_properties( - cpp_example_test - PROPERTIES - TIMEOUT "15") - - if(NOT MSVC) - add_executable(signals signals.cpp) - target_link_libraries(signals kit_test) - add_test( - NAME signals_test - COMMAND signals --no-carriage-return) - set_tests_properties( - signals_test - PROPERTIES - TIMEOUT "15") - endif() -endif() diff --git a/source/test/programs/cpp_example.cpp b/source/test/programs/cpp_example.cpp deleted file mode 100644 index 523186b..0000000 --- a/source/test/programs/cpp_example.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#include "../../kit_test/test.h" - -TEST("foo") { - REQUIRE(20 + 22 == 42); -} - -TEST("bar") { - REQUIRE(true); -} - -int main(int argc, char **argv) { - return run_tests(argc, argv); -} diff --git a/source/test/programs/signals.cpp b/source/test/programs/signals.cpp deleted file mode 100644 index e2532c2..0000000 --- a/source/test/programs/signals.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include "../../kit_test/test.h" - -#include -#include - -/* FIXME - * MSVC tests fail in GitHub Actions. - */ - -TEST("c++ exception") { - throw std::exception(); -} - -TEST("abort") { - abort(); -} - -TEST("invalid access") { - *(volatile int *) nullptr = 42; -} - -int main(int argc, char **argv) { -#ifndef _MSC_VER - if (run_tests(argc, argv) != 1) - return 1; -#endif - - return 0; -} diff --git a/source/test/programs/too_many_assertions.c b/source/test/programs/too_many_assertions.c deleted file mode 100644 index 06b440b..0000000 --- a/source/test/programs/too_many_assertions.c +++ /dev/null @@ -1,13 +0,0 @@ -#include "../../kit_test/test.h" - -TEST("foo") { - int i; - for (i = 0; i <= KIT_TEST_ASSERTIONS_LIMIT; i++) REQUIRE(1); -} - -int main(int argc, char **argv) { - if (run_tests(argc, argv) != 1) - return 1; - - return 0; -} diff --git a/source/test/programs/too_many_tests.c b/source/test/programs/too_many_tests.c deleted file mode 100644 index ac1cbf7..0000000 --- a/source/test/programs/too_many_tests.c +++ /dev/null @@ -1,14 +0,0 @@ -#include "../../kit_test/test.h" - -void bar(int index, kit_test_report_fn report) { } - -int main(int argc, char **argv) { - int i; - for (i = 0; i <= KIT_TESTS_SIZE_LIMIT; i++) - test_register("foo", __FILE__, bar); - - if (run_tests(argc, argv) != 1) - return 1; - - return 0; -} diff --git a/source/test/unittests/CMakeLists.txt b/source/test/unittests/CMakeLists.txt deleted file mode 100644 index e071ed4..0000000 --- a/source/test/unittests/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -target_sources( - kit_test_suite - PRIVATE - async_function.test.c bigint.test.c mutex.test.c test_duration.test.c - main.test.c string_ref.test.c atomic.test.c foo.bench.c thread.test.c - array_ref.test.c input_stream.test.c sha256.test.c lower_bound.test.c - secure_random.test.c condition_variable.test.c mersenne_twister_64.test.c - input_buffer.test.c move_back.test.c dynamic_array.test.c file.test.c) diff --git a/source/test/unittests/array_ref.test.c b/source/test/unittests/array_ref.test.c deleted file mode 100644 index c6083ee..0000000 --- a/source/test/unittests/array_ref.test.c +++ /dev/null @@ -1,65 +0,0 @@ -#include "../../kit/array_ref.h" - -#define KIT_TEST_FILE array_ref -#include "../../kit_test/test.h" - -TEST("array ref const wrap") { - int foo[] = { 1, 2, 3 }; - AR_WRAP(ref, int, foo); - - REQUIRE(ref.size == 3); - REQUIRE(ref.values[0] == 1); - REQUIRE(ref.values[1] == 2); - REQUIRE(ref.values[2] == 3); -} - -TEST("array ref wrap") { - int foo[] = { 1, 2, 3 }; - AR_MUT_WRAP(ref, int, foo); - - REQUIRE(ref.size == 3); - REQUIRE(ref.values[0] == 1); - REQUIRE(ref.values[1] == 2); - REQUIRE(ref.values[2] == 3); - - ref.values[1] = 42; - REQUIRE(ref.values[1] == 42); -} - -TEST("array ref equal") { - int foo[] = { 1, 2, 3, 4, 5, 6, 7 }; - int bar[] = { 3, 4, 5 }; - - AR(int) foo_ref = { .size = 3, .values = foo + 2 }; - AR(int) bar_ref = { .size = 3, .values = bar }; - - REQUIRE(AR_EQUAL(foo_ref, bar_ref)); -} - -static int compare(int const *left, int const *right) { - return *left - *right; -} - -TEST("array ref compare") { - int foo[] = { 1, 2, 3, 5 }; - int bar[] = { 1, 2, 4, 5 }; - - AR(int) foo_ref = { .size = 3, .values = foo }; - AR(int) bar_ref = { .size = 3, .values = bar }; - - REQUIRE(AR_COMPARE(foo_ref, bar_ref, compare) < 0); - REQUIRE(AR_COMPARE(bar_ref, foo_ref, compare) > 0); - REQUIRE(AR_COMPARE(foo_ref, foo_ref, compare) == 0); -} - -TEST("array ref different element sizes") { - int foo[] = { 1, 2, 3 }; - char bar[] = { 1, 2, 3 }; - - AR(int) foo_ref = { .size = 3, .values = foo }; - AR(char) bar_ref = { .size = 3, .values = bar }; - - REQUIRE(!AR_EQUAL(foo_ref, bar_ref)); - REQUIRE(AR_COMPARE(foo_ref, bar_ref, compare) > 0); - REQUIRE(AR_COMPARE(bar_ref, foo_ref, compare) < 0); -} diff --git a/source/test/unittests/async_function.test.c b/source/test/unittests/async_function.test.c deleted file mode 100644 index 32aff4e..0000000 --- a/source/test/unittests/async_function.test.c +++ /dev/null @@ -1,132 +0,0 @@ -#include "../../kit/async_function.h" - -#define KIT_TEST_FILE async_function -#include "../../kit_test/test.h" - -AF_STATE(int, test_foo, ); -static AF_DECL(test_foo); - -CORO_IMPL(test_foo) { - AF_RETURN(42); -} -CORO_END - -AF_STATE(int, test_bar, ); -static AF_DECL(test_bar); - -CORO_IMPL(test_bar) { - AF_YIELD_VOID; - AF_RETURN(42); -} -CORO_END - -STATIC_CORO(int, test_gen, int i; int min; int max;) { - for (self->i = self->min; self->i < self->max; self->i++) - AF_YIELD(self->i); - AF_RETURN(self->max); -} -CORO_END - -STATIC_CORO_VOID(test_task, ) { - AF_YIELD_VOID; - AF_YIELD_VOID; - AF_RETURN_VOID; -} -CORO_END - -STATIC_CORO_VOID(test_nest_task, AF_TYPE(test_task) promise;) { - AF_INIT(self->promise, test_task, ); - AF_AWAIT(self->promise); - AF_AWAIT(self->promise); - AF_AWAIT(self->promise); -} -CORO_END - -STATIC_CORO(int, test_nest_generator, AF_TYPE(test_gen) promise;) { - AF_INIT(self->promise, test_gen, .min = 1, .max = 3); - AF_YIELD_AWAIT(self->promise); -} -CORO_END - -TEST("coroutine create") { - AF_CREATE(promise, test_foo, ); - REQUIRE(!AF_FINISHED(promise)); -} - -TEST("coroutine init") { - AF_TYPE(test_foo) promise; - AF_INIT(promise, test_foo, ); - REQUIRE(!AF_FINISHED(promise)); -} - -TEST("coroutine init with value") { - AF_TYPE(test_foo) promise; - AF_INIT(promise, test_foo, .return_value = 42); - REQUIRE(promise.return_value == 42); - REQUIRE(!AF_FINISHED(promise)); -} - -TEST("coroutine create with value") { - AF_CREATE(promise, test_foo, .return_value = -1); - REQUIRE(promise.return_value == -1); - REQUIRE(!AF_FINISHED(promise)); -} - -TEST("coroutine execute and return") { - AF_CREATE(promise, test_foo, ); - REQUIRE(AF_NEXT(promise) == 42); - REQUIRE(AF_FINISHED(promise)); -} - -TEST("coroutine execute two steps") { - AF_CREATE(promise, test_bar, .return_value = 0); - AF_EXECUTE(promise); - REQUIRE(promise.return_value == 0); - AF_EXECUTE(promise); - REQUIRE(promise.return_value == 42); -} - -TEST("coroutine generator") { - int i; - AF_CREATE(promise, test_gen, .min = 10, .max = 15); - for (i = 0; i <= 5; i++) REQUIRE(AF_NEXT(promise) == 10 + i); -} - -TEST("coroutine status finished") { - AF_CREATE(promise, test_bar, ); - REQUIRE(!AF_FINISHED(promise)); - AF_EXECUTE(promise); - REQUIRE(!AF_FINISHED(promise)); - AF_EXECUTE(promise); - REQUIRE(AF_FINISHED(promise)); -} - -TEST("coroutine task") { - AF_CREATE(promise, test_task, ); - AF_EXECUTE(promise); - REQUIRE(!AF_FINISHED(promise)); - AF_EXECUTE(promise); - REQUIRE(!AF_FINISHED(promise)); - AF_EXECUTE(promise); - REQUIRE(AF_FINISHED(promise)); -} - -TEST("coroutine nested task") { - AF_CREATE(promise, test_nest_task, ); - AF_EXECUTE(promise); - REQUIRE(!AF_FINISHED(promise)); - AF_EXECUTE(promise); - REQUIRE(!AF_FINISHED(promise)); - AF_EXECUTE(promise); - REQUIRE(AF_FINISHED(promise)); -} - -TEST("coroutine nested generator") { - AF_CREATE(promise, test_nest_generator, ); - REQUIRE(AF_NEXT(promise) == 1); - REQUIRE(AF_NEXT(promise) == 2); - REQUIRE(AF_NEXT(promise) == 3); - REQUIRE(!AF_FINISHED(promise)); - AF_EXECUTE(promise); - REQUIRE(AF_FINISHED(promise)); -} diff --git a/source/test/unittests/atomic.test.c b/source/test/unittests/atomic.test.c deleted file mode 100644 index 7d8b35a..0000000 --- a/source/test/unittests/atomic.test.c +++ /dev/null @@ -1,218 +0,0 @@ -#include "../../kit/atomic.h" -#include "../../kit/thread.h" - -#define KIT_TEST_FILE atomic -#include "../../kit_test/test.h" - -TEST("atomic store and load") { - ATOMIC(int) value; - atomic_store_explicit(&value, 20, memory_order_relaxed); - REQUIRE(atomic_load_explicit(&value, memory_order_relaxed) == 20); -} - -TEST("atomic exchange") { - ATOMIC(int) value; - atomic_store_explicit(&value, 20, memory_order_relaxed); - REQUIRE(atomic_exchange_explicit(&value, 42, - memory_order_relaxed) == 20); - REQUIRE(atomic_load_explicit(&value, memory_order_relaxed) == 42); -} - -TEST("atomic fetch add") { - ATOMIC(int) value; - atomic_store_explicit(&value, 20, memory_order_relaxed); - REQUIRE(atomic_fetch_add_explicit(&value, 22, - memory_order_relaxed) == 20); - REQUIRE(atomic_load_explicit(&value, memory_order_relaxed) == 42); -} - -enum { THREAD_COUNT = 20, TICK_COUNT = 10000 }; - -static int test_8_(void *p) { - ptrdiff_t i; - ATOMIC(int8_t) *x = (ATOMIC(int8_t) *) p; - - for (i = 0; i < TICK_COUNT; i++) { - atomic_fetch_add_explicit(x, 20, memory_order_relaxed); - thrd_yield(); - atomic_fetch_add_explicit(x, 22, memory_order_relaxed); - thrd_yield(); - atomic_fetch_add_explicit(x, -42, memory_order_relaxed); - thrd_yield(); - } - - return 0; -} - -TEST("atomic types") { - ATOMIC(int8_t) b_1; - ATOMIC(int8_t) b_2; - ATOMIC(int16_t) i16; - ATOMIC(int32_t) i32; - ATOMIC(int64_t) i64; - - atomic_store_explicit(&b_1, 42, memory_order_relaxed); - atomic_store_explicit(&b_2, 43, memory_order_relaxed); - atomic_store_explicit(&i16, 4242, memory_order_relaxed); - atomic_store_explicit(&i32, 42424242, memory_order_relaxed); - atomic_store_explicit(&i64, 4242424242424242ll, - memory_order_relaxed); - - atomic_fetch_add_explicit(&b_1, -20, memory_order_relaxed); - atomic_fetch_add_explicit(&b_2, -20, memory_order_relaxed); - atomic_fetch_add_explicit(&i16, -2020, memory_order_relaxed); - atomic_fetch_add_explicit(&i32, -20202020, memory_order_relaxed); - atomic_fetch_add_explicit(&i64, -2020202020202020ll, - memory_order_relaxed); - - REQUIRE(atomic_exchange_explicit(&b_1, 0, memory_order_relaxed) == - 22); - REQUIRE(atomic_exchange_explicit(&b_2, 0, memory_order_relaxed) == - 23); - REQUIRE(atomic_exchange_explicit(&i16, 0, memory_order_relaxed) == - 2222); - REQUIRE(atomic_exchange_explicit(&i32, 0, memory_order_relaxed) == - 22222222); - REQUIRE(atomic_exchange_explicit(&i64, 0, memory_order_relaxed) == - 2222222222222222ll); - - REQUIRE(atomic_load_explicit(&b_1, memory_order_relaxed) == 0); - REQUIRE(atomic_load_explicit(&b_2, memory_order_relaxed) == 0); - REQUIRE(atomic_load_explicit(&i16, memory_order_relaxed) == 0); - REQUIRE(atomic_load_explicit(&i32, memory_order_relaxed) == 0); - REQUIRE(atomic_load_explicit(&i64, memory_order_relaxed) == 0ll); -} - -TEST("atomic byte concurrency") { - ptrdiff_t i; - - ATOMIC(int8_t) foo; - ATOMIC(int8_t) bar; - - atomic_store_explicit(&foo, 42, memory_order_relaxed); - atomic_store_explicit(&bar, 43, memory_order_relaxed); - - thrd_t threads[THREAD_COUNT]; - for (i = 0; i < THREAD_COUNT; i++) - REQUIRE_EQ(thrd_create(threads + i, test_8_, - (void *) ((i % 2) ? &foo : &bar)), - thrd_success); - for (i = 0; i < THREAD_COUNT; i++) thrd_join(threads[i], NULL); - - REQUIRE(atomic_load_explicit(&foo, memory_order_relaxed) == 42); - REQUIRE(atomic_load_explicit(&bar, memory_order_relaxed) == 43); -} - -static int test_16_(void *p) { - ptrdiff_t i; - - ATOMIC(int16_t) *x = (ATOMIC(int16_t) *) p; - - for (i = 0; i < TICK_COUNT; i++) { - atomic_fetch_add_explicit(x, 2020, memory_order_relaxed); - thrd_yield(); - atomic_fetch_add_explicit(x, 2222, memory_order_relaxed); - thrd_yield(); - atomic_fetch_add_explicit(x, -4242, memory_order_relaxed); - thrd_yield(); - } - - return 0; -} - -TEST("atomic int16 concurrency") { - ptrdiff_t i; - - ATOMIC(int16_t) foo; - ATOMIC(int16_t) bar; - - atomic_store_explicit(&foo, 42, memory_order_relaxed); - atomic_store_explicit(&bar, 43, memory_order_relaxed); - - thrd_t threads[THREAD_COUNT]; - for (i = 0; i < THREAD_COUNT; i++) - REQUIRE_EQ(thrd_create(threads + i, test_16_, - (void *) ((i % 2) ? &foo : &bar)), - thrd_success); - for (i = 0; i < THREAD_COUNT; i++) thrd_join(threads[i], NULL); - - REQUIRE(atomic_load_explicit(&foo, memory_order_relaxed) == 42); - REQUIRE(atomic_load_explicit(&bar, memory_order_relaxed) == 43); -} - -static int test_32_(void *p) { - ptrdiff_t i; - - ATOMIC(int32_t) *x = (ATOMIC(int32_t) *) p; - - for (i = 0; i < TICK_COUNT; i++) { - atomic_fetch_add_explicit(x, 202020, memory_order_relaxed); - thrd_yield(); - atomic_fetch_add_explicit(x, 222222, memory_order_relaxed); - thrd_yield(); - atomic_fetch_add_explicit(x, -424242, memory_order_relaxed); - thrd_yield(); - } - - return 0; -} - -TEST("atomic int32 concurrency") { - ptrdiff_t i; - - ATOMIC(int32_t) foo; - ATOMIC(int32_t) bar; - - atomic_store_explicit(&foo, 42, memory_order_relaxed); - atomic_store_explicit(&bar, 43, memory_order_relaxed); - - thrd_t threads[THREAD_COUNT]; - for (i = 0; i < THREAD_COUNT; i++) - REQUIRE_EQ(thrd_create(threads + i, test_32_, - (void *) ((i % 2) ? &foo : &bar)), - thrd_success); - for (i = 0; i < THREAD_COUNT; i++) thrd_join(threads[i], NULL); - - REQUIRE(atomic_load_explicit(&foo, memory_order_relaxed) == 42); - REQUIRE(atomic_load_explicit(&bar, memory_order_relaxed) == 43); -} - -static int test_64_(void *p) { - ptrdiff_t i; - - ATOMIC(int64_t) *x = (ATOMIC(int64_t) *) p; - - for (i = 0; i < TICK_COUNT; i++) { - atomic_fetch_add_explicit(x, 20202020202020ll, - memory_order_relaxed); - thrd_yield(); - atomic_fetch_add_explicit(x, 22222222222222ll, - memory_order_relaxed); - thrd_yield(); - atomic_fetch_add_explicit(x, -42424242424242ll, - memory_order_relaxed); - thrd_yield(); - } - - return 0; -} - -TEST("atomic int64 concurrency") { - ptrdiff_t i; - - ATOMIC(int64_t) foo; - ATOMIC(int64_t) bar; - - atomic_store_explicit(&foo, 42, memory_order_relaxed); - atomic_store_explicit(&bar, 43, memory_order_relaxed); - - thrd_t threads[THREAD_COUNT]; - for (i = 0; i < THREAD_COUNT; i++) - REQUIRE_EQ(thrd_create(threads + i, test_64_, - (void *) ((i % 2) ? &foo : &bar)), - thrd_success); - for (i = 0; i < THREAD_COUNT; i++) thrd_join(threads[i], NULL); - - REQUIRE(atomic_load_explicit(&foo, memory_order_relaxed) == 42); - REQUIRE(atomic_load_explicit(&bar, memory_order_relaxed) == 43); -} diff --git a/source/test/unittests/bigint.test.c b/source/test/unittests/bigint.test.c deleted file mode 100644 index 260b0ec..0000000 --- a/source/test/unittests/bigint.test.c +++ /dev/null @@ -1,108 +0,0 @@ -#define KIT_BIGINT_SIZE 256 -#include "../../kit/bigint.h" - -#define KIT_TEST_FILE bigint -#include "../../kit_test/test.h" - -#if __STDC_VERSION__ >= 199901L -static_assert(sizeof(bigint_t) == 256, "KIT_BIGINT_SIZE check"); -#endif - -TEST("bigint bin hex") { - REQUIRE(bi_equal(HEX("10"), BIN("10000"))); - REQUIRE(bi_equal(HEX("20"), BIN("100000"))); - REQUIRE(bi_equal(HEX("40"), BIN("1000000"))); - REQUIRE(bi_equal(HEX("80"), BIN("10000000"))); - REQUIRE(bi_equal(HEX("310"), BIN("1100010000"))); - REQUIRE(bi_equal(HEX("420"), BIN("10000100000"))); - REQUIRE(bi_equal(HEX("540"), BIN("10101000000"))); - REQUIRE(bi_equal(HEX("780"), BIN("11110000000"))); -} - -TEST("bigint hex add") { - REQUIRE(bi_equal( - bi_add(HEX("4242424242424242424242424242424242424242"), - HEX("1111111111111111111111111111111111111111")), - HEX("5353535353535353535353535353535353535353"))); -} - -TEST("bigint hex sub") { - REQUIRE(bi_equal( - bi_sub(HEX("4242424242424242424242424242424242424242"), - HEX("1111111111111111111111111111111111111111")), - HEX("3131313131313131313131313131313131313131"))); -} - -TEST("bigint base58") { - REQUIRE(bi_equal(BASE58("31"), bi_uint32(58 * 2))); -} - -TEST("bigint base58 add") { - REQUIRE(bi_equal( - bi_add(BASE58("4242424242424242424242424242424242424242"), - BASE58("2222222222222222222222222222222222222222")), - BASE58("5353535353535353535353535353535353535353"))); -} - -TEST("bigint base58 sub") { - REQUIRE(bi_equal( - bi_sub(BASE58("4242424242424242424242424242424242424242"), - BASE58("2222222222222222222222222222222222222222")), - BASE58("3131313131313131313131313131313131313131"))); -} - -TEST("bigint base58 mul") { - REQUIRE(bi_equal(bi_mul(BASE58("2111111111111111111111"), - BASE58("foofoofoofoofoo")), - BASE58("foofoofoofoofoo111111111111111111111"))); -} - -TEST("bigint div") { - REQUIRE(bi_equal(bi_div(bi_int32(-1), bi_int32(-1)).quotient, - bi_int32(1))); - REQUIRE(bi_equal(bi_div(bi_int32(-1), bi_int32(-1)).remainder, - bi_int32(0))); - REQUIRE(bi_equal(bi_div(bi_int32(-3), bi_int32(2)).quotient, - bi_int32(-2))); - REQUIRE(bi_equal(bi_div(bi_int32(-3), bi_int32(2)).remainder, - bi_int32(1))); - REQUIRE(bi_equal(bi_div(bi_int32(3), bi_int32(-2)).quotient, - bi_int32(-1))); - REQUIRE(bi_equal(bi_div(bi_int32(3), bi_int32(-2)).remainder, - bi_int32(1))); - REQUIRE(bi_equal(bi_div(bi_int32(-3), bi_int32(4)).quotient, - bi_int32(-1))); - REQUIRE(bi_equal(bi_div(bi_int32(-3), bi_int32(4)).remainder, - bi_int32(3))); - REQUIRE(bi_equal(bi_div(bi_int32(3), bi_int32(-4)).quotient, - bi_int32(0))); - REQUIRE(bi_equal(bi_div(bi_int32(3), bi_int32(-4)).remainder, - bi_int32(3))); - - REQUIRE( - bi_equal(bi_div(HEX("100"), HEX("10")).quotient, HEX("10"))); - - REQUIRE(bi_equal(bi_div(bi_mul(BASE58("foofoofoofoofoofoo"), - BASE58("barbarbarbarbarbar")), - BASE58("barbarbarbarbarbar")) - .quotient, - BASE58("foofoofoofoofoofoo"))); - - REQUIRE(bi_equal(bi_div(bi_mul(BASE58("foofoofoofoofoofoofoofoo"), - BASE58("barbarbarbarbarbar")), - BASE58("barbarbarbarbarbar")) - .quotient, - BASE58("foofoofoofoofoofoofoofoo"))); - - REQUIRE(bi_equal( - bi_div( - bi_mul(BASE58("foofoofoofoofoofoofoofoofoofoofoofoofoofoofo" - "ofoofoofoo"), - BASE58("barbarbarbarbarbarbarbarbarbarbarbarbarbarba" - "rbar")), - BASE58("barbarbarbarbarbarbarbarbarbarbarbarbarbarbarbar")) - .quotient, - BASE58( - "foofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoo"))); -} - diff --git a/source/test/unittests/condition_variable.test.c b/source/test/unittests/condition_variable.test.c deleted file mode 100644 index 2dba7ca..0000000 --- a/source/test/unittests/condition_variable.test.c +++ /dev/null @@ -1,84 +0,0 @@ -#include "../../kit/condition_variable.h" -#include "../../kit/thread.h" - -#define KIT_TEST_FILE condition_variable -#include "../../kit_test/test.h" - -typedef struct { - mtx_t m; - int in; - int out; - cnd_t send; - cnd_t receive; - int value; -} test_data_t; - -static int test_run(void *p) { - test_data_t *data = (test_data_t *) p; - - mtx_lock(&data->m); - data->value = 20; - data->out = 1; - mtx_unlock(&data->m); - - cnd_broadcast(&data->send); - - mtx_lock(&data->m); - if (data->in == 0) - cnd_wait(&data->receive, &data->m); - data->in = 0; - data->value = 22; - data->out = 1; - mtx_unlock(&data->m); - - cnd_broadcast(&data->send); - - return 0; -} - -TEST("condition variable") { - int i; - int ok = 1; - - for (i = 0; i < 10; i++) { - test_data_t data; - - data.in = 0; - data.out = 0; - data.value = 0; - - ok = ok && (mtx_init(&data.m, mtx_plain) == thrd_success); - ok = ok && (cnd_init(&data.send) == thrd_success); - ok = ok && (cnd_init(&data.receive) == thrd_success); - - thrd_t t; - ok = ok && (thrd_create(&t, test_run, &data) == thrd_success); - - ok = ok && (mtx_lock(&data.m) == thrd_success); - if (data.out == 0) - ok = ok && (cnd_wait(&data.send, &data.m) == thrd_success); - data.out = 0; - int x = data.value; - data.in = 1; - ok = ok && (mtx_unlock(&data.m) == thrd_success); - - ok = ok && (cnd_broadcast(&data.receive) == thrd_success); - - ok = ok && (mtx_lock(&data.m) == thrd_success); - if (data.out == 0) - ok = ok && (cnd_wait(&data.send, &data.m) == thrd_success); - data.out = 0; - x += data.value; - ok = ok && (mtx_unlock(&data.m) == thrd_success); - - ok = ok && (thrd_join(t, NULL) == thrd_success); - - mtx_destroy(&data.m); - cnd_destroy(&data.send); - cnd_destroy(&data.receive); - - ok = ok && (x == 42); - } - - REQUIRE(ok); -} diff --git a/source/test/unittests/dynamic_array.test.c b/source/test/unittests/dynamic_array.test.c deleted file mode 100644 index fad8d6d..0000000 --- a/source/test/unittests/dynamic_array.test.c +++ /dev/null @@ -1,174 +0,0 @@ -#include "../../kit/dynamic_array.h" - -#define KIT_TEST_FILE dynamic_array -#include "../../kit_test/test.h" - -TEST("dynamic array empty") { - DA_CREATE(v, char, 0); - - REQUIRE(v.size == 0); - - DA_DESTROY(v); -} - -TEST("dynamic array resize") { - DA_CREATE(v, char, 0); - DA_RESIZE(v, 10); - - REQUIRE(v.size == 10); - - DA_DESTROY(v); -} - -TEST("dynamic array grow") { - DA_CREATE(v, char, 2); - DA_RESIZE(v, 10); - - REQUIRE(v.size == 10); - - DA_DESTROY(v); -} - -TEST("dynamic array diminish") { - DA_CREATE(v, char, 10); - DA_RESIZE(v, 9); - - REQUIRE(v.size == 9); - - DA_DESTROY(v); -} - -TEST("dynamic array of chars") { - DA_CREATE(v, char, 100); - - REQUIRE(v.size == 100); - REQUIRE(v.capacity >= 100); - REQUIRE(v.values != NULL); - - DA_DESTROY(v); -} - -TEST("dynamic array push") { - DA_CREATE(v, char, 0); - DA_APPEND(v, 'x'); - - REQUIRE(v.size == 1); - REQUIRE(v.values[0] == 'x'); - - DA_DESTROY(v); -} - -TEST("dynamic array insert front") { - DA_CREATE(v, char, 3); - - v.values[0] = 'a'; - v.values[1] = 'b'; - v.values[2] = 'c'; - - DA_INSERT(v, 0, 'x'); - - REQUIRE(v.size == 4); - REQUIRE(v.values[0] == 'x'); - REQUIRE(v.values[1] == 'a'); - REQUIRE(v.values[2] == 'b'); - REQUIRE(v.values[3] == 'c'); - - DA_DESTROY(v); -} - -TEST("dynamic array insert back") { - DA_CREATE(v, char, 3); - - v.values[0] = 'a'; - v.values[1] = 'b'; - v.values[2] = 'c'; - - DA_INSERT(v, 3, 'x'); - - REQUIRE(v.size == 4); - REQUIRE(v.values[0] == 'a'); - REQUIRE(v.values[1] == 'b'); - REQUIRE(v.values[2] == 'c'); - REQUIRE(v.values[3] == 'x'); - - DA_DESTROY(v); -} - -TEST("dynamic array insert middle") { - DA_CREATE(v, char, 3); - - v.values[0] = 'a'; - v.values[1] = 'b'; - v.values[2] = 'c'; - - DA_INSERT(v, 2, 'x'); - - REQUIRE(v.size == 4); - REQUIRE(v.values[0] == 'a'); - REQUIRE(v.values[1] == 'b'); - REQUIRE(v.values[2] == 'x'); - REQUIRE(v.values[3] == 'c'); - - DA_DESTROY(v); -} - -TEST("dynamic array erase front") { - DA_CREATE(v, char, 3); - - v.values[0] = 'a'; - v.values[1] = 'b'; - v.values[2] = 'c'; - - DA_ERASE(v, 0); - - REQUIRE(v.size == 2); - REQUIRE(v.values[0] == 'b'); - REQUIRE(v.values[1] == 'c'); - - DA_DESTROY(v); -} - -TEST("dynamic array erase back") { - DA_CREATE(v, char, 3); - - v.values[0] = 'a'; - v.values[1] = 'b'; - v.values[2] = 'c'; - - DA_ERASE(v, 2); - - REQUIRE(v.size == 2); - REQUIRE(v.values[0] == 'a'); - REQUIRE(v.values[1] == 'b'); - - DA_DESTROY(v); -} - -TEST("dynamic array erase middle") { - DA_CREATE(v, char, 3); - - v.values[0] = 'a'; - v.values[1] = 'b'; - v.values[2] = 'c'; - - DA_ERASE(v, 1); - - REQUIRE(v.size == 2); - REQUIRE(v.values[0] == 'a'); - REQUIRE(v.values[1] == 'c'); - - DA_DESTROY(v); -} - -TEST("dynamic array of ints") { - DA_CREATE(v, int, 10); - DA_RESIZE(v, 5); - v.values[4] = 42; - DA_APPEND(v, 43); - - REQUIRE(v.size == 6); - REQUIRE(v.values[4] == 42); - REQUIRE(v.values[5] == 43); - - DA_DESTROY(v); -} diff --git a/source/test/unittests/file.test.c b/source/test/unittests/file.test.c deleted file mode 100644 index 732f122..0000000 --- a/source/test/unittests/file.test.c +++ /dev/null @@ -1,220 +0,0 @@ -#include "../../kit/file.h" -#include "../../kit/string_ref.h" -#include - -#define KIT_TEST_FILE file -#include "../../kit_test/test.h" - -TEST("file path cache") { - kit_allocator_t alloc = kit_alloc_default(); - - string_t user = path_user(alloc); - string_t cache = path_cache(alloc); - - DA_RESIZE(cache, cache.size + 1); - cache.values[cache.size - 1] = '\0'; - DA_RESIZE(cache, cache.size - 1); - - string_t expected = -#if defined(_WIN32) && !defined(__CYGWIN__) - path_join(WRAP_STR(user), SZ("AppData" PATH_DELIM "Local"), - alloc); -#elif defined(__APPLE__) - path_join(WRAP_STR(user), SZ("Library" PATH_DELIM "Caches"), - alloc); -#else - path_join(WRAP_STR(user), SZ(".cache"), alloc); -#endif - - REQUIRE(AR_EQUAL(cache, expected)); - - DA_DESTROY(user); - DA_DESTROY(cache); - DA_DESTROY(expected); -} - -TEST("file path normalize one") { - str_t foo = SZ("foo/bar/../baz"); - str_t foo_norm = SZ("foo" PATH_DELIM "baz"); - - string_t bar = path_norm(foo, kit_alloc_default()); - - REQUIRE(AR_EQUAL(foo_norm, bar)); - - DA_DESTROY(bar); -} - -TEST("file path normalize two") { - str_t foo = SZ("foo/bar/../../baz"); - str_t foo_norm = SZ("baz"); - - string_t bar = path_norm(foo, kit_alloc_default()); - - REQUIRE(AR_EQUAL(foo_norm, bar)); - - DA_DESTROY(bar); -} - -TEST("file path normalize parent") { - str_t foo = SZ("../baz"); - str_t foo_norm = SZ(".." PATH_DELIM "baz"); - - string_t bar = path_norm(foo, kit_alloc_default()); - - REQUIRE(AR_EQUAL(foo_norm, bar)); - - DA_DESTROY(bar); -} - -TEST("file path normalize double parent") { - str_t foo = SZ("foo/../../baz"); - str_t foo_norm = SZ(".." PATH_DELIM "baz"); - - string_t bar = path_norm(foo, kit_alloc_default()); - - REQUIRE(AR_EQUAL(foo_norm, bar)); - - DA_DESTROY(bar); -} - -TEST("file path normalize windows delim") { - str_t foo = SZ("foo\\bar\\..\\baz"); - str_t foo_norm = SZ("foo" PATH_DELIM "baz"); - - string_t bar = path_norm(foo, kit_alloc_default()); - - REQUIRE(AR_EQUAL(foo_norm, bar)); - - DA_DESTROY(bar); -} - -TEST("file path join no delim") { - str_t foo = SZ("foo"); - str_t bar = SZ("bar"); - str_t joined = SZ("foo" PATH_DELIM "bar"); - - string_t foobar = path_join(foo, bar, kit_alloc_default()); - - REQUIRE(AR_EQUAL(joined, foobar)); - - DA_DESTROY(foobar); -} - -TEST("file path join delim left") { - str_t foo = SZ("foo/"); - str_t bar = SZ("bar"); - str_t joined = SZ("foo" PATH_DELIM "bar"); - - string_t foobar = path_join(foo, bar, kit_alloc_default()); - - REQUIRE(AR_EQUAL(joined, foobar)); - - DA_DESTROY(foobar); -} - -TEST("file path join delim right") { - str_t foo = SZ("foo"); - str_t bar = SZ("/bar"); - str_t joined = SZ("foo" PATH_DELIM "bar"); - - string_t foobar = path_join(foo, bar, kit_alloc_default()); - - REQUIRE(AR_EQUAL(joined, foobar)); - - DA_DESTROY(foobar); -} - -TEST("file path join delim both") { - str_t foo = SZ("foo/"); - str_t bar = SZ("/bar"); - str_t joined = SZ("foo" PATH_DELIM "bar"); - - string_t foobar = path_join(foo, bar, kit_alloc_default()); - - REQUIRE(AR_EQUAL(joined, foobar)); - - DA_DESTROY(foobar); -} - -TEST("file path user") { - string_t user = path_user(kit_alloc_default()); - - REQUIRE(user.size > 0); - - DA_DESTROY(user); -} - -TEST("file path index relative") { - str_t foobar = SZ("foo/bar"); - str_t foo = SZ("foo"); - str_t bar = SZ("bar"); - - REQUIRE(AR_EQUAL(path_index(foobar, 0), foo)); - REQUIRE(AR_EQUAL(path_index(foobar, 1), bar)); - REQUIRE(path_index(foobar, 2).size == 0); -} - -TEST("file path index absolute") { - str_t foobar = SZ("/foo/bar"); - str_t foo = SZ("foo"); - str_t bar = SZ("bar"); - - REQUIRE(AR_EQUAL(path_index(foobar, 0), foo)); - REQUIRE(AR_EQUAL(path_index(foobar, 1), bar)); - REQUIRE(path_index(foobar, 2).size == 0); -} - -TEST("file path index windows disk name") { - str_t foobar = SZ("c:\\foo\\bar"); - str_t disk = SZ("c:"); - str_t foo = SZ("foo"); - str_t bar = SZ("bar"); - - REQUIRE(AR_EQUAL(path_index(foobar, 0), disk)); - REQUIRE(AR_EQUAL(path_index(foobar, 1), foo)); - REQUIRE(AR_EQUAL(path_index(foobar, 2), bar)); - REQUIRE(path_index(foobar, 3).size == 0); -} - -TEST("file path take relative") { - str_t foobar = SZ("foo/bar/"); - str_t foo = SZ("foo"); - str_t bar = SZ("foo/bar"); - str_t bar_end = SZ("foo/bar/"); - - REQUIRE(AR_EQUAL(path_take(foobar, 0), foo)); - REQUIRE(AR_EQUAL(path_take(foobar, 1), bar)); - REQUIRE(AR_EQUAL(path_take(foobar, 2), bar_end)); -} - -TEST("file path take absolute") { - str_t foobar = SZ("/foo/bar"); - str_t foo = SZ("/foo"); - str_t bar = SZ("/foo/bar"); - - REQUIRE(AR_EQUAL(path_take(foobar, 0), foo)); - REQUIRE(AR_EQUAL(path_take(foobar, 1), bar)); -} - -TEST("file path take windows disk name") { - str_t foobar = SZ("c:\\foo\\bar"); - str_t disk = SZ("c:"); - str_t foo = SZ("c:\\foo"); - str_t bar = SZ("c:\\foo\\bar"); - - REQUIRE(AR_EQUAL(path_take(foobar, 0), disk)); - REQUIRE(AR_EQUAL(path_take(foobar, 1), foo)); - REQUIRE(AR_EQUAL(path_take(foobar, 2), bar)); -} - -TEST("file create folder") { } - -TEST("file create folder recursive") { } - -TEST("file remove") { } - -TEST("file remove folder") { } - -TEST("file remove recursive") { } - -TEST("file enum folder") { } diff --git a/source/test/unittests/foo.bench.c b/source/test/unittests/foo.bench.c deleted file mode 100644 index ac1e0b5..0000000 --- a/source/test/unittests/foo.bench.c +++ /dev/null @@ -1,41 +0,0 @@ -#define KIT_TEST_FILE foo -#include "../../kit_test/bench.h" - -struct test_foo_ { - double f; -}; - -BENCHMARK("foo") { - - /* Benchmark setup. - */ - - BENCHMARK_BEGIN; - { - /* Measured code snippet. - */ - - int x = 0; - struct test_foo_ f = { 0. }; - - for (int i = 0; i < 100000; i++) { - x += (1 << 1); - x ^= i; - f.f += 0.1; - } - - DO_NOT_OPTIMIZE(x); - DO_NOT_OPTIMIZE(f); - } - BENCHMARK_END; -} - -BENCHMARK("bar") { - BENCHMARK_REPEAT(10); - BENCHMARK_REPEAT(100); - - BENCHMARK_BEGIN; - BENCHMARK_END; -} - -BENCHMARK("empty") { } diff --git a/source/test/unittests/input_buffer.test.c b/source/test/unittests/input_buffer.test.c deleted file mode 100644 index c062052..0000000 --- a/source/test/unittests/input_buffer.test.c +++ /dev/null @@ -1,105 +0,0 @@ -#include "../../kit/input_buffer.h" - -#define KIT_TEST_FILE input_buffer -#include "../../kit_test/test.h" - -TEST("input buffer read once") { - str_t text = { .size = 3, .values = "foo" }; - is_handle_t in = IS_WRAP_STRING(text); - ib_handle_t first = IB_WRAP(in); - - ib_handle_t second = ib_read(first, 3); - - REQUIRE(second.status == KIT_OK); - REQUIRE(second.data.size == 3); - REQUIRE(AR_EQUAL(text, second.data)); - - ib_destroy(second); - ib_destroy(first); - is_destroy(in); -} - -TEST("input buffer read again") { - str_t text = { .size = 6, .values = "foobar" }; - str_t foo = { .size = 3, .values = "foo" }; - is_handle_t in = IS_WRAP_STRING(text); - ib_handle_t first = IB_WRAP(in); - - ib_handle_t second = ib_read(first, 3); - ib_handle_t third = ib_read(first, 3); - - REQUIRE(AR_EQUAL(foo, second.data)); - REQUIRE(AR_EQUAL(foo, third.data)); - - ib_destroy(third); - ib_destroy(second); - ib_destroy(first); - is_destroy(in); -} - -TEST("input buffer read twice") { - str_t text = { .size = 6, .values = "foobar" }; - str_t foo = { .size = 3, .values = "foo" }; - str_t bar = { .size = 3, .values = "bar" }; - is_handle_t in = IS_WRAP_STRING(text); - ib_handle_t first = IB_WRAP(in); - - ib_handle_t second = ib_read(first, 3); - ib_handle_t third = ib_read(second, 3); - - REQUIRE(AR_EQUAL(foo, second.data)); - REQUIRE(AR_EQUAL(bar, third.data)); - - ib_destroy(third); - ib_destroy(second); - ib_destroy(first); - is_destroy(in); -} - -static int is_integer_(str_t const data) { - for (ptrdiff_t i = 0; i < data.size; i++) - if (data.values[i] < '0' || data.values[i] > '9') - return 0; - return 1; -} - -TEST("input buffer read integer once") { - str_t text = { .size = 9, .values = "31415 foo" }; - str_t num = { .size = 5, .values = "31415" }; - is_handle_t in = IS_WRAP_STRING(text); - ib_handle_t first = IB_WRAP(in); - - ib_handle_t second = ib_read_while(first, is_integer_); - - REQUIRE(second.status == KIT_OK); - REQUIRE(second.data.size == 5); - REQUIRE(AR_EQUAL(num, second.data)); - - ib_destroy(second); - ib_destroy(first); - is_destroy(in); -} - -TEST("input buffer read integer twice") { - str_t text = { .size = 6, .values = "314 15" }; - str_t num_0 = { .size = 3, .values = "314" }; - str_t num_1 = { .size = 2, .values = "15" }; - is_handle_t in = IS_WRAP_STRING(text); - ib_handle_t first = IB_WRAP(in); - - ib_handle_t second = ib_read_while(first, is_integer_); - ib_handle_t third = ib_read(second, 1); - ib_handle_t fourth = ib_read_while(third, is_integer_); - - REQUIRE(fourth.status == KIT_OK); - REQUIRE(second.data.size == 3); - REQUIRE(fourth.data.size == 2); - REQUIRE(AR_EQUAL(num_0, second.data)); - REQUIRE(AR_EQUAL(num_1, fourth.data)); - - ib_destroy(first); - ib_destroy(second); - ib_destroy(third); - ib_destroy(fourth); - is_destroy(in); -} diff --git a/source/test/unittests/input_stream.test.c b/source/test/unittests/input_stream.test.c deleted file mode 100644 index 7dce043..0000000 --- a/source/test/unittests/input_stream.test.c +++ /dev/null @@ -1,23 +0,0 @@ -#include "../../kit/input_stream.h" - -#define KIT_TEST_FILE input_stream -#include "../../kit_test/test.h" - -TEST("input stream wrap string") { - char foo[] = "test"; - char bar[] = "test"; - - str_t foo_ref = { .size = sizeof(foo) - 1, .values = foo }; - str_t bar_ref = { .size = sizeof(bar) - 1, .values = bar }; - - is_handle_t in = IS_WRAP_STRING(foo_ref); - - char buf[4]; - out_str_t buf_ref = { .size = sizeof(buf), .values = buf }; - - REQUIRE(IS_READ(in, buf_ref) == buf_ref.size); - REQUIRE(AR_EQUAL(foo_ref, bar_ref)); - REQUIRE(AR_EQUAL(buf_ref, bar_ref)); - - is_destroy(in); -} diff --git a/source/test/unittests/lower_bound.test.c b/source/test/unittests/lower_bound.test.c deleted file mode 100644 index 24752a6..0000000 --- a/source/test/unittests/lower_bound.test.c +++ /dev/null @@ -1,178 +0,0 @@ -#include "../../kit/lower_bound.h" -#include "../../kit/array_ref.h" - -#define KIT_TEST_FILE lower_bound -#include "../../kit_test/test.h" - -static int kit_less_int(int left, int right) { - return left < right; -} - -static int kit_less_int_ref(int const *left, int const *right) { - return *left < *right; -} - -TEST("lower bound empty") { - AR(int) ref = { .size = 0, .values = NULL }; - - ptrdiff_t index; - LOWER_BOUND(index, ref, 42, kit_less_int); - REQUIRE(index == 0); -} - -TEST("lower bound single left") { - int const v[1] = { 42 }; - AR(int) ref = { .size = 1, .values = v }; - - ptrdiff_t index; - LOWER_BOUND(index, ref, 42, kit_less_int); - REQUIRE(index == 0); -} - -TEST("lower bound single right") { - int const v[1] = { 42 }; - AR(int) ref = { .size = 1, .values = v }; - - ptrdiff_t index; - LOWER_BOUND(index, ref, 43, kit_less_int); - REQUIRE(index == 1); -} - -TEST("lower bound first of four") { - int const v[4] = { 1, 2, 3, 4 }; - AR(int) ref = { .size = 4, .values = v }; - - ptrdiff_t index; - LOWER_BOUND(index, ref, 1, kit_less_int); - REQUIRE(index == 0); -} - -TEST("lower bound second of four") { - int const v[4] = { 1, 2, 3, 4 }; - AR(int) ref = { .size = 4, .values = v }; - - ptrdiff_t index; - LOWER_BOUND(index, ref, 2, kit_less_int); - REQUIRE(index == 1); -} - -TEST("lower bound third of four") { - int const v[4] = { 1, 2, 3, 4 }; - AR(int) ref = { .size = 4, .values = v }; - - ptrdiff_t index; - LOWER_BOUND(index, ref, 3, kit_less_int); - REQUIRE(index == 2); -} - -TEST("lower bound forth of four") { - int const v[4] = { 1, 2, 3, 4 }; - AR(int) ref = { .size = 4, .values = v }; - - ptrdiff_t index; - LOWER_BOUND(index, ref, 4, kit_less_int); - REQUIRE(index == 3); -} - -TEST("lower bound fifth of four") { - int const v[4] = { 1, 2, 3, 4 }; - AR(int) ref = { .size = 4, .values = v }; - - ptrdiff_t index; - LOWER_BOUND(index, ref, 5, kit_less_int); - REQUIRE(index == 4); -} - -TEST("lower bound first of five") { - int const v[5] = { 1, 2, 3, 4, 5 }; - AR(int) ref = { .size = 5, .values = v }; - - ptrdiff_t index; - LOWER_BOUND(index, ref, 1, kit_less_int); - REQUIRE(index == 0); -} - -TEST("lower bound second of five") { - int const v[5] = { 1, 2, 3, 4, 5 }; - AR(int) ref = { .size = 5, .values = v }; - - ptrdiff_t index; - LOWER_BOUND(index, ref, 2, kit_less_int); - REQUIRE(index == 1); -} - -TEST("lower bound third of five") { - int const v[5] = { 1, 2, 3, 4, 5 }; - AR(int) ref = { .size = 5, .values = v }; - - ptrdiff_t index; - LOWER_BOUND(index, ref, 3, kit_less_int); - REQUIRE(index == 2); -} - -TEST("lower bound forth of five") { - int const v[5] = { 1, 2, 3, 4, 5 }; - AR(int) ref = { .size = 5, .values = v }; - - ptrdiff_t index; - LOWER_BOUND(index, ref, 4, kit_less_int); - REQUIRE(index == 3); -} - -TEST("lower bound fifth of five") { - int const v[5] = { 1, 2, 3, 4, 5 }; - AR(int) ref = { .size = 5, .values = v }; - - ptrdiff_t index; - LOWER_BOUND(index, ref, 5, kit_less_int); - REQUIRE(index == 4); -} - -TEST("lower bound sixth of five") { - int const v[5] = { 1, 2, 3, 4, 5 }; - AR(int) ref = { .size = 5, .values = v }; - - ptrdiff_t index; - LOWER_BOUND(index, ref, 6, kit_less_int); - REQUIRE(index == 5); -} - -TEST("lower bound ref first of four") { - int const v[4] = { 1, 2, 3, 4 }; - int const value = 1; - AR(int) ref = { .size = 4, .values = v }; - - ptrdiff_t index; - LOWER_BOUND_REF(index, ref, &value, kit_less_int_ref); - REQUIRE(index == 0); -} - -TEST("lower bound ref second of four") { - int const v[4] = { 1, 2, 3, 4 }; - int const value = 2; - AR(int) ref = { .size = 4, .values = v }; - - ptrdiff_t index; - LOWER_BOUND_REF(index, ref, &value, kit_less_int_ref); - REQUIRE(index == 1); -} - -TEST("lower bound ref fifth of five") { - int const v[5] = { 1, 2, 3, 4, 5 }; - int const value = 5; - AR(int) ref = { .size = 5, .values = v }; - - ptrdiff_t index; - LOWER_BOUND_REF(index, ref, &value, kit_less_int_ref); - REQUIRE(index == 4); -} - -TEST("lower bound ref sixth of five") { - int const v[5] = { 1, 2, 3, 4, 5 }; - int const value = 6; - AR(int) ref = { .size = 5, .values = v }; - - ptrdiff_t index; - LOWER_BOUND_REF(index, ref, &value, kit_less_int_ref); - REQUIRE(index == 5); -} diff --git a/source/test/unittests/main.test.c b/source/test/unittests/main.test.c deleted file mode 100644 index 60c2e36..0000000 --- a/source/test/unittests/main.test.c +++ /dev/null @@ -1,9 +0,0 @@ -#include "../../kit_test/bench.h" -#include "../../kit_test/test.h" - -int main(int argc, char **argv) { - int status = run_tests(argc, argv); - if (status == 0) - status = run_benchmarks(argc, argv); - return status; -} diff --git a/source/test/unittests/mersenne_twister_64.test.c b/source/test/unittests/mersenne_twister_64.test.c deleted file mode 100644 index e523154..0000000 --- a/source/test/unittests/mersenne_twister_64.test.c +++ /dev/null @@ -1,38 +0,0 @@ -#include "../../kit/mersenne_twister_64.h" -#include "../../kit/secure_random.h" - -#define KIT_TEST_FILE mersenne_twister_64 -#include "../../kit_test/test.h" - -enum { SIZE = 1000 }; - -TEST("mt64 same seeds") { - ptrdiff_t i; - uint64_t seed; - secure_random(sizeof seed, &seed); - - mt64_state_t foo, bar; - mt64_init(&foo, seed); - mt64_init(&bar, seed); - - int ok = 1; - for (i = 0; i < SIZE; i++) - ok = ok && mt64_generate(&foo) == mt64_generate(&bar); - - REQUIRE(ok); -} - -TEST("mt64 different seeds") { - ptrdiff_t i; - - mt64_state_t foo, bar; - mt64_init(&foo, 42); - mt64_init(&bar, 4242424242); - - ptrdiff_t difference_count = 0; - for (i = 0; i < SIZE; i++) - if (mt64_generate(&foo) != mt64_generate(&bar)) - difference_count++; - - REQUIRE(difference_count > SIZE / 2); -} diff --git a/source/test/unittests/move_back.test.c b/source/test/unittests/move_back.test.c deleted file mode 100644 index 399619d..0000000 --- a/source/test/unittests/move_back.test.c +++ /dev/null @@ -1,148 +0,0 @@ -#include "../../kit/move_back.h" - -#define KIT_TEST_FILE move_back -#include "../../kit_test/test.h" - -static int is_equal(int const x, int const y) { - return x == y; -} - -static int is_equal_ref(int const *const x, int const y) { - return *x == y; -} - -static int is_even(int const x, int const _) { - return (x % 2) == 0; -} - -static int is_even_ref(int const *const x, int const _) { - return (*x % 2) == 0; -} - -TEST("move back val") { - int v[] = { 1, 2, 2, 2, 1, 1 }; - - struct { - int size; - int *values; - } ref = { .size = sizeof v / sizeof *v, .values = v }; - - MOVE_BACK(ref.size, ref, 2, is_equal); - - REQUIRE_EQ(ref.size, 3); - REQUIRE_EQ(v[0], 1); - REQUIRE_EQ(v[1], 1); - REQUIRE_EQ(v[2], 1); -} - -TEST("move back ref val") { - int v[] = { 1, 2, 2, 2, 1, 1 }; - - struct { - int size; - int *values; - } ref = { .size = sizeof v / sizeof *v, .values = v }; - - MOVE_BACK_REF(ref.size, ref, 2, is_equal_ref); - - REQUIRE(ref.size == 3); - REQUIRE(v[0] == 1); - REQUIRE(v[1] == 1); - REQUIRE(v[2] == 1); -} - -TEST("move back 1") { - int v[] = { 1, 2, 3, 4, 5, 6 }; - - struct { - int size; - int *values; - } ref = { .size = sizeof v / sizeof *v, .values = v }; - - MOVE_BACK(ref.size, ref, 0, is_even); - - REQUIRE(ref.size == 3); - REQUIRE(v[0] == 1); - REQUIRE(v[1] == 5); - REQUIRE(v[2] == 3); -} - -TEST("move back 2") { - int v[] = { 2, 4, 6, 1, 3, 5 }; - - struct { - int size; - int *values; - } ref = { .size = sizeof v / sizeof *v, .values = v }; - - MOVE_BACK(ref.size, ref, 0, is_even); - - REQUIRE(ref.size == 3); - REQUIRE(v[0] == 5); - REQUIRE(v[1] == 3); - REQUIRE(v[2] == 1); -} - -TEST("move back 3") { - int v[] = { 1, 3, 5, 2, 4, 6 }; - - struct { - int size; - int *values; - } ref = { .size = sizeof v / sizeof *v, .values = v }; - - MOVE_BACK(ref.size, ref, 0, is_even); - - REQUIRE(ref.size == 3); - REQUIRE(v[0] == 1); - REQUIRE(v[1] == 3); - REQUIRE(v[2] == 5); -} - -TEST("move back ref 1") { - int v[] = { 1, 2, 3, 4, 5, 6 }; - - struct { - int size; - int *values; - } ref = { .size = sizeof v / sizeof *v, .values = v }; - - MOVE_BACK_REF(ref.size, ref, 0, is_even_ref); - - REQUIRE(ref.size == 3); - REQUIRE(v[0] == 1); - REQUIRE(v[1] == 5); - REQUIRE(v[2] == 3); -} - -TEST("move back ref 2") { - int v[] = { 2, 4, 6, 1, 3, 5 }; - - struct { - int size; - int *values; - } ref = { .size = sizeof v / sizeof *v, .values = v }; - - MOVE_BACK_REF(ref.size, ref, 0, is_even_ref); - - REQUIRE(ref.size == 3); - REQUIRE(v[0] == 5); - REQUIRE(v[1] == 3); - REQUIRE(v[2] == 1); -} - -TEST("move back ref 3") { - int v[] = { 1, 3, 5, 2, 4, 6 }; - - struct { - int size; - int *values; - } ref = { .size = sizeof v / sizeof *v, .values = v }; - - MOVE_BACK_REF(ref.size, ref, 0, is_even_ref); - - REQUIRE(ref.size == 3); - REQUIRE(v[0] == 1); - REQUIRE(v[1] == 3); - REQUIRE(v[2] == 5); -} diff --git a/source/test/unittests/mutex.test.c b/source/test/unittests/mutex.test.c deleted file mode 100644 index 1bd2b3d..0000000 --- a/source/test/unittests/mutex.test.c +++ /dev/null @@ -1,79 +0,0 @@ -#include "../../kit/mutex.h" -#include "../../kit/thread.h" - -#define KIT_TEST_FILE mutex -#include "../../kit_test/test.h" - -enum { SLEEP = 400000000, TICK_COUNT = 200, THREAD_COUNT = 100 }; - -typedef struct { - mtx_t lock; - int value; -} test_data_t; - -static int test_run(void *data) { - int i; - test_data_t *x = (test_data_t *) data; - for (i = 0; i < TICK_COUNT; i++) { - mtx_lock(&x->lock); - - x->value += i; - thrd_yield(); - x->value -= i + 42; - thrd_yield(); - x->value += i + 20; - thrd_yield(); - x->value += 22 - i; - - mtx_unlock(&x->lock); - } - return 0; -} - -TEST("mutex lock") { - ptrdiff_t i; - - test_data_t data; - thrd_t pool[THREAD_COUNT]; - data.value = 42; - REQUIRE(mtx_init(&data.lock, mtx_plain) == thrd_success); - - for (i = 0; i < THREAD_COUNT; i++) - thrd_create(pool + i, test_run, &data); - for (i = 0; i < THREAD_COUNT; i++) thrd_join(pool[i], NULL); - - mtx_destroy(&data.lock); - REQUIRE(data.value == 42); -} - -static int test_lock(void *data) { - mtx_t *m = (mtx_t *) data; - mtx_lock(m); - - struct timespec sec = { .tv_sec = 0, .tv_nsec = SLEEP }; - thrd_sleep(&sec, NULL); - - mtx_unlock(m); - - return 0; -} - -TEST("mutex try lock") { - mtx_t m; - REQUIRE(mtx_init(&m, mtx_plain) == thrd_success); - - thrd_t t; - REQUIRE(thrd_create(&t, test_lock, &m) == thrd_success); - - struct timespec sec = { .tv_sec = 0, .tv_nsec = SLEEP / 2 }; - REQUIRE(thrd_sleep(&sec, NULL) == thrd_success); - - REQUIRE(mtx_trylock(&m) == thrd_busy); - - REQUIRE(thrd_join(t, NULL) == thrd_success); - - REQUIRE(mtx_trylock(&m) == thrd_success); - REQUIRE(mtx_unlock(&m) == thrd_success); - - mtx_destroy(&m); -} diff --git a/source/test/unittests/secure_random.test.c b/source/test/unittests/secure_random.test.c deleted file mode 100644 index bde68a5..0000000 --- a/source/test/unittests/secure_random.test.c +++ /dev/null @@ -1,24 +0,0 @@ -#include "../../kit/secure_random.h" -#include - -#define KIT_TEST_FILE secure_random -#include "../../kit_test/test.h" - -TEST("secure random") { - int i, j; - - int v[20]; - memset(v, 0, sizeof v); - - secure_random(40, v); - secure_random(40, v + 10); - - int repeats = 0; - - for (i = 1; i < sizeof v / sizeof *v; i++) - for (j = 0; j < i; j++) - if (v[i] == v[j]) - repeats++; - - REQUIRE(repeats == 0); -} diff --git a/source/test/unittests/sha256.test.c b/source/test/unittests/sha256.test.c deleted file mode 100644 index e74b286..0000000 --- a/source/test/unittests/sha256.test.c +++ /dev/null @@ -1,42 +0,0 @@ -#include "../../kit/sha256.h" -#include "../../kit/array_ref.h" - -#define KIT_TEST_FILE sha256_64 -#include "../../kit_test/test.h" - -#include - -TEST("sha256") { - uint8_t text1[] = "abc"; - uint8_t text2[] = - "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; - - uint8_t text3[1000000]; - memset(text3, 'a', sizeof text3); - - uint8_t hash1[] = { - 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, - 0xde, 0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, - 0x7a, 0x9c, 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad - }; - uint8_t hash2[] = { - 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8, 0xe5, 0xc0, 0x26, - 0x93, 0x0c, 0x3e, 0x60, 0x39, 0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, - 0x21, 0x67, 0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1 - }; - uint8_t hash3[] = { - 0xcd, 0xc7, 0x6e, 0x5c, 0x99, 0x14, 0xfb, 0x92, 0x81, 0xa1, 0xc7, - 0xe2, 0x84, 0xd7, 0x3e, 0x67, 0xf1, 0x80, 0x9a, 0x48, 0xa4, 0x97, - 0x20, 0x0e, 0x04, 0x6d, 0x39, 0xcc, 0xc7, 0x11, 0x2c, 0xd0 - }; - - REQUIRE(ar_equal_bytes(1, SHA256_BLOCK_SIZE, - sha256((sizeof text1) - 1, text1).v, 1, - SHA256_BLOCK_SIZE, hash1)); - REQUIRE(ar_equal_bytes(1, SHA256_BLOCK_SIZE, - sha256((sizeof text2) - 1, text2).v, 1, - SHA256_BLOCK_SIZE, hash2)); - REQUIRE(ar_equal_bytes(1, SHA256_BLOCK_SIZE, - sha256(sizeof text3, text3).v, 1, - SHA256_BLOCK_SIZE, hash3)); -} diff --git a/source/test/unittests/string_ref.test.c b/source/test/unittests/string_ref.test.c deleted file mode 100644 index 5ec9414..0000000 --- a/source/test/unittests/string_ref.test.c +++ /dev/null @@ -1,23 +0,0 @@ -#include "../../kit/string_ref.h" - -#define KIT_TEST_FILE string_ref -#include "../../kit_test/test.h" - -TEST("static string wrap") { - str_t ref = SZ("foo bar"); - - REQUIRE(ref.size == 7); - REQUIRE(ref.values[0] == 'f'); - REQUIRE(ref.values[1] == 'o'); - REQUIRE(ref.values[2] == 'o'); - REQUIRE(ref.values[3] == ' '); - REQUIRE(ref.values[4] == 'b'); - REQUIRE(ref.values[5] == 'a'); - REQUIRE(ref.values[6] == 'r'); -} - -TEST("string literal") { - str_t foo = SZ("foo"); - str_t bar = foo; - (void) bar; -} diff --git a/source/test/unittests/test_duration.test.c b/source/test/unittests/test_duration.test.c deleted file mode 100644 index 0912d9f..0000000 --- a/source/test/unittests/test_duration.test.c +++ /dev/null @@ -1,20 +0,0 @@ -#define KIT_TEST_FILE test_duration -#include "../../kit_test/test.h" - -#include - -#if defined(_WIN32) && !defined(__CYGWIN__) -__declspec(dllimport) void __stdcall Sleep(unsigned long timeout); -static void kit_sleep(int ms) { - Sleep(ms); -} -#else -# include -static void kit_sleep(int ms) { - usleep(ms * 1000); -} -#endif - -TEST("test duration") { - kit_sleep(100); -} diff --git a/source/test/unittests/thread.test.c b/source/test/unittests/thread.test.c deleted file mode 100644 index 01198c2..0000000 --- a/source/test/unittests/thread.test.c +++ /dev/null @@ -1,91 +0,0 @@ -#include "../../kit/thread.h" - -#define KIT_TEST_FILE thread -#include "../../kit_test/test.h" - -static int test_nothing(void *_) { - return 0; -} - -static int test_run(void *data) { - int *n = (int *) data; - return *n + 20; -} - -static int test_exit(void *data) { - int *n = (int *) data; - - *n = 1; - thrd_exit(3); - *n = 2; - return 4; -} - -static int test_yield(void *data) { - thrd_yield(); - return 0; -} - -static int test_sleep(void *data) { - struct timespec t = { .tv_sec = 0, .tv_nsec = 10000000 }; - thrd_sleep(&t, NULL); - return 0; -} - -TEST("thread run") { - thrd_t t; - int data = 22; - int result; - REQUIRE(thrd_create(&t, test_run, &data) == thrd_success); - REQUIRE(thrd_join(t, &result) == thrd_success); - REQUIRE(result == 42); -} - -TEST("thread stack size") { - thrd_t foo; - REQUIRE(thrd_create_with_stack(&foo, test_nothing, NULL, 30000) == - thrd_success); - REQUIRE(thrd_join(foo, NULL) == thrd_success); -} - -TEST("thread equal") { - thrd_t foo, bar; - REQUIRE(thrd_create(&foo, test_nothing, NULL) == thrd_success); - REQUIRE(thrd_create(&bar, test_nothing, NULL) == thrd_success); - REQUIRE(thrd_equal(foo, foo)); - REQUIRE(!thrd_equal(foo, bar)); - REQUIRE(!thrd_equal(foo, thrd_current())); - REQUIRE(thrd_join(foo, NULL) == thrd_success); - REQUIRE(thrd_join(bar, NULL) == thrd_success); -} - -TEST("thread exit") { - thrd_t foo; - int data; - int result; - REQUIRE(thrd_create(&foo, test_exit, &data) == thrd_success); - REQUIRE(thrd_join(foo, &result) == thrd_success); - REQUIRE(data == 1); - REQUIRE(result == 3); -} - -TEST("thread yield") { - thrd_t foo; - REQUIRE(thrd_create(&foo, test_yield, NULL) == thrd_success); - REQUIRE(thrd_join(foo, NULL) == thrd_success); -} - -TEST("thread sleep") { - thrd_t foo; - REQUIRE(thrd_create(&foo, test_sleep, NULL) == thrd_success); - REQUIRE(thrd_join(foo, NULL) == thrd_success); -} - -TEST("thread detach") { - thrd_t foo; - REQUIRE(thrd_create(&foo, test_nothing, NULL) == thrd_success); - REQUIRE(thrd_detach(foo) == thrd_success); - - struct timespec t = { .tv_sec = 0, .tv_nsec = 10000000 }; - thrd_sleep(&t, NULL); -} diff --git a/source/tests/_static.c b/source/tests/_static.c new file mode 100644 index 0000000..4b7543d --- /dev/null +++ b/source/tests/_static.c @@ -0,0 +1,55 @@ +#include "array_ref.test.c" +#undef KIT_TEST_FILE + +#include "async_function.test.c" +#undef KIT_TEST_FILE + +#include "bigint.test.c" +#undef KIT_TEST_FILE + +#include "condition_variable.test.c" +#undef KIT_TEST_FILE + +#include "dynamic_array.test.c" +#undef KIT_TEST_FILE + +#include "file.test.c" +#undef KIT_TEST_FILE + +#include "input_buffer.test.c" +#undef KIT_TEST_FILE + +#include "input_stream.test.c" +#undef KIT_TEST_FILE + +#include "lower_bound.test.c" +#undef KIT_TEST_FILE + +#include "mersenne_twister_64.test.c" +#undef KIT_TEST_FILE + +#include "move_back.test.c" +#undef KIT_TEST_FILE + +#include "mutex.test.c" +#undef KIT_TEST_FILE + +#include "secure_random.test.c" +#undef KIT_TEST_FILE + +#include "sha256.test.c" +#undef KIT_TEST_FILE + +#include "string_ref.test.c" +#undef KIT_TEST_FILE + +#include "test_duration.test.c" +#undef KIT_TEST_FILE + +#include "thread.test.c" +#undef KIT_TEST_FILE + +#include "bench.test.c" +#undef KIT_TEST_FILE + +#include "main.test.c" diff --git a/source/tests/array_ref.test.c b/source/tests/array_ref.test.c new file mode 100644 index 0000000..da20aa0 --- /dev/null +++ b/source/tests/array_ref.test.c @@ -0,0 +1,65 @@ +#include "../kit/array_ref.h" + +#define KIT_TEST_FILE array_ref +#include "../kit_test/test.h" + +TEST("array ref const wrap") { + int foo[] = { 1, 2, 3 }; + AR_WRAP(ref, int, foo); + + REQUIRE(ref.size == 3); + REQUIRE(ref.values[0] == 1); + REQUIRE(ref.values[1] == 2); + REQUIRE(ref.values[2] == 3); +} + +TEST("array ref wrap") { + int foo[] = { 1, 2, 3 }; + AR_MUT_WRAP(ref, int, foo); + + REQUIRE(ref.size == 3); + REQUIRE(ref.values[0] == 1); + REQUIRE(ref.values[1] == 2); + REQUIRE(ref.values[2] == 3); + + ref.values[1] = 42; + REQUIRE(ref.values[1] == 42); +} + +TEST("array ref equal") { + int foo[] = { 1, 2, 3, 4, 5, 6, 7 }; + int bar[] = { 3, 4, 5 }; + + AR(int) foo_ref = { .size = 3, .values = foo + 2 }; + AR(int) bar_ref = { .size = 3, .values = bar }; + + REQUIRE(AR_EQUAL(foo_ref, bar_ref)); +} + +static int compare(int const *left, int const *right) { + return *left - *right; +} + +TEST("array ref compare") { + int foo[] = { 1, 2, 3, 5 }; + int bar[] = { 1, 2, 4, 5 }; + + AR(int) foo_ref = { .size = 3, .values = foo }; + AR(int) bar_ref = { .size = 3, .values = bar }; + + REQUIRE(AR_COMPARE(foo_ref, bar_ref, compare) < 0); + REQUIRE(AR_COMPARE(bar_ref, foo_ref, compare) > 0); + REQUIRE(AR_COMPARE(foo_ref, foo_ref, compare) == 0); +} + +TEST("array ref different element sizes") { + int foo[] = { 1, 2, 3 }; + char bar[] = { 1, 2, 3 }; + + AR(int) foo_ref = { .size = 3, .values = foo }; + AR(char) bar_ref = { .size = 3, .values = bar }; + + REQUIRE(!AR_EQUAL(foo_ref, bar_ref)); + REQUIRE(AR_COMPARE(foo_ref, bar_ref, compare) > 0); + REQUIRE(AR_COMPARE(bar_ref, foo_ref, compare) < 0); +} diff --git a/source/tests/async_function.test.c b/source/tests/async_function.test.c new file mode 100644 index 0000000..35ce0ce --- /dev/null +++ b/source/tests/async_function.test.c @@ -0,0 +1,132 @@ +#include "../kit/async_function.h" + +#define KIT_TEST_FILE async_function +#include "../kit_test/test.h" + +AF_STATE(int, test_foo, ); +static AF_DECL(test_foo); + +CORO_IMPL(test_foo) { + AF_RETURN(42); +} +CORO_END + +AF_STATE(int, test_bar, ); +static AF_DECL(test_bar); + +CORO_IMPL(test_bar) { + AF_YIELD_VOID; + AF_RETURN(42); +} +CORO_END + +STATIC_CORO(int, test_gen, int i; int min; int max;) { + for (self->i = self->min; self->i < self->max; self->i++) + AF_YIELD(self->i); + AF_RETURN(self->max); +} +CORO_END + +STATIC_CORO_VOID(test_task, ) { + AF_YIELD_VOID; + AF_YIELD_VOID; + AF_RETURN_VOID; +} +CORO_END + +STATIC_CORO_VOID(test_nest_task, AF_TYPE(test_task) promise;) { + AF_INIT(self->promise, test_task, ); + AF_AWAIT(self->promise); + AF_AWAIT(self->promise); + AF_AWAIT(self->promise); +} +CORO_END + +STATIC_CORO(int, test_nest_generator, AF_TYPE(test_gen) promise;) { + AF_INIT(self->promise, test_gen, .min = 1, .max = 3); + AF_YIELD_AWAIT(self->promise); +} +CORO_END + +TEST("coroutine create") { + AF_CREATE(promise, test_foo, ); + REQUIRE(!AF_FINISHED(promise)); +} + +TEST("coroutine init") { + AF_TYPE(test_foo) promise; + AF_INIT(promise, test_foo, ); + REQUIRE(!AF_FINISHED(promise)); +} + +TEST("coroutine init with value") { + AF_TYPE(test_foo) promise; + AF_INIT(promise, test_foo, .return_value = 42); + REQUIRE(promise.return_value == 42); + REQUIRE(!AF_FINISHED(promise)); +} + +TEST("coroutine create with value") { + AF_CREATE(promise, test_foo, .return_value = -1); + REQUIRE(promise.return_value == -1); + REQUIRE(!AF_FINISHED(promise)); +} + +TEST("coroutine execute and return") { + AF_CREATE(promise, test_foo, ); + REQUIRE(AF_NEXT(promise) == 42); + REQUIRE(AF_FINISHED(promise)); +} + +TEST("coroutine execute two steps") { + AF_CREATE(promise, test_bar, .return_value = 0); + AF_EXECUTE(promise); + REQUIRE(promise.return_value == 0); + AF_EXECUTE(promise); + REQUIRE(promise.return_value == 42); +} + +TEST("coroutine generator") { + int i; + AF_CREATE(promise, test_gen, .min = 10, .max = 15); + for (i = 0; i <= 5; i++) REQUIRE(AF_NEXT(promise) == 10 + i); +} + +TEST("coroutine status finished") { + AF_CREATE(promise, test_bar, ); + REQUIRE(!AF_FINISHED(promise)); + AF_EXECUTE(promise); + REQUIRE(!AF_FINISHED(promise)); + AF_EXECUTE(promise); + REQUIRE(AF_FINISHED(promise)); +} + +TEST("coroutine task") { + AF_CREATE(promise, test_task, ); + AF_EXECUTE(promise); + REQUIRE(!AF_FINISHED(promise)); + AF_EXECUTE(promise); + REQUIRE(!AF_FINISHED(promise)); + AF_EXECUTE(promise); + REQUIRE(AF_FINISHED(promise)); +} + +TEST("coroutine nested task") { + AF_CREATE(promise, test_nest_task, ); + AF_EXECUTE(promise); + REQUIRE(!AF_FINISHED(promise)); + AF_EXECUTE(promise); + REQUIRE(!AF_FINISHED(promise)); + AF_EXECUTE(promise); + REQUIRE(AF_FINISHED(promise)); +} + +TEST("coroutine nested generator") { + AF_CREATE(promise, test_nest_generator, ); + REQUIRE(AF_NEXT(promise) == 1); + REQUIRE(AF_NEXT(promise) == 2); + REQUIRE(AF_NEXT(promise) == 3); + REQUIRE(!AF_FINISHED(promise)); + AF_EXECUTE(promise); + REQUIRE(AF_FINISHED(promise)); +} diff --git a/source/tests/atomic.test.c b/source/tests/atomic.test.c new file mode 100644 index 0000000..c1831a3 --- /dev/null +++ b/source/tests/atomic.test.c @@ -0,0 +1,218 @@ +#include "../kit/atomic.h" +#include "../kit/thread.h" + +#define KIT_TEST_FILE atomic +#include "../kit_test/test.h" + +TEST("atomic store and load") { + ATOMIC(int) value; + atomic_store_explicit(&value, 20, memory_order_relaxed); + REQUIRE(atomic_load_explicit(&value, memory_order_relaxed) == 20); +} + +TEST("atomic exchange") { + ATOMIC(int) value; + atomic_store_explicit(&value, 20, memory_order_relaxed); + REQUIRE(atomic_exchange_explicit(&value, 42, + memory_order_relaxed) == 20); + REQUIRE(atomic_load_explicit(&value, memory_order_relaxed) == 42); +} + +TEST("atomic fetch add") { + ATOMIC(int) value; + atomic_store_explicit(&value, 20, memory_order_relaxed); + REQUIRE(atomic_fetch_add_explicit(&value, 22, + memory_order_relaxed) == 20); + REQUIRE(atomic_load_explicit(&value, memory_order_relaxed) == 42); +} + +enum { THREAD_COUNT = 20, TICK_COUNT = 10000 }; + +static int test_8_(void *p) { + ptrdiff_t i; + ATOMIC(int8_t) *x = (ATOMIC(int8_t) *) p; + + for (i = 0; i < TICK_COUNT; i++) { + atomic_fetch_add_explicit(x, 20, memory_order_relaxed); + thrd_yield(); + atomic_fetch_add_explicit(x, 22, memory_order_relaxed); + thrd_yield(); + atomic_fetch_add_explicit(x, -42, memory_order_relaxed); + thrd_yield(); + } + + return 0; +} + +TEST("atomic types") { + ATOMIC(int8_t) b_1; + ATOMIC(int8_t) b_2; + ATOMIC(int16_t) i16; + ATOMIC(int32_t) i32; + ATOMIC(int64_t) i64; + + atomic_store_explicit(&b_1, 42, memory_order_relaxed); + atomic_store_explicit(&b_2, 43, memory_order_relaxed); + atomic_store_explicit(&i16, 4242, memory_order_relaxed); + atomic_store_explicit(&i32, 42424242, memory_order_relaxed); + atomic_store_explicit(&i64, 4242424242424242ll, + memory_order_relaxed); + + atomic_fetch_add_explicit(&b_1, -20, memory_order_relaxed); + atomic_fetch_add_explicit(&b_2, -20, memory_order_relaxed); + atomic_fetch_add_explicit(&i16, -2020, memory_order_relaxed); + atomic_fetch_add_explicit(&i32, -20202020, memory_order_relaxed); + atomic_fetch_add_explicit(&i64, -2020202020202020ll, + memory_order_relaxed); + + REQUIRE(atomic_exchange_explicit(&b_1, 0, memory_order_relaxed) == + 22); + REQUIRE(atomic_exchange_explicit(&b_2, 0, memory_order_relaxed) == + 23); + REQUIRE(atomic_exchange_explicit(&i16, 0, memory_order_relaxed) == + 2222); + REQUIRE(atomic_exchange_explicit(&i32, 0, memory_order_relaxed) == + 22222222); + REQUIRE(atomic_exchange_explicit(&i64, 0, memory_order_relaxed) == + 2222222222222222ll); + + REQUIRE(atomic_load_explicit(&b_1, memory_order_relaxed) == 0); + REQUIRE(atomic_load_explicit(&b_2, memory_order_relaxed) == 0); + REQUIRE(atomic_load_explicit(&i16, memory_order_relaxed) == 0); + REQUIRE(atomic_load_explicit(&i32, memory_order_relaxed) == 0); + REQUIRE(atomic_load_explicit(&i64, memory_order_relaxed) == 0ll); +} + +TEST("atomic byte concurrency") { + ptrdiff_t i; + + ATOMIC(int8_t) foo; + ATOMIC(int8_t) bar; + + atomic_store_explicit(&foo, 42, memory_order_relaxed); + atomic_store_explicit(&bar, 43, memory_order_relaxed); + + thrd_t threads[THREAD_COUNT]; + for (i = 0; i < THREAD_COUNT; i++) + REQUIRE_EQ(thrd_create(threads + i, test_8_, + (void *) ((i % 2) ? &foo : &bar)), + thrd_success); + for (i = 0; i < THREAD_COUNT; i++) thrd_join(threads[i], NULL); + + REQUIRE(atomic_load_explicit(&foo, memory_order_relaxed) == 42); + REQUIRE(atomic_load_explicit(&bar, memory_order_relaxed) == 43); +} + +static int test_16_(void *p) { + ptrdiff_t i; + + ATOMIC(int16_t) *x = (ATOMIC(int16_t) *) p; + + for (i = 0; i < TICK_COUNT; i++) { + atomic_fetch_add_explicit(x, 2020, memory_order_relaxed); + thrd_yield(); + atomic_fetch_add_explicit(x, 2222, memory_order_relaxed); + thrd_yield(); + atomic_fetch_add_explicit(x, -4242, memory_order_relaxed); + thrd_yield(); + } + + return 0; +} + +TEST("atomic int16 concurrency") { + ptrdiff_t i; + + ATOMIC(int16_t) foo; + ATOMIC(int16_t) bar; + + atomic_store_explicit(&foo, 42, memory_order_relaxed); + atomic_store_explicit(&bar, 43, memory_order_relaxed); + + thrd_t threads[THREAD_COUNT]; + for (i = 0; i < THREAD_COUNT; i++) + REQUIRE_EQ(thrd_create(threads + i, test_16_, + (void *) ((i % 2) ? &foo : &bar)), + thrd_success); + for (i = 0; i < THREAD_COUNT; i++) thrd_join(threads[i], NULL); + + REQUIRE(atomic_load_explicit(&foo, memory_order_relaxed) == 42); + REQUIRE(atomic_load_explicit(&bar, memory_order_relaxed) == 43); +} + +static int test_32_(void *p) { + ptrdiff_t i; + + ATOMIC(int32_t) *x = (ATOMIC(int32_t) *) p; + + for (i = 0; i < TICK_COUNT; i++) { + atomic_fetch_add_explicit(x, 202020, memory_order_relaxed); + thrd_yield(); + atomic_fetch_add_explicit(x, 222222, memory_order_relaxed); + thrd_yield(); + atomic_fetch_add_explicit(x, -424242, memory_order_relaxed); + thrd_yield(); + } + + return 0; +} + +TEST("atomic int32 concurrency") { + ptrdiff_t i; + + ATOMIC(int32_t) foo; + ATOMIC(int32_t) bar; + + atomic_store_explicit(&foo, 42, memory_order_relaxed); + atomic_store_explicit(&bar, 43, memory_order_relaxed); + + thrd_t threads[THREAD_COUNT]; + for (i = 0; i < THREAD_COUNT; i++) + REQUIRE_EQ(thrd_create(threads + i, test_32_, + (void *) ((i % 2) ? &foo : &bar)), + thrd_success); + for (i = 0; i < THREAD_COUNT; i++) thrd_join(threads[i], NULL); + + REQUIRE(atomic_load_explicit(&foo, memory_order_relaxed) == 42); + REQUIRE(atomic_load_explicit(&bar, memory_order_relaxed) == 43); +} + +static int test_64_(void *p) { + ptrdiff_t i; + + ATOMIC(int64_t) *x = (ATOMIC(int64_t) *) p; + + for (i = 0; i < TICK_COUNT; i++) { + atomic_fetch_add_explicit(x, 20202020202020ll, + memory_order_relaxed); + thrd_yield(); + atomic_fetch_add_explicit(x, 22222222222222ll, + memory_order_relaxed); + thrd_yield(); + atomic_fetch_add_explicit(x, -42424242424242ll, + memory_order_relaxed); + thrd_yield(); + } + + return 0; +} + +TEST("atomic int64 concurrency") { + ptrdiff_t i; + + ATOMIC(int64_t) foo; + ATOMIC(int64_t) bar; + + atomic_store_explicit(&foo, 42, memory_order_relaxed); + atomic_store_explicit(&bar, 43, memory_order_relaxed); + + thrd_t threads[THREAD_COUNT]; + for (i = 0; i < THREAD_COUNT; i++) + REQUIRE_EQ(thrd_create(threads + i, test_64_, + (void *) ((i % 2) ? &foo : &bar)), + thrd_success); + for (i = 0; i < THREAD_COUNT; i++) thrd_join(threads[i], NULL); + + REQUIRE(atomic_load_explicit(&foo, memory_order_relaxed) == 42); + REQUIRE(atomic_load_explicit(&bar, memory_order_relaxed) == 43); +} diff --git a/source/tests/bench.test.c b/source/tests/bench.test.c new file mode 100644 index 0000000..92e216d --- /dev/null +++ b/source/tests/bench.test.c @@ -0,0 +1,41 @@ +#define KIT_TEST_FILE bench +#include "../kit_test/bench.h" + +struct test_foo_ { + double f; +}; + +BENCHMARK("foo") { + + /* Benchmark setup. + */ + + BENCHMARK_BEGIN; + { + /* Measured code snippet. + */ + + int x = 0; + struct test_foo_ f = { 0. }; + + for (int i = 0; i < 100000; i++) { + x += (1 << 1); + x ^= i; + f.f += 0.1; + } + + DO_NOT_OPTIMIZE(x); + DO_NOT_OPTIMIZE(f); + } + BENCHMARK_END; +} + +BENCHMARK("bar") { + BENCHMARK_REPEAT(10); + BENCHMARK_REPEAT(100); + + BENCHMARK_BEGIN; + BENCHMARK_END; +} + +BENCHMARK("empty") { } diff --git a/source/tests/bigint.test.c b/source/tests/bigint.test.c new file mode 100644 index 0000000..c8ac44f --- /dev/null +++ b/source/tests/bigint.test.c @@ -0,0 +1,108 @@ +#define KIT_BIGINT_SIZE 256 +#include "../kit/bigint.h" + +#define KIT_TEST_FILE bigint +#include "../kit_test/test.h" + +#if __STDC_VERSION__ >= 199901L +static_assert(sizeof(bigint_t) == 256, "KIT_BIGINT_SIZE check"); +#endif + +TEST("bigint bin hex") { + REQUIRE(bi_equal(HEX("10"), BIN("10000"))); + REQUIRE(bi_equal(HEX("20"), BIN("100000"))); + REQUIRE(bi_equal(HEX("40"), BIN("1000000"))); + REQUIRE(bi_equal(HEX("80"), BIN("10000000"))); + REQUIRE(bi_equal(HEX("310"), BIN("1100010000"))); + REQUIRE(bi_equal(HEX("420"), BIN("10000100000"))); + REQUIRE(bi_equal(HEX("540"), BIN("10101000000"))); + REQUIRE(bi_equal(HEX("780"), BIN("11110000000"))); +} + +TEST("bigint hex add") { + REQUIRE(bi_equal( + bi_add(HEX("4242424242424242424242424242424242424242"), + HEX("1111111111111111111111111111111111111111")), + HEX("5353535353535353535353535353535353535353"))); +} + +TEST("bigint hex sub") { + REQUIRE(bi_equal( + bi_sub(HEX("4242424242424242424242424242424242424242"), + HEX("1111111111111111111111111111111111111111")), + HEX("3131313131313131313131313131313131313131"))); +} + +TEST("bigint base58") { + REQUIRE(bi_equal(BASE58("31"), bi_uint32(58 * 2))); +} + +TEST("bigint base58 add") { + REQUIRE(bi_equal( + bi_add(BASE58("4242424242424242424242424242424242424242"), + BASE58("2222222222222222222222222222222222222222")), + BASE58("5353535353535353535353535353535353535353"))); +} + +TEST("bigint base58 sub") { + REQUIRE(bi_equal( + bi_sub(BASE58("4242424242424242424242424242424242424242"), + BASE58("2222222222222222222222222222222222222222")), + BASE58("3131313131313131313131313131313131313131"))); +} + +TEST("bigint base58 mul") { + REQUIRE(bi_equal(bi_mul(BASE58("2111111111111111111111"), + BASE58("foofoofoofoofoo")), + BASE58("foofoofoofoofoo111111111111111111111"))); +} + +TEST("bigint div") { + REQUIRE(bi_equal(bi_div(bi_int32(-1), bi_int32(-1)).quotient, + bi_int32(1))); + REQUIRE(bi_equal(bi_div(bi_int32(-1), bi_int32(-1)).remainder, + bi_int32(0))); + REQUIRE(bi_equal(bi_div(bi_int32(-3), bi_int32(2)).quotient, + bi_int32(-2))); + REQUIRE(bi_equal(bi_div(bi_int32(-3), bi_int32(2)).remainder, + bi_int32(1))); + REQUIRE(bi_equal(bi_div(bi_int32(3), bi_int32(-2)).quotient, + bi_int32(-1))); + REQUIRE(bi_equal(bi_div(bi_int32(3), bi_int32(-2)).remainder, + bi_int32(1))); + REQUIRE(bi_equal(bi_div(bi_int32(-3), bi_int32(4)).quotient, + bi_int32(-1))); + REQUIRE(bi_equal(bi_div(bi_int32(-3), bi_int32(4)).remainder, + bi_int32(3))); + REQUIRE(bi_equal(bi_div(bi_int32(3), bi_int32(-4)).quotient, + bi_int32(0))); + REQUIRE(bi_equal(bi_div(bi_int32(3), bi_int32(-4)).remainder, + bi_int32(3))); + + REQUIRE( + bi_equal(bi_div(HEX("100"), HEX("10")).quotient, HEX("10"))); + + REQUIRE(bi_equal(bi_div(bi_mul(BASE58("foofoofoofoofoofoo"), + BASE58("barbarbarbarbarbar")), + BASE58("barbarbarbarbarbar")) + .quotient, + BASE58("foofoofoofoofoofoo"))); + + REQUIRE(bi_equal(bi_div(bi_mul(BASE58("foofoofoofoofoofoofoofoo"), + BASE58("barbarbarbarbarbar")), + BASE58("barbarbarbarbarbar")) + .quotient, + BASE58("foofoofoofoofoofoofoofoo"))); + + REQUIRE(bi_equal( + bi_div( + bi_mul(BASE58("foofoofoofoofoofoofoofoofoofoofoofoofoofoofo" + "ofoofoofoo"), + BASE58("barbarbarbarbarbarbarbarbarbarbarbarbarbarba" + "rbar")), + BASE58("barbarbarbarbarbarbarbarbarbarbarbarbarbarbarbar")) + .quotient, + BASE58( + "foofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoo"))); +} + diff --git a/source/tests/condition_variable.test.c b/source/tests/condition_variable.test.c new file mode 100644 index 0000000..dfbe4a6 --- /dev/null +++ b/source/tests/condition_variable.test.c @@ -0,0 +1,84 @@ +#include "../kit/condition_variable.h" +#include "../kit/thread.h" + +#define KIT_TEST_FILE condition_variable +#include "../kit_test/test.h" + +typedef struct { + mtx_t m; + int in; + int out; + cnd_t send; + cnd_t receive; + int value; +} cnd_test_data_t; + +static int cnd_test_run(void *p) { + cnd_test_data_t *data = (cnd_test_data_t *) p; + + mtx_lock(&data->m); + data->value = 20; + data->out = 1; + mtx_unlock(&data->m); + + cnd_broadcast(&data->send); + + mtx_lock(&data->m); + if (data->in == 0) + cnd_wait(&data->receive, &data->m); + data->in = 0; + data->value = 22; + data->out = 1; + mtx_unlock(&data->m); + + cnd_broadcast(&data->send); + + return 0; +} + +TEST("condition variable") { + int i; + int ok = 1; + + for (i = 0; i < 10; i++) { + cnd_test_data_t data; + + data.in = 0; + data.out = 0; + data.value = 0; + + ok = ok && (mtx_init(&data.m, mtx_plain) == thrd_success); + ok = ok && (cnd_init(&data.send) == thrd_success); + ok = ok && (cnd_init(&data.receive) == thrd_success); + + thrd_t t; + ok = ok && (thrd_create(&t, cnd_test_run, &data) == thrd_success); + + ok = ok && (mtx_lock(&data.m) == thrd_success); + if (data.out == 0) + ok = ok && (cnd_wait(&data.send, &data.m) == thrd_success); + data.out = 0; + int x = data.value; + data.in = 1; + ok = ok && (mtx_unlock(&data.m) == thrd_success); + + ok = ok && (cnd_broadcast(&data.receive) == thrd_success); + + ok = ok && (mtx_lock(&data.m) == thrd_success); + if (data.out == 0) + ok = ok && (cnd_wait(&data.send, &data.m) == thrd_success); + data.out = 0; + x += data.value; + ok = ok && (mtx_unlock(&data.m) == thrd_success); + + ok = ok && (thrd_join(t, NULL) == thrd_success); + + mtx_destroy(&data.m); + cnd_destroy(&data.send); + cnd_destroy(&data.receive); + + ok = ok && (x == 42); + } + + REQUIRE(ok); +} diff --git a/source/tests/cpp.cpp b/source/tests/cpp.cpp new file mode 100644 index 0000000..8b762e4 --- /dev/null +++ b/source/tests/cpp.cpp @@ -0,0 +1,13 @@ +#include "../kit_test/test.h" + +TEST("foo") { + REQUIRE(20 + 22 == 42); +} + +TEST("bar") { + REQUIRE(true); +} + +int main(int argc, char **argv) { + return run_tests(argc, argv); +} diff --git a/source/tests/dynamic_array.test.c b/source/tests/dynamic_array.test.c new file mode 100644 index 0000000..8701e6c --- /dev/null +++ b/source/tests/dynamic_array.test.c @@ -0,0 +1,174 @@ +#include "../kit/dynamic_array.h" + +#define KIT_TEST_FILE dynamic_array +#include "../kit_test/test.h" + +TEST("dynamic array empty") { + DA_CREATE(v, char, 0); + + REQUIRE(v.size == 0); + + DA_DESTROY(v); +} + +TEST("dynamic array resize") { + DA_CREATE(v, char, 0); + DA_RESIZE(v, 10); + + REQUIRE(v.size == 10); + + DA_DESTROY(v); +} + +TEST("dynamic array grow") { + DA_CREATE(v, char, 2); + DA_RESIZE(v, 10); + + REQUIRE(v.size == 10); + + DA_DESTROY(v); +} + +TEST("dynamic array diminish") { + DA_CREATE(v, char, 10); + DA_RESIZE(v, 9); + + REQUIRE(v.size == 9); + + DA_DESTROY(v); +} + +TEST("dynamic array of chars") { + DA_CREATE(v, char, 100); + + REQUIRE(v.size == 100); + REQUIRE(v.capacity >= 100); + REQUIRE(v.values != NULL); + + DA_DESTROY(v); +} + +TEST("dynamic array push") { + DA_CREATE(v, char, 0); + DA_APPEND(v, 'x'); + + REQUIRE(v.size == 1); + REQUIRE(v.values[0] == 'x'); + + DA_DESTROY(v); +} + +TEST("dynamic array insert front") { + DA_CREATE(v, char, 3); + + v.values[0] = 'a'; + v.values[1] = 'b'; + v.values[2] = 'c'; + + DA_INSERT(v, 0, 'x'); + + REQUIRE(v.size == 4); + REQUIRE(v.values[0] == 'x'); + REQUIRE(v.values[1] == 'a'); + REQUIRE(v.values[2] == 'b'); + REQUIRE(v.values[3] == 'c'); + + DA_DESTROY(v); +} + +TEST("dynamic array insert back") { + DA_CREATE(v, char, 3); + + v.values[0] = 'a'; + v.values[1] = 'b'; + v.values[2] = 'c'; + + DA_INSERT(v, 3, 'x'); + + REQUIRE(v.size == 4); + REQUIRE(v.values[0] == 'a'); + REQUIRE(v.values[1] == 'b'); + REQUIRE(v.values[2] == 'c'); + REQUIRE(v.values[3] == 'x'); + + DA_DESTROY(v); +} + +TEST("dynamic array insert middle") { + DA_CREATE(v, char, 3); + + v.values[0] = 'a'; + v.values[1] = 'b'; + v.values[2] = 'c'; + + DA_INSERT(v, 2, 'x'); + + REQUIRE(v.size == 4); + REQUIRE(v.values[0] == 'a'); + REQUIRE(v.values[1] == 'b'); + REQUIRE(v.values[2] == 'x'); + REQUIRE(v.values[3] == 'c'); + + DA_DESTROY(v); +} + +TEST("dynamic array erase front") { + DA_CREATE(v, char, 3); + + v.values[0] = 'a'; + v.values[1] = 'b'; + v.values[2] = 'c'; + + DA_ERASE(v, 0); + + REQUIRE(v.size == 2); + REQUIRE(v.values[0] == 'b'); + REQUIRE(v.values[1] == 'c'); + + DA_DESTROY(v); +} + +TEST("dynamic array erase back") { + DA_CREATE(v, char, 3); + + v.values[0] = 'a'; + v.values[1] = 'b'; + v.values[2] = 'c'; + + DA_ERASE(v, 2); + + REQUIRE(v.size == 2); + REQUIRE(v.values[0] == 'a'); + REQUIRE(v.values[1] == 'b'); + + DA_DESTROY(v); +} + +TEST("dynamic array erase middle") { + DA_CREATE(v, char, 3); + + v.values[0] = 'a'; + v.values[1] = 'b'; + v.values[2] = 'c'; + + DA_ERASE(v, 1); + + REQUIRE(v.size == 2); + REQUIRE(v.values[0] == 'a'); + REQUIRE(v.values[1] == 'c'); + + DA_DESTROY(v); +} + +TEST("dynamic array of ints") { + DA_CREATE(v, int, 10); + DA_RESIZE(v, 5); + v.values[4] = 42; + DA_APPEND(v, 43); + + REQUIRE(v.size == 6); + REQUIRE(v.values[4] == 42); + REQUIRE(v.values[5] == 43); + + DA_DESTROY(v); +} diff --git a/source/tests/file.test.c b/source/tests/file.test.c new file mode 100644 index 0000000..e72df83 --- /dev/null +++ b/source/tests/file.test.c @@ -0,0 +1,220 @@ +#include "../kit/file.h" +#include "../kit/string_ref.h" +#include + +#define KIT_TEST_FILE file +#include "../kit_test/test.h" + +TEST("file path cache") { + kit_allocator_t alloc = kit_alloc_default(); + + string_t user = path_user(alloc); + string_t cache = path_cache(alloc); + + DA_RESIZE(cache, cache.size + 1); + cache.values[cache.size - 1] = '\0'; + DA_RESIZE(cache, cache.size - 1); + + string_t expected = +#if defined(_WIN32) && !defined(__CYGWIN__) + path_join(WRAP_STR(user), SZ("AppData" PATH_DELIM "Local"), + alloc); +#elif defined(__APPLE__) + path_join(WRAP_STR(user), SZ("Library" PATH_DELIM "Caches"), + alloc); +#else + path_join(WRAP_STR(user), SZ(".cache"), alloc); +#endif + + REQUIRE(AR_EQUAL(cache, expected)); + + DA_DESTROY(user); + DA_DESTROY(cache); + DA_DESTROY(expected); +} + +TEST("file path normalize one") { + str_t foo = SZ("foo/bar/../baz"); + str_t foo_norm = SZ("foo" PATH_DELIM "baz"); + + string_t bar = path_norm(foo, kit_alloc_default()); + + REQUIRE(AR_EQUAL(foo_norm, bar)); + + DA_DESTROY(bar); +} + +TEST("file path normalize two") { + str_t foo = SZ("foo/bar/../../baz"); + str_t foo_norm = SZ("baz"); + + string_t bar = path_norm(foo, kit_alloc_default()); + + REQUIRE(AR_EQUAL(foo_norm, bar)); + + DA_DESTROY(bar); +} + +TEST("file path normalize parent") { + str_t foo = SZ("../baz"); + str_t foo_norm = SZ(".." PATH_DELIM "baz"); + + string_t bar = path_norm(foo, kit_alloc_default()); + + REQUIRE(AR_EQUAL(foo_norm, bar)); + + DA_DESTROY(bar); +} + +TEST("file path normalize double parent") { + str_t foo = SZ("foo/../../baz"); + str_t foo_norm = SZ(".." PATH_DELIM "baz"); + + string_t bar = path_norm(foo, kit_alloc_default()); + + REQUIRE(AR_EQUAL(foo_norm, bar)); + + DA_DESTROY(bar); +} + +TEST("file path normalize windows delim") { + str_t foo = SZ("foo\\bar\\..\\baz"); + str_t foo_norm = SZ("foo" PATH_DELIM "baz"); + + string_t bar = path_norm(foo, kit_alloc_default()); + + REQUIRE(AR_EQUAL(foo_norm, bar)); + + DA_DESTROY(bar); +} + +TEST("file path join no delim") { + str_t foo = SZ("foo"); + str_t bar = SZ("bar"); + str_t joined = SZ("foo" PATH_DELIM "bar"); + + string_t foobar = path_join(foo, bar, kit_alloc_default()); + + REQUIRE(AR_EQUAL(joined, foobar)); + + DA_DESTROY(foobar); +} + +TEST("file path join delim left") { + str_t foo = SZ("foo/"); + str_t bar = SZ("bar"); + str_t joined = SZ("foo" PATH_DELIM "bar"); + + string_t foobar = path_join(foo, bar, kit_alloc_default()); + + REQUIRE(AR_EQUAL(joined, foobar)); + + DA_DESTROY(foobar); +} + +TEST("file path join delim right") { + str_t foo = SZ("foo"); + str_t bar = SZ("/bar"); + str_t joined = SZ("foo" PATH_DELIM "bar"); + + string_t foobar = path_join(foo, bar, kit_alloc_default()); + + REQUIRE(AR_EQUAL(joined, foobar)); + + DA_DESTROY(foobar); +} + +TEST("file path join delim both") { + str_t foo = SZ("foo/"); + str_t bar = SZ("/bar"); + str_t joined = SZ("foo" PATH_DELIM "bar"); + + string_t foobar = path_join(foo, bar, kit_alloc_default()); + + REQUIRE(AR_EQUAL(joined, foobar)); + + DA_DESTROY(foobar); +} + +TEST("file path user") { + string_t user = path_user(kit_alloc_default()); + + REQUIRE(user.size > 0); + + DA_DESTROY(user); +} + +TEST("file path index relative") { + str_t foobar = SZ("foo/bar"); + str_t foo = SZ("foo"); + str_t bar = SZ("bar"); + + REQUIRE(AR_EQUAL(path_index(foobar, 0), foo)); + REQUIRE(AR_EQUAL(path_index(foobar, 1), bar)); + REQUIRE(path_index(foobar, 2).size == 0); +} + +TEST("file path index absolute") { + str_t foobar = SZ("/foo/bar"); + str_t foo = SZ("foo"); + str_t bar = SZ("bar"); + + REQUIRE(AR_EQUAL(path_index(foobar, 0), foo)); + REQUIRE(AR_EQUAL(path_index(foobar, 1), bar)); + REQUIRE(path_index(foobar, 2).size == 0); +} + +TEST("file path index windows disk name") { + str_t foobar = SZ("c:\\foo\\bar"); + str_t disk = SZ("c:"); + str_t foo = SZ("foo"); + str_t bar = SZ("bar"); + + REQUIRE(AR_EQUAL(path_index(foobar, 0), disk)); + REQUIRE(AR_EQUAL(path_index(foobar, 1), foo)); + REQUIRE(AR_EQUAL(path_index(foobar, 2), bar)); + REQUIRE(path_index(foobar, 3).size == 0); +} + +TEST("file path take relative") { + str_t foobar = SZ("foo/bar/"); + str_t foo = SZ("foo"); + str_t bar = SZ("foo/bar"); + str_t bar_end = SZ("foo/bar/"); + + REQUIRE(AR_EQUAL(path_take(foobar, 0), foo)); + REQUIRE(AR_EQUAL(path_take(foobar, 1), bar)); + REQUIRE(AR_EQUAL(path_take(foobar, 2), bar_end)); +} + +TEST("file path take absolute") { + str_t foobar = SZ("/foo/bar"); + str_t foo = SZ("/foo"); + str_t bar = SZ("/foo/bar"); + + REQUIRE(AR_EQUAL(path_take(foobar, 0), foo)); + REQUIRE(AR_EQUAL(path_take(foobar, 1), bar)); +} + +TEST("file path take windows disk name") { + str_t foobar = SZ("c:\\foo\\bar"); + str_t disk = SZ("c:"); + str_t foo = SZ("c:\\foo"); + str_t bar = SZ("c:\\foo\\bar"); + + REQUIRE(AR_EQUAL(path_take(foobar, 0), disk)); + REQUIRE(AR_EQUAL(path_take(foobar, 1), foo)); + REQUIRE(AR_EQUAL(path_take(foobar, 2), bar)); +} + +TEST("file create folder") { } + +TEST("file create folder recursive") { } + +TEST("file remove") { } + +TEST("file remove folder") { } + +TEST("file remove recursive") { } + +TEST("file enum folder") { } diff --git a/source/tests/input_buffer.test.c b/source/tests/input_buffer.test.c new file mode 100644 index 0000000..3cd84b6 --- /dev/null +++ b/source/tests/input_buffer.test.c @@ -0,0 +1,105 @@ +#include "../kit/input_buffer.h" + +#define KIT_TEST_FILE input_buffer +#include "../kit_test/test.h" + +TEST("input buffer read once") { + str_t text = { .size = 3, .values = "foo" }; + is_handle_t in = IS_WRAP_STRING(text); + ib_handle_t first = IB_WRAP(in); + + ib_handle_t second = ib_read(first, 3); + + REQUIRE(second.status == KIT_OK); + REQUIRE(second.data.size == 3); + REQUIRE(AR_EQUAL(text, second.data)); + + ib_destroy(second); + ib_destroy(first); + is_destroy(in); +} + +TEST("input buffer read again") { + str_t text = { .size = 6, .values = "foobar" }; + str_t foo = { .size = 3, .values = "foo" }; + is_handle_t in = IS_WRAP_STRING(text); + ib_handle_t first = IB_WRAP(in); + + ib_handle_t second = ib_read(first, 3); + ib_handle_t third = ib_read(first, 3); + + REQUIRE(AR_EQUAL(foo, second.data)); + REQUIRE(AR_EQUAL(foo, third.data)); + + ib_destroy(third); + ib_destroy(second); + ib_destroy(first); + is_destroy(in); +} + +TEST("input buffer read twice") { + str_t text = { .size = 6, .values = "foobar" }; + str_t foo = { .size = 3, .values = "foo" }; + str_t bar = { .size = 3, .values = "bar" }; + is_handle_t in = IS_WRAP_STRING(text); + ib_handle_t first = IB_WRAP(in); + + ib_handle_t second = ib_read(first, 3); + ib_handle_t third = ib_read(second, 3); + + REQUIRE(AR_EQUAL(foo, second.data)); + REQUIRE(AR_EQUAL(bar, third.data)); + + ib_destroy(third); + ib_destroy(second); + ib_destroy(first); + is_destroy(in); +} + +static int is_integer_(str_t const data) { + for (ptrdiff_t i = 0; i < data.size; i++) + if (data.values[i] < '0' || data.values[i] > '9') + return 0; + return 1; +} + +TEST("input buffer read integer once") { + str_t text = { .size = 9, .values = "31415 foo" }; + str_t num = { .size = 5, .values = "31415" }; + is_handle_t in = IS_WRAP_STRING(text); + ib_handle_t first = IB_WRAP(in); + + ib_handle_t second = ib_read_while(first, is_integer_); + + REQUIRE(second.status == KIT_OK); + REQUIRE(second.data.size == 5); + REQUIRE(AR_EQUAL(num, second.data)); + + ib_destroy(second); + ib_destroy(first); + is_destroy(in); +} + +TEST("input buffer read integer twice") { + str_t text = { .size = 6, .values = "314 15" }; + str_t num_0 = { .size = 3, .values = "314" }; + str_t num_1 = { .size = 2, .values = "15" }; + is_handle_t in = IS_WRAP_STRING(text); + ib_handle_t first = IB_WRAP(in); + + ib_handle_t second = ib_read_while(first, is_integer_); + ib_handle_t third = ib_read(second, 1); + ib_handle_t fourth = ib_read_while(third, is_integer_); + + REQUIRE(fourth.status == KIT_OK); + REQUIRE(second.data.size == 3); + REQUIRE(fourth.data.size == 2); + REQUIRE(AR_EQUAL(num_0, second.data)); + REQUIRE(AR_EQUAL(num_1, fourth.data)); + + ib_destroy(first); + ib_destroy(second); + ib_destroy(third); + ib_destroy(fourth); + is_destroy(in); +} diff --git a/source/tests/input_stream.test.c b/source/tests/input_stream.test.c new file mode 100644 index 0000000..61c2254 --- /dev/null +++ b/source/tests/input_stream.test.c @@ -0,0 +1,23 @@ +#include "../kit/input_stream.h" + +#define KIT_TEST_FILE input_stream +#include "../kit_test/test.h" + +TEST("input stream wrap string") { + char foo[] = "test"; + char bar[] = "test"; + + str_t foo_ref = { .size = sizeof(foo) - 1, .values = foo }; + str_t bar_ref = { .size = sizeof(bar) - 1, .values = bar }; + + is_handle_t in = IS_WRAP_STRING(foo_ref); + + char buf[4]; + out_str_t buf_ref = { .size = sizeof(buf), .values = buf }; + + REQUIRE(IS_READ(in, buf_ref) == buf_ref.size); + REQUIRE(AR_EQUAL(foo_ref, bar_ref)); + REQUIRE(AR_EQUAL(buf_ref, bar_ref)); + + is_destroy(in); +} diff --git a/source/tests/lower_bound.test.c b/source/tests/lower_bound.test.c new file mode 100644 index 0000000..3b62325 --- /dev/null +++ b/source/tests/lower_bound.test.c @@ -0,0 +1,178 @@ +#include "../kit/lower_bound.h" +#include "../kit/array_ref.h" + +#define KIT_TEST_FILE lower_bound +#include "../kit_test/test.h" + +static int kit_less_int(int left, int right) { + return left < right; +} + +static int kit_less_int_ref(int const *left, int const *right) { + return *left < *right; +} + +TEST("lower bound empty") { + AR(int) ref = { .size = 0, .values = NULL }; + + ptrdiff_t index; + LOWER_BOUND(index, ref, 42, kit_less_int); + REQUIRE(index == 0); +} + +TEST("lower bound single left") { + int const v[1] = { 42 }; + AR(int) ref = { .size = 1, .values = v }; + + ptrdiff_t index; + LOWER_BOUND(index, ref, 42, kit_less_int); + REQUIRE(index == 0); +} + +TEST("lower bound single right") { + int const v[1] = { 42 }; + AR(int) ref = { .size = 1, .values = v }; + + ptrdiff_t index; + LOWER_BOUND(index, ref, 43, kit_less_int); + REQUIRE(index == 1); +} + +TEST("lower bound first of four") { + int const v[4] = { 1, 2, 3, 4 }; + AR(int) ref = { .size = 4, .values = v }; + + ptrdiff_t index; + LOWER_BOUND(index, ref, 1, kit_less_int); + REQUIRE(index == 0); +} + +TEST("lower bound second of four") { + int const v[4] = { 1, 2, 3, 4 }; + AR(int) ref = { .size = 4, .values = v }; + + ptrdiff_t index; + LOWER_BOUND(index, ref, 2, kit_less_int); + REQUIRE(index == 1); +} + +TEST("lower bound third of four") { + int const v[4] = { 1, 2, 3, 4 }; + AR(int) ref = { .size = 4, .values = v }; + + ptrdiff_t index; + LOWER_BOUND(index, ref, 3, kit_less_int); + REQUIRE(index == 2); +} + +TEST("lower bound forth of four") { + int const v[4] = { 1, 2, 3, 4 }; + AR(int) ref = { .size = 4, .values = v }; + + ptrdiff_t index; + LOWER_BOUND(index, ref, 4, kit_less_int); + REQUIRE(index == 3); +} + +TEST("lower bound fifth of four") { + int const v[4] = { 1, 2, 3, 4 }; + AR(int) ref = { .size = 4, .values = v }; + + ptrdiff_t index; + LOWER_BOUND(index, ref, 5, kit_less_int); + REQUIRE(index == 4); +} + +TEST("lower bound first of five") { + int const v[5] = { 1, 2, 3, 4, 5 }; + AR(int) ref = { .size = 5, .values = v }; + + ptrdiff_t index; + LOWER_BOUND(index, ref, 1, kit_less_int); + REQUIRE(index == 0); +} + +TEST("lower bound second of five") { + int const v[5] = { 1, 2, 3, 4, 5 }; + AR(int) ref = { .size = 5, .values = v }; + + ptrdiff_t index; + LOWER_BOUND(index, ref, 2, kit_less_int); + REQUIRE(index == 1); +} + +TEST("lower bound third of five") { + int const v[5] = { 1, 2, 3, 4, 5 }; + AR(int) ref = { .size = 5, .values = v }; + + ptrdiff_t index; + LOWER_BOUND(index, ref, 3, kit_less_int); + REQUIRE(index == 2); +} + +TEST("lower bound forth of five") { + int const v[5] = { 1, 2, 3, 4, 5 }; + AR(int) ref = { .size = 5, .values = v }; + + ptrdiff_t index; + LOWER_BOUND(index, ref, 4, kit_less_int); + REQUIRE(index == 3); +} + +TEST("lower bound fifth of five") { + int const v[5] = { 1, 2, 3, 4, 5 }; + AR(int) ref = { .size = 5, .values = v }; + + ptrdiff_t index; + LOWER_BOUND(index, ref, 5, kit_less_int); + REQUIRE(index == 4); +} + +TEST("lower bound sixth of five") { + int const v[5] = { 1, 2, 3, 4, 5 }; + AR(int) ref = { .size = 5, .values = v }; + + ptrdiff_t index; + LOWER_BOUND(index, ref, 6, kit_less_int); + REQUIRE(index == 5); +} + +TEST("lower bound ref first of four") { + int const v[4] = { 1, 2, 3, 4 }; + int const value = 1; + AR(int) ref = { .size = 4, .values = v }; + + ptrdiff_t index; + LOWER_BOUND_REF(index, ref, &value, kit_less_int_ref); + REQUIRE(index == 0); +} + +TEST("lower bound ref second of four") { + int const v[4] = { 1, 2, 3, 4 }; + int const value = 2; + AR(int) ref = { .size = 4, .values = v }; + + ptrdiff_t index; + LOWER_BOUND_REF(index, ref, &value, kit_less_int_ref); + REQUIRE(index == 1); +} + +TEST("lower bound ref fifth of five") { + int const v[5] = { 1, 2, 3, 4, 5 }; + int const value = 5; + AR(int) ref = { .size = 5, .values = v }; + + ptrdiff_t index; + LOWER_BOUND_REF(index, ref, &value, kit_less_int_ref); + REQUIRE(index == 4); +} + +TEST("lower bound ref sixth of five") { + int const v[5] = { 1, 2, 3, 4, 5 }; + int const value = 6; + AR(int) ref = { .size = 5, .values = v }; + + ptrdiff_t index; + LOWER_BOUND_REF(index, ref, &value, kit_less_int_ref); + REQUIRE(index == 5); +} diff --git a/source/tests/main.test.c b/source/tests/main.test.c new file mode 100644 index 0000000..2a41d4b --- /dev/null +++ b/source/tests/main.test.c @@ -0,0 +1,9 @@ +#include "../kit_test/bench.h" +#include "../kit_test/test.h" + +int main(int argc, char **argv) { + int status = run_tests(argc, argv); + if (status == 0) + status = run_benchmarks(argc, argv); + return status; +} diff --git a/source/tests/mersenne_twister_64.test.c b/source/tests/mersenne_twister_64.test.c new file mode 100644 index 0000000..6bf5b9c --- /dev/null +++ b/source/tests/mersenne_twister_64.test.c @@ -0,0 +1,38 @@ +#include "../kit/mersenne_twister_64.h" +#include "../kit/secure_random.h" + +#define KIT_TEST_FILE mersenne_twister_64 +#include "../kit_test/test.h" + +enum { SIZE = 1000 }; + +TEST("mt64 same seeds") { + ptrdiff_t i; + uint64_t seed; + secure_random(sizeof seed, &seed); + + mt64_state_t foo, bar; + mt64_init(&foo, seed); + mt64_init(&bar, seed); + + int ok = 1; + for (i = 0; i < SIZE; i++) + ok = ok && mt64_generate(&foo) == mt64_generate(&bar); + + REQUIRE(ok); +} + +TEST("mt64 different seeds") { + ptrdiff_t i; + + mt64_state_t foo, bar; + mt64_init(&foo, 42); + mt64_init(&bar, 4242424242); + + ptrdiff_t difference_count = 0; + for (i = 0; i < SIZE; i++) + if (mt64_generate(&foo) != mt64_generate(&bar)) + difference_count++; + + REQUIRE(difference_count > SIZE / 2); +} diff --git a/source/tests/move_back.test.c b/source/tests/move_back.test.c new file mode 100644 index 0000000..f08d190 --- /dev/null +++ b/source/tests/move_back.test.c @@ -0,0 +1,148 @@ +#include "../kit/move_back.h" + +#define KIT_TEST_FILE move_back +#include "../kit_test/test.h" + +static int is_equal(int const x, int const y) { + return x == y; +} + +static int is_equal_ref(int const *const x, int const y) { + return *x == y; +} + +static int is_even(int const x, int const _) { + return (x % 2) == 0; +} + +static int is_even_ref(int const *const x, int const _) { + return (*x % 2) == 0; +} + +TEST("move back val") { + int v[] = { 1, 2, 2, 2, 1, 1 }; + + struct { + int size; + int *values; + } ref = { .size = sizeof v / sizeof *v, .values = v }; + + MOVE_BACK(ref.size, ref, 2, is_equal); + + REQUIRE_EQ(ref.size, 3); + REQUIRE_EQ(v[0], 1); + REQUIRE_EQ(v[1], 1); + REQUIRE_EQ(v[2], 1); +} + +TEST("move back ref val") { + int v[] = { 1, 2, 2, 2, 1, 1 }; + + struct { + int size; + int *values; + } ref = { .size = sizeof v / sizeof *v, .values = v }; + + MOVE_BACK_REF(ref.size, ref, 2, is_equal_ref); + + REQUIRE(ref.size == 3); + REQUIRE(v[0] == 1); + REQUIRE(v[1] == 1); + REQUIRE(v[2] == 1); +} + +TEST("move back 1") { + int v[] = { 1, 2, 3, 4, 5, 6 }; + + struct { + int size; + int *values; + } ref = { .size = sizeof v / sizeof *v, .values = v }; + + MOVE_BACK(ref.size, ref, 0, is_even); + + REQUIRE(ref.size == 3); + REQUIRE(v[0] == 1); + REQUIRE(v[1] == 5); + REQUIRE(v[2] == 3); +} + +TEST("move back 2") { + int v[] = { 2, 4, 6, 1, 3, 5 }; + + struct { + int size; + int *values; + } ref = { .size = sizeof v / sizeof *v, .values = v }; + + MOVE_BACK(ref.size, ref, 0, is_even); + + REQUIRE(ref.size == 3); + REQUIRE(v[0] == 5); + REQUIRE(v[1] == 3); + REQUIRE(v[2] == 1); +} + +TEST("move back 3") { + int v[] = { 1, 3, 5, 2, 4, 6 }; + + struct { + int size; + int *values; + } ref = { .size = sizeof v / sizeof *v, .values = v }; + + MOVE_BACK(ref.size, ref, 0, is_even); + + REQUIRE(ref.size == 3); + REQUIRE(v[0] == 1); + REQUIRE(v[1] == 3); + REQUIRE(v[2] == 5); +} + +TEST("move back ref 1") { + int v[] = { 1, 2, 3, 4, 5, 6 }; + + struct { + int size; + int *values; + } ref = { .size = sizeof v / sizeof *v, .values = v }; + + MOVE_BACK_REF(ref.size, ref, 0, is_even_ref); + + REQUIRE(ref.size == 3); + REQUIRE(v[0] == 1); + REQUIRE(v[1] == 5); + REQUIRE(v[2] == 3); +} + +TEST("move back ref 2") { + int v[] = { 2, 4, 6, 1, 3, 5 }; + + struct { + int size; + int *values; + } ref = { .size = sizeof v / sizeof *v, .values = v }; + + MOVE_BACK_REF(ref.size, ref, 0, is_even_ref); + + REQUIRE(ref.size == 3); + REQUIRE(v[0] == 5); + REQUIRE(v[1] == 3); + REQUIRE(v[2] == 1); +} + +TEST("move back ref 3") { + int v[] = { 1, 3, 5, 2, 4, 6 }; + + struct { + int size; + int *values; + } ref = { .size = sizeof v / sizeof *v, .values = v }; + + MOVE_BACK_REF(ref.size, ref, 0, is_even_ref); + + REQUIRE(ref.size == 3); + REQUIRE(v[0] == 1); + REQUIRE(v[1] == 3); + REQUIRE(v[2] == 5); +} diff --git a/source/tests/mutex.test.c b/source/tests/mutex.test.c new file mode 100644 index 0000000..ce26991 --- /dev/null +++ b/source/tests/mutex.test.c @@ -0,0 +1,79 @@ +#include "../kit/mutex.h" +#include "../kit/thread.h" + +#define KIT_TEST_FILE mutex +#include "../kit_test/test.h" + +enum { SLEEP = 400000000, TICK_COUNT = 200, THREAD_COUNT = 100 }; + +typedef struct { + mtx_t lock; + int value; +} mtx_test_data_t; + +static int mtx_test_run(void *data) { + int i; + mtx_test_data_t *x = (mtx_test_data_t *) data; + for (i = 0; i < TICK_COUNT; i++) { + mtx_lock(&x->lock); + + x->value += i; + thrd_yield(); + x->value -= i + 42; + thrd_yield(); + x->value += i + 20; + thrd_yield(); + x->value += 22 - i; + + mtx_unlock(&x->lock); + } + return 0; +} + +TEST("mutex lock") { + ptrdiff_t i; + + mtx_test_data_t data; + thrd_t pool[THREAD_COUNT]; + data.value = 42; + REQUIRE(mtx_init(&data.lock, mtx_plain) == thrd_success); + + for (i = 0; i < THREAD_COUNT; i++) + thrd_create(pool + i, mtx_test_run, &data); + for (i = 0; i < THREAD_COUNT; i++) thrd_join(pool[i], NULL); + + mtx_destroy(&data.lock); + REQUIRE(data.value == 42); +} + +static int test_lock(void *data) { + mtx_t *m = (mtx_t *) data; + mtx_lock(m); + + struct timespec sec = { .tv_sec = 0, .tv_nsec = SLEEP }; + thrd_sleep(&sec, NULL); + + mtx_unlock(m); + + return 0; +} + +TEST("mutex try lock") { + mtx_t m; + REQUIRE(mtx_init(&m, mtx_plain) == thrd_success); + + thrd_t t; + REQUIRE(thrd_create(&t, test_lock, &m) == thrd_success); + + struct timespec sec = { .tv_sec = 0, .tv_nsec = SLEEP / 2 }; + REQUIRE(thrd_sleep(&sec, NULL) == thrd_success); + + REQUIRE(mtx_trylock(&m) == thrd_busy); + + REQUIRE(thrd_join(t, NULL) == thrd_success); + + REQUIRE(mtx_trylock(&m) == thrd_success); + REQUIRE(mtx_unlock(&m) == thrd_success); + + mtx_destroy(&m); +} diff --git a/source/tests/secure_random.test.c b/source/tests/secure_random.test.c new file mode 100644 index 0000000..22bdd37 --- /dev/null +++ b/source/tests/secure_random.test.c @@ -0,0 +1,24 @@ +#include "../kit/secure_random.h" +#include + +#define KIT_TEST_FILE secure_random +#include "../kit_test/test.h" + +TEST("secure random") { + int i, j; + + int v[20]; + memset(v, 0, sizeof v); + + secure_random(40, v); + secure_random(40, v + 10); + + int repeats = 0; + + for (i = 1; i < sizeof v / sizeof *v; i++) + for (j = 0; j < i; j++) + if (v[i] == v[j]) + repeats++; + + REQUIRE(repeats == 0); +} diff --git a/source/tests/sha256.test.c b/source/tests/sha256.test.c new file mode 100644 index 0000000..0f751df --- /dev/null +++ b/source/tests/sha256.test.c @@ -0,0 +1,42 @@ +#include "../kit/sha256.h" +#include "../kit/array_ref.h" + +#define KIT_TEST_FILE sha256_64 +#include "../kit_test/test.h" + +#include + +TEST("sha256") { + uint8_t text1[] = "abc"; + uint8_t text2[] = + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; + + uint8_t text3[1000000]; + memset(text3, 'a', sizeof text3); + + uint8_t hash1[] = { + 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, + 0xde, 0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, + 0x7a, 0x9c, 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad + }; + uint8_t hash2[] = { + 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8, 0xe5, 0xc0, 0x26, + 0x93, 0x0c, 0x3e, 0x60, 0x39, 0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, + 0x21, 0x67, 0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1 + }; + uint8_t hash3[] = { + 0xcd, 0xc7, 0x6e, 0x5c, 0x99, 0x14, 0xfb, 0x92, 0x81, 0xa1, 0xc7, + 0xe2, 0x84, 0xd7, 0x3e, 0x67, 0xf1, 0x80, 0x9a, 0x48, 0xa4, 0x97, + 0x20, 0x0e, 0x04, 0x6d, 0x39, 0xcc, 0xc7, 0x11, 0x2c, 0xd0 + }; + + REQUIRE(ar_equal_bytes(1, SHA256_BLOCK_SIZE, + sha256((sizeof text1) - 1, text1).v, 1, + SHA256_BLOCK_SIZE, hash1)); + REQUIRE(ar_equal_bytes(1, SHA256_BLOCK_SIZE, + sha256((sizeof text2) - 1, text2).v, 1, + SHA256_BLOCK_SIZE, hash2)); + REQUIRE(ar_equal_bytes(1, SHA256_BLOCK_SIZE, + sha256(sizeof text3, text3).v, 1, + SHA256_BLOCK_SIZE, hash3)); +} diff --git a/source/tests/signals.cpp b/source/tests/signals.cpp new file mode 100644 index 0000000..0f6d77a --- /dev/null +++ b/source/tests/signals.cpp @@ -0,0 +1,29 @@ +#include "../kit_test/test.h" + +#include +#include + +/* FIXME + * MSVC tests fail in GitHub Actions. + */ + +TEST("c++ exception") { + throw std::exception(); +} + +TEST("abort") { + abort(); +} + +TEST("invalid access") { + *(volatile int *) nullptr = 42; +} + +int main(int argc, char **argv) { +#ifndef _MSC_VER + if (run_tests(argc, argv) != 1) + return 1; +#endif + + return 0; +} diff --git a/source/tests/string_ref.test.c b/source/tests/string_ref.test.c new file mode 100644 index 0000000..2891f16 --- /dev/null +++ b/source/tests/string_ref.test.c @@ -0,0 +1,23 @@ +#include "../kit/string_ref.h" + +#define KIT_TEST_FILE string_ref +#include "../kit_test/test.h" + +TEST("static string wrap") { + str_t ref = SZ("foo bar"); + + REQUIRE(ref.size == 7); + REQUIRE(ref.values[0] == 'f'); + REQUIRE(ref.values[1] == 'o'); + REQUIRE(ref.values[2] == 'o'); + REQUIRE(ref.values[3] == ' '); + REQUIRE(ref.values[4] == 'b'); + REQUIRE(ref.values[5] == 'a'); + REQUIRE(ref.values[6] == 'r'); +} + +TEST("string literal") { + str_t foo = SZ("foo"); + str_t bar = foo; + (void) bar; +} diff --git a/source/tests/test_duration.test.c b/source/tests/test_duration.test.c new file mode 100644 index 0000000..27384b4 --- /dev/null +++ b/source/tests/test_duration.test.c @@ -0,0 +1,19 @@ +#define KIT_TEST_FILE test_duration +#include "../kit_test/test.h" + +#if defined(_WIN32) && !defined(__CYGWIN__) +__declspec(dllimport) void __stdcall Sleep(unsigned long timeout); +static void kit_sleep(int ms) { + Sleep(ms); +} +#else +# include +# include +static void kit_sleep(int ms) { + usleep(ms * 1000); +} +#endif + +TEST("test duration") { + kit_sleep(100); +} diff --git a/source/tests/thread.test.c b/source/tests/thread.test.c new file mode 100644 index 0000000..50f7c04 --- /dev/null +++ b/source/tests/thread.test.c @@ -0,0 +1,91 @@ +#include "../kit/thread.h" + +#define KIT_TEST_FILE thread +#include "../kit_test/test.h" + +static int test_nothing(void *_) { + return 0; +} + +static int test_run(void *data) { + int *n = (int *) data; + return *n + 20; +} + +static int test_exit(void *data) { + int *n = (int *) data; + + *n = 1; + thrd_exit(3); + *n = 2; + return 4; +} + +static int test_yield(void *data) { + thrd_yield(); + return 0; +} + +static int test_sleep(void *data) { + struct timespec t = { .tv_sec = 0, .tv_nsec = 10000000 }; + thrd_sleep(&t, NULL); + return 0; +} + +TEST("thread run") { + thrd_t t; + int data = 22; + int result; + REQUIRE(thrd_create(&t, test_run, &data) == thrd_success); + REQUIRE(thrd_join(t, &result) == thrd_success); + REQUIRE(result == 42); +} + +TEST("thread stack size") { + thrd_t foo; + REQUIRE(thrd_create_with_stack(&foo, test_nothing, NULL, 30000) == + thrd_success); + REQUIRE(thrd_join(foo, NULL) == thrd_success); +} + +TEST("thread equal") { + thrd_t foo, bar; + REQUIRE(thrd_create(&foo, test_nothing, NULL) == thrd_success); + REQUIRE(thrd_create(&bar, test_nothing, NULL) == thrd_success); + REQUIRE(thrd_equal(foo, foo)); + REQUIRE(!thrd_equal(foo, bar)); + REQUIRE(!thrd_equal(foo, thrd_current())); + REQUIRE(thrd_join(foo, NULL) == thrd_success); + REQUIRE(thrd_join(bar, NULL) == thrd_success); +} + +TEST("thread exit") { + thrd_t foo; + int data; + int result; + REQUIRE(thrd_create(&foo, test_exit, &data) == thrd_success); + REQUIRE(thrd_join(foo, &result) == thrd_success); + REQUIRE(data == 1); + REQUIRE(result == 3); +} + +TEST("thread yield") { + thrd_t foo; + REQUIRE(thrd_create(&foo, test_yield, NULL) == thrd_success); + REQUIRE(thrd_join(foo, NULL) == thrd_success); +} + +TEST("thread sleep") { + thrd_t foo; + REQUIRE(thrd_create(&foo, test_sleep, NULL) == thrd_success); + REQUIRE(thrd_join(foo, NULL) == thrd_success); +} + +TEST("thread detach") { + thrd_t foo; + REQUIRE(thrd_create(&foo, test_nothing, NULL) == thrd_success); + REQUIRE(thrd_detach(foo) == thrd_success); + + struct timespec t = { .tv_sec = 0, .tv_nsec = 10000000 }; + thrd_sleep(&t, NULL); +} diff --git a/source/tests/too_many_assertions.c b/source/tests/too_many_assertions.c new file mode 100644 index 0000000..662207d --- /dev/null +++ b/source/tests/too_many_assertions.c @@ -0,0 +1,13 @@ +#include "../kit_test/test.h" + +TEST("foo") { + int i; + for (i = 0; i <= KIT_TEST_ASSERTIONS_LIMIT; i++) REQUIRE(1); +} + +int main(int argc, char **argv) { + if (run_tests(argc, argv) != 1) + return 1; + + return 0; +} diff --git a/source/tests/too_many_tests.c b/source/tests/too_many_tests.c new file mode 100644 index 0000000..d4842e4 --- /dev/null +++ b/source/tests/too_many_tests.c @@ -0,0 +1,14 @@ +#include "../kit_test/test.h" + +void bar(int index, kit_test_report_fn report) { } + +int main(int argc, char **argv) { + int i; + for (i = 0; i <= KIT_TESTS_SIZE_LIMIT; i++) + test_register("foo", __FILE__, bar); + + if (run_tests(argc, argv) != 1) + return 1; + + return 0; +} -- cgit v1.2.3