GFS: fix sizeof: saved by the bell
[yaz-moved-to-github.git] / src / test.c
1 /* This file is part of the YAZ toolkit.
2  * Copyright (C) 1995-2010 Index Data
3  * See the file LICENSE for details.
4  */
5
6 /** \file test.c
7     \brief Unit Test for YAZ
8 */
9
10 #if HAVE_CONFIG_H
11 #include <config.h>
12 #endif
13
14 #include <stdio.h>
15 #include <string.h>
16 #include <stdlib.h>
17 #if HAVE_UNISTSD_H
18 #include <unistd.h>
19 #endif
20
21 #include <yaz/test.h>
22 #include <yaz/log.h>
23
24 static FILE *test_fout = 0; /* can't use '= stdout' on some systems */
25 static int test_total = 0;
26 static int test_failed = 0;
27 static int test_todo = 0;
28 static int test_verbose = 1;
29 static const char *test_prog = 0;
30 static int log_tests = 0; 
31
32 static FILE *get_file(void)
33 {
34     if (test_fout)
35         return test_fout;
36     return stdout;
37 }
38
39 static const char *progname(const char *argv0)
40 {
41     const char *cp = strrchr(argv0, '/');
42     if (cp)
43         return cp+1;
44     cp = strrchr(argv0, '\\');
45     if (cp)
46         return cp+1;
47     return argv0;
48 }
49
50 void yaz_check_init1(int *argc_p, char ***argv_p)
51 {
52     int i = 0;
53     int argc = *argc_p;
54     char **argv = *argv_p;
55
56     test_prog = progname(argv[0]);
57
58     for (i = 1; i<argc; i++)
59     {
60         if (strlen(argv[i]) >= 7 && !memcmp(argv[i], "--test-", 7))
61         {
62             const char *suf = argv[i]+7;
63             if (i < argc-1 && !strcmp(suf, "file"))
64             {
65                 i++;
66                 if (test_fout)
67                     fclose(test_fout);
68                 test_fout = fopen(argv[i], "w");
69                 continue;
70             }
71             else if (i < argc-1 && !strcmp(suf, "verbose"))
72             {
73                 i++;
74                 test_verbose = atoi(argv[i]);
75                 continue;
76             }
77             else if (!strcmp(suf, "help"))
78             {
79                 fprintf(stderr, 
80                         "--test-help           help\n"
81                         "--test-file fname     output to fname\n"
82                         "--test-verbose level  verbose level\n"
83                         "       0=Quiet. Only exit code tells what's wrong\n"
84                         "       1=Report+Summary only if tests fail.\n"
85                         "       2=Report failures. Print summary always\n"
86                         "       3=Report + summary always\n"
87                         "       4=Report + summary + extra prints from tests\n"
88                     );
89                 exit(0);
90             }
91             else
92             {
93                 fprintf(stderr, "Unrecognized option for YAZ test: %s\n",
94                         argv[i]);
95                 fprintf(stderr, "Use --test-help for more info\n");
96                 exit(1);
97             }
98             
99         }
100         break;
101     }
102     /* remove --test- options from argc, argv so that they disappear */
103     (*argv_p)[i-1] = **argv_p;  /* program name */
104     --i;
105     *argc_p -= i;
106     *argv_p += i;
107 }
108
109 /** \brief  Initialize the log system */
110 void yaz_check_init_log(const char *argv0)
111 {
112     char logfilename[2048];
113     log_tests = 1; 
114     sprintf(logfilename,"%s.log", progname(argv0) );
115     yaz_log_init_file(logfilename);
116     yaz_log_trunc();
117
118 }
119
120 void  yaz_check_inc_todo(void)
121 {
122     test_todo++;
123 }
124
125 void yaz_check_term1(void)
126 {
127     /* summary */
128     if (test_failed)
129     {
130         if (test_verbose >= 1) {
131             if (test_todo)
132                 fprintf(get_file(), "%d out of %d tests failed for program %s"
133                         " (%d TODO's remaining)\n",
134                     test_failed, test_total, test_prog,test_todo);
135             else
136                 fprintf(get_file(), "%d out of %d tests failed for program %s\n",
137                     test_failed, test_total, test_prog);
138         }
139     }
140     else
141     {
142         if (test_verbose >= 2) {
143             if (test_todo)
144                 fprintf(get_file(), "%d tests passed for program %s"
145                         " (%d TODO's remaining)\n",
146                     test_total, test_prog,test_todo);
147             else
148                 fprintf(get_file(), "%d tests passed for program %s\n",
149                     test_total, test_prog);
150         }
151     }
152     if (test_fout)
153         fclose(test_fout);
154     if (test_failed)
155         exit(1);
156     exit(0);
157 }
158
159 void yaz_check_eq1(int type, const char *file, int line,
160                    const char *left, const char *right, int lval, int rval)
161 {
162     char formstr[2048];
163     
164     if (type == YAZ_TEST_TYPE_OK) 
165         sprintf(formstr, "%.500s == %.500s ", left, right);
166     else
167         sprintf(formstr, "%.500s != %.500s\n %d != %d", left, right, lval,rval);
168     yaz_check_print1(type, file, line, formstr);
169 }
170
171 void yaz_check_print1(int type, const char *file, int line, 
172                       const char *expr)
173 {
174     const char *msg = "unknown";
175     int printit = 1;
176
177     test_total++;
178     switch(type)
179     {
180     case YAZ_TEST_TYPE_FAIL:
181         test_failed++;
182         msg = "FAILED";
183         if (test_verbose < 1)
184             printit = 0;
185         break;
186     case YAZ_TEST_TYPE_OK:
187         msg = "ok";
188         if (test_verbose < 3)
189             printit = 0;
190         break;
191     }
192     if (printit)
193     {
194         fprintf(get_file(), "%s:%d: %s: ", file, line, msg);
195         fprintf(get_file(), "%s\n", expr);
196     }
197     if (log_tests)
198     {
199         yaz_log(YLOG_LOG, "%s:%d %s: ", file, line, msg);
200         yaz_log(YLOG_LOG, "%s", expr);
201     }
202 }
203
204
205 int yaz_test_get_verbosity()
206 {
207     return test_verbose;
208 }
209
210 /*
211  * Local variables:
212  * c-basic-offset: 4
213  * c-file-style: "Stroustrup"
214  * indent-tabs-mode: nil
215  * End:
216  * vim: shiftwidth=4 tabstop=8 expandtab
217  */
218