Skip to content

Commit d84bee9

Browse files
Merge pull request #33 from dreamer-coding/pr_scan_assertions
Pull Request Scan Assertions
2 parents 854830a + 253ec7b commit d84bee9

File tree

4 files changed

+105
-81
lines changed

4 files changed

+105
-81
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ To integrate Fossil Test into your project, follow these steps:
5252
# ======================
5353
[wrap-git]
5454
url = https://github.com/fossillogic/fossil-test.git
55-
revision = v1.1.2
55+
revision = v1.1.3
5656

5757
[provide]
5858
fossil-test = fossil_test_dep

code/logic/fossil/test/testing.h

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,22 @@
1818
#define MAX_NAME_LENGTH 256
1919

2020
// Color codes
21-
#define COLOR_RESET "\033[0m"
22-
#define COLOR_PASS "\033[32m" // Green
23-
#define COLOR_FAIL "\033[31m" // Red
24-
#define COLOR_SKIP "\033[33m" // Yellow
25-
#define COLOR_INFO "\033[34m" // Blue
26-
#define COLOR_BDD "\033[35m" // Magenta
27-
#define COLOR_CYAN "\033[36m" // Cyan
21+
#define FOSSIL_TEST_COLOR_RESET "\033[0m" // Reset
22+
#define FOSSIL_TEST_COLOR_GREEN "\033[32m" // Green
23+
#define FOSSIL_TEST_COLOR_RED "\033[31m" // Red
24+
#define FOSSIL_TEST_COLOR_YELLOW "\033[33m" // Yellow
25+
#define FOSSIL_TEST_COLOR_BLUE "\033[34m" // Blue
26+
#define FOSSIL_TEST_COLOR_MAGENTA "\033[35m" // Magenta
27+
#define FOSSIL_TEST_COLOR_CYAN "\033[36m" // Cyan
28+
#define FOSSIL_TEST_COLOR_WHITE "\033[97m" // White
29+
#define FOSSIL_TEST_COLOR_PURPLE "\033[35m" // Purple
30+
#define FOSSIL_TEST_COLOR_ORANGE "\033[38;5;208m" // Orange
31+
32+
#define FOSSIL_TEST_ATTR_BOLD "\033[1m" // Bold
33+
#define FOSSIL_TEST_ATTR_DIM "\033[2m" // Dim
34+
#define FOSSIL_TEST_ATTR_UNDERLINE "\033[4m" // Underline
35+
#define FOSSIL_TEST_ATTR_ITATIC "\033[3m" // Italic
36+
2837

2938
#include <setjmp.h>
3039
#include <stddef.h>
@@ -54,6 +63,7 @@ typedef enum {
5463
TEST_STATUS_PASS,
5564
TEST_STATUS_FAIL,
5665
TEST_STATUS_SKIP,
66+
TEST_STATUS_EMPTY,
5767
TEST_STATUS_TTIMEOUT
5868
} test_status_t;
5969

@@ -95,6 +105,7 @@ typedef struct fossil_test_env {
95105
int pass_count;
96106
int fail_count;
97107
int skip_count;
108+
int empty_count;
98109
int timeout_count;
99110
int unexpected_count;
100111
double start_execution_time;
@@ -229,7 +240,7 @@ void fossil_test_print_stack_trace(stack_frame_t *stack_trace);
229240
#define _FOSSIL_TEST_SKIP(test_name, message) \
230241
test_name##_test_case.status = TEST_STATUS_SKIP; \
231242
test_name##_test_case.failure_message = message; \
232-
printf(COLOR_SKIP "SKIP: %s - %s\n" COLOR_RESET, #test_name, message); \
243+
printf(FOSSIL_TEST_COLOR_YELLOW "SKIP: %s - %s\n" FOSSIL_TEST_COLOR_RESET, #test_name, message); \
233244

234245
/**
235246
* @brief Macro to define a test case.
@@ -447,7 +458,7 @@ void fossil_test_print_stack_trace(stack_frame_t *stack_trace);
447458
*/
448459
#define _GIVEN(description) \
449460
if (0) { \
450-
printf(COLOR_BDD "Given %s\n" COLOR_RESET, description); \
461+
printf(FOSSIL_TEST_COLOR_MAGENTA "Given %s\n" FOSSIL_TEST_COLOR_RESET, description); \
451462
}
452463

453464
/**
@@ -460,7 +471,7 @@ void fossil_test_print_stack_trace(stack_frame_t *stack_trace);
460471
*/
461472
#define _WHEN(description) \
462473
if (0) { \
463-
printf(COLOR_BDD "When %s\n" COLOR_RESET, description); \
474+
printf(FOSSIL_TEST_COLOR_MAGENTA "When %s\n" FOSSIL_TEST_COLOR_RESET, description); \
464475
}
465476

466477
/**
@@ -473,7 +484,7 @@ void fossil_test_print_stack_trace(stack_frame_t *stack_trace);
473484
*/
474485
#define _THEN(description) \
475486
if (0) { \
476-
printf(COLOR_BDD "Then %s\n" COLOR_RESET, description); \
487+
printf(FOSSIL_TEST_COLOR_MAGENTA "Then %s\n" FOSSIL_TEST_COLOR_RESET, description); \
477488
}
478489

479490
#ifdef __cplusplus

code/logic/testing.c

Lines changed: 81 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,7 @@ const char *timeout_messages[] = {
280280
#endif
281281

282282
jmp_buf test_jump_buffer; // This will hold the jump buffer for longjmp
283+
static int _ASSERT_COUNT = 0; // Counter for the number of assertions
283284

284285

285286
// Custom implementation of strdup to avoid warnings on some platforms
@@ -320,7 +321,7 @@ void usage_info(void) {
320321

321322
void version_info(void) {
322323
printf("Fossil Logic Test Framework\n");
323-
printf("Version: 1.1.2\n");
324+
printf("Version: 1.1.3\n");
324325
printf("Author: Michael Gene Brockus (Dreamer)\n");
325326
printf("License: Mozila Public License 2.0\n");
326327
}
@@ -457,7 +458,7 @@ void fossil_test_register_suite(fossil_test_env_t *env, test_suite_t *suite) {
457458
suite->next = env->test_suites;
458459
env->test_suites = suite;
459460
if (env->options.show_info) {
460-
printf(COLOR_INFO "Registered test suite: %s\n" COLOR_RESET, suite->name);
461+
printf(FOSSIL_TEST_COLOR_BLUE "Registered test suite: %s\n" FOSSIL_TEST_COLOR_RESET, suite->name);
461462
}
462463
}
463464

@@ -505,6 +506,53 @@ void fossil_test_case_teardown(test_case_t *test_case) {
505506
}
506507
}
507508

509+
// Run all test cases in a test suite
510+
void fossil_test_run_suite(test_suite_t *suite, fossil_test_env_t *env) {
511+
if (!suite) return;
512+
513+
if (env->options.show_info) {
514+
printf(FOSSIL_TEST_COLOR_BLUE "Running suite: %s\n" FOSSIL_TEST_COLOR_RESET, suite->name);
515+
}
516+
517+
if (env->options.shuffle_enabled){
518+
shuffle_test_cases(&suite->tests);
519+
}
520+
521+
if (env->options.reverse) {
522+
reverse_test_cases(&suite->tests);
523+
}
524+
525+
if (suite->suite_setup_func) {
526+
suite->suite_setup_func();
527+
}
528+
529+
double total_execution_time = 0.0;
530+
test_case_t *current_test = suite->tests;
531+
while (current_test) {
532+
fossil_test_run_case(current_test, env);
533+
total_execution_time += current_test->execution_time;
534+
current_test = current_test->next;
535+
}
536+
537+
if (suite->suite_teardown_func) {
538+
suite->suite_teardown_func();
539+
}
540+
541+
if (env->options.show_info) {
542+
printf(FOSSIL_TEST_COLOR_CYAN "Total execution time for suite %s: %.3f seconds\n" FOSSIL_TEST_COLOR_RESET, suite->name, total_execution_time);
543+
}
544+
}
545+
546+
// Internal function to handle assertions
547+
void fossil_test_assert_internal(bool condition, const char *message, const char *file, int line, const char *func) {
548+
_ASSERT_COUNT++; // Increment the assertion count
549+
550+
if (!condition) {
551+
printf(FOSSIL_TEST_COLOR_RED "Assertion failed: %s (%s:%d in %s)\n" FOSSIL_TEST_COLOR_RESET, message, file, line, func);
552+
longjmp(test_jump_buffer, 1); // Jump back to test case failure handler
553+
}
554+
}
555+
508556
// Run an individual test case
509557
void fossil_test_run_case(test_case_t *test_case, fossil_test_env_t *env) {
510558
if (!test_case) return;
@@ -517,86 +565,50 @@ void fossil_test_run_case(test_case_t *test_case, fossil_test_env_t *env) {
517565
clock_t test_start_time = clock();
518566
clock_t timeout_limit = test_start_time + 3 * 60 * CLOCKS_PER_SEC; // 3 minutes timeout
519567

568+
_ASSERT_COUNT = 0; // Reset assertion count before running the test
569+
520570
if (setjmp(env->env) == 0) {
521571
for (int i = 0; i < env->options.repeat_count; i++) {
522572
test_case->test_func();
523573
if (clock() > timeout_limit) {
524574
test_case->status = TEST_STATUS_TTIMEOUT;
525-
printf(COLOR_FAIL "TIMEOUT: " COLOR_INFO " %s\n" COLOR_RESET, test_case->name);
575+
printf(FOSSIL_TEST_COLOR_ORANGE "TIMEOUT: " FOSSIL_TEST_COLOR_BLUE " %s\n" FOSSIL_TEST_COLOR_RESET, test_case->name);
526576
break;
527577
}
528578
}
529579
} else {
530580
test_case->status = TEST_STATUS_FAIL;
531-
printf(COLOR_FAIL "FAIL: " COLOR_INFO " %s\n", test_case->name);
532-
printf("Failure Message: %s\n" COLOR_RESET, test_case->failure_message);
581+
printf(FOSSIL_TEST_COLOR_RED "FAIL: " FOSSIL_TEST_COLOR_BLUE " %s\n", test_case->name);
582+
printf("Failure Message: %s\n" FOSSIL_TEST_COLOR_RESET, test_case->failure_message);
533583
}
534584
test_case->execution_time = (double)(clock() - test_start_time) / CLOCKS_PER_SEC;
535585

586+
// Check if the test case is empty
587+
if (_ASSERT_COUNT == 0) {
588+
printf(FOSSIL_TEST_COLOR_YELLOW "WARNING: " FOSSIL_TEST_COLOR_BLUE " %s contains no assertions\n" FOSSIL_TEST_COLOR_RESET, test_case->name);
589+
}
590+
536591
// Run teardown
537592
fossil_test_case_teardown(test_case);
538593

539594
// Log result
540595
if (test_case->status == TEST_STATUS_PASS) {
541596
if (env->options.show_info) {
542-
printf(COLOR_PASS "PASS: " COLOR_INFO " %s (%.3f seconds)\n" COLOR_RESET, test_case->name, test_case->execution_time);
597+
printf(FOSSIL_TEST_COLOR_GREEN "PASS: " FOSSIL_TEST_COLOR_BLUE " %s (%.3f seconds)\n" FOSSIL_TEST_COLOR_RESET, test_case->name, test_case->execution_time);
543598
}
544599
} else if (test_case->status == TEST_STATUS_FAIL) {
545600
env->fail_count++;
546601
} else if (test_case->status == TEST_STATUS_SKIP) {
547602
env->skip_count++;
548603
} else if (test_case->status == TEST_STATUS_TTIMEOUT) {
549604
env->timeout_count++;
605+
} else if (test_case->status == TEST_STATUS_EMPTY) {
606+
env->empty_count++;
550607
} else {
551608
env->unexpected_count++;
552609
}
553610
}
554611

555-
// Run all test cases in a test suite
556-
void fossil_test_run_suite(test_suite_t *suite, fossil_test_env_t *env) {
557-
if (!suite) return;
558-
559-
if (env->options.show_info) {
560-
printf(COLOR_INFO "Running suite: %s\n" COLOR_RESET, suite->name);
561-
}
562-
563-
if (env->options.shuffle_enabled){
564-
shuffle_test_cases(&suite->tests);
565-
}
566-
567-
if (env->options.reverse) {
568-
reverse_test_cases(&suite->tests);
569-
}
570-
571-
if (suite->suite_setup_func) {
572-
suite->suite_setup_func();
573-
}
574-
575-
double total_execution_time = 0.0;
576-
test_case_t *current_test = suite->tests;
577-
while (current_test) {
578-
fossil_test_run_case(current_test, env);
579-
total_execution_time += current_test->execution_time;
580-
current_test = current_test->next;
581-
}
582-
583-
if (suite->suite_teardown_func) {
584-
suite->suite_teardown_func();
585-
}
586-
587-
if (env->options.show_info) {
588-
printf(COLOR_CYAN "Total execution time for suite %s: %.3f seconds\n" COLOR_RESET, suite->name, total_execution_time);
589-
}
590-
}
591-
592-
// Internal function to handle assertions
593-
void fossil_test_assert_internal(bool condition, const char *message, const char *file, int line, const char *func) {
594-
if (!condition) {
595-
printf("Assertion failed: %s (%s:%d in %s)\n", message, file, line, func);
596-
longjmp(test_jump_buffer, 1); // Jump back to test case failure handler
597-
}
598-
}
599-
600612
void fossil_test_run_all(fossil_test_env_t *env) {
601613
test_suite_t *current_suite = env->test_suites;
602614

@@ -619,6 +631,7 @@ void fossil_test_init(fossil_test_env_t *env, int argc, char **argv) {
619631
env->pass_count = 0;
620632
env->fail_count = 0;
621633
env->skip_count = 0;
634+
env->empty_count = 0;
622635
env->total_tests = 0;
623636
env->timeout_count = 0;
624637
env->start_execution_time = clock();
@@ -632,16 +645,16 @@ void fossil_test_message(fossil_test_env_t *env) {
632645
// Seed random number generator
633646
srand(time(NULL));
634647

635-
if (env->pass_count == 0 && env->fail_count == 0 && env->skip_count == 0 && env->timeout_count == 0) {
636-
printf(COLOR_INFO "%s\n" COLOR_RESET, sarcastic_messages[rand() % 30]);
648+
if (env->pass_count == 0 && env->fail_count == 0 && env->skip_count == 0 && env->timeout_count == 0 && env->empty_count > 0) {
649+
printf(FOSSIL_TEST_COLOR_YELLOW FOSSIL_TEST_ATTR_ITATIC "%s\n" FOSSIL_TEST_COLOR_RESET, sarcastic_messages[rand() % 30]);
637650
} else if (env->fail_count > 0) {
638-
printf(COLOR_FAIL "%s\n" COLOR_RESET, humorous_messages[rand() % 30]);
651+
printf(FOSSIL_TEST_COLOR_RED FOSSIL_TEST_ATTR_ITATIC "%s\n" FOSSIL_TEST_COLOR_RESET, humorous_messages[rand() % 30]);
639652
} else if (env->pass_count > 0) {
640-
printf(COLOR_PASS "%s\n" COLOR_RESET, great_news_messages[rand() % 30]);
653+
printf(FOSSIL_TEST_COLOR_GREEN FOSSIL_TEST_ATTR_ITATIC "%s\n" FOSSIL_TEST_COLOR_RESET, great_news_messages[rand() % 30]);
641654
} else if (env->timeout_count > 0) {
642-
printf(COLOR_FAIL "%s\n" COLOR_RESET, timeout_messages[rand() % 30]);
655+
printf(FOSSIL_TEST_COLOR_ORANGE FOSSIL_TEST_ATTR_ITATIC "%s\n" FOSSIL_TEST_COLOR_RESET, timeout_messages[rand() % 30]);
643656
} else {
644-
printf(COLOR_INFO "Test results are in. Keep pushing, you're getting there! 💪\n" COLOR_RESET);
657+
printf(FOSSIL_TEST_COLOR_BLUE FOSSIL_TEST_ATTR_ITATIC "Test results are in. Keep pushing, you're getting there! 💪\n" FOSSIL_TEST_COLOR_RESET);
645658
}
646659
}
647660

@@ -672,25 +685,25 @@ void fossil_test_summary(fossil_test_env_t *env) {
672685
}
673686
env->end_execution_time = clock();
674687

675-
printf(COLOR_INFO "===================================================================" COLOR_RESET);
676-
printf(COLOR_INFO "\nFossil Test Summary:\n" COLOR_RESET);
677-
printf(COLOR_INFO "===================================================================\n" COLOR_RESET);
688+
printf(FOSSIL_TEST_COLOR_BLUE FOSSIL_TEST_ATTR_BOLD "===================================================================" FOSSIL_TEST_COLOR_RESET);
689+
printf(FOSSIL_TEST_COLOR_CYAN FOSSIL_TEST_ATTR_BOLD FOSSIL_TEST_ATTR_ITATIC "\nFossil Test Summary:\n" FOSSIL_TEST_COLOR_RESET);
690+
printf(FOSSIL_TEST_COLOR_BLUE FOSSIL_TEST_ATTR_BOLD "===================================================================\n" FOSSIL_TEST_COLOR_RESET);
678691

679-
printf(COLOR_INFO "Passed: " COLOR_PASS " %d\n" COLOR_RESET, env->pass_count);
680-
printf(COLOR_INFO "Failed: " COLOR_FAIL " %d\n" COLOR_RESET, env->fail_count);
681-
printf(COLOR_INFO "Skipped: " COLOR_SKIP " %d\n" COLOR_RESET, env->skip_count);
682-
printf(COLOR_INFO "Timeout: " COLOR_SKIP " %d\n" COLOR_RESET, env->timeout_count);
683-
printf(COLOR_INFO "Total: %d tests\n" COLOR_RESET, env->pass_count + env->fail_count + env->skip_count);
692+
printf(FOSSIL_TEST_COLOR_CYAN FOSSIL_TEST_ATTR_ITATIC "Passed: " FOSSIL_TEST_COLOR_ORANGE " %d\n" FOSSIL_TEST_COLOR_RESET, env->pass_count);
693+
printf(FOSSIL_TEST_COLOR_CYAN FOSSIL_TEST_ATTR_ITATIC "Failed: " FOSSIL_TEST_COLOR_ORANGE " %d\n" FOSSIL_TEST_COLOR_RESET, env->fail_count);
694+
printf(FOSSIL_TEST_COLOR_CYAN FOSSIL_TEST_ATTR_ITATIC "Skipped:" FOSSIL_TEST_COLOR_ORANGE " %d\n" FOSSIL_TEST_COLOR_RESET, env->skip_count);
695+
printf(FOSSIL_TEST_COLOR_CYAN FOSSIL_TEST_ATTR_ITATIC "Timeout:" FOSSIL_TEST_COLOR_ORANGE " %d\n" FOSSIL_TEST_COLOR_RESET, env->timeout_count);
696+
printf(FOSSIL_TEST_COLOR_CYAN FOSSIL_TEST_ATTR_ITATIC "Total: %d tests\n" FOSSIL_TEST_COLOR_RESET, env->pass_count + env->fail_count + env->skip_count);
684697

685698
// Optionally, you could add the total execution time summary here
686699
double total_execution_time = (double)(env->end_execution_time - env->start_execution_time) / CLOCKS_PER_SEC;
687700
int seconds = (int)total_execution_time;
688701
int milliseconds = (int)((total_execution_time - seconds) * 1000);
689702
int microseconds = (int)((total_execution_time - seconds - milliseconds / 1000.0) * 1000000);
690703

691-
printf(COLOR_INFO "===================================================================\n" COLOR_RESET);
692-
printf(COLOR_INFO "Execution time: (%.2d) seconds, (%.2d) milliseconds, (%.3d) microseconds\n" COLOR_RESET, seconds, milliseconds, microseconds);
693-
printf(COLOR_INFO "===================================================================\n" COLOR_RESET);
704+
printf(FOSSIL_TEST_COLOR_BLUE FOSSIL_TEST_ATTR_BOLD "===================================================================\n" FOSSIL_TEST_COLOR_RESET);
705+
printf(FOSSIL_TEST_COLOR_CYAN FOSSIL_TEST_ATTR_ITATIC "Execution time: (%.2d) seconds, (%.2d) milliseconds, (%.3d) microseconds\n" FOSSIL_TEST_COLOR_RESET, seconds, milliseconds, microseconds);
706+
printf(FOSSIL_TEST_COLOR_BLUE FOSSIL_TEST_ATTR_BOLD "===================================================================\n" FOSSIL_TEST_COLOR_RESET);
694707

695708
fossil_test_message(env);
696709
}

meson.build

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
project('Fossil Test', 'c', 'cpp',
22
meson_version: '>=1.3.0',
33
license: 'MPL-2.0',
4-
version: '1.1.2',
4+
version: '1.1.3',
55
default_options: ['c_std=c11,c18', 'cpp_std=c++20'])
66

77
subdir('code')

0 commit comments

Comments
 (0)