1 /* 2 Stupidly simple test framework 3 Copyright (C) 2001-2004, Joe Orton <joe@manyfish.co.uk> 4 5 This library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Library General Public 7 License as published by the Free Software Foundation; either 8 version 2 of the License, or (at your option) any later version. 9 10 This library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Library General Public License for more details. 14 15 You should have received a copy of the GNU Library General Public 16 License along with this library; if not, write to the Free 17 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, 18 MA 02111-1307, USA 19 20 */ 21 22 #ifndef TESTS_H 23 #define TESTS_H 1 24 25 #ifdef HAVE_STRING_H 26 #include <string.h> 27 #endif 28 29 #include <stdio.h> 30 31 #define OK 0 32 #define FAIL 1 33 #define FAILHARD 2 /* fail and skip all succeeding tests in this suite. */ 34 #define SKIP 3 /* test was skipped because precondition was not met */ 35 #define SKIPREST 4 /* skipped, and skip all succeeding tests in suite */ 36 37 /* A test function. Must return any of OK, FAIL, FAILHARD, SKIP, or 38 * SKIPREST. May call t_warning() any number of times. If not 39 * returning OK, optionally call t_context to provide an error 40 * message. */ 41 typedef int (*test_func)(void); 42 43 typedef struct { 44 test_func fn; /* the function to test. */ 45 const char *name; /* the name of the test. */ 46 int flags; 47 } ne_test; 48 49 /* possible values for flags: */ 50 #define T_CHECK_LEAKS (1) /* check for memory leaks */ 51 #define T_EXPECT_FAIL (2) /* expect failure */ 52 #define T_EXPECT_LEAKS (4) /* expect memory leak failures */ 53 54 /* array of tests to run: must be defined by each test suite. */ 55 extern ne_test tests[]; 56 57 /* define a test function which has the same name as the function, 58 * and does check for memory leaks. */ 59 #define T(fn) { fn, #fn, T_CHECK_LEAKS } 60 /* define a test function which is expected to return FAIL. */ 61 #define T_XFAIL(fn) { fn, #fn, T_EXPECT_FAIL | T_CHECK_LEAKS } 62 /* define a test function which isn't checked for memory leaks. */ 63 #define T_LEAKY(fn) { fn, #fn, 0 } 64 /* define a test function which is expected to fail memory leak checks */ 65 #define T_XLEAKY(fn) { fn, #fn, T_EXPECT_LEAKS } 66 67 /* current test number */ 68 extern int test_num; 69 70 /* name of test suite */ 71 extern const char *test_suite; 72 73 /* Provide result context message. */ 74 void t_context(const char *ctx, ...) 75 #ifdef __GNUC__ 76 __attribute__ ((format (printf, 1, 2))) 77 #endif /* __GNUC__ */ 78 ; 79 80 extern char test_context[]; 81 82 /* the command-line arguments passed in to the test suite: */ 83 extern char **test_argv; 84 extern int test_argc; 85 86 /* child process should call this. */ 87 void in_child(void); 88 89 /* issue a warning. */ 90 void t_warning(const char *str, ...) 91 #ifdef __GNUC__ 92 __attribute__ ((format (printf, 1, 2))) 93 #endif /* __GNUC__ */ 94 ; 95 96 /* Macros for easily writing is-not-zero comparison tests; the ON* 97 * macros fail the function if a comparison is not zero. 98 * 99 * ONV(x,vs) takes a comparison X, and a printf varargs list for 100 * the failure message. 101 * e.g. ONV(strcmp(bar, "foo"), ("bar was %s not 'foo'", bar)) 102 * 103 * ON(x) takes a comparison X, and uses the line number for the failure 104 * message. e.g. ONV(strcmp(bar, "foo")) 105 * 106 * ONN(n, x) takes a comparison X, and a flat string failure message. 107 * e.g. ONN("foo was wrong", strcmp(bar, "foo")) */ 108 109 #define ONV(x,vs) do { if ((x)) { t_context vs; return FAIL; } } while (0) 110 #define ON(x) ONV((x), ("line %d", __LINE__ )) 111 #define ONN(n,x) ONV((x), (n)) 112 113 /* ONCMP(exp, act, name): 'exp' is the expected string, 'act' is the 114 * actual string for some field 'name'. Succeeds if strcmp(exp,act) 115 * == 0 or both are NULL. */ 116 #define ONCMP(exp, act, ctx, name) do { \ 117 ONV(exp && !act, ("%s: " name " was NULL, expected '%s'", ctx, exp)); \ 118 ONV(!exp && act, ("%s: " name " was '%s', expected NULL", ctx, act)); \ 119 ONV(exp && strcmp(exp, act), ("%s: " name " was '%s' not '%s'", ctx, act, exp)); \ 120 } while (0) 121 122 /* return immediately with result of test 'x' if it fails. */ 123 #define CALL(x) do { int t_ret = (x); if (t_ret != OK) return t_ret; } while (0) 124 125 /* PRECOND: skip current test if condition 'x' is not true. */ 126 #define PRECOND(x) do { if (!(x)) { return SKIP; } } while (0) 127 128 #endif /* TESTS_H */ 129