1 //: A simple test harness. To create new tests, define functions starting with
2 //: 'test_'. To run all tests so defined, run:
5 //: Every layer should include tests, and can reach into previous layers.
6 //: However, it seems like a good idea never to reach into tests from previous
7 //: layers. Every test should be a contract that always passes as originally
8 //: written, regardless of any later layers. Avoid writing 'temporary' tests
9 //: that are only meant to work until some layer.
12 typedef void (*test_fn
)(void);
14 // move a global ahead into types that we can't generate an extern declaration for
15 const test_fn Tests
[] = {
16 #include "test_list" // auto-generated; see 'build*' scripts
19 :(before
"End Globals")
20 bool Run_tests
= false;
21 bool Passed
= true; // set this to false inside any test to indicate failure
23 :(before
"End Includes")
25 if (Passed && !(X)) { \
26 cerr << "\nF - " << __FUNCTION__ << "(" << __FILE__ << ":" << __LINE__ << "): " << #X << '\n'; \
28 return; /* Currently we stop at the very first failure. */ \
31 #define CHECK_EQ(X, Y) \
32 if (Passed && (X) != (Y)) { \
33 cerr << "\nF - " << __FUNCTION__ << "(" << __FILE__ << ":" << __LINE__ << "): " << #X << " == " << #Y << '\n'; \
34 cerr << " got " << (X) << '\n'; /* BEWARE: multiple eval */ \
36 return; /* Currently we stop at the very first failure. */ \
42 :(before
"End Commandline Parsing")
43 if (argc
> 1 && is_equal(argv
[1], "test")) {
44 Run_tests
= true; --argc
; ++argv
; // shift 'test' out of commandline args
50 // we run some tests and then exit; assume no state need be maintained afterward
52 long num_failures
= 0;
53 // End Test Run Initialization
55 cerr
<< "C tests: " << ctime(&t
);
56 for (size_t i
=0; i
< sizeof(Tests
)/sizeof(Tests
[0]); ++i
) {
57 //? cerr << "running " << Test_names[i] << '\n';
59 if (Passed
) cerr
<< '.';
64 if (num_failures
> 0) {
65 cerr
<< num_failures
<< " failure"
66 << (num_failures
> 1 ? "s" : "")
74 void run_test(size_t i
) {
75 if (i
>= sizeof(Tests
)/sizeof(Tests
[0])) {
76 cerr
<< "no test " << i
<< '\n';
85 //: Convenience: run a single test
87 // Names for each element of the 'Tests' global, respectively.
88 const string Test_names
[] = {
89 #include "test_name_list" // auto-generated; see 'build*' scripts
92 string maybe_single_test_to_run
= argv
[argc
-1];
93 if (!starts_with(maybe_single_test_to_run
, "test_"))
94 maybe_single_test_to_run
.insert(0, "test_");
95 for (size_t i
=0; i
< sizeof(Tests
)/sizeof(Tests
[0]); ++i
) {
96 if (Test_names
[i
] == maybe_single_test_to_run
) {
98 if (Passed
) cerr
<< ".\n";
103 :(before
"End Includes")