GCC Code Coverage Report


Directory: src/gate/
File: src/gate/tests.c
Date: 2025-12-12 23:40:09
Exec Total Coverage
Lines: 252 302 83.4%
Functions: 26 30 86.7%
Branches: 62 112 55.4%

Line Branch Exec Source
1 /* GATE PROJECT LICENSE:
2 +----------------------------------------------------------------------------+
3 | Copyright(c) 2018-2025, Stefan Meislinger <sm@opengate.at> |
4 | All rights reserved. |
5 | |
6 | Redistribution and use in source and binary forms, with or without |
7 | modification, are permitted provided that the following conditions are met:|
8 | |
9 | 1. Redistributions of source code must retain the above copyright notice, |
10 | this list of conditions and the following disclaimer. |
11 | 2. Redistributions in binary form must reproduce the above copyright |
12 | notice, this list of conditions and the following disclaimer in the |
13 | documentation and/or other materials provided with the distribution. |
14 | |
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"|
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
18 | ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
25 | THE POSSIBILITY OF SUCH DAMAGE. |
26 +----------------------------------------------------------------------------+
27 */
28
29 #include "gate/tests.h"
30 #include "gate/streams.h"
31 #include "gate/strings.h"
32 #include "gate/console.h"
33 #include "gate/arrays.h"
34 #include "gate/files.h"
35 #include "gate/environments.h"
36
37 typedef struct gate_test_session_class
38 {
39 gate_stream_t* stream;
40 gate_test_report_t reports[256];
41 unsigned reports_used;
42 gate_bool_t save_checks;
43 gate_linkedlist_t checks;
44 } gate_test_session_t;
45
46 typedef struct gate_test_history_class
47 {
48 char const* test_name;
49 char message[128];
50 gate_bool_t failed;
51 char const* origin;
52 unsigned line;
53
54 } gate_test_history_t;
55
56 static gate_test_session_t test_session = GATE_INIT_EMPTY;
57
58
59 224 static gate_test_report_t* gate_test_register(char const* unit_name)
60 {
61 224 gate_test_report_t* ptr = NULL;
62 224 gate_size_t unit_name_len = gate_str_length(unit_name);
63 224 gate_size_t const max_reports = sizeof(test_session.reports) / sizeof(test_session.reports[0]);
64
1/2
✓ Branch 0 taken 224 times.
✗ Branch 1 not taken.
224 if (test_session.reports_used < max_reports)
65 {
66 224 ptr = &test_session.reports[test_session.reports_used];
67 224 ++test_session.reports_used;
68 224 gate_mem_clear(ptr, sizeof(gate_test_report_t));
69 224 gate_str_print_text(ptr->name, sizeof(ptr->name), unit_name, unit_name_len);
70 224 ptr->test_counter = 0;
71 224 ptr->error_counter = 0;
72 }
73 else
74 {
75 ptr = &test_session.reports[max_reports - 1];
76 }
77 224 return ptr;
78 }
79
80 263496 static gate_test_report_t* gate_test_current_unit()
81 {
82
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 263496 times.
263496 if (test_session.reports_used == 0)
83 {
84 return gate_test_register("unnamed_unit_test");
85 }
86 263496 return &test_session.reports[test_session.reports_used - 1];
87 }
88
89 243 static gate_stream_t* gate_test_current_stream()
90 {
91 243 return test_session.stream;
92 }
93
94 224 static void gate_test_print_source(gate_stream_t* stream, char const* filepath, unsigned codeline)
95 {
96
1/2
✓ Branch 0 taken 224 times.
✗ Branch 1 not taken.
224 if (filepath)
97 {
98 224 gate_stream_print(stream,
99 GATE_PRINT_CSTR, filepath,
100 GATE_PRINT_CSTR, "(",
101 GATE_PRINT_UI32, (gate_uint32_t)codeline,
102 GATE_PRINT_CSTR, "): ",
103 GATE_PRINT_END
104 );
105 }
106 224 }
107
108 static gate_bool_t volatile global_trace_on;
109 static gate_bool_t volatile global_history_on;
110
111 void gate_test_trace_enable(gate_bool_t on)
112 {
113 global_trace_on = on;
114 }
115
116 19 void gate_test_history_enable(gate_bool_t on)
117 {
118 19 global_history_on = on;
119 19 }
120
121 224 static void gate_test_print_message(char const* msg_type, char const* message, char const* filepath, unsigned codeline)
122 {
123 224 gate_stream_t* stream = gate_test_current_stream();
124
125 224 gate_test_print_source(stream, filepath, codeline);
126 224 gate_stream_print(stream,
127 GATE_PRINT_CSTR, msg_type,
128 GATE_PRINT_CSTR, message,
129 GATE_PRINT_NEWLINE,
130 GATE_PRINT_END);
131 224 }
132
133 30 void gate_test_init(gate_stream_t* stream)
134 {
135 30 gate_mem_clear(&test_session, sizeof(test_session));
136 30 test_session.reports_used = 0;
137
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 if (stream == NULL)
138 {
139 30 gate_console_t* con = gate_console();
140
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 if (con)
141 {
142 30 test_session.stream = (gate_stream_t*)con;
143 }
144 else
145 {
146 test_session.stream = gate_nullstream();
147 }
148 }
149 else
150 {
151 test_session.stream = stream;
152 }
153
2/2
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 11 times.
30 if (global_history_on)
154 {
155 19 gate_linkedlist_create(&test_session.checks, sizeof(gate_test_history_t), NULL, NULL);
156 19 test_session.save_checks = true;
157 }
158 30 }
159
160 19 void gate_test_uninit()
161 {
162
1/2
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
19 if (test_session.save_checks)
163 {
164 19 gate_linkedlist_destroy(&test_session.checks);
165 }
166 19 gate_mem_clear(&test_session, sizeof(test_session));
167 19 }
168
169 131860 static void add_test_history_entry(gate_bool_t failed, char const* message, char const* filepath, unsigned codeline)
170 {
171 131860 gate_test_report_t* ptr = gate_test_current_unit();
172 131860 gate_test_history_t entry = GATE_INIT_EMPTY;
173 131860 entry.test_name = ptr->name;
174 131860 gate_str_print_text(entry.message, sizeof(entry.message), message, gate_str_length(message));
175 131860 entry.failed = failed;
176 131860 entry.origin = filepath;
177 131860 entry.line = codeline;
178 131860 gate_linkedlist_add(&test_session.checks, &entry);
179 131860 }
180
181 224 void gate_test_unit_begin(char const* unit_name, char const* filepath, unsigned codeline)
182 {
183 224 gate_test_register(unit_name);
184 224 gate_test_print_message("TEST-BEGIN: ", unit_name, filepath, codeline);
185
1/2
✓ Branch 0 taken 224 times.
✗ Branch 1 not taken.
224 if (test_session.save_checks)
186 {
187 224 add_test_history_entry(false, unit_name, filepath, codeline);
188 }
189 224 }
190
191
192 131806 void gate_test_trace_message(char const* message, char const* filepath, unsigned codeline)
193 {
194
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 131806 times.
131806 if (global_trace_on)
195 {
196 gate_test_print_message("TRACE: ", message, filepath, codeline);
197 }
198 131806 }
199
200 27 void gate_test_trace_value(gate_int64_t value, char const* filepath, unsigned codeline)
201 {
202 27 char buffer[128] = GATE_INIT_EMPTY;
203 27 gate_str_print_int64(buffer, sizeof(buffer), value);
204 27 gate_test_trace_message(buffer, filepath, codeline);
205 27 }
206
207 131636 void gate_test_success_message(char const* message, char const* filepath, unsigned codeline)
208 {
209
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 131636 times.
131636 if (global_trace_on)
210 {
211 gate_test_print_message("SUCCESS: ", message, filepath, codeline);
212 }
213
1/2
✓ Branch 0 taken 131636 times.
✗ Branch 1 not taken.
131636 if (test_session.save_checks)
214 {
215 131636 add_test_history_entry(false, message, filepath, codeline);
216 }
217 131636 }
218
219 void gate_test_error_message(char const* message, char const* filepath, unsigned codeline)
220 {
221 gate_test_print_message("ERROR: ", message, filepath, codeline);
222 if (test_session.save_checks)
223 {
224 add_test_history_entry(true, message, filepath, codeline);
225 }
226 }
227
228
229 131636 void gate_test_count_test()
230 {
231 131636 gate_test_report_t* ptr = gate_test_current_unit();
232
1/2
✓ Branch 0 taken 131636 times.
✗ Branch 1 not taken.
131636 if (ptr)
233 {
234 131636 ++ptr->test_counter;
235 }
236 131636 }
237
238 void gate_test_count_error()
239 {
240 gate_test_report_t* ptr = gate_test_current_unit();
241 if (ptr)
242 {
243 ++ptr->error_counter;
244 }
245 }
246
247 unsigned gate_test_get_reports(gate_test_report_t* target_report_array, unsigned max_reports)
248 {
249 unsigned count = (max_reports < test_session.reports_used) ? max_reports : test_session.reports_used;
250 gate_mem_copy(target_report_array, &test_session.reports[0], count * sizeof(gate_test_report_t));
251 return count;
252 }
253
254 19 static void print_history_intro(gate_stream_t* stream, char const* test_name,
255 unsigned tests_count, unsigned skipped, unsigned errors, unsigned failures, float duration)
256 {
257 19 gate_stream_println_cstr(stream, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
258 19 gate_stream_print_cstr(stream, "<testsuite name=\""); gate_stream_print_cstr(stream, test_name);
259 19 gate_stream_print_cstr(stream, "\" tests=\""); gate_stream_print_uint(stream, tests_count);
260 19 gate_stream_print_cstr(stream, "\" skipped=\""); gate_stream_print_uint(stream, skipped);
261 19 gate_stream_print_cstr(stream, "\" errors=\""); gate_stream_print_uint(stream, errors);
262 19 gate_stream_print_cstr(stream, "\" failures=\""); gate_stream_print_uint(stream, failures);
263 19 gate_stream_print_cstr(stream, "\" time=\""); gate_stream_print_real(stream, duration, 0, 6, 0);
264 19 gate_stream_println_cstr(stream, "\">");
265 19 }
266
267 19 static void print_history_outro(gate_stream_t* stream)
268 {
269 19 gate_stream_println_cstr(stream, "</testsuite>");
270 19 }
271
272 224 static void print_history_testcase(gate_stream_t* stream,
273 char const* test_name, char const* case_name, unsigned assertions_count, float duration,
274 char const* file_path, unsigned line,
275 gate_strbuilder_t* success_lines, gate_strbuilder_t* failure_lines)
276 {
277 224 gate_stream_print_cstr(stream, "<testcase name=\""); gate_stream_print_cstr(stream, case_name);
278 224 gate_stream_print_cstr(stream, "\" classname=\""); gate_stream_print_cstr(stream, test_name);
279 224 gate_stream_print_cstr(stream, "\" assertions=\""); gate_stream_print_uint(stream, assertions_count);
280 224 gate_stream_print_cstr(stream, "\" time=\""); gate_stream_print_real(stream, duration, 0, 6, 0);
281 224 gate_stream_print_cstr(stream, "\" file=\""); gate_stream_print_cstr(stream, file_path);
282 224 gate_stream_print_cstr(stream, "\" line=\""); gate_stream_print_uint(stream, line);
283 224 gate_stream_println_cstr(stream, "\">");
284
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 224 times.
224 if (gate_strbuilder_length(failure_lines) > 0)
285 {
286 gate_stream_println_cstr(stream, "<failure message=\"failure\" type=\"assertion error\"><![CDATA[FAILURE:");
287 if (gate_strbuilder_length(failure_lines) > 0)
288 {
289 gate_stream_print_cstr(stream, gate_strbuilder_ptr(failure_lines, 0));
290 }
291 gate_stream_println_cstr(stream, "]]></failure>");
292 }
293
1/2
✓ Branch 1 taken 224 times.
✗ Branch 2 not taken.
224 if (gate_strbuilder_length(success_lines) > 0)
294 {
295 224 gate_stream_println_cstr(stream, "<system-out><![CDATA[OUTPUT:");
296
1/2
✓ Branch 1 taken 224 times.
✗ Branch 2 not taken.
224 if (gate_strbuilder_length(success_lines) > 0)
297 {
298 224 gate_stream_print_cstr(stream, gate_strbuilder_ptr(success_lines, 0));
299 }
300 224 gate_stream_println_cstr(stream, "]]></system-out>");
301 }
302 224 gate_stream_println_cstr(stream, "</testcase>");
303 224 }
304
305 19 static void build_sum_of_testcases(gate_linkedlist_t* checks, unsigned* ptr_succeeded, unsigned* ptr_failed, float* ptr_duration)
306 {
307 gate_linkedentry_t const* entry;
308 19 unsigned succeeded = 0;
309 19 unsigned failed = 0;
310 19 float duration = 0.0f;
311 19 entry = gate_linkedlist_first(checks);
312
313
2/2
✓ Branch 0 taken 131860 times.
✓ Branch 1 taken 19 times.
131879 while (entry != NULL)
314 {
315 131860 gate_test_history_t const* record = (gate_test_history_t const*)entry->data;
316
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 131860 times.
131860 if (record->failed)
317 {
318 ++failed;
319 }
320 else
321 {
322 131860 ++succeeded;
323 }
324 131860 duration += 0.1f;
325
326 131860 entry = gate_linkedlist_next(entry);
327 }
328
1/2
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
19 if (ptr_succeeded) *ptr_succeeded = succeeded;
329
1/2
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
19 if (ptr_failed) *ptr_failed = failed;
330
1/2
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
19 if (ptr_duration) *ptr_duration = duration;
331 19 }
332
333 131860 static void add_history_entry_text(gate_strbuilder_t* builder, gate_test_history_t const* entry)
334 {
335 131860 gate_strbuilder_append_cstr(builder, entry->origin);
336 131860 gate_strbuilder_append_cstr(builder, "(");
337 131860 gate_strbuilder_append_uint32(builder, entry->line);
338 131860 gate_strbuilder_append_cstr(builder, "): ");
339 131860 gate_strbuilder_append_cstr(builder, entry->message);
340 131860 gate_strbuilder_append_cstr(builder, GATE_STR_NEWLINE);
341 131860 }
342
343 19 static void print_history_junit(gate_stream_t* stream, gate_linkedlist_t* checks)
344 {
345 gate_linkedentry_t const* entry;
346 19 char const* current_name = NULL;
347 19 char const* current_file = NULL;
348 19 unsigned current_line = 0;
349 gate_strbuilder_t ok_text;
350 gate_strbuilder_t err_text;
351 19 unsigned succeeded = 0;
352 19 unsigned failed = 0;
353 unsigned all;
354 19 unsigned asserts = 0;
355 19 float duration = 0.0f;
356 19 char const* exe_name = "gate_test";
357
358 19 build_sum_of_testcases(checks, &succeeded, &failed, &duration);
359 19 all = succeeded + failed;
360
361 19 print_history_intro(stream, exe_name, all, 0, 0, failed, duration);
362
363 19 gate_strbuilder_create(&err_text, 512);
364 19 gate_strbuilder_create(&ok_text, 512);
365
366
2/2
✓ Branch 1 taken 131860 times.
✓ Branch 2 taken 19 times.
131879 for(entry = gate_linkedlist_first(checks); entry != NULL; entry = gate_linkedlist_next(entry))
367 {
368 131860 gate_test_history_t const* record = (gate_test_history_t const*)entry->data;
369
2/2
✓ Branch 0 taken 224 times.
✓ Branch 1 taken 131636 times.
131860 if(record->test_name != current_name)
370 {
371
2/2
✓ Branch 0 taken 205 times.
✓ Branch 1 taken 19 times.
224 if(current_name != NULL)
372 {
373 205 print_history_testcase(stream, exe_name, current_name, asserts, (float)asserts / 10.0f,
374 current_file, current_line, &ok_text, &err_text);
375 }
376 224 current_name = record->test_name;
377 224 current_file = record->origin;
378 224 current_line = record->line;
379 224 gate_strbuilder_discard(&ok_text, GATE_STR_NPOS);
380 224 gate_strbuilder_discard(&err_text, GATE_STR_NPOS);
381 }
382
383
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 131860 times.
131860 add_history_entry_text((record->failed ? &err_text : &ok_text), record);
384 131860 ++asserts;
385 }
386
387
1/2
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
19 if(current_name != NULL)
388 {
389 19 print_history_testcase(stream, exe_name, current_name, asserts, (float)asserts / 10.0f,
390 current_file, current_line, &ok_text, &err_text);
391 }
392
393 19 print_history_outro(stream);
394
395 19 gate_strbuilder_release(&ok_text);
396 19 gate_strbuilder_release(&err_text);
397 19 }
398
399 19 gate_bool_t gate_test_print_history(gate_stream_t* stream, gate_enumint_t flags)
400 {
401
1/2
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
19 if (GATE_FLAG_ENABLED(flags, GATE_TEST_HISTORY_FORMAT_JUNIT))
402 {
403 19 print_history_junit(stream, &test_session.checks);
404 19 return true;
405 }
406 return false;
407 }
408
409
410 19 void gate_test_print_reports()
411 {
412 19 gate_stream_t* stream = gate_test_current_stream();
413 unsigned ndx;
414 19 gate_uint16_t total_tests = 0;
415 19 gate_uint16_t total_errors = 0;
416
417 19 gate_stream_print(stream,
418 GATE_PRINT_CSTR, "----------------------------------------",
419 GATE_PRINT_NEWLINE,
420 GATE_PRINT_END);
421
422
2/2
✓ Branch 0 taken 224 times.
✓ Branch 1 taken 19 times.
243 for (ndx = 0; ndx != test_session.reports_used; ++ndx)
423 {
424 224 gate_test_report_t* ptr = &test_session.reports[ndx];
425 224 total_tests += ptr->test_counter;
426 224 total_errors += ptr->error_counter;
427
428
1/2
✓ Branch 0 taken 224 times.
✗ Branch 1 not taken.
224 if (ptr->error_counter == 0)
429 {
430 224 gate_stream_print_cstr(stream, "UNIT OK: ");
431 }
432 else
433 {
434 gate_stream_print_cstr(stream, "UNIT FAILED: ");
435 }
436
437 448 gate_stream_print(stream,
438 224 GATE_PRINT_CSTR, ptr->name,
439 GATE_PRINT_CSTR, ", ",
440 224 GATE_PRINT_UI16, ptr->test_counter,
441 GATE_PRINT_CSTR, " tests",
442 GATE_PRINT_END);
443
444
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 224 times.
224 if (ptr->error_counter != 0)
445 {
446 gate_stream_print(stream,
447 GATE_PRINT_CSTR, ", ",
448 GATE_PRINT_UI16, ptr->error_counter,
449 GATE_PRINT_CSTR, " failures",
450 GATE_PRINT_END);
451 }
452
453 224 gate_stream_print(stream,
454 GATE_PRINT_NEWLINE,
455 GATE_PRINT_END);
456 }
457
458 19 gate_stream_print(stream,
459 GATE_PRINT_CSTR, "----------------------------------------",
460 GATE_PRINT_NEWLINE,
461 GATE_PRINT_CSTR, "TOTAL: ",
462 GATE_PRINT_UI16, total_tests,
463 GATE_PRINT_CSTR, " tests, ",
464 GATE_PRINT_END);
465
1/2
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
19 if (total_errors == 0)
466 {
467 19 gate_stream_print(stream,
468 GATE_PRINT_CSTR, "No errors detected",
469 GATE_PRINT_NEWLINE,
470 GATE_PRINT_END);
471 }
472 else
473 {
474 gate_stream_print(stream,
475 GATE_PRINT_UI16, total_errors,
476 GATE_PRINT_CSTR, " errors detected",
477 GATE_PRINT_NEWLINE,
478 GATE_PRINT_END);
479 }
480
481 19 }
482
483 19 gate_bool_t gate_test_failed()
484 {
485 unsigned ndx;
486
2/2
✓ Branch 0 taken 224 times.
✓ Branch 1 taken 19 times.
243 for (ndx = 0; ndx != test_session.reports_used; ++ndx)
487 {
488 224 gate_test_report_t* const ptr = &test_session.reports[ndx];
489
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 224 times.
224 if (ptr->error_counter != 0)
490 {
491 return true;
492 }
493 }
494 19 return false;
495 }
496
497
498 9 gate_bool_t gate_test_cases_run(gate_test_case_t const* test_cases, gate_size_t test_cases_count)
499 {
500 gate_size_t ndx;
501 9 gate_bool_t succeeded = true;
502 9 gate_test_case_t const* ptr_case = NULL;
503
504 9 GATE_TEST_INIT_DEFAULT();
505
506
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 9 times.
57 for (ndx = 0; ndx != test_cases_count; ++ndx)
507 {
508 48 ptr_case = &test_cases[ndx];
509 48 succeeded = test_cases[ndx].test_function();
510 }
511
512 9 return !gate_test_failed();
513 }
514
515 48 static gate_bool_t is_test_case_selected(char const* tc_name, char const* const* patterns, gate_size_t patterns_count)
516 {
517
1/2
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
48 if (patterns_count == 0)
518 {
519 /* no pattern defined -> all TCs are selected */
520 48 return true;
521 }
522 else
523 {
524 gate_size_t const tc_name_len = gate_str_length(tc_name);
525 gate_size_t ndx;
526
527 for (ndx = 0; ndx != patterns_count; ++ndx)
528 {
529 char const* const pattern = patterns[ndx];
530 size_t const pattern_len = gate_str_length(pattern);
531 if (gate_str_like(tc_name, tc_name_len, pattern, pattern_len))
532 {
533 /* matching pattern found */
534 return true;
535 }
536 }
537 return false;
538 }
539
540 }
541
542 11 int gate_test_main(gate_test_case_t const* test_cases, gate_size_t test_cases_count,
543 char const* const* arguments, gate_size_t argcount)
544 {
545 gate_test_case_t selected_test_cases[256];
546 11 gate_size_t selected_test_cases_count = 0;
547 11 const gate_size_t selected_test_cases_max = sizeof(selected_test_cases) / sizeof(selected_test_cases[0]);
548 char const* test_patterns[256];
549 11 gate_size_t test_patterns_count = 0;
550 11 const gate_size_t test_pattern_max = sizeof(test_patterns) / sizeof(test_patterns[0]);
551 gate_bool_t succeeded;
552 gate_size_t ndx;
553 11 gate_bool_t show_help = false;
554 11 gate_bool_t enable_trace = false;
555 11 gate_bool_t enable_junit = true;
556 11 gate_bool_t list_tests = false;
557 11 gate_stream_t* con = (gate_stream_t*)gate_console();
558
559 11 GATE_TEST_INIT_DEFAULT();
560
561
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 11 times.
13 for (ndx = 0; ndx != argcount; ++ndx)
562 {
563 2 char const* const arg = arguments[ndx];
564
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
2 if (gate_str_comp_ic(arg, "--help") == 0)
565 {
566 1 show_help = true;
567 }
568
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 else if (gate_str_comp_ic(arg, "--list") == 0)
569 {
570 1 list_tests = true;
571 }
572 else if (gate_str_comp_ic(arg, "--trace") == 0)
573 {
574 enable_trace = true;
575 }
576 else if (gate_str_comp_ic(arg, "--junit") == 0)
577 {
578 enable_junit = true;
579 }
580 else
581 {
582 if (test_patterns_count < test_pattern_max)
583 {
584 test_patterns[test_patterns_count] = arg;
585 ++test_patterns_count;
586 }
587 }
588 }
589
590
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 10 times.
11 if (show_help)
591 {
592 1 gate_stream_print(con,
593 GATE_PRINT_CSTR, "Usage:", GATE_PRINT_NEWLINE,
594 GATE_PRINT_CSTR, "testapp --help", GATE_PRINT_NEWLINE,
595 GATE_PRINT_CSTR, "\tPrint test program usage description", GATE_PRINT_NEWLINE,
596 GATE_PRINT_CSTR, "testapp --list", GATE_PRINT_NEWLINE,
597 GATE_PRINT_CSTR, "\tLists all registered test cases by their anmes", GATE_PRINT_NEWLINE,
598 GATE_PRINT_CSTR, "testapp", GATE_PRINT_NEWLINE,
599 GATE_PRINT_CSTR, "\tExecutes all registered test cases", GATE_PRINT_NEWLINE,
600 GATE_PRINT_CSTR, "testapp test_case_name1 test_case_name2", GATE_PRINT_NEWLINE,
601 GATE_PRINT_CSTR, "\tExecutes only test cases named by arguments", GATE_PRINT_NEWLINE,
602 GATE_PRINT_CSTR, "testapp --trace test_case_name1 test_case_name2", GATE_PRINT_NEWLINE,
603 GATE_PRINT_CSTR, "\tExecutes given test cases with trace-mode enabled", GATE_PRINT_NEWLINE,
604 GATE_PRINT_END);
605 1 return 0;
606 }
607
608
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 9 times.
10 if (list_tests)
609 {
610
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 1 times.
18 for (ndx = 0; ndx != test_cases_count; ++ndx)
611 {
612 17 gate_test_case_t const* tc = &test_cases[ndx];
613 17 gate_stream_print(con,
614 GATE_PRINT_CSTR, tc->name, GATE_PRINT_NEWLINE,
615 GATE_PRINT_END);
616 }
617 1 return 0;
618 }
619
620
621
3/4
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 48 times.
✗ Branch 3 not taken.
57 for (ndx = 0; (ndx != test_cases_count) && (selected_test_cases_count < selected_test_cases_max); ++ndx)
622 {
623 48 gate_test_case_t const* tc = &test_cases[ndx];
624
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 if (is_test_case_selected(tc->name, test_patterns, test_patterns_count))
625 {
626 48 selected_test_cases[selected_test_cases_count] = test_cases[ndx];
627 48 ++selected_test_cases_count;
628 }
629 }
630
631
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 if (enable_trace)
632 {
633 gate_test_trace_on();
634 }
635
636
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 if (enable_junit)
637 {
638 9 gate_test_history_on();
639 }
640
641 9 succeeded = gate_test_cases_run(selected_test_cases, selected_test_cases_count);
642 9 gate_test_print_reports();
643
644
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 if (enable_junit)
645 {
646 9 gate_filestream_t* fs = NULL;
647 9 gate_string_t filename = GATE_STRING_INIT_EMPTY;
648 gate_result_t result;
649 char filepath[GATE_MAX_FILENAME_LENGTH];
650 9 gate_size_t filepathlen = sizeof(filepath);
651
652 9 result = gate_env_app_executable_name_str(filepath, &filepathlen);
653
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 if(GATE_FAILED(result))
654 {
655 filepathlen = gate_str_print_text(filepath, sizeof(filepath), "test", 4);
656 }
657 9 gate_str_print_text(&filepath[filepathlen], sizeof(filepath) - filepathlen, ".junit.xml", 10);
658 9 gate_string_create_static(&filename, filepath);
659
660 9 result = gate_file_openstream(&filename, GATE_STREAM_OPEN_WRITE, &fs);
661
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 if(GATE_SUCCEEDED(result))
662 {
663 9 gate_test_print_history((gate_stream_t*)fs, GATE_TEST_HISTORY_FORMAT_JUNIT);
664 9 gate_object_release(fs);
665 }
666 }
667
668 9 gate_test_uninit();
669 9 return succeeded ? 0 : 1;
670 }
671