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 |