| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | |||
| 2 | #ifndef SIMPLE_TAP_TEST_UTIL_H | ||
| 3 | #define SIMPLE_TAP_TEST_UTIL_H | ||
| 4 | |||
| 5 | |||
| 6 | #include <stdio.h> | ||
| 7 | #include <stdbool.h> | ||
| 8 | #include <string.h> | ||
| 9 | #include <stdlib.h> | ||
| 10 | |||
| 11 | struct test_location { const char* const file; const char* const function ; const int line; }; | ||
| 12 | #define TEST_LOCATION() (struct test_location){.line=__LINE__, .file=__FILE__ , .function=__func__ } | ||
| 13 | |||
| 14 | struct test_true { int assertion; const char* const description; }; | ||
| 15 | #define test_true(assertVal, ...) test_true((struct test_true){ .assertion=assertVal, .description=#assertVal, __VA_ARGS__}, TEST_LOCATION() ); | ||
| 16 | |||
| 17 | struct test_string_equals { const char* result; const char* const expected ; const char* const description; }; | ||
| 18 | #define test_string_equals(...) test_string_equals((struct test_string_equals){ .description=#__VA_ARGS__, __VA_ARGS__ }, TEST_LOCATION() ); | ||
| 19 | |||
| 20 | #define test_autofree_string_equals(...) test_autofree_string_equals((struct test_string_equals){ .description=#__VA_ARGS__, __VA_ARGS__ }, TEST_LOCATION() ); | ||
| 21 | |||
| 22 | |||
| 23 | struct test_uint_equals { unsigned int result; unsigned int expected ; const char* const description; }; | ||
| 24 | #define test_uint_equals(...) test_uint_equals((struct test_uint_equals){ .description=#__VA_ARGS__, __VA_ARGS__ }, TEST_LOCATION() ); | ||
| 25 | |||
| 26 | |||
| 27 | struct test_execution | ||
| 28 | { | ||
| 29 | char* text; | ||
| 30 | struct test_execution * next; | ||
| 31 | }; | ||
| 32 | |||
| 33 | struct test_suite | ||
| 34 | { | ||
| 35 | unsigned int testNumber; | ||
| 36 | struct test_execution * first; | ||
| 37 | struct test_execution * last; | ||
| 38 | }; | ||
| 39 | |||
| 40 | |||
| 41 | |||
| 42 | static struct test_suite suite = { .testNumber = 0, .first = NULL, .last = NULL }; | ||
| 43 | |||
| 44 | |||
| 45 | 16 | static void print_tap(bool result, struct test_location location, const char* const description){ | |
| 46 | char * text; | ||
| 47 |
1/2✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
|
16 | const char * resultText = result ? "ok" : "not ok" ; |
| 48 | 16 | suite.testNumber++; | |
| 49 | 16 | asprintf(&text, "%s %d [%s:%d] %s", resultText ,suite.testNumber, location.file, location.line, description); | |
| 50 | 16 | struct test_execution * new_text_execution = (struct test_execution*) malloc(sizeof(struct test_execution)); | |
| 51 | 16 | new_text_execution->text = text; | |
| 52 | 16 | new_text_execution->next = NULL; | |
| 53 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 15 times.
|
16 | if( suite.first == NULL ){ |
| 54 | 1 | suite.first = new_text_execution; | |
| 55 | 1 | suite.last = new_text_execution; | |
| 56 | } else { | ||
| 57 | 15 | suite.last->next = new_text_execution; | |
| 58 | 15 | suite.last = new_text_execution; | |
| 59 | } | ||
| 60 | |||
| 61 | 16 | } | |
| 62 | |||
| 63 | /* use parentheses to avoid macro subst */ | ||
| 64 | 7 | static void (test_true)(struct test_true parameters, struct test_location location) { | |
| 65 |
1/2✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
|
7 | const char* const description = parameters.description ? parameters.description : ""; |
| 66 | 7 | print_tap((bool) parameters.assertion, location, description); | |
| 67 | 7 | } | |
| 68 | |||
| 69 | /* use parentheses to avoid macro subst */ | ||
| 70 | 7 | static void (test_string_equals)(struct test_string_equals parameters, struct test_location location) { | |
| 71 | 7 | bool result = strcmp(parameters.result, parameters.expected) == 0 ? true : false; | |
| 72 |
1/2✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
|
7 | const char* description = parameters.description ? parameters.description : ""; |
| 73 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
|
7 | if(!result){ |
| 74 | char * text; | ||
| 75 | ✗ | asprintf(&text, "%s --- \n result: %s\n expected: %s\n ---", description ,parameters.result, parameters.expected); | |
| 76 | ✗ | print_tap(result, location, text); | |
| 77 | ✗ | free(text); | |
| 78 | } else { | ||
| 79 | 7 | print_tap(result, location, description); | |
| 80 | } | ||
| 81 | 7 | } | |
| 82 | |||
| 83 | /* use parentheses to avoid macro subst */ | ||
| 84 | 2 | static void (test_autofree_string_equals)(struct test_string_equals parameters, struct test_location location) { | |
| 85 | 2 | (test_string_equals)(parameters, location); | |
| 86 | 2 | free( (char*) parameters.result); | |
| 87 | 2 | } | |
| 88 | |||
| 89 | /* use parentheses to avoid macro subst */ | ||
| 90 | 2 | static void (test_uint_equals)(struct test_uint_equals parameters, struct test_location location) { | |
| 91 | 2 | bool result = parameters.result == parameters.expected; | |
| 92 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | const char* description = parameters.description ? parameters.description : ""; |
| 93 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if(!result){ |
| 94 | char * text; | ||
| 95 | ✗ | asprintf(&text, "%s --- \n result: %d\n expected: %d\n ---", description ,parameters.result, parameters.expected); | |
| 96 | ✗ | print_tap(result, location, text); | |
| 97 | ✗ | free(text); | |
| 98 | } else { | ||
| 99 | 2 | print_tap(result, location, description); | |
| 100 | } | ||
| 101 | 2 | } | |
| 102 | |||
| 103 | 1 | static int test_finish(){ | |
| 104 | 1 | printf("1..%d\n", suite.testNumber); | |
| 105 | 1 | struct test_execution * current = suite.first; | |
| 106 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 1 times.
|
17 | while(current != NULL){ |
| 107 | 16 | struct test_execution * next = current -> next; | |
| 108 | 16 | printf("%s\n", current->text); | |
| 109 | 16 | free(current->text); | |
| 110 | 16 | free(current); | |
| 111 | 16 | current = next; | |
| 112 | } | ||
| 113 | 1 | return 0; | |
| 114 | } | ||
| 115 | |||
| 116 | #endif // SIMPLE_TAP_TEST_UTIL_H | ||
| 117 |