GnuCash  2.6.99
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
test-print-parse-amount.c
1 #include "config.h"
2 #include <glib.h>
3 #include <stdlib.h>
4 #include <glib/gprintf.h>
5 
6 #include "gnc-ui-util.h"
7 #include "gnc-numeric.h"
8 #include "test-engine-stuff.h"
9 #include "test-stuff.h"
10 #include <unittest-support.h>
11 
12 static void
13 test_num_print_info (gnc_numeric n, GNCPrintAmountInfo print_info, int line)
14 {
15  gnc_numeric n_parsed = gnc_numeric_zero();
16  const char *s;
17  gboolean ok, print_ok;
18 
19  gchar *msg = "[PrintAmountInternal()] Bad numeric from rounding: GNC_ERROR_OVERFLOW.";
20  gchar *log_domain = "gnc.gui";
21  guint loglevel = G_LOG_LEVEL_WARNING, hdlr;
22  TestErrorStruct check = { loglevel, log_domain, msg };
23 
24  /* Throws overflows during rounding step in xaccPrintAmount when the "fraction" is high. See bug 665707. */
25  hdlr = g_log_set_handler (log_domain, loglevel,
26  (GLogFunc)test_checked_handler, &check);
27  s = xaccPrintAmount (n, print_info);
28  print_ok = (s && s[0] != '\0');
29  if (!print_ok)
30  return;
31 
32  ok = xaccParseAmount (s, print_info.monetary, &n_parsed, NULL);
33  g_log_remove_handler (log_domain, hdlr);
34 
35 
36  do_test_args (ok, "parsing failure", __FILE__, __LINE__,
37  "num: %s, string %s (line %d)", gnc_numeric_to_string (n), s, line);
38 
39  ok = gnc_numeric_equal (n, n_parsed);
40  do_test_args (ok, "not equal", __FILE__, __LINE__,
41  "start: %s, string %s, finish: %s (line %d)",
42  gnc_numeric_to_string (n), s,
43  gnc_numeric_to_string (n_parsed), line);
44 
45 }
46 
47 static void
48 test_num (gnc_numeric n)
49 {
50  GNCPrintAmountInfo print_info;
51  int fraction;
52  int i;
53 
54  print_info.commodity = NULL;
55  print_info.min_decimal_places = 0;
56  print_info.use_locale = 1;
57  print_info.use_symbol = 0;
58 
59  for (i = 1, fraction = 10; i < 9; i++, fraction *= 10)
60  {
61  gnc_numeric n1;
62 
63  print_info.use_separators = 1;
64  print_info.monetary = 1;
65  print_info.max_decimal_places = i;
66  print_info.force_fit = 0;
67  print_info.round = 0;
68 
70  if (gnc_numeric_check(n1))
71  {
72  do_test_args((gnc_numeric_check(n1) == GNC_ERROR_OVERFLOW),
73  "BAD NUMERIC CONVERSION", __FILE__, __LINE__,
74  "num: %s, fraction: %d", gnc_numeric_to_string(n), fraction);
75  continue;
76  }
77 
78  test_num_print_info (n1, print_info, __LINE__);
79 
80  print_info.monetary = 0;
81  test_num_print_info (n1, print_info, __LINE__);
82 
83  print_info.use_separators = 0;
84  test_num_print_info (n1, print_info, __LINE__);
85 
86  print_info.round = 1;
87  test_num_print_info (n1, print_info, __LINE__);
88 
89  print_info.round = 0;
90  print_info.force_fit = 1;
91  test_num_print_info (n1, print_info, __LINE__);
92 
93  print_info.round = 1;
94  test_num_print_info (n1, print_info, __LINE__);
95  }
96 }
97 
98 #define IS_VALID_NUM(n,m) \
99  if (gnc_numeric_check(n)) { \
100  do_test_args(gnc_numeric_check(n) == GNC_ERROR_OVERFLOW, \
101  "BAD NUMERIC", __FILE__, __LINE__, \
102  "num: %s (from %s)", \
103  gnc_numeric_to_string(n), \
104  gnc_numeric_to_string(m)); \
105  continue; \
106  } else { m = n; }
107 
108 static void
109 run_tests (void)
110 {
111  int i;
112 
113  for (i = 0; i < 50; i++)
114  {
115  gnc_numeric n;
116  gnc_numeric n1;
117 
118  n = get_random_gnc_numeric (GNC_DENOM_AUTO);
119  IS_VALID_NUM(n, n);
120  test_num (n);
121 
122  n1 = gnc_numeric_mul (n, n, n.denom, GNC_HOW_RND_ROUND_HALF_UP);
123  IS_VALID_NUM(n1, n);
124  test_num (n);
125 
126  n1 = gnc_numeric_mul (n, n, n.denom, GNC_HOW_RND_ROUND_HALF_UP);
127  IS_VALID_NUM(n1, n);
128  test_num (n);
129  }
130 }
131 
132 int
133 main (int argc, char **argv)
134 {
135  run_tests ();
136  print_test_results ();
137  exit (get_rv ());
138 }
gboolean gnc_numeric_equal(gnc_numeric a, gnc_numeric b)
utility functions for the GnuCash UI
An exact-rational-number library for gnucash. (to be renamed qofnumeric.h in libqof2) ...
gchar * gnc_numeric_to_string(gnc_numeric n)
gnc_numeric gnc_numeric_convert(gnc_numeric n, gint64 denom, gint how)
gnc_numeric gnc_numeric_mul(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
GNCNumericErrorCode gnc_numeric_check(gnc_numeric a)
#define GNC_DENOM_AUTO
Definition: gnc-numeric.h:246