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