Created
August 12, 2024 19:22
-
-
Save sutyum/882d1147de586a7b68be55e13e5eacac to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #ifndef U_TEST_H | |
| #define U_TEST_H | |
| #include <stdio.h> | |
| #include <stdbool.h> | |
| #include <string.h> | |
| // Colored output macros | |
| #define ANSI_COLOR_RED "\x1b[31m" | |
| #define ANSI_COLOR_GREEN "\x1b[32m" | |
| #define ANSI_COLOR_RESET "\x1b[0m" | |
| // Test information structure | |
| typedef struct { | |
| const char* name; | |
| const char* file; | |
| int line; | |
| const char* condition; | |
| bool passed; | |
| } TestInfo; | |
| // Maximum number of tests | |
| #define MAX_TESTS 10000 | |
| // Global test information | |
| static TestInfo g_tests[MAX_TESTS]; | |
| static size_t g_test_count = 0; | |
| static TestInfo* g_current_test = NULL; | |
| // Assert function | |
| static void test_assert(bool condition, const char* condition_str, const char* file, int line) { | |
| if (g_current_test) { | |
| if (!condition) { | |
| g_current_test->passed = false; | |
| g_current_test->file = file; | |
| g_current_test->line = line; | |
| g_current_test->condition = condition_str; | |
| } | |
| } | |
| } | |
| // Macro for assert | |
| #define assert(condition) test_assert(condition, #condition, __FILE__, __LINE__) | |
| // Test registration function | |
| static void register_test(const char* name, void (*test_func)(void)) { | |
| if (g_test_count < MAX_TESTS) { | |
| g_tests[g_test_count].name = name; | |
| g_tests[g_test_count].passed = true; | |
| g_test_count++; | |
| g_current_test = &g_tests[g_test_count - 1]; | |
| test_func(); | |
| g_current_test = NULL; | |
| } | |
| } | |
| // Macro for test definition | |
| #define test(name) \ | |
| static void test_func_##name(void); \ | |
| static void __attribute__((constructor)) register_##name(void) { \ | |
| register_test(#name, test_func_##name); \ | |
| } \ | |
| static void test_func_##name(void) | |
| // Function to print test results | |
| static void print_test_results(void) { | |
| size_t passed = 0, failed = 0; | |
| printf("\nDetailed Test Results:\n"); | |
| for (size_t i = 0; i < g_test_count; i++) { | |
| if (g_tests[i].passed) { | |
| passed++; | |
| printf(ANSI_COLOR_GREEN "PASS" ANSI_COLOR_RESET " %s\n", g_tests[i].name); | |
| } else { | |
| failed++; | |
| printf(ANSI_COLOR_RED "FAIL" ANSI_COLOR_RESET " %s\n", g_tests[i].name); | |
| printf(" in %s, line %d: assert(%s)\n", | |
| g_tests[i].file, g_tests[i].line, g_tests[i].condition); | |
| } | |
| } | |
| printf("\nTest Summary:\n"); | |
| printf(" Total tests: %zu\n", g_test_count); | |
| printf(" " ANSI_COLOR_GREEN "Passed: %zu" ANSI_COLOR_RESET "\n", passed); | |
| printf(" " ANSI_COLOR_RED "Failed: %zu" ANSI_COLOR_RESET "\n", failed); | |
| } | |
| // Macro for main function | |
| #define U_TEST_MAIN() \ | |
| int main(void) { \ | |
| print_test_results(); \ | |
| return g_test_count > 0 && g_test_count == (size_t)g_tests[g_test_count - 1].passed; \ | |
| } | |
| #endif // U_TEST_H | |
| /* | |
| // Usage | |
| // --- | |
| #include "utest.h" | |
| test(simple_addition) { | |
| assert(2 + 2 == 4); | |
| } | |
| test(always_fails) { | |
| assert(1 == 2); | |
| } | |
| U_TEST_MAIN() | |
| */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment