/** * utest.h * Sam's favorite unit testing macros. Make sure to link your file * with utest.o and the various *-utils.o. */ #ifndef __UTEST_H__ #define __UTEST_H__ // +---------+-------------------------------------------------------- // | Headers | // +---------+ #include // For FILE #include "misc-utils.h" // +--------+--------------------------------------------------------- // | Macros | // +--------+ /** * Macro: * CHECK * Parameters: * EXPRESSION, an expression * EXPECTED, another expression, preferably a constant * TYPE, the type of the two expressions * COMPARE, a function that compares two values of type TYPE * PRINT, a function that prints values of type TYPE * Purpose: * Evaluate EXPRESSION and ensure that its value matches EXPECTED. * If not, report an error. * Produces: * [Nothing; Called for the side effects. * Problems: * If the evaluation or expression or expected would cause the program * to crash, it crashes. (Ideally, this would catch the error.) */ #define CHECK (EXPRESSION, EXPECTED, TYPE, COMPARE, PRINT) \ BLOCK ( \ utest_test (#EXPRESSION); \ TYPE _v1_ = EXPECTED; \ TYPE _v2_ = EXPRESSION; \ if (COMPARE (_v1_, _v2_) != 0) \ { \ utest_error (#EXPRESSION); \ fprintf (stderr, "ERROR\n"); \ fprintf (stderr, " Expression: %s\n", expression); \ fprintf (stderr, " Expected: "); \ PRINT (stderr, _v1_); \ fprintf (stderr, "\n"); \ fprintf (stderr, " Result: "); \ PRINT (stderr, _v2_); \ fprintf (stderr, "\n"); \ } \ ) /** * Macros: * CHECK_INT * CHECK_INT_ARRAY * CHECK_STRING * CHECK_STRING_ARRAY * Parameters: * EXPRESSION, an expression * EXPECTED, another expression * Purpose: * Evaluate EXPRESSION and ensure that its value matches EXPECTED. * If not, report an error. * Produces: * [Nothing; Called for the side effects.] * Philosophy: * Easier to read (and use) versions of CHECK. */ #define CHECK_INT(EXPRESSION, EXPECTED) \ CHECK (EXPRESSION, EXPECTED, int, int_compare, int_fprint) #define CHECK_INT_ARRAY(EXPRESSION, EXPECTED) \ CHECK (EXPRESSION, EXPECTED, int *, int_array_compare, int_array_fprint) #define CHECK_STRING(EXPRESSION, EXPECTED) \ CHECK (EXPRESSION, EXPECTED, char *, string_compare, string_fprint) #define CHECK_STRING_ARRAY(EXPRESSION, EXPECTED) \ CHECK (EXPRESSION, EXPECTED, char **, string_array_compare, string_array_fprint) // +-----------+------------------------------------------------------ // | Functions | // +-----------+ /** * Procedure: * utest_count * Parameters: * [None] * Purpose: * Determine how many errors have been encountered so far. * Produces: * errors, an integer. */ int utest_count (void); /** * Procedure: * utest_error * Parameters: * expression, a string * Purpose: * Reports that the evaluation of expression gave an unexpected result. * Produces: * [Nothing; Called for the side effect] */ void utest_error (char *expression); /** * Procedure: * utest_report * Parameters: * fp, a FILE * * Purpose: * Report on the errors encountered. * Produces: * [Nothing; Called for the side effect] */ void utest_report (FILE *fp); /** * Procedure: * utest_reset * Parameters: * [None] * Purpose: * Reset testing. * Produces: * [Nothing; Called for the side effect.] */ void utest_reset (); /** * Procedure: * utest_test * Parameters: * test, a string * Purpose: * Note that a test that is about to be conducted. * Produces: * [Nothing; Called for the side effect.] */ void utest_test (char *test); #endif // __UTEST_H__