1 /*
2 * Created 20010320 by bstanley to hold only those
3 * testing functions which are independent of the rest of
4 * the GNUCash system.
5 *
6 * This allows me to compile simple test programs standalone...
7 *
8 */
9 /********************************************************************\
10 * This program is free software; you can redistribute it and/or *
11 * modify it under the terms of the GNU General Public License as *
12 * published by the Free Software Foundation; either version 2 of *
13 * the License, or (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License*
21 * along with this program; if not, contact: *
22 * *
23 * Free Software Foundation Voice: +1-617-542-5942 *
24 * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
25 * Boston, MA 02110-1301, USA gnu@gnu.org *
26 * *
27 \********************************************************************/
28
29
30
31 #include <config.h>
32
33 #include <unistd.h>
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 #include <fcntl.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <glib.h>
41 #include <glib/gprintf.h>
42 #include "test-stuff.h"
43
44
45 void vsuccess_args(
46 const char *test_title,
47 const char *file,
48 int line,
49 const char *format,
50 va_list ap);
51
52 void vfailure_args(
53 const char *test_title,
54 const char *file,
55 int line,
56 const char *format,
57 va_list ap);
58
59 static guint successes;
60 static guint failures;
61 static gboolean success_should_print = FALSE;
62
63 void
success_call(const char * test_title,const char * file,int line)64 success_call(
65 const char *test_title,
66 const char* file,
67 int line )
68 {
69 success_args( test_title, file, line, "" );
70 }
71
72 void
success_args(const char * test_title,const char * file,int line,const char * format,...)73 success_args(
74 const char *test_title,
75 const char *file,
76 int line,
77 const char *format,
78 ... )
79 {
80 va_list ap;
81 va_start(ap, format);
82 vsuccess_args( test_title, file, line, format, ap );
83 va_end(ap);
84 }
85
86 void
vsuccess_args(const char * test_title,const char * file,int line,const char * format,va_list ap)87 vsuccess_args(
88 const char *test_title,
89 const char *file,
90 int line,
91 const char *format,
92 va_list ap)
93 {
94 if ( success_should_print )
95 {
96 printf("SUCCESS: %s, %s:%d ", test_title, file, line );
97 vprintf(format, ap);
98 printf("\n");
99 fflush(stdout);
100 }
101 ++successes;
102 }
103
104 void
failure_call(const char * test_title,const char * file,int line)105 failure_call(
106 const char *test_title,
107 const char *file,
108 int line)
109 {
110 failure_args( test_title, file, line, "" );
111 }
112
113
114 void
failure_args(const char * test_title,const char * file,int line,const char * format,...)115 failure_args(
116 const char *test_title,
117 const char *file,
118 int line,
119 const char *format,
120 ... )
121 {
122 va_list ap;
123 va_start(ap, format);
124 vfailure_args( test_title, file, line, format, ap );
125 va_end(ap);
126 }
127 void
vfailure_args(const char * test_title,const char * file,int line,const char * format,va_list ap)128 vfailure_args(
129 const char *test_title,
130 const char* file,
131 int line,
132 const char *format,
133 va_list ap)
134 {
135 printf("FAILURE %s %s:%d ", test_title, file, line );
136 vprintf(format, ap);
137 printf("\n");
138 fflush(stdout);
139
140 ++failures;
141 }
142
143 int
get_rv(void)144 get_rv(void)
145 {
146 return failures;
147 }
148
149 gboolean
do_test_call(gboolean result,const char * test_title,const char * filename,int line)150 do_test_call(gboolean result, const char* test_title, const char* filename,
151 int line )
152 {
153 if (result)
154 success_args( test_title, filename, line, "" );
155 else
156 failure_args( test_title, filename, line, "" );
157
158 return result;
159 }
160
161 gboolean
do_test_args(gboolean result,const char * test_title,const char * filename,int line,const char * format,...)162 do_test_args(
163 gboolean result,
164 const char* test_title,
165 const char* filename,
166 int line,
167 const char* format,
168 ... )
169 {
170 va_list ap;
171 va_start(ap, format);
172
173 if ( result )
174 {
175 vsuccess_args( test_title, filename, line, format, ap );
176 }
177 else
178 {
179 vfailure_args( test_title, filename, line, format, ap );
180 }
181 va_end(ap);
182
183 return result;
184 }
185
186 void
print_test_results(void)187 print_test_results(void)
188 {
189 guint total = successes + failures;
190 if ( total == 1 )
191 {
192 printf( "Executed 1 test." );
193 }
194 else
195 {
196 printf("Executed %d tests.", successes + failures );
197 }
198 if ( failures )
199 {
200 if ( failures == 1 )
201 {
202 printf(" There was 1 failure." );
203 }
204 else
205 {
206 printf(" There were %d failures.", failures );
207 }
208 }
209 else
210 {
211 printf(" All tests passed.");
212 }
213 printf("\n");
214 fflush(stdout);
215 }
216
217 void
set_success_print(gboolean in_should_print)218 set_success_print( gboolean in_should_print )
219 {
220 success_should_print = in_should_print;
221 }
222
223 gboolean
get_random_boolean(void)224 get_random_boolean(void)
225 {
226 return get_random_int_in_range (0, 1);
227 }
228
229 gint
get_random_int_in_range(int start,int end)230 get_random_int_in_range(int start, int end)
231 {
232 return CLAMP (start + (int)((double)(end - start + 1) * rand() /
233 (RAND_MAX + 1.0)),
234 start,
235 end);
236 }
237
238 static char *random_chars = NULL;
239
240 static char plain_chars[] =
241 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
242 "abcdefghijklmnopqrstuvwxyz"
243 "1234567890"
244 " ";
245
246 static char funky_chars[] =
247 ",.'\"`~!@#$%^*(){}[]/=?+-_\\|"
248 "<>&"
249 "\n\t";
250
251 static int rcend = 0;
252
253 void
random_character_include_funky_chars(gboolean use_funky_chars)254 random_character_include_funky_chars (gboolean use_funky_chars)
255 {
256 g_free (random_chars);
257
258 if (use_funky_chars)
259 random_chars = g_strconcat (plain_chars, funky_chars, NULL);
260 else
261 random_chars = g_strdup (plain_chars);
262
263 rcend = strlen (random_chars) - 1;
264 }
265
266 gchar
get_random_character(void)267 get_random_character(void)
268 {
269 if (!rcend)
270 random_character_include_funky_chars (TRUE);
271
272 return random_chars[get_random_int_in_range(0, rcend)];
273 }
274
275 gchar *
get_random_string_length_in_range(int minlen,int maxlen)276 get_random_string_length_in_range(int minlen, int maxlen)
277 {
278 gchar *ret;
279 int i, len = get_random_int_in_range(minlen, maxlen);
280
281 ret = g_new0(gchar, len);
282
283 for (i = 0; i < len - 1; i++)
284 ret[i] = get_random_character ();
285
286 return g_strstrip(ret);
287 }
288
289 gchar *
get_random_string_without(const char * exclude_chars)290 get_random_string_without(const char *exclude_chars)
291 {
292 gchar *ret;
293 int len;
294 int i;
295
296 switch (get_random_int_in_range(0, 9))
297 {
298 /* case 0: */
299 /* return ""; */
300 /* case 1: */
301 /* return NULL; */
302 /* case 2: */
303 /* len = get_random_int_in_range(1000, 5000); */
304 /* break; */
305 case 3:
306 len = get_random_int_in_range(100, 500);
307 break;
308 default:
309 len = get_random_int_in_range(5, 20);
310 break;
311 }
312 ret = g_new0(gchar, len);
313
314 for (i = 0; i < len - 1; i++)
315 {
316 char c;
317
318 do
319 {
320 c = get_random_character ();
321 }
322 while (exclude_chars && strchr (exclude_chars, c));
323
324 ret[i] = c;
325 }
326
327 return g_strstrip (ret);
328 }
329
330 gchar *
get_random_string(void)331 get_random_string(void)
332 {
333 return get_random_string_without (NULL);
334 }
335
336 gint32
get_random_gint32(void)337 get_random_gint32 (void)
338 {
339 gint32 ret = 0;
340
341 if (RAND_MAX > (1 << 15))
342 return rand ();
343
344 if (RAND_MAX > (1 << 7))
345 {
346 ret = rand ();
347 ret <<= 16;
348 ret += rand ();
349 return ret;
350 }
351
352 ret = rand ();
353 ret <<= 8;
354 ret += rand ();
355 ret <<= 8;
356 ret += rand ();
357 ret <<= 8;
358 ret += rand ();
359 return ret;
360 }
361
362 gint64
get_random_gint64(void)363 get_random_gint64(void)
364 {
365 gint64 ret = 0;
366
367 ret = get_random_gint32 ();
368 ret <<= 32;
369 ret += get_random_gint32 ();
370
371 return ret;
372 }
373
374 double
get_random_double(void)375 get_random_double(void)
376 {
377 double d;
378 guint i;
379
380 i = (guint)get_random_int_in_range(8, 13);
381 /* using 0.9 and 7 increases chances of getting lots of decimals */
382 d = ((double)get_random_int_in_range(8, 999999) * i * 0.9 / 7);
383 return d;
384 }
385
386 const char*
get_random_string_in_array(const char * str_list[])387 get_random_string_in_array(const char* str_list[])
388 {
389 int num;
390
391 /* count number of items in list */
392 for (num = 0; str_list[num] != NULL; num++)
393 ;
394
395 num = get_random_int_in_range(0, num - 1);
396 return str_list[num];
397 }
398