-
Notifications
You must be signed in to change notification settings - Fork 21
/
tinytest.h
112 lines (101 loc) · 3.18 KB
/
tinytest.h
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
/* TinyTest: A really really really tiny and simple no-hassle C unit-testing framework.
*
* Features:
* - No library dependencies. Not even itself. Just a header file.
* - Simple ANSI C. Should work with virtually every C or C++ compiler on
* virtually any platform.
* - Reports assertion failures, including expressions and line numbers.
* - Stops test on first failed assertion.
* - ANSI color output for maximum visibility.
* - Easy to embed in apps for runtime tests (e.g. environment tests).
*
* Example Usage:
*
* #include "tinytest.h"
* #include "mylib.h"
*
* void test_sheep()
* {
* ASSERT("Sheep are cool", are_sheep_cool());
* ASSERT_EQUALS(4, sheep.legs);
* }
*
* void test_cheese()
* {
* ASSERT("Cheese is tangy", cheese.tanginess > 0);
* ASSERT_STRING_EQUALS("Wensleydale", cheese.name);
* }
*
* int main()
* {
* RUN(test_sheep);
* RUN(test_cheese);
* return TEST_REPORT();
* }
*
* To run the tests, compile the tests as a binary and run it.
*
* Project home page: http://github.com/joewalnes/tinytest
*
* 2010, -Joe Walnes <joe@walnes.com> http://joewalnes.com
*/
#ifndef _TINYTEST_INCLUDED
#define _TINYTEST_INCLUDED
#include <stdio.h>
#include <stdlib.h>
/* Main assertion method */
#define ASSERT(msg, expression) if (!tt_assert(__FILE__, __LINE__, (msg), (#expression), (expression) ? 1 : 0)) return
/* Convenient assertion methods */
/* TODO: Generate readable error messages for assert_equals or assert_str_equals */
#define ASSERT_EQUALS(expected, actual) ASSERT((#actual), (expected) == (actual))
#define ASSERT_STRING_EQUALS(expected, actual) ASSERT((#actual), strcmp((expected),(actual)) == 0)
/* Run a test() function */
#define RUN(test_function) tt_execute((#test_function), (test_function))
#define TEST_REPORT() tt_report()
#define TT_COLOR_CODE 0x1B
#define TT_COLOR_RED "[1;31m"
#define TT_COLOR_GREEN "[1;32m"
#define TT_COLOR_RESET "[0m"
int tt_passes = 0;
int tt_fails = 0;
int tt_current_test_failed = 0;
const char* tt_current_msg = NULL;
const char* tt_current_expression = NULL;
const char* tt_current_file = NULL;
int tt_current_line = 0;
void tt_execute(const char* name, void (*test_function)())
{
tt_current_test_failed = 0;
test_function();
if (tt_current_test_failed) {
printf("failure: %s:%d: In test %s():\n %s (%s)\n",
tt_current_file, tt_current_line, name, tt_current_msg, tt_current_expression);
tt_fails++;
} else {
tt_passes++;
}
}
int tt_assert(const char* file, int line, const char* msg, const char* expression, int pass)
{
tt_current_msg = msg;
tt_current_expression = expression;
tt_current_file = file;
tt_current_line = line;
tt_current_test_failed = !pass;
return pass;
}
int tt_report(void)
{
if (tt_fails) {
printf("%c%sFAILED%c%s [%s] (passed:%d, failed:%d, total:%d)\n",
TT_COLOR_CODE, TT_COLOR_RED, TT_COLOR_CODE, TT_COLOR_RESET,
tt_current_file, tt_passes, tt_fails, tt_passes + tt_fails);
return -1;
} else {
printf("%c%sPASSED%c%s [%s] (total:%d)\n",
TT_COLOR_CODE, TT_COLOR_GREEN, TT_COLOR_CODE, TT_COLOR_RESET,
tt_current_file, tt_passes);
return 0;
}
}
#endif