aboutsummaryrefslogtreecommitdiff
path: root/test/test.c
blob: 97af6a4d663df42a43601ec33b3fbbea48c5e876 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151

#include "kpl_test.h"

static kpl_test *_kpl_test_head = NULL, *_kpl_test_tail = NULL, *_kpl_error_head = NULL, *_kpl_error_tail = NULL;

static int32_t _kpl_test_count = 0, _kpl_test_error_count = 0;

void kpl_test_add(kpl_test *_test) {
    _kpl_test_count++;
    if (_kpl_test_head)
        _kpl_test_tail = _kpl_test_tail->next_test = _test;
    else
        _kpl_test_head = _kpl_test_tail = _test;
}

static void kpl_test_report(kpl_test *_test) {
    printf(KPL_COLOR(BOLD) "%s" KPL_COLOR(RESET) ":" KPL_COLOR(LIGHT_CYAN) "%s" KPL_COLOR(RESET),
        _test->file_name, _test->test_name);
}

static void kpl_test_report_success(kpl_test *_test) {
    printf(KPL_COLOR2(BOLD, LIGHT_GREEN) "PASSED " KPL_COLOR(RESET));
    kpl_test_report(_test);
    putchar('\n');
}

static void kpl_test_report_error(kpl_test *_test, bool failed_status) {
    if (failed_status)
        printf(KPL_COLOR2(BOLD, LIGHT_RED) "FAILED " KPL_COLOR(RESET));
    kpl_test_report(_test);
    printf(":" KPL_COLOR(LIGHT_MAGENTA) "%d" KPL_COLOR(RESET) "::"
        KPL_COLOR(LIGHT_RED) "%s\n" KPL_COLOR(RESET), _test->error_line_number, _test->error_message);
}

static int32_t kpl_test_error_list(void) {
    if (!_kpl_test_error_count) {
        printf(KPL_COLOR2(BOLD, LIGHT_GREEN) "ALL TESTS PASSED\n" KPL_COLOR(RESET));
        return KPL_EXIT_CODE_SUCCESS;
    }
    printf(KPL_COLOR2(BOLD, LIGHT_RED) "FAILED TEST COUNT:" KPL_COLOR(RESET)
        KPL_COLOR(WHITE) " %d\n\n" KPL_COLOR(RESET), _kpl_test_error_count);
    while (_kpl_error_head) {
        kpl_test_report_error(_kpl_error_head, false);
        putchar('\n');
        _kpl_error_head = _kpl_error_head->next_test;
    }
    return KPL_EXIT_CODE_ERROR;
}

static void kpl_test_run(kpl_test *_test) {
    _test->test_function(_test);
    if (_test->error_line_number == -1) {
        kpl_test_report_success(_test);
        return;
    }
    _kpl_test_error_count++;
    kpl_test_report_error(_test, true);
    if (_kpl_error_head)
        _kpl_error_tail = _kpl_error_tail->next_test = _test;
    else
      _kpl_error_head = _kpl_error_tail = _test;
}

static kpl_test *kpl_test_next(void) {
    if (!_kpl_test_head)
        return NULL;
    kpl_test *_test = _kpl_test_head;
    _kpl_test_head = _kpl_test_head->next_test;
    _test->next_test = NULL;
    return _test;
}

static int32_t kpl_test_run_all(void) {
    kpl_test *_test = NULL;
    while ((_test = kpl_test_next()))
        kpl_test_run(_test);
    return kpl_test_error_list();
}

static int32_t kpl_test_help(const char *argv0) {
    printf("\nUsage: " KPL_COLOR(BOLD) "%s " KPL_COLOR(RESET)
        KPL_COLOR(WHITE) "[OPTIONS] [TEST NAMES]\n\n" KPL_COLOR(RESET), argv0);
    printf("Where " KPL_COLOR(WHITE) "[OPTIONS]" KPL_COLOR(RESET) " are:\n");
    printf(KPL_COLOR(LIGHT_YELLOW) "\t-a " KPL_COLOR(RESET) "Run All Tests\n");
    printf(KPL_COLOR(LIGHT_YELLOW) "\t-h " KPL_COLOR(RESET) "Show Help\n");
    printf(KPL_COLOR(LIGHT_YELLOW) "\t-l " KPL_COLOR(RESET) "List Test Names\n");
    putchar('\n');
    return KPL_EXIT_CODE_HELP;
}

static int32_t kpl_test_list(void) {
    printf("\nTest Count: " KPL_COLOR(WHITE) "%d\n\n"
        KPL_COLOR(RESET) KPL_COLOR(LIGHT_CYAN), _kpl_test_count);
    while (_kpl_test_head) {
        printf("%s ", _kpl_test_head->test_name);
        _kpl_test_head = _kpl_test_head->next_test;
    }
    printf(KPL_COLOR(RESET) "\n\n");
    return KPL_EXIT_CODE_HELP;
}

static int32_t kpl_test_run_by_name(int32_t argc, char *argv[], const int32_t named_arg_position) {
    if (named_arg_position == argc) {
        printf(KPL_COLOR(LIGHT_RED) "\nNo Tests Specified\n" KPL_COLOR(RESET));
        return kpl_test_help(argv[0]);
    }
    int32_t tests_ran = 0;
    kpl_test *_test = NULL;
    while ((_test = kpl_test_next()))
        for (int32_t test_name_position = named_arg_position; test_name_position < argc; test_name_position++)
            if (strcmp(argv[test_name_position], _test->test_name) == 0) {
                kpl_test_run(_test);
                tests_ran++;
            }
    if (!tests_ran) {
        printf(KPL_COLOR(LIGHT_RED) "\nNo Matching Tests Found, for help run: " KPL_COLOR(RESET)
            KPL_COLOR(BOLD) "%s -h\n\n" KPL_COLOR(RESET), argv[0]);
        return KPL_EXIT_CODE_ERROR;
    }
    return kpl_test_error_list();
}

int32_t main(int32_t argc, char *argv[]) {
    int32_t arg_position = 1;
    while (arg_position < argc) {
        if (argv[arg_position][0] != '-' || !argv[arg_position][1] || argv[arg_position][2])
            break;
        switch (argv[arg_position][1]) {
            case 'a':
                return kpl_test_run_all();
            case 'h':
                return kpl_test_help(argv[0]);
            case 'l':
                return kpl_test_list();
            default:
                return kpl_test_run_by_name(argc, argv, arg_position);
        }
        arg_position++;
    }
    return kpl_test_run_by_name(argc, argv, arg_position);
}

KPL_TEST(test_pass_by_default) {
    // Pass by default
    // Uncomment below to f ail
    // KPL_FAIL("Failure Message");
}

KPL_TEST(test_counting) {
    KPL_ASSERT(_kpl_test_count > 0, "Test counter not incrementing");
}