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