GnuCash  2.6.99
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
utest-Budget.c
1 /********************************************************************
2  * utest-Budget.c: GLib g_test test suite for gnc-budget.c. *
3  * Copyright 2012 Phil Longstaff <[email protected]> *
4  * *
5  * This program is free software; you can redistribute it and/or *
6  * modify it under the terms of the GNU General Public License as *
7  * published by the Free Software Foundation; either version 2 of *
8  * the License, or (at your option) any later version. *
9  * *
10  * This program 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 *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License*
16  * along with this program; if not, contact: *
17  * *
18  * Free Software Foundation Voice: +1-617-542-5942 *
19  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
20  * Boston, MA 02110-1301, USA [email protected] *
21 ********************************************************************/
22 #include "config.h"
23 #include <string.h>
24 #include <glib.h>
25 #include <unittest-support.h>
26 #include <gnc-event.h>
27 /* Add specific headers for this class */
28 #include "gnc-budget.h"
29 
30 static const gchar *suitename = "/engine/Budget";
31 void test_suite_budget(void);
32 
33 #if 0
34 typedef struct
35 {
36  Account *acct;
38 } Fixture;
39 
40 typedef struct
41 {
42  GNCAccountType type;
43  char *name;
44  char *parent;
45  char *code;
46  char *desc;
47  char *color;
48  char *notes;
49  char *num;
50  GNCPolicy *policy;
51 } AccountParms;
52 
53 typedef struct
54 {
55  char *memo;
56  char *account;
57  char reconciled;
58  gnc_numeric amount;
59  gnc_numeric value;
60  guint lotnum;
61 } SplitParms;
62 
63 typedef struct
64 {
65  gchar *desc;
66  gint date_offset;
67  SplitParms splits[2];
68 } TxnParms;
69 
70 typedef struct
71 {
72  guint num_accounts;
73  AccountParms **accounts;
74  guint num_txns;
75  TxnParms **txns;
76 } SetupData;
77 
78 static AccountParms bad_names[] =
79 {
80  {ACCT_TYPE_NONE, "foo:bar", "", "", "", "", "", "", NULL},
81  {ACCT_TYPE_NONE, "baz", "", "", "", "", "", "", NULL},
82  {ACCT_TYPE_NONE, "waldo:pepper", "", "", "", "", "", "", NULL}
83 };
84 
85 static AccountParms good_names[] =
86 {
87  {ACCT_TYPE_NONE, "foo", "", "", "", "", "", "", NULL},
88  {ACCT_TYPE_NONE, "baz", "foo", "", "", "", "", "", NULL},
89  {ACCT_TYPE_NONE, "waldo", "baz", "", "", "", "", "", NULL}
90 };
91 
92 static SetupData bad_data = {3, (AccountParms**)(&bad_names), 0, NULL};
93 static SetupData good_data = {3, (AccountParms**)(&good_names), 0, NULL};
94 
95 static AccountParms some_names[] =
96 {
97  {ACCT_TYPE_NONE, "foo", "root", "", "", "", "", "", NULL},
98  {ACCT_TYPE_NONE, "baz", "foo", "", "", "", "", "", NULL},
99  {ACCT_TYPE_NONE, "bar", "root", "", "", "", "", "", NULL},
100  {ACCT_TYPE_NONE, "meh", "bar", "", "", "", "", "", NULL},
101 
102 };
103 
104 static TxnParms some_txns[] =
105 {
106  {
107  "waldo", -9, {
108  {"waldo_baz", "baz", NREC, { -150000, 100}, {0, 1}, 0},
109  {"waldo_meh", "meh", NREC, {150000, 100}, {0, 1}, 0}
110  }
111  },
112  {
113  "pepper", -7, {
114  {"pepper_baz", "baz", CREC, { -12345, 100}, {0, 1}, 0},
115  {"pepper_meh", "meh", CREC, {12345, 100}, {0, 1}, 0}
116  }
117  },
118  {
119  "salt", -2, {
120  {"salt_baz", "baz", YREC, { -31415, 100}, {0, 1}, 0},
121  {"salt_meh", "meh", YREC, {31415, 100}, {0, 1}, 0}
122  }
123  },
124  {
125  "pork", 3, {
126  {"pork_baz", "baz", YREC, {23746, 100}, {0, 1}, 0},
127  {"pork_meh", "meh", YREC, { -23746, 100}, {0, 1}, 0}
128  }
129  },
130  {
131  "sausage", 5, {
132  {"sausage_baz", "baz", NREC, { -1143, 100}, {0, 1}, 0},
133  {"sausage_meh", "meh", NREC, {1143, 100}, {0, 1}, 0}
134  }
135  }
136 };
137 
138 static SetupData some_data = {4, (AccountParms**)(&some_names),
139  5, (TxnParms**)(&some_txns)
140  };
141 
142 static AccountParms complex_accts[] =
143 {
144  {ACCT_TYPE_EXPENSE, "expense", "root", "3000", "", "", "", "", NULL},
145  {ACCT_TYPE_EXPENSE, "ordinary", "expense", "3100", "", "", "", NULL},
146  {ACCT_TYPE_EXPENSE, "deductible", "expense", "3200", "", "", "", NULL},
147  {ACCT_TYPE_INCOME, "income", "root", "4000", "", "", "", "", NULL},
148  {ACCT_TYPE_INCOME, "taxable", "income", "4100", "", "", "", "", NULL},
149  {ACCT_TYPE_INCOME, "exempt", "income", "4200", "", "", "", "", NULL},
150  {ACCT_TYPE_INCOME, "wage", "taxable", "4150", "", "", "", "", NULL},
151  {ACCT_TYPE_INCOME, "div", "taxable", "4140", "", "", "", "", NULL},
152  {ACCT_TYPE_INCOME, "div1", "taxable", "4140", "", "", "", "", NULL},
153  {ACCT_TYPE_INCOME, "qdiv", "div1", "4141", "", "", "", "", NULL},
154  {ACCT_TYPE_INCOME, "odiv", "div1", "4142", "", "", "", "", NULL},
155  {ACCT_TYPE_INCOME, "int", "taxable", "4160", "", "", "", "", NULL},
156  {ACCT_TYPE_INCOME, "ltcg", "taxable", "4120", "", "", "", "", NULL},
157  {ACCT_TYPE_INCOME, "stcg", "taxable", "4110", "", "", "", "", NULL},
158  {ACCT_TYPE_INCOME, "int", "exempt", "4210", "", "", "", "", NULL},
159  {ACCT_TYPE_INCOME, "div", "exempt", "4230", "", "", "", "", NULL},
160  {ACCT_TYPE_INCOME, "gift", "exempt", "4220", "", "", "", "", NULL},
161  {ACCT_TYPE_ASSET, "assets", "root", "2000", "", "", "", "", NULL},
162  {ACCT_TYPE_BANK, "bank", "assets", "2300", "", "", "", "", NULL},
163  {ACCT_TYPE_ASSET, "broker", "assets", "2200", "", "", NULL},
164  {ACCT_TYPE_BANK, "money", "broker", "2210", "", "", NULL},
165  {ACCT_TYPE_STOCK, "stocks", "broker", "2220", "", "", NULL},
166  {ACCT_TYPE_EXPENSE, "food", "ordinary", "3110", "", "", "", NULL},
167  {ACCT_TYPE_EXPENSE, "utilities", "ordinary", "3150", "", "", "", NULL},
168  {ACCT_TYPE_EXPENSE, "auto", "ordinary", "3120", "", "", "", NULL},
169  {ACCT_TYPE_EXPENSE, "mortgage-int", "deductible", "3230", "", "", "", NULL},
170  {ACCT_TYPE_EXPENSE, "medical", "deductible", "3220", "", "", "", NULL},
171  {ACCT_TYPE_STOCK, "foo", "stocks", "2221", "", "", NULL},
172  {ACCT_TYPE_STOCK, "bar", "stocks", "2222", "", "", NULL},
173  /* Note the repetition of the stock account "baz". The variations are
174  * used to test gnc_account_merge_children. */
175  {ACCT_TYPE_STOCK, "baz", "stocks", "2223", "baz", "", NULL},
176  {ACCT_TYPE_STOCK, "baz2", "stocks", "2223", "baz", "", NULL},
177  {ACCT_TYPE_MUTUAL, "baz", "stocks", "2223", "baz", "", NULL},
178  {ACCT_TYPE_STOCK, "baz", "stocks", "2223", "baz company", "", NULL},
179  {ACCT_TYPE_STOCK, "baz", "stocks", "2224", "baz", "", NULL},
180 
181 };
182 
183 static TxnParms lot_txns[] =
184 {
185  {
186  "funding", -12, {
187  {"funding_money", "money", NREC, {1000000, 100}, {0, 1}, 0},
188  {"funding_gift", "gift", NREC, {1000000, 100}, {0, 1}, 0}
189  }
190  },
191  {
192  "waldo", -9, {
193  {"waldo_baz", "baz", NREC, {1500, 1}, {150899, 100}, 1},
194  {"waldo_money", "money", NREC, { -150899, 100}, {0, 1}, 0}
195  }
196  },
197  {
198  "pepper", -7, {
199  {"pepper_baz", "baz", CREC, { -500, 1}, { -69101, 100}, 1},
200  {"pepper_money", "money", CREC, {69101, 100}, {0, 1}, 0}
201  }
202  },
203  {
204  "salt", -2, {
205  {"salt_baz", "baz", YREC, {1000, 1}, {120899, 10}, 2},
206  {"salt_money", "money", YREC, { -120899, 100}, {0, 1}, 0}
207  }
208  },
209  {
210  "pork", 3, {
211  {"pork_baz", "baz", YREC, { -1000, 1}, { -79101, 100}, 1},
212  {"pork_money", "money", YREC, {79101, 100}, {0, 1}, 0}
213  }
214  },
215  {
216  "sausage", 5, {
217  {"sausage_baz", "baz", NREC, { -500, 1}, { -74101, 100}, 2},
218  {"sausage_mmoney", "money", NREC, {74101, 100}, {0, 1}, 0}
219  }
220  },
221  {
222  "pork", 3, {
223  {"pork_baz2", "baz2", YREC, { -1000, 1}, { -79101, 100}, 1},
224  {"pork_money", "money", YREC, {79101, 100}, {0, 1}, 0}
225  }
226  },
227  {
228  "sausage", 5, {
229  {"sausage_baz2", "baz2", NREC, { -500, 1}, { -74101, 100}, 2},
230  {"sausage_mmoney", "money", NREC, {74101, 100}, {0, 1}, 0}
231  }
232  },
233  {
234  "links", 1, {
235  {"links_baz", "baz", NREC, {500, 1}, {60899, 100}, 3},
236  {"links_mmoney", "money", NREC, { -60899, 100}, {0, 1}, 0}
237  }
238  }
239 };
240 
241 static SetupData complex = {G_N_ELEMENTS (complex_accts),
242  (AccountParms**)(&complex_accts), 0, NULL
243  };
244 
245 static SetupData complex_data = {G_N_ELEMENTS (complex_accts),
246  (AccountParms**)(&complex_accts),
247  G_N_ELEMENTS (lot_txns),
248  (TxnParms**)(&lot_txns)
249  };
250 
251 static Split*
252 insert_split (Account *parent, Transaction *txn, SplitParms *p)
253 {
254  QofBook *book = gnc_account_get_book (parent);
255  Split *split = xaccMallocSplit (book);
256  Account *acct = gnc_account_lookup_by_name (parent, p->account);
257  LotList* lotlist = xaccAccountGetLotList (acct);
258  GNCLot* lot = NULL;
259  g_assert (acct != NULL);
260  xaccSplitSetParent (split, txn);
261  xaccSplitSetMemo (split, p->memo);
262  xaccSplitSetReconcile (split, (p->reconciled ? p->reconciled : NREC));
263  g_object_set (split,
264  "account", acct,
265  "memo", p->memo,
266  "amount", &(p->amount),
267  "value", &(p->value),
268  NULL);
269 
270  gnc_account_insert_split (acct, split);
271  if (p->lotnum == 0)
272  return split;
273 
274  if (p->lotnum > g_list_length (lotlist))
275  lot = gnc_lot_new (book);
276  else
277  lot = GNC_LOT (g_list_nth_data (lotlist, p->lotnum - 1));
278 
279  gnc_lot_add_split (lot, split);
280  return split;
281 }
282 
283 static void
284 setup (Fixture *fixture, gconstpointer pData)
285 {
286  QofBook *book = qof_book_new ();
287  Account *root = gnc_account_create_root (book), *acct = NULL;
288  SetupData *parms = (SetupData *)pData;
289  TxnParms *t_arr;
290  AccountParms *p_arr;
291  GHashTable *accts = g_hash_table_new (g_str_hash, g_str_equal);
292  guint ind;
293 
294  g_hash_table_insert (accts, "root", root);
295  fixture->func = _utest_account_fill_functions ();
296  if (parms == NULL)
297  {
298  fixture->acct = root;
299  return;
300  }
301  acct = root;
302 
303  p_arr = (AccountParms*)parms->accounts;
304  for (ind = 0; ind < parms->num_accounts; ind++)
305  {
306  Account *child = xaccMallocAccount (book);
307  AccountParms p = p_arr[ind];
308  if (p.parent && strlen (p.parent) > 0)
309  {
310  Account *parent = g_hash_table_lookup (accts, p.parent);
311  g_assert (parent != NULL);
312  gnc_account_append_child (parent, child);
313  }
314  else
315  gnc_account_append_child (acct, child);
316  acct = child;
317  xaccAccountSetType (acct, p.type);
318  if (p.name)
319  {
320  xaccAccountSetName (acct, p.name);
321  g_hash_table_insert (accts, p.name, acct);
322  }
323  if (p.code)
324  xaccAccountSetCode (acct, p.code);
325  if (p.desc)
326  xaccAccountSetDescription (acct, p.desc);
327  if (p.color)
328  xaccAccountSetColor (acct, p.color);
329  if (p.notes)
330  xaccAccountSetNotes (acct, p.notes);
331  if (p.num)
332  xaccAccountSetLastNum (acct, p.num);
333  if (p.policy)
334  gnc_account_set_policy (acct, p.policy);
335  }
336 
337  t_arr = (TxnParms*)parms->txns;
338  for (ind = 0; ind < parms->num_txns; ind++)
339  {
340  Transaction *txn = xaccMallocTransaction (book);
341  TxnParms p = t_arr[ind];
342  GDate *date = g_date_new ();
343  gnc_gdate_set_time64 (date, gnc_time (NULL));
344  xaccTransBeginEdit (txn);
345  if (p.desc)
346  xaccTransSetDescription (txn, p.desc);
347  if (p.date_offset < 0)
348  g_date_subtract_days (date, (guint)(-p.date_offset));
349  else
350  g_date_add_days (date, (guint)(p.date_offset));
351  xaccTransSetDatePostedGDate (txn, *date);
352  insert_split (root, txn, &p.splits[0]);
353  insert_split (root, txn, &p.splits[1]);
354  /* xaccTransCommitEdit () does a bunch of scrubbing that we don't need */
355  qof_commit_edit (QOF_INSTANCE (txn));
356  }
357  fixture->acct = acct;
358  g_hash_table_destroy (accts);
359  gnc_set_account_separator (":");
360 }
361 
362 static void
363 teardown ( Fixture *fixture, gconstpointer pData)
364 {
365  Account *child = fixture->acct;
366  qof_book_destroy (gnc_account_get_book (child));
367  /* No need to free the last account, qof_book_destroy did that */
368  g_free (fixture->func);
369 }
370 
371 
372 /* gnc_get_account_separator_string
373 const gchar *
374 gnc_get_account_separator_string (void)// C: 31 in 7 SCM: 64 in 6*/
375 //Simple Getter. No Test.
376 /* static void
377 test_gnc_get_account_separator_string (Fixture *fixture, gconstpointer pData)
378 {
379 }*/
380 /* gnc_get_account_separator
381 gunichar
382 gnc_get_account_separator (void)// C: 8 in 4 */
383 //Simple Getter. No Test.
384 /* gnc_set_account_separator
385 void
386 gnc_set_account_separator (const gchar *separator)// C: 5 in 3 */
387 static void
388 test_gnc_set_account_separator ()
389 {
390  gchar sep_str[6];
391  const gunichar pass_sep = 0xE5A;
392  const gunichar fail_sep = 0x92A;
393  const gunichar default_sep = ':';
394  gunichar sep = gnc_get_account_separator ();
395 
396  g_assert (sep == default_sep);
397  memset (sep_str, 0, sizeof (sep_str));
398  g_unichar_to_utf8 (fail_sep, sep_str);
399  gnc_set_account_separator (sep_str);
400  sep = gnc_get_account_separator ();
401  g_assert (sep != fail_sep);
402  g_assert (sep == default_sep);
403  memset (sep_str, 0, sizeof (sep_str));
404  g_unichar_to_utf8 (pass_sep, sep_str);
405  gnc_set_account_separator (sep_str);
406  sep = gnc_get_account_separator ();
407  g_assert (sep == pass_sep);
408 }
409 /* Note: gnc_account_name_violations and gnc_account_list_name_violations should work with unicode. Change the functions and the tests accordingly. */
410 /* gnc_account_name_violations_errmsg
411 gchar *gnc_account_name_violations_errmsg (const gchar *separator, GList* invalid_account_names)// C: 6 in 4 */
412 static void
413 test_gnc_account_name_violations_errmsg ()
414 {
415  GList *badnames = NULL, *nonames = NULL, *node = NULL;
416  gchar *separator = ":", *message, *validation_message, *account_list = NULL;
417  /* FUT wants to free the strings, so we alloc them */
418  badnames = g_list_prepend (badnames, g_strdup ("Foo:bar"));
419  badnames = g_list_prepend (badnames, g_strdup ("baz"));
420  badnames = g_list_prepend (badnames, g_strdup ("waldo:pepper"));
421  message = gnc_account_name_violations_errmsg (separator, nonames);
422  for (node = badnames; node; node = g_list_next (node))
423  {
424  if (!account_list)
425  account_list = g_strdup (node->data);
426  else
427  {
428  gchar *tmp_list = g_strconcat ( account_list, "\n",
429  node->data, NULL);
430  g_free (account_list);
431  account_list = tmp_list;
432  }
433  }
434  message = gnc_account_name_violations_errmsg (separator, nonames);
435  g_assert (message == NULL);
436  validation_message = g_strdup_printf (
437  "The separator character \"%s\" is used in one or more account "
438  "names.\n\nThis will result in unexpected behaviour. "
439  "Either change the account names or choose another separator "
440  "character.\n\nBelow you will find the list of invalid account names:\n"
441  "%s", separator, account_list);
442  message = gnc_account_name_violations_errmsg (separator, badnames);
443  g_assert_cmpstr ( message, == , validation_message);
444  g_free (validation_message);
445  g_free (message);
446 }
447 /* This should be qof_BOOK_list_name_violations */
448 /* gnc_account_list_name_violations
449 GList *gnc_account_list_name_violations (QofBook *book, const gchar *separator)// C: 6 in 4 */
450 static void
451 test_gnc_account_list_name_violations (Fixture *fixture, gconstpointer pData)
452 {
453  guint log_level = G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL;
454  gchar *log_domain = "gnc.engine";
455  gchar *msg = "gnc_account_list_name_violations: assertion `separator != NULL' failed";
456  TestErrorStruct check = { log_level, log_domain, msg, 0 };
457  GList *results, *res_iter;
458  gchar *sep = ":";
459  QofBook *book = gnc_account_get_book (fixture->acct);
460  /* Because of GLib bug 653052, we have to set the logging user_data to
461  * affect the test_log_fatal_handler
462  */
463  GLogFunc oldlogger = g_log_set_default_handler ((GLogFunc)test_null_handler, &check);
464  g_test_log_set_fatal_handler ((GTestLogFatalFunc)test_checked_handler, &check);
465  g_assert (gnc_account_list_name_violations (NULL, NULL) == NULL);
466  g_assert_cmpint (check.hits, ==, 1);
467  g_assert (gnc_account_list_name_violations (book, NULL) == NULL);
468  g_assert_cmpint (check.hits, ==, 2);
469  g_assert (gnc_account_list_name_violations (NULL, sep) == NULL);
470  g_log_set_default_handler (oldlogger, NULL);
471  results = gnc_account_list_name_violations (book, sep);
472  g_assert_cmpuint (g_list_length (results), == , 2);
473  g_assert_cmpint (check.hits, ==, 2);
474  for (res_iter = results; res_iter; res_iter = g_list_next (res_iter))
475  test_free (res_iter->data);
476  g_list_free (results);
477 }
478 /* mark_account
479 void
480 mark_account (Account *acc)// C: 2 in 1 */
481 /*Simple passthrough of qof_instance_set_dirty; Don't test.*/
482 // Not Used
483 /* gnc_account_init
484 G_DEFINE_TYPE (Account, gnc_account, QOF_TYPE_INSTANCE)
485 static void
486 gnc_account_init (Account* acc)// 1
487 */
488 /* test_gnc_account_create_and_destroy (void):
489  * Tests the following functions:
490  * gnc_account_init ()
491  * gnc_account_class_init ()
492  * gnc_account_get_property ()
493  * gnc_account_set_property ()
494  * xaccAccountGetColor ()
495  * xaccAccountGetNotes ()
496  *
497  * Exercises the following functions, may not thoroughly test them:
498  * xaccAccountSetName ()
499  * xaccAccountSetCode ()
500  * xaccAccountSetDescription ()
501  * xaccAccountSetColor ()
502  * xaccAccountSetNotes ()
503  * xaccAccountSetType ()
504  * xaccAccountSetCommodity ()
505  * xaccAccountSetCommoditySCU ()
506  * xaccAccountSetNotStdSCU ()
507  * gnc_account_set_sort_dirty ()
508  * gnc_account_set_balance ()
509  * gnc_account_set_start_balance ()
510  * gnc_account_set_start_cleared_balance ()
511  * gnc_account_set_start_reconciled_balance ()
512  * gnc_account_set_policy ()
513  * xaccAccountSetMark () *** Not Used ***
514  * xaccAccountSetTaxRelated ()
515  * xaccAccountSetTaxUSCode ()
516  * xaccAccountSetTaxUSPayerNameSource ()
517  * xaccAccountSetTaxUSCopyNumber ()
518  * xaccAccountSetHidden ()
519  * xaccAccountSetPlaceholder ()
520 
521  * Note very well that this is only the GObject portion of creating
522  * and destroying Account objects. There are other parts (which is a
523  * major problem), see in particular the note at test_xaccFreeAccount.
524  */
525 
526 static void
527 test_gnc_account_create_and_destroy (void)
528 {
529  Account *acc = g_object_new (GNC_TYPE_ACCOUNT, NULL);
530  gchar *name, *fname, *code, *desc, *color, *notes, *tax_code, *tax_src;
531  GNCAccountType type;
532  gnc_commodity *commo;
533  gint commo_scu, mark;
534  gboolean non_std_scu, sort_dirty, bal_dirty, tax_rel, hide, hold;
535  gint64 copy_num;
536  gnc_numeric *start_bal, *start_clr_bal, *start_rec_bal;
537  gnc_numeric *end_bal, *end_clr_bal, *end_rec_bal;
538  GNCPolicy *pol;
539 
540  g_object_get (acc,
541  "name", &name,
542  "fullname", &fname,
543  "code", &code,
544  "description", &desc,
545  "color", &color,
546  "notes", &notes,
547  "type", &type,
548  "commodity", &commo,
549  "commodity_scu", &commo_scu,
550  "non-std-scu", &non_std_scu,
551  "sort-dirty", &sort_dirty,
552  "balance-dirty", &bal_dirty,
553  "start-balance", &start_bal,
554  "start-cleared-balance", &start_clr_bal,
555  "start-reconciled-balance", &start_rec_bal,
556  "end-balance", &end_bal,
557  "end-cleared-balance", &end_clr_bal,
558  "end-reconciled-balance", &end_rec_bal,
559  "policy", &pol,
560  "acct-mark", &mark,
561  "tax-related", &tax_rel,
562  "tax-code", &tax_code,
563  "tax-source", &tax_src,
564  "tax-copy-number", &copy_num,
565  "hidden", &hide,
566  "placeholder", &hold,
567  NULL);
568 
569  g_assert_cmpstr (name, == , "");
570  g_assert_cmpstr (fname, == , "");
571  g_assert_cmpstr (code, == , "");
572  g_assert_cmpstr (desc, == , "");
573  g_assert (!color);
574  g_assert (!notes);
575  g_assert (type == ACCT_TYPE_NONE);
576  g_assert (!commo);
577  g_assert (!commo_scu);
578  g_assert (!non_std_scu);
579  g_assert (!sort_dirty);
580  g_assert (!bal_dirty);
581  g_assert (gnc_numeric_zero_p (*end_bal));
582  g_assert (gnc_numeric_zero_p (*end_clr_bal));
583  g_assert (gnc_numeric_zero_p (*end_rec_bal));
584  g_assert (gnc_numeric_zero_p (*start_bal));
585  g_assert (gnc_numeric_zero_p (*start_clr_bal));
586  g_assert (gnc_numeric_zero_p (*start_rec_bal));
587  g_assert (pol == xaccGetFIFOPolicy ());
588  g_assert (!mark);
589  g_assert (!tax_rel);
590  g_assert (!tax_code);
591  g_assert (!tax_src);
592  g_assert (copy_num == 1);
593  g_assert (!hide);
594  g_assert (!hold);
595  g_assert (gnc_account_get_parent (acc) == NULL);
596  g_assert (gnc_account_get_children (acc) == NULL);
597  g_assert (xaccAccountGetLotList (acc) == NULL);
598  g_assert (xaccAccountGetSplitList (acc) == NULL);
599  g_free (name);
600  g_free (fname);
601  g_free (code);
602  g_free (desc);
603  g_free (color);
604  g_free (notes);
605  g_free (tax_code);
606  g_free (tax_src);
607 
608  g_object_unref (acc);
609  /* There's no good way to test that the object has been properly
610  * destroyed; on the other hand, that's GObject's job.
611  */
612 
613 }
614 /* xaccInitAccount
615 static void
616 xaccInitAccount (Account * acc, QofBook *book)// 3
617 Simple pass-through for qof_instance_init_data ()
618 */
619 /* gnc_account_get_book
620 QofBook *
621 gnc_account_get_book (const Account *account)// C: 30 in 21 SCM: 8 in 4
622 Simple pass-through for qof_instance_get_book ()
623 */
624 /* gnc_coll_get_root_account
625 static Account *
626 gnc_coll_get_root_account (QofCollection *col)// 3
627 Simple pass-through for qof_collection_get_data ()
628 */
629 
630 /* test_gnc_book_set_get_root_account:
631  * Tests the following:
632  * gnc_coll_set_root_account ()
633  * gnc_coll_get_root_account ()
634  * gnc_book_set_root_account ()
635  * gnc_book_get_root_account ()
636  * Note that the first two are static helper functions which
637  * generalize the second pair -- but in vain, because they're used
638  * only in one place.
639  */
640 static void
641 test_gnc_book_set_get_root_account (Fixture *fixture, gconstpointer pData)
642 {
643  guint log_level = G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL;
644  gchar *log_domain = "gnc.account";
645  gchar *msg = "[gnc_book_set_root_account()] cannot mix and match books freely!";
646  TestErrorStruct check = { log_level, log_domain, msg, 0 };
647  Account *acc1, *acc2;
648  QofBook* book1 = qof_book_new ();
649  GLogFunc oldlogger;
650  QofBook *book2 = gnc_account_get_book (fixture->acct);
651  acc1 = gnc_book_get_root_account (NULL);
652  g_assert (!acc1);
653  /* Check that an account is created, and that it isn't the same as the
654  * one in fixture.
655  */
656  acc1 = gnc_book_get_root_account (book1);
657  g_assert (acc1);
658  g_assert (acc1 != fixture->acct);
659  /* Now try to set the book's root account to the fixture
660  * accout. Should throw an error.
661  */
662  oldlogger = g_log_set_default_handler ((GLogFunc)test_null_handler, &check);
663  g_test_log_set_fatal_handler ((GTestLogFatalFunc)test_checked_handler,
664  &check);
665  gnc_book_set_root_account (book1, fixture->acct);
666  g_assert (gnc_book_get_root_account (book1) == acc1);
667  g_assert_cmpint (check.hits, ==, 1);
668  g_log_set_default_handler (oldlogger, NULL);
669  /* Check that if we set the same root, it stays set */
670  gnc_book_set_root_account (book2, fixture->acct);
671  g_assert (gnc_book_get_root_account (book2) == fixture->acct);
672  /* Create a new account in book1 and check that we can set it to root */
673  acc2 = xaccMallocAccount (book1);
674  gnc_book_set_root_account (book1, acc2);
675  g_assert (gnc_book_get_root_account (book1) != acc1);
676  g_assert (gnc_book_get_root_account (book1) == acc2);
677  /* Clean up */
678  /* acc1 gets freed by setting the root accout to acc2
679  g_object_unref (acc1);
680  */
681  g_object_unref (book1);
682  g_object_unref (acc2);
683 }
684 
685 /* xaccMallocAccount
686 Account *
687 xaccMallocAccount (QofBook *book)// C: 24 in 17 SCM: 9 in 6*/
688 static void
689 test_xaccMallocAccount (void)
690 {
691  QofBook *book = qof_book_new ();
692  Account *acc;
693  TestSignal signal = test_signal_new (NULL, QOF_EVENT_CREATE, NULL);
694  acc = xaccMallocAccount (book);
695  g_assert (acc != NULL);
696  test_signal_assert_hits (signal, 1);
697  test_signal_free (signal);
698  g_object_unref (book);
699  g_object_unref (acc);
700 }
701 
702 /* gnc_account_create_root
703 Account *
704 gnc_account_create_root (QofBook *book)// C: 5 in 3 */
705 static void
706 test_gnc_account_create_root (void)
707 {
708  QofBook *book = qof_book_new ();
709  QofCollection *coll = qof_book_get_collection (book, GNC_ID_ROOT_ACCOUNT);
710  Account *acc;
711  gchar *name;
712  AccountTestFunctions *func = _utest_account_fill_functions ();
713  /* Can't use gnc_book_get_root_account, it creates one if it doesn't
714  * yet exist */
715  g_assert (func->coll_get_root_account (coll) == NULL);
716  acc = gnc_account_create_root (book);
717  g_assert (acc);
718  g_object_get (acc, "name", &name, NULL);
719  g_assert_cmpstr (name, == , "Root Account");
720  g_assert (gnc_book_get_root_account (book) == acc);
721  g_object_unref (book);
722  g_object_unref (acc);
723  g_free (func);
724  g_free (name);
725 }
726 /* xaccCloneAccountCommon
727 static Account *
728 xaccCloneAccountCommon (const Account *from, QofBook *book)// 3
729 */
730 static void
731 test_xaccCloneAccount (Fixture *fixture, gconstpointer pData)
732 {
733  Account *clone;
734  QofBook *book = gnc_account_get_book (fixture->acct);
735  guint loglevel = G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL;
736  gchar *msg1 = "xaccCloneAccount: assertion `GNC_IS_ACCOUNT(from)' failed";
737  gchar *msg2 = "xaccCloneAccount: assertion `QOF_IS_BOOK(book)' failed";
738  TestErrorStruct check = { loglevel, "gnc.engine", msg1, 0 };
739  GLogFunc oldlogger;
740  AccountPrivate *acct_p, *clone_p;
741  oldlogger = g_log_set_default_handler ((GLogFunc)test_null_handler, &check);
742  g_test_log_set_fatal_handler ((GTestLogFatalFunc)test_checked_handler, &check);
743  clone = xaccCloneAccount (NULL, book);
744  g_assert (clone == NULL);
745  g_assert_cmpint (check.hits, ==, 1);
746  check.msg = msg2;
747  clone = xaccCloneAccount (fixture->acct, NULL);
748  g_assert (clone == NULL);
749  g_assert_cmpint (check.hits, ==, 2);
750  g_log_set_default_handler (oldlogger, NULL);
751  /* Now test the real clone */
752  clone = xaccCloneAccount (fixture->acct, book);
753  g_assert (clone);
754  acct_p = fixture->func->get_private (fixture->acct);
755  clone_p = fixture->func->get_private (clone);
756  g_assert (clone_p->type == acct_p->type);
757  g_assert (clone_p->accountName == acct_p->accountName);
758  g_assert (clone_p->accountCode == acct_p->accountCode);
759  g_assert (clone_p->description == acct_p->description);
760  g_assert (kvp_frame_compare (clone->inst.kvp_data,
761  fixture->acct->inst.kvp_data) == 0);
762  g_assert (gnc_commodity_equal (clone_p->commodity, acct_p->commodity));
763  g_assert (clone_p->commodity_scu == acct_p->commodity_scu);
764  g_assert (clone_p->non_standard_scu == acct_p->non_standard_scu);
765  /* Clean Up */
766  g_object_unref (clone);
767 
768 }
769 /* xaccFreeOneChildAccount
770 static void
771 xaccFreeOneChildAccount (Account *acc, gpointer dummy)// 2
772 No need to test, it's a passthrough for xaccAccountDestroy
773 */
774 /* xaccFreeAccountChildren
775 static void
776 xaccFreeAccountChildren (Account *acc)// 3
777 */
778 static void
779 test_xaccFreeAccountChildren (Fixture *fixture, gconstpointer pData)
780 {
781  Account *root = gnc_account_get_root (fixture->acct);
782  AccountPrivate *priv = fixture->func->get_private (root);
783  g_assert_cmpuint (g_list_length (priv->children), > , 0);
784  fixture->func->xaccFreeAccountChildren (root);
785  /* We'd like to check for the child actually having been freed, but
786  * there's not good way to do that. */
787  g_assert_cmpuint (g_list_length (priv->children), == , 0);
788  qof_book_destroy (gnc_account_get_book (root));
789  /* No need to unref the root account, qof_book_destroy did that. */
790  g_free (fixture->func);
791 }
792 /* xaccFreeAccount
793 static void
794 xaccFreeAccount (Account *acc)//
795 The approved way to call this is via xaccAccountDestroy-->xaccAccountCommitEdit-->qof_instance_commit_edit2-->acc_free-->xaccFreeAccount
796 
797 Note that none of this is called by gnc_account_dispose, and xaccFreeAccount calls unref on itself. (Not run dispose, unref.)
798 
799 This "works" as follows:
800 xaccAccountDestroy sets a "destroying" flag in qof_instance and calls xaccAccountCommitEdit.
801 xaccAccountCommitEdit checks the flag and finding it true:
802  calls xaccFreeACcountChildren
803  tests qof_book_shutting_down and either deletes the split list for the account (trusting the Transaction code to delete the splits if it is shutting down) or deletes the actual splits while it's clearing the list. (What happens to the references in the transactions then? It's calling xaccSplitDestroy, not g_oject_unref!)
804  Again checking that the book isn't shutting down:
805  run destroy_pending_splits_for_account
806  destroy all of the lots in the lots list (again, destroy, not unref or even dispose)
807  free the lot list (regardless of whether the book is shuttin down) and NULL the pointer
808  set the instance dirty
809 unconditionally calls qof_commit_edit_part2 with acc_free
810 qof_commit_edit_part2:
811  calls the backend's commit if there is one
812  calls acc_free
813  calls acc_done (which only fires off a qof_event, so we'll ignore it)
814 acc_free removes the account from the parent if there is one and calls xaccFreeAccount, then calls xaccFreeAccount
815 xaccFreeAccount calls:
816  xaccFreeAccountChildren
817  destroys the lots (unless commitEdit did so already) and NULLs the pointer
818  destroys the splits unless commitEdit did so already
819  removes the name, code, and description strings from the string cache
820  zeroes out the priv structure variables
821  unrefs the account (should call run_dispose).
822 dispose calls parent->dispose.
823 
824 acc_free
825 */
826 /* Aside from being broken (the assert at the end of freeing the splits fails),
827  Account deallocation is implemented wrong. We don't run this test, and the function will be replaced when the time comes. */
828 static void
829 test_xaccFreeAccount (Fixture *fixture, gconstpointer pData)
830 {
831  gchar *msg1 = "[xaccFreeAccount()] instead of calling xaccFreeAccount(), please call \n"
832  " xaccAccountBeginEdit(); xaccAccountDestroy(); \n";
833  gchar *msg2 = "xaccTransGetSplitIndex: assertion `trans && split' failed";
834  guint loglevel = G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL;
835  TestErrorStruct check1 = { loglevel, "gnc.account", msg1, 0 };
836  TestErrorStruct check2 = { loglevel, "gnc.engine", msg2, 0 };
837  QofBook *book = gnc_account_get_book (fixture->acct);
838  Account *parent = gnc_account_get_parent (fixture->acct);
839  AccountPrivate *p_priv = fixture->func->get_private (parent);
840  const guint numItems = 3;
841  guint i = 0;
842  guint hdlr1, hdlr2;
843  gnc_commodity *commodity = gnc_commodity_new (book, "US Dollar", "CURRENCY", "USD", "0", 100);
844  test_add_error (&check1);
845  test_add_error (&check2);
846  hdlr1 = g_log_set_handler ("gnc.account", loglevel,
847  (GLogFunc)test_checked_handler, &check1);
848  hdlr2 = g_log_set_handler ("gnc.engine", loglevel,
849  (GLogFunc)test_checked_handler, &check2);
850  g_test_log_set_fatal_handler ((GTestLogFatalFunc)test_list_handler, NULL);
851  for (i = 0; i < numItems; i++)
852  {
853  Split *split = xaccMallocSplit (book);
854  xaccSplitSetAccount (split, parent);
855  gnc_account_insert_split (parent, split);
856  xaccAccountInsertLot (parent, gnc_lot_new (book));
857  }
858  xaccAccountSetCommodity (parent, commodity);
859  /* Check that we've got children, lots, and splits to remove */
860  g_assert (p_priv->children != NULL);
861  g_assert (p_priv->lots != NULL);
862  g_assert (p_priv->splits != NULL);
863  g_assert (p_priv->parent != NULL);
864  g_assert (p_priv->commodity != NULL);
865  g_assert_cmpint (check1.hits, ==, 0);
866  g_assert_cmpint (check2.hits, ==, 0);
867  /* Now set the other private parts to something so that they can be set back */
868  p_priv->cleared_balance = gnc_numeric_create ( 5, 12);
869  p_priv->reconciled_balance = gnc_numeric_create ( 5, 12);
870  p_priv->balance = gnc_numeric_create ( 5, 12);
871  p_priv->balance_dirty = TRUE;
872  p_priv->sort_dirty = TRUE;
873  fixture->func->xaccFreeAccount (parent);
874  g_assert_cmpint (check1.hits, ==, 6);
875  g_assert_cmpint (check2.hits, ==, 6);
876  /* cleanup what's left */
877  g_log_remove_handler ("gnc.account", hdlr1);
878  g_log_remove_handler ("gnc.engine", hdlr2);
879  test_clear_error_list ();
880  qof_book_destroy (book);
881  g_free (fixture->func);
882 }
883 /* xaccAccountBeginEdit
884 void
885 xaccAccountBeginEdit (Account *acc)// C: 80 in 29 SCM: 15 in 9
886 
887 No test, just a passthrough.
888 */
889 /* static void
890 test_xaccAccountBeginEdit (Fixture *fixture, gconstpointer pData)
891 {
892 }*/
893 /* on_done
894 static void on_done (QofInstance *inst)// 2
895 ***Callback for qof_commit_edit_part2
896 No test, just queues a qof event.
897 */
898 /* static void
899 test_on_done (Fixture *fixture, gconstpointer pData)
900 {
901 }*/
902 /* on_err
903 static void on_err (QofInstance *inst, QofBackendError errcode)// 2
904 ***Callback for qof_commit_edit_part2
905 */
906 /* static void
907 test_on_err (Fixture *fixture, gconstpointer pData)
908 No test, just a pass-through.
909 {
910 }*/
911 /* acc_free
912 static void acc_free (QofInstance *inst)// 2
913 ***Callback for qof_commit_edit_part2
914 No test, just a passthrough -- plus see comment at test_xaccFreeAccount, which is what this is a passtrough of.
915 */
916 /* static void
917 test_acc_free (Fixture *fixture, gconstpointer pData)
918 {
919 }*/
920 /* destroy_pending_splits_for_account
921 static void
922 destroy_pending_splits_for_account (QofInstance *ent, gpointer acc)// 2
923 
924 Pass-through, no test.
925 */
926 /* static void
927 test_destroy_pending_splits_for_account (Fixture *fixture, gconstpointer pData)
928 {
929 }*/
930 /* xaccAccountCommitEdit
931 void
932 xaccAccountCommitEdit (Account *acc)// C: 65 in 26 SCM: 11 in 7
933 Also tests:
934  xaccAccountDestroy
935 */
936 static void
937 test_xaccAccountCommitEdit (Fixture *fixture, gconstpointer pData)
938 {
939  gchar *msg1 = "[xaccFreeAccount()] instead of calling xaccFreeAccount(), please call \n"
940  " xaccAccountBeginEdit(); xaccAccountDestroy(); \n";
941  gchar *msg2 = "xaccTransGetSplitIndex: assertion `trans && split' failed";
942  guint loglevel = G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL;
943  TestErrorStruct check1 = { loglevel, "gnc.account", msg1, 0 };
944  TestErrorStruct check2 = { loglevel, "gnc.engine", msg2, 0 };
945  guint hdlr1, hdlr2;
946  TestSignal sig1, sig2;
947  QofBook *book = gnc_account_get_book (fixture->acct);
948  Account *parent = gnc_account_get_parent (fixture->acct);
949  AccountPrivate *p_priv = fixture->func->get_private (parent);
950  const guint numItems = 3;
951  guint i = 0;
952  gnc_commodity *commodity = gnc_commodity_new (book, "US Dollar", "CURRENCY", "USD", "0", 100);
953  test_add_error (&check1);
954  test_add_error (&check2);
955  hdlr1 = g_log_set_handler ("gnc.account", loglevel,
956  (GLogFunc)test_checked_handler, &check1);
957  hdlr2 = g_log_set_handler ("gnc.engine", loglevel,
958  (GLogFunc)test_checked_handler, &check2);
959  g_test_log_set_fatal_handler ((GTestLogFatalFunc)test_list_handler, NULL);
960  for (i = 0; i < numItems; i++)
961  {
962  Split *split = xaccMallocSplit (book);
963  xaccSplitSetAccount (split, parent);
964  gnc_account_insert_split (parent, split);
965  xaccAccountInsertLot (parent, gnc_lot_new (book));
966  }
967  xaccAccountSetCommodity (parent, commodity);
968  /* Check that we've got children, lots, and splits to remove */
969  g_assert (p_priv->children != NULL);
970  g_assert (p_priv->lots != NULL);
971  g_assert (p_priv->splits != NULL);
972  g_assert (p_priv->parent != NULL);
973  g_assert (p_priv->commodity != NULL);
974  g_assert_cmpint (check1.hits, ==, 0);
975  g_assert_cmpint (check2.hits, ==, 0);
976 
977  sig1 = test_signal_new (&parent->inst, QOF_EVENT_MODIFY, NULL);
978  sig2 = test_signal_new (&parent->inst, QOF_EVENT_DESTROY, NULL);
979  /* Now we're ready to start testing. */
980  xaccAccountBeginEdit (parent);
981  xaccAccountCommitEdit (parent);
982  /* Make sure that the account didn't get destroyed */
983  test_signal_assert_hits (sig1, 1);
984  test_signal_assert_hits (sig2, 0);
985  g_assert (p_priv->children != NULL);
986  g_assert (p_priv->lots != NULL);
987  g_assert (p_priv->splits != NULL);
988  g_assert (p_priv->parent != NULL);
989  g_assert (p_priv->commodity != NULL);
990  g_assert_cmpint (check1.hits, ==, 0);
991  g_assert_cmpint (check2.hits, ==, 0);
992  /* xaccAccountDestroy destroys the account by calling
993  * qof_instance_set_destroying (), then xaccAccountCommitEdit ();
994  */
995  xaccAccountBeginEdit (parent);
996  xaccAccountDestroy (parent);
997  /* So this time we make sure that the account is destroyed */
998  test_signal_assert_hits (sig1, 2);
999  test_signal_assert_hits (sig2, 1);
1000  g_assert_cmpint (check1.hits, ==, 2);
1001  g_assert_cmpint (check2.hits, ==, 12);
1002  /* And clean up */
1003  test_signal_free (sig1);
1004  test_signal_free (sig2);
1005  g_log_remove_handler ("gnc.account", hdlr1);
1006  g_log_remove_handler ("gnc.engine", hdlr2);
1007  test_clear_error_list ();
1008  qof_book_destroy (book);
1009  g_free (fixture->func);
1010 }
1011 /* xaccAcctChildrenEqual
1012 static gboolean
1013 xaccAcctChildrenEqual (const GList *na,// 2
1014 */
1015 /* static void
1016 test_xaccAcctChildrenEqual (Fixture *fixture, gconstpointer pData)
1017 {
1018 }*/
1019 /* xaccAccountEqual
1020 gboolean
1021 xaccAccountEqual (const Account *aa, const Account *ab, gboolean check_guids)// C: 8 in 6
1022 Test support only; don't test for now.
1023 */
1024 /* static void
1025 test_xaccAccountEqual (Fixture *fixture, gconstpointer pData)
1026 {
1027 }*/
1028 /*
1029  The following are getters and setters, unworthy of testing:
1030  gnc_account_get_sort_dirty *** Test Only ***
1031  gnc_account_set_sort_dirty
1032  gnc_account_get_balance_dirty *** Test Only ***
1033  gnc_account_set_balance_dirty
1034 */
1035 /* gnc_account_find_split *** Test Only ***
1036  */
1037 /* gnc_account_insert_split
1038 gboolean
1039 gnc_account_insert_split (Account *acc, Split *s)// C: 5 in 3
1040 
1041 Also tests gnc_account_remove_split ()
1042 */
1043 static void
1044 test_gnc_account_insert_remove_split (Fixture *fixture, gconstpointer pData)
1045 {
1046  QofBook *book = gnc_account_get_book (fixture->acct);
1047  Split *split1 = xaccMallocSplit (book);
1048  Split *split2 = xaccMallocSplit (book);
1049  Split *split3 = xaccMallocSplit (book);
1050  TestSignal sig1, sig2, sig3;
1051  AccountPrivate *priv = fixture->func->get_private (fixture->acct);
1052  gchar *msg1 = "gnc_account_insert_split: assertion `GNC_IS_ACCOUNT(acc)' failed";
1053  gchar *msg2 = "gnc_account_insert_split: assertion `GNC_IS_SPLIT(s)' failed";
1054  guint loglevel = G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL;
1055 // gchar *log_domain = "gnc.engine";
1056  TestErrorStruct check1 = { loglevel, "gnc.engine", msg1, 0 };
1057  TestErrorStruct check2 = { loglevel, "gnc.engine", msg2, 0 };
1058  TestErrorStruct check3 = { loglevel, "gnc.engine", NULL, 0 };
1059  guint logger;
1060  sig1 = test_signal_new (&fixture->acct->inst, QOF_EVENT_MODIFY, NULL);
1061  sig2 = test_signal_new (&fixture->acct->inst, GNC_EVENT_ITEM_ADDED, split1);
1062 
1063  test_add_error (&check1);
1064  test_add_error (&check2);
1065  logger = g_log_set_handler ("gnc.engine", loglevel,
1066  (GLogFunc)test_null_handler, &check3);
1067  g_test_log_set_fatal_handler ((GTestLogFatalFunc)test_list_handler, NULL);
1068 
1069  /* Check that the call fails with invalid account and split (throws) */
1070  g_assert (!gnc_account_insert_split (NULL, split1));
1071  g_assert_cmpuint (g_list_length (priv->splits), == , 0);
1072  g_assert (!priv->sort_dirty);
1073  g_assert (!priv->balance_dirty);
1074  test_signal_assert_hits (sig1, 0);
1075  test_signal_assert_hits (sig2, 0);
1076  g_assert (!gnc_account_insert_split (fixture->acct, NULL));
1077  g_assert_cmpuint (g_list_length (priv->splits), == , 0);
1078  g_assert (!priv->sort_dirty);
1079  g_assert (!priv->balance_dirty);
1080  test_signal_assert_hits (sig1, 0);
1081  test_signal_assert_hits (sig2, 0);
1082  /* g_assert (!gnc_account_insert_split (fixture->acct, (Split*)priv)); */
1083  /* g_assert_cmpuint (g_list_length (priv->splits), == , 0); */
1084  /* g_assert (!priv->sort_dirty); */
1085  /* g_assert (!priv->balance_dirty); */
1086  /* test_signal_assert_hits (sig1, 0); */
1087  /* test_signal_assert_hits (sig2, 0); */
1088  g_assert_cmpint (check1.hits, ==, 1);
1089  g_assert_cmpint (check2.hits, ==, 1);
1090  g_assert_cmpint (check3.hits, ==, 0);
1091  g_log_remove_handler ("gnc.engine", logger);
1092  test_clear_error_list ();
1093 
1094  /* Check that it works the first time */
1095  g_assert (gnc_account_insert_split (fixture->acct, split1));
1096  g_assert_cmpuint (g_list_length (priv->splits), == , 1);
1097  g_assert (!priv->sort_dirty);
1098  g_assert (priv->balance_dirty);
1099  test_signal_assert_hits (sig1, 1);
1100  test_signal_assert_hits (sig2, 1);
1101  /* Check that it fails if the split has already been added once */
1102  g_assert (!gnc_account_insert_split (fixture->acct, split1));
1103  /* Free up hdlr2 and set up hdlr2 */
1104  test_signal_free (sig2);
1105  sig3 = test_signal_new (&fixture->acct->inst, GNC_EVENT_ITEM_ADDED, split2);
1106  /* Now add a second split to the account and check that sort_dirty isn't set. We have to bump the editlevel to force this. */
1107  g_assert (gnc_account_insert_split (fixture->acct, split2));
1108  g_assert_cmpuint (g_list_length (priv->splits), == , 2);
1109  g_assert (!priv->sort_dirty);
1110  g_assert (priv->balance_dirty);
1111  test_signal_assert_hits (sig1, 2);
1112  test_signal_assert_hits (sig3, 1);
1113  /* One more add, incrementing the editlevel to get sort_dirty set. */
1114  test_signal_free (sig3);
1115  sig3 = test_signal_new (&fixture->acct->inst, GNC_EVENT_ITEM_ADDED, split3);
1116  qof_instance_increase_editlevel (fixture->acct);
1117  g_assert (gnc_account_insert_split (fixture->acct, split3));
1118  qof_instance_decrease_editlevel (fixture->acct);
1119  g_assert_cmpuint (g_list_length (priv->splits), == , 3);
1120  g_assert (priv->sort_dirty);
1121  g_assert (priv->balance_dirty);
1122  test_signal_assert_hits (sig1, 3);
1123  test_signal_assert_hits (sig3, 1);
1124  /* Finally delete a split. It's going to recompute the balance, so
1125  * balance_dirty will be false. */
1126  test_signal_free (sig3);
1127  sig3 = test_signal_new (&fixture->acct->inst, GNC_EVENT_ITEM_REMOVED,
1128  split3);
1129  g_assert (gnc_account_remove_split (fixture->acct, split3));
1130  g_assert_cmpuint (g_list_length (priv->splits), == , 2);
1131  g_assert (priv->sort_dirty);
1132  g_assert (!priv->balance_dirty);
1133  test_signal_assert_hits (sig1, 4);
1134  test_signal_assert_hits (sig3, 1);
1135  /* And do it again to make sure that it fails when the split has
1136  * already been removed */
1137  g_assert (!gnc_account_remove_split (fixture->acct, split3));
1138  g_assert_cmpuint (g_list_length (priv->splits), == , 2);
1139  g_assert (priv->sort_dirty);
1140  g_assert (!priv->balance_dirty);
1141  test_signal_assert_hits (sig1, 4);
1142  test_signal_assert_hits (sig3, 1);
1143 
1144  /* Clean up the handlers */
1145  test_signal_free (sig3);
1146  test_signal_free (sig1);
1147 }
1148 /* xaccAccountSortSplits
1149 void
1150 xaccAccountSortSplits (Account *acc, gboolean force)// C: 4 in 2
1151 Make static?
1152 Passthrough, no test.
1153 */
1154 /* xaccAccountBringUpToDate
1155 static void
1156 xaccAccountBringUpToDate (Account *acc)// 3
1157 Passthrough, no test.
1158 */
1159 /* xaccAccountSetGUID
1160 void
1161 xaccAccountSetGUID (Account *acc, const GncGUID *guid)// C: 5 in 4
1162 Getter/Setter, no test.
1163 * Naughty function: GUID should be set at object construction and be invariant thereafter.
1164  */
1165 /* xaccAccountLookup
1166 Account *
1167 xaccAccountLookup (const GncGUID *guid, QofBook *book)// C: 37 in 28 SCM: 2 in 1
1168 Passthrough, no test.
1169 */
1170 /* More getters/setters:
1171  xaccAccountGetMark *** Test Only ***
1172  xaccAccountSetMark *** Not Used ***
1173  xaccClearMark *** Not Used ***
1174  xaccClearMarkDown
1175  gnc_account_get_policy
1176  gnc_account_set_policy
1177 */
1178 /* xaccAccountRemoveLot
1179 void
1180 xaccAccountRemoveLot (Account *acc, GNCLot *lot)// C: 6 in 4 */
1181 static void
1182 test_xaccAccountInsertRemoveLot (Fixture *fixture, gconstpointer pData)
1183 {
1184  QofBook *book = gnc_account_get_book (fixture->acct);
1185  GNCLot *lot = gnc_lot_new (book);
1186  Account *parent = gnc_account_get_parent (fixture->acct);
1187  TestSignal sig1 = test_signal_new (QOF_INSTANCE (lot),
1188  QOF_EVENT_ADD, NULL);
1189  TestSignal sig2 = test_signal_new (&fixture->acct->inst,
1190  QOF_EVENT_MODIFY, NULL);
1191  TestSignal sig3 = test_signal_new (QOF_INSTANCE (lot),
1192  QOF_EVENT_REMOVE, NULL);
1193  TestSignal sig4 = test_signal_new (&parent->inst, QOF_EVENT_MODIFY, NULL);
1194 
1195  AccountPrivate *a_priv = fixture->func->get_private (fixture->acct);
1196  AccountPrivate *p_priv = fixture->func->get_private (parent);
1197 
1198  g_assert_cmpuint (g_list_length (a_priv->lots), == , 0);
1199  g_assert_cmpuint (g_list_length (p_priv->lots), == , 0);
1200  xaccAccountInsertLot (fixture->acct, lot);
1201  g_assert (gnc_lot_get_account (lot) == fixture->acct);
1202  g_assert_cmpuint (g_list_length (a_priv->lots), == , 1);
1203  test_signal_assert_hits (sig1, 1);
1204  test_signal_assert_hits (sig2, 1);
1205  /* Make sure that inserting again doesn't do anything */
1206  xaccAccountInsertLot (fixture->acct, lot);
1207  g_assert (gnc_lot_get_account (lot) == fixture->acct);
1208  g_assert_cmpuint (g_list_length (a_priv->lots), == , 1);
1209  test_signal_assert_hits (sig1, 1);
1210  test_signal_assert_hits (sig2, 1);
1211  /* Check that inserting the lot into a different account changes the lot */
1212  xaccAccountInsertLot (parent, lot);
1213  g_assert (gnc_lot_get_account (lot) == parent);
1214  g_assert_cmpuint (g_list_length (a_priv->lots), == , 0);
1215  g_assert_cmpuint (g_list_length (p_priv->lots), == , 1);
1216  test_signal_assert_hits (sig1, 2);
1217  test_signal_assert_hits (sig4, 1);
1218  test_signal_assert_hits (sig2, 1);
1219  /* Check that removing the lot works */
1220  xaccAccountRemoveLot (parent, lot);
1221  /* The following test should fail, but it doesn't because of an
1222  * error in the routine: When removing a lot from an account, the
1223  * account reference in the lot object should be NULLed. */
1224  g_assert (gnc_lot_get_account (lot) != NULL);
1225  g_assert_cmpuint (g_list_length (a_priv->lots), == , 0);
1226  g_assert_cmpuint (g_list_length (p_priv->lots), == , 0);
1227  test_signal_assert_hits (sig3, 1);
1228  test_signal_assert_hits (sig4, 2);
1229  test_signal_assert_hits (sig2, 1);
1230  /* Check that destroying the lot removes its reference */
1231  /* Because the lot's account pointer doesn't get nulled when the lot
1232  * is removed, we have to do that for the next test to work: */
1233  gnc_lot_set_account (lot, NULL);
1234  xaccAccountInsertLot (parent, lot);
1235  g_assert_cmpuint (g_list_length (p_priv->lots), == , 1);
1236  g_assert (gnc_lot_get_account (lot) == parent);
1237  gnc_lot_destroy (lot);
1238  /* Destroying the lot should remove it from the account; Not Happening. */
1239  g_assert_cmpuint (g_list_length (p_priv->lots), != , 0);
1240  test_signal_assert_hits (sig1, 3);
1241  /* We get a modify only on the insert, since there is no remove when
1242  * the lot is destroyed. */
1243  test_signal_assert_hits (sig4, 3);
1244  /* Same thing: There should be a "removed" signal on the lot, but
1245  * since it isn't removed, no signal. */
1246  test_signal_assert_hits (sig3, 1);
1247  test_signal_free (sig1);
1248  test_signal_free (sig2);
1249  test_signal_free (sig3);
1250  test_signal_free (sig4);
1251 
1252 }
1253 /*
1254 static void
1255 xaccPreSplitMove (Split *split, gpointer dummy)// 2
1256 static void
1257 xaccPostSplitMove (Split *split, Account *accto)// 2
1258 void
1259 xaccAccountMoveAllSplits (Account *accfrom, Account *accto)// C: 5 in 3
1260 
1261 * All of the work is done in other classes which in turn call other
1262 * Account functions (gnc_account_add_split and
1263 * gnc_account_remove_split). Mock classes with the functions that call
1264 * those wouldn't really achieve anything, since the actual functions
1265 * could break by failing to call gnc_account_*_split and the test
1266 * wouldn't know.
1267 */
1268 
1269 /* xaccAccountRecomputeBalance
1270 void
1271 xaccAccountRecomputeBalance (Account * acc)// C: 9 in 5 */
1272 static void
1273 test_xaccAccountRecomputeBalance (Fixture *fixture, gconstpointer pData)
1274 {
1275  AccountPrivate *priv = fixture->func->get_private (fixture->acct);
1276  gnc_numeric bal = gnc_numeric_zero (), rec_bal = gnc_numeric_zero (),
1277  clr_bal = gnc_numeric_zero ();
1278  SetupData *sdata = (SetupData*)pData;
1279  TxnParms* t_arr;
1280  int ind;
1281  g_assert (sdata != NULL);
1282  t_arr = (TxnParms*)sdata->txns;
1283  for (ind = 0; ind < sdata->num_txns; ind++)
1284  {
1285  SplitParms p = t_arr[ind].splits[1];
1286  bal = gnc_numeric_add_fixed (bal, p.amount);
1287  if (p.reconciled != NREC)
1288  clr_bal = gnc_numeric_add_fixed (clr_bal, p.amount);
1289  if (p.reconciled == YREC || p.reconciled == FREC)
1290  rec_bal = gnc_numeric_add_fixed (rec_bal, p.amount);
1291  }
1292  g_assert (gnc_numeric_zero_p (priv->starting_balance));
1293  g_assert (gnc_numeric_zero_p (priv->balance));
1294  priv->balance_dirty = TRUE;
1295  xaccAccountRecomputeBalance (fixture->acct);
1296  g_assert (gnc_numeric_zero_p (priv->starting_balance));
1297  g_assert (gnc_numeric_eq (priv->balance, bal));
1298  g_assert (gnc_numeric_eq (priv->cleared_balance, clr_bal));
1299  g_assert (gnc_numeric_eq (priv->reconciled_balance, rec_bal));
1300  g_assert (!priv->balance_dirty);
1301 }
1302 
1303 /* xaccAccountOrder
1304 int
1305 xaccAccountOrder (const Account *aa, const Account *ab)// C: 11 in 3 */
1306 static void
1307 test_xaccAccountOrder ( )
1308 {
1309  Account *aa = NULL, *ab = NULL;
1310  QofBook *book = qof_book_new ();
1311 
1312 
1313  g_assert (xaccAccountOrder (aa, ab) == 0);
1314  aa = xaccMallocAccount (book);
1315  g_assert (xaccAccountOrder (aa, ab) == -1);
1316  g_assert (xaccAccountOrder (ab, aa) == 1);
1317 
1318  ab = xaccMallocAccount (book);
1319  g_object_set (G_OBJECT (aa),
1320  "code", "3333",
1321  "type", ACCT_TYPE_ASSET,
1322  "name", "foo",
1323  NULL);
1324  g_object_set (G_OBJECT (ab),
1325  "code", "3333",
1326  "type", ACCT_TYPE_ASSET,
1327  "name", "foo",
1328  NULL);
1329 
1330  g_assert_cmpint (xaccAccountOrder (aa, aa), == , 0);
1331  g_assert_cmpint (xaccAccountOrder (aa, ab), == ,
1332  qof_instance_guid_compare (aa, ab));
1333  g_object_set (G_OBJECT (ab), "name", "bar", NULL);
1334  g_assert_cmpint (xaccAccountOrder (aa, ab), > , 0);
1335  g_object_set (G_OBJECT (ab), "name", "waldo", NULL);
1336  g_assert_cmpint (xaccAccountOrder (aa, ab), < , 0);
1337 
1338  g_object_set (G_OBJECT (ab), "type", ACCT_TYPE_BANK, NULL);
1339  g_test_message ("The next test should fail: There's an error in the sort"
1340  " sequence that causes ACCT_TYPE_BANK to sort last"
1341  " instead of first\n");
1342  g_assert_cmpint (xaccAccountOrder (aa, ab), < , 0);
1343  g_object_set (G_OBJECT (ab), "type", ACCT_TYPE_STOCK, NULL);
1344  g_assert_cmpint (xaccAccountOrder (aa, ab), > , 0);
1345  g_object_set (G_OBJECT (ab),
1346  "type", ACCT_TYPE_INCOME,
1347  "name", "bar",
1348  NULL);
1349  g_assert_cmpint (xaccAccountOrder (aa, ab), < , 0);
1350 
1351  g_object_set (G_OBJECT (ab), "code", "2222",
1352  "name", "waldo",
1353  NULL);
1354  g_assert_cmpint (xaccAccountOrder (aa, ab), > , 0);
1355  g_object_set (G_OBJECT (ab),
1356  "code", "4444",
1357  "type", ACCT_TYPE_STOCK,
1358  "name", "bar",
1359  NULL);
1360  g_assert_cmpint (xaccAccountOrder (aa, ab), < , 0);
1361 
1362  xaccAccountBeginEdit (aa);
1363  xaccAccountDestroy (aa);
1364  xaccAccountBeginEdit (ab);
1365  xaccAccountDestroy (ab);
1366  g_object_unref (book);
1367 }
1368 /* qof_xaccAccountOrder
1369 static int
1370 qof_xaccAccountOrder (const Account **aa, const Account **ab)// 2
1371 Pass-through
1372 */
1373 /*
1374  * The following functions are tested in get/set above:
1375  * xaccAccountSetType
1376  * xaccAccountSetName
1377  * xaccAccountSetCode
1378  * xaccAccountSetDescription
1379  * xaccAccountSetColor
1380  * xaccAccountSetNotes
1381  * xaccAccountSetCommodity
1382  * xaccAccountSetCommoditySCU
1383  * xaccAccountGetCommoditySCUi
1384  * xaccAccountGetCommoditySCU
1385  * xaccAccountSetNonStdSCU
1386  * xaccAccountGetNonStdSCU
1387  */
1388 /* DxaccAccountSetCurrency
1389 void
1390 DxaccAccountSetCurrency (Account * acc, gnc_commodity * currency)// C: 7 in 5
1391 Deprecated, don't test
1392 
1393 */
1394 
1395 /* qofAccountSetParent
1396 static void
1397 qofAccountSetParent (Account *acc, QofInstance *parent)// 2
1398 */
1399 static void
1400 test_qofAccountSetParent (Fixture *fixture, gconstpointer pData)
1401 {
1402  Account *root = gnc_account_get_root (fixture->acct);
1403  Account *old_parent = gnc_account_get_parent (fixture->acct);
1404  AccountTestFunctions *func = _utest_account_fill_functions ();
1405  g_assert (root != old_parent);
1406  /* qofAccountSetParent doesn't check to see if the parent is already
1407  * set, nor does gnc_account_append_child, which is the passed-through
1408  * function.
1409  */
1410  func->qofAccountSetParent (fixture->acct, QOF_INSTANCE (root));
1411  g_assert (root == gnc_account_get_parent (fixture->acct));
1412  g_assert (qof_instance_get_dirty (QOF_INSTANCE (fixture->acct)));
1413  g_assert (qof_instance_get_dirty (QOF_INSTANCE (root)));
1414  g_assert (qof_instance_get_dirty (QOF_INSTANCE (old_parent)));
1415 }
1416 /* gnc_account_append_child
1417 void
1418 gnc_account_append_child (Account *new_parent, Account *child)// C: 29 in 18 SCM: 7 in 4*/
1419 /* gnc_account_remove_child
1420 void
1421 gnc_account_remove_child (Account *parent, Account *child)// C: 4 in 2 */
1422 static void
1423 test_gnc_account_append_remove_child (Fixture *fixture, gconstpointer pData)
1424 {
1425  QofBook *book = gnc_account_get_book (fixture->acct);
1426  QofBook *fbook = qof_book_new ();
1427  Account *froot = gnc_account_create_root (fbook);
1428  Account *account = xaccMallocAccount (fbook);
1429  gchar *logdomain = "gnc.account";
1430  gchar *msg1 = "[gnc_account_append_child()] reparenting accounts across books is not correctly supported\n";
1431  gchar *msg2 = "[gnc_account_remove_child()] account not a child of parent";
1432  guint log_handler = 0;
1433  TestErrorStruct check_warn = {G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL, "gnc.account", msg1, 0 };
1434  TestErrorStruct check_err = {G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL, "gnc.account", msg2, 0 };
1435  TestSignal sig1, sig2, sig3;
1436  AccountTestFunctions *func = _utest_account_fill_functions ();
1437  AccountPrivate *frpriv = func->get_private (froot),
1438  *apriv = func->get_private (fixture->acct);
1439  const GncGUID *acct_guid = qof_instance_get_guid (QOF_INSTANCE (account));
1440  sig1 = test_signal_new (QOF_INSTANCE (account), QOF_EVENT_ADD, NULL);
1441  sig2 = test_signal_new (QOF_INSTANCE (account), QOF_EVENT_DESTROY, NULL);
1442  sig3 = test_signal_new (QOF_INSTANCE (account), QOF_EVENT_CREATE, NULL);
1443 
1444  gnc_account_append_child (froot, account);
1445  g_assert (gnc_account_get_parent (account) == froot);
1446  test_signal_assert_hits (sig1, 1);
1447  test_signal_assert_hits (sig2, 0);
1448  test_signal_assert_hits (sig3, 0);
1449  g_assert_cmpint (check_warn.hits, ==, 0);
1450  g_assert_cmpint (check_err.hits, ==, 0);
1451  g_assert (qof_instance_get_dirty (QOF_INSTANCE (froot)));
1452  g_assert (qof_instance_get_dirty (QOF_INSTANCE (account)));
1453  g_assert (g_list_find (frpriv->children, account));
1454  g_assert (qof_collection_lookup_entity (
1455  qof_book_get_collection (fbook, GNC_ID_ACCOUNT),
1456  acct_guid));
1457  log_handler = g_log_set_handler (logdomain, G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, (GLogFunc)test_null_handler, &check_warn);
1458  g_test_log_set_fatal_handler ((GTestLogFatalFunc)test_checked_handler, &check_warn);
1459  gnc_account_append_child (fixture->acct, account);
1460  g_log_remove_handler (logdomain, log_handler);
1461  g_assert_cmpstr (msg1, == , check_warn.msg);
1462  g_assert (gnc_account_get_parent (account) == fixture->acct);
1463  test_signal_assert_hits (sig1, 2);
1464  test_signal_assert_hits (sig2, 1);
1465  test_signal_assert_hits (sig3, 1);
1466  g_assert_cmpint (check_warn.hits, ==, 1);
1467  g_assert_cmpint (check_err.hits, ==, 0);
1468  g_assert (!qof_collection_lookup_entity (
1469  qof_book_get_collection (fbook, GNC_ID_ACCOUNT),
1470  acct_guid));
1471  g_assert (qof_collection_lookup_entity (
1472  qof_book_get_collection (book, GNC_ID_ACCOUNT),
1473  acct_guid));
1474  g_assert (qof_instance_get_dirty (QOF_INSTANCE (fixture->acct)));
1475  g_assert (g_list_find (frpriv->children, account) == NULL);
1476  g_assert (g_list_find (apriv->children, account));
1477 
1478  test_signal_free (sig1);
1479  test_signal_free (sig2);
1480  test_signal_free (sig3);
1481  sig1 = test_signal_new (&account->inst, QOF_EVENT_REMOVE, NULL);
1482  sig2 = test_signal_new (&(fixture->acct)->inst, QOF_EVENT_MODIFY, NULL);
1483  log_handler = g_log_set_handler (logdomain, G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL,
1484  (GLogFunc)test_null_handler, &check_err);
1485  g_test_log_set_fatal_handler ((GTestLogFatalFunc)test_checked_handler, &check_err);
1486  gnc_account_remove_child (froot, account);
1487  g_log_remove_handler (logdomain, log_handler);
1488 
1489  test_signal_assert_hits (sig1, 0);
1490  test_signal_assert_hits (sig2, 0);
1491  g_assert_cmpint (check_err.hits, ==, 1);
1492  g_assert_cmpint (check_warn.hits, ==, 1);
1493 
1494  gnc_account_remove_child (fixture->acct, account);
1495  g_assert (gnc_account_get_parent (account) == NULL);
1496  g_assert (g_list_find (apriv->children, account) == NULL);
1497  test_signal_assert_hits (sig1, 1);
1498  test_signal_assert_hits (sig2, 1);
1499  g_assert_cmpint (check_warn.hits, ==, 1);
1500  g_assert_cmpint (check_err.hits, ==, 1);
1501  test_signal_free (sig1);
1502  test_signal_free (sig2);
1503  xaccAccountBeginEdit (account);
1504  xaccAccountDestroy (account);
1505  xaccAccountBeginEdit (froot);
1506  xaccAccountDestroy (froot);
1507  g_object_unref (fbook);
1508 
1509 }
1510 /* Simple Getters or passthroughs, no tests:
1511  * gnc_account_get_parent
1512  * gnc_account_get_root
1513  * gnc_account_is_root
1514  * gnc_account_get_children
1515  * gnc_account_get_children_sorted
1516  * gnc_account_n_children
1517  * gnc_account_child_index
1518  * gnc_account_nth_child
1519  */
1520 /* gnc_account_n_descendants
1521 gint
1522 gnc_account_n_descendants (const Account *account)// C: 12 in 6 */
1523 static void
1524 test_gnc_account_n_descendants (Fixture *fixture, gconstpointer pData)
1525 {
1526  g_assert_cmpint (
1528  gnc_account_get_root (fixture->acct)), == , 4);
1529 }
1530 /* gnc_account_get_current_depth
1531 gint
1532 gnc_account_get_current_depth (const Account *account)// C: 4 in 2 SCM: 12 in 4*/
1533 static void
1534 test_gnc_account_get_current_depth (Fixture *fixture, gconstpointer pData)
1535 {
1536  g_assert_cmpint (
1537  gnc_account_get_current_depth (fixture->acct), == , 2);
1538 }
1539 /* gnc_account_get_tree_depth
1540 gint
1541 gnc_account_get_tree_depth (const Account *account)// C: 4 in 2 SCM: 3 in 3*/
1542 static void
1543 test_gnc_account_get_tree_depth (Fixture *fixture, gconstpointer pData)
1544 {
1545  /* Magic result value based on depth of the "complex" AccountParms array. */
1546  g_assert_cmpint (
1548  gnc_account_get_root (fixture->acct)), == , 5);
1549  g_assert_cmpint (
1550  gnc_account_get_tree_depth (fixture->acct), == , 1);
1551 }
1552 /* gnc_account_get_descendants
1553 GList *
1554 gnc_account_get_descendants (const Account *account)// C: 24 in 17 SCM: 6 in 6*/
1555 static void
1556 print_account (gpointer item, gpointer data)
1557 {
1558  Account *account = (Account *)item;
1559  gchar *name, *code, *desc;
1560  GNCAccountType type;
1561  const gchar *typestr;
1562  g_object_get (account,
1563  "type", &type,
1564  "name", &name,
1565  "code", &code,
1566  "description", &desc,
1567  NULL);
1568  typestr = xaccAccountGetTypeStr (type);
1569  g_test_message ("%s: %s, %s %s", typestr, code, name, desc);
1570  g_free (code);
1571  g_free (name);
1572  g_free (desc);
1573 }
1574 
1575 static void
1576 test_gnc_account_get_descendants (Fixture *fixture, gconstpointer pData)
1577 {
1578 
1579  GList *list = gnc_account_get_descendants (
1580  gnc_account_get_root (fixture->acct));
1581  g_assert (list != NULL);
1582  g_assert_cmpuint (g_list_length (list), == , 34);
1583  g_assert_cmpint (g_list_index (list, fixture->acct), == , 33);
1584  g_list_free (list);
1585  list = gnc_account_get_descendants (fixture->acct);
1586  g_assert (list == NULL);
1587 }
1588 /* gnc_account_get_descendants_sorted
1589 GList *
1590 gnc_account_get_descendants_sorted (const Account *account)// C: 6 in 4 SCM: 62 in 46*/
1591 static void
1592 test_gnc_account_get_descendants_sorted (Fixture *fixture, gconstpointer pData)
1593 {
1594  GList *list = gnc_account_get_descendants_sorted (
1595  gnc_account_get_root (fixture->acct));
1596  g_assert (list != NULL);
1597  g_list_foreach (list, print_account, NULL);
1598  g_assert_cmpuint (g_list_length (list), == , 34);
1599  g_assert_cmpint (g_list_index (list, fixture->acct), == , 10);
1600  g_list_free (list);
1601 }
1602 /* gnc_account_lookup_by_name
1603 Account *
1604 gnc_account_lookup_by_name (const Account *parent, const char * name)// C: 22 in 12 */
1605 static void
1606 test_gnc_account_lookup_by_name (Fixture *fixture, gconstpointer pData)
1607 {
1608  Account *root, *target;
1609  gchar *code;
1610  root = gnc_account_get_root (fixture->acct);
1611  target = gnc_account_lookup_by_name (root, "income");
1612  g_assert (target != NULL);
1613  g_object_get (target, "code", &code, NULL);
1614  g_assert_cmpstr (code, == , "4000");
1615  target = gnc_account_lookup_by_name (target, "int");
1616  g_assert (target != NULL);
1617  g_free (code);
1618  g_object_get (target, "code", &code, NULL);
1619  g_assert_cmpstr (code, == , "4160");
1620  target = gnc_account_lookup_by_name (root, "bank");
1621  g_assert (target != NULL);
1622  g_free (code);
1623  g_object_get (target, "code", &code, NULL);
1624  g_assert_cmpstr (code, == , "2300");
1625  target = gnc_account_lookup_by_name (target, "int");
1626  g_assert (target == NULL);
1627  g_free (code);
1628 
1629 }
1630 /* gnc_account_lookup_by_code
1631 Account *
1632 gnc_account_lookup_by_code (const Account *parent, const char * code)// C: 5 in 3 */
1633 static void
1634 test_gnc_account_lookup_by_code (Fixture *fixture, gconstpointer pData)
1635 {
1636  Account *root, *target;
1637  gchar *name;
1638  root = gnc_account_get_root (fixture->acct);
1639  target = gnc_account_lookup_by_code (root, "3100");
1640  g_assert (target != NULL);
1641  g_object_get (target, "name", &name, NULL);
1642  g_assert_cmpstr (name, == , "ordinary");
1643  g_free (name);
1644  target = gnc_account_lookup_by_code (target, "3150");
1645  g_assert (target != NULL);
1646  g_object_get (target, "name", &name, NULL);
1647  g_assert_cmpstr (name, == , "utilities");
1648  target = gnc_account_lookup_by_code (target, "2100");
1649  g_assert (target == NULL);
1650  g_free (name);
1651 }
1652 /* gnc_account_lookup_by_full_name_helper
1653 static Account *
1654 gnc_account_lookup_by_full_name_helper (const Account *parent,// 3
1655 */
1656 static void
1657 test_gnc_account_lookup_by_full_name_helper ( Fixture *fixture,
1658  gconstpointer pData )
1659 {
1660  Account *root, *target;
1661  gchar *names1[] = {"income", "taxable", "int", NULL};
1662  gchar *names2[] = {"income", "exempt", "int", NULL};
1663  gchar *names3[] = {"expense", "taxable", "int", NULL};
1664  gchar *code;
1665  AccountTestFunctions *func = _utest_account_fill_functions ();
1666 
1667  root = gnc_account_get_root (fixture->acct);
1668  target = func->gnc_account_lookup_by_full_name_helper (root, names1);
1669  g_assert (target != NULL);
1670  g_object_get (target, "code", &code, NULL);
1671  g_assert_cmpstr (code, == , "4160");
1672  g_free (code);
1673  target = func->gnc_account_lookup_by_full_name_helper (root, names2);
1674  g_assert (target != NULL);
1675  g_object_get (target, "code", &code, NULL);
1676  g_assert_cmpstr (code, == , "4210");
1677  target = func->gnc_account_lookup_by_full_name_helper (root, names3);
1678  g_assert (target == NULL);
1679  g_free (code);
1680 }
1681 /* gnc_account_lookup_by_full_name
1682 Account *
1683 gnc_account_lookup_by_full_name (const Account *any_acc,// C: 15 in 11 SCM: 8 in 4*/
1684 static void
1685 test_gnc_account_lookup_by_full_name (Fixture *fixture, gconstpointer pData)
1686 {
1687  Account *root, *target;
1688  gchar *names1 = "income:taxable:int";
1689  gchar *names2 = "income:exempt:int";
1690  gchar *names3 = "expense:taxable:int";
1691  gchar *code;
1692 
1693  root = gnc_account_get_root (fixture->acct);
1694  target = gnc_account_lookup_by_full_name (root, names1);
1695  g_assert (target != NULL);
1696  g_object_get (target, "code", &code, NULL);
1697  g_assert_cmpstr (code, == , "4160");
1698  g_free (code);
1699  target = gnc_account_lookup_by_full_name (root, names2);
1700  g_assert (target != NULL);
1701  g_object_get (target, "code", &code, NULL);
1702  g_assert_cmpstr (code, == , "4210");
1703  target = gnc_account_lookup_by_full_name (root, names3);
1704  g_assert (target == NULL);
1705  g_free (code);
1706 }
1707 
1708 static void
1709 thunk (Account *s, gpointer data)
1710 {
1711  guint *counter = (guint*)data;
1712  g_assert (GNC_IS_ACCOUNT (s));
1713  ++(*counter);
1714 }
1715 
1716 static gpointer
1717 thunk2 (Account *s, gpointer data)
1718 {
1719  guint *counter = (guint*)data;
1720  gchar *name;
1721  g_assert (GNC_IS_ACCOUNT (s));
1722  g_object_get (G_OBJECT (s), "name", &name, NULL);
1723  if (!g_strcmp0 (name, "int"))
1724  {
1725  g_free (name);
1726  return s;
1727  }
1728  g_free (name);
1729  ++(*counter);
1730  return NULL;
1731 }
1732 /* gnc_account_foreach_child
1733 void
1734 gnc_account_foreach_child (const Account *acc,// C: 6 in 3 */
1735 static void
1736 test_gnc_account_foreach_child (Fixture *fixture, gconstpointer pData)
1737 {
1738  Account *root = gnc_account_get_root (fixture->acct);
1739  Account *begin = gnc_account_lookup_by_code (root, "4000");
1740  guint counter = 0;
1741  gnc_account_foreach_child (begin, thunk, &counter);
1742  g_assert_cmpint (counter, == , 2);
1743 }
1744 /* gnc_account_foreach_child_until *** Not Used ***
1745 gpointer
1746 gnc_account_foreach_child_until (const Account *acc,// C: 4 in 2 */
1747 /*static void
1748 test_gnc_account_foreach_child_until (Fixture *fixture, gconstpointer pData)
1749 {
1750  Account *root = gnc_account_get_root (fixture->acct);
1751  Account *first = gnc_account_lookup_by_code (root, "4000");
1752  Account *second = gnc_account_lookup_by_code (root, "4100");
1753  Account *expected = gnc_account_lookup_by_code (root, "4160");
1754  Account *result;
1755  guint counter = 0;
1756  result = gnc_account_foreach_child_until (first, thunk2, &counter);
1757  g_assert_cmpint (counter, ==, 2);
1758  g_assert (result == NULL);
1759  counter = 0;
1760  result = gnc_account_foreach_child_until (second, thunk2, &counter);
1761  g_assert (result == expected);
1762  g_assert_cmpint (counter, ==, 3);
1763  }*/
1764 /* gnc_account_foreach_descendant
1765 void
1766 gnc_account_foreach_descendant (const Account *acc,// C: 23 in 14 */
1767 static void
1768 test_gnc_account_foreach_descendant (Fixture *fixture, gconstpointer pData)
1769 {
1770  Account *root = gnc_account_get_root (fixture->acct);
1771  Account *begin = gnc_account_lookup_by_code (root, "4000");
1772  guint counter = 0;
1773  gnc_account_foreach_descendant (begin, thunk, &counter);
1774  g_assert_cmpint (counter, == , 13);
1775 }
1776 /* gnc_account_foreach_descendant_until
1777 gpointer
1778 gnc_account_foreach_descendant_until (const Account *acc,// C: 8 in 6 */
1779 static void
1780 test_gnc_account_foreach_descendant_until (Fixture *fixture, gconstpointer pData)
1781 {
1782  Account *root = gnc_account_get_root (fixture->acct);
1783  Account *first = gnc_account_lookup_by_code (root, "2000");
1784  Account *second = gnc_account_lookup_by_code (root, "4000");
1785  Account *expected = gnc_account_lookup_by_code (root, "4160");
1786  Account *result;
1787  guint counter = 0;
1788  result = gnc_account_foreach_descendant_until (first, thunk2, &counter);
1789  g_assert_cmpint (counter, == , 11);
1790  g_assert (result == NULL);
1791  counter = 0;
1792  result = gnc_account_foreach_descendant_until (second, thunk2, &counter);
1793  g_assert (result == expected);
1794  g_assert_cmpint (counter, == , 6);
1795 }
1796 /* More getter/setters:
1797  * xaccAccountGetType
1798  * qofAccountGetTypeString
1799  * qofAccountSetType
1800  * xaccAccountGetName
1801  * xaccAccountGetCode
1802  * xaccAccountGetDescription
1803  * xaccAccountGetColor
1804  * xaccAccountGetNotes
1805  * xaccAccountGetCommodity
1806  * gnc_account_set_start_balance
1807  * gnc_account_set_start_cleared_balance
1808  * gnc_account_set_start_reconciled_balance
1809  * xaccAccountGetBalance
1810  * xaccAccountGetClearedBalance C: 1
1811  * xaccAccountGetReconciledBalance
1812  */
1813 /* gnc_account_get_full_name
1814 gchar *
1815 gnc_account_get_full_name (const Account *account)// C: 38 in 21 SCM: 29 in 19*/
1816 static void
1817 test_gnc_account_get_full_name (Fixture *fixture, gconstpointer pData)
1818 {
1819  gchar *result;
1820  result = gnc_account_get_full_name (NULL);
1821  g_assert (result != NULL);
1822  g_assert_cmpstr (result, == , "");
1823  g_free (result);
1824  result = gnc_account_get_full_name (gnc_account_get_root (fixture->acct));
1825  g_assert (result != NULL);
1826  g_assert_cmpstr (result, == , "");
1827  g_free (result);
1828  result = gnc_account_get_full_name (fixture->acct);
1829  g_assert (result != NULL);
1830  g_assert_cmpstr (result, == , "foo:baz:waldo");
1831  g_free (result);
1832 
1833 }
1834 
1835 /* DxaccAccountGetCurrency
1836 gnc_commodity *
1837 DxaccAccountGetCurrency (const Account *acc)// C: 9 in 5
1838 Deprecated, Don't test.
1839 */
1840 /* xaccAccountGetProjectedMinimumBalance
1841 gnc_numeric
1842 xaccAccountGetProjectedMinimumBalance (const Account *acc)// C: 4 in 2 */
1843 static void
1844 test_xaccAccountGetProjectedMinimumBalance (Fixture *fixture, gconstpointer pData)
1845 {
1846  gnc_numeric val, bal = gnc_numeric_zero ();
1847  gfloat dval;
1848  gfloat dbal = 0.0;
1849  SetupData *sdata = (SetupData*)pData;
1850  TxnParms* t_arr;
1851  int ind;
1852  gint min_ind = 4;
1853  g_assert (sdata != NULL);
1854  t_arr = (TxnParms*)sdata->txns;
1855  for (ind = 0; ind < min_ind; ind++)
1856  {
1857  SplitParms p = t_arr[ind].splits[1];
1858  bal = gnc_numeric_add_fixed (bal, p.amount);
1859  }
1860  dbal = gnc_numeric_to_double (bal);
1861  val = xaccAccountGetProjectedMinimumBalance (fixture->acct);
1862  dval = gnc_numeric_to_double (val);
1863  g_assert_cmpfloat (dval, == , 0.0);
1864  xaccAccountRecomputeBalance (fixture->acct);
1865  val = xaccAccountGetProjectedMinimumBalance (fixture->acct);
1866  dval = gnc_numeric_to_double (val);
1867  g_assert_cmpfloat (dval, == , dbal);
1868 }
1869 /* xaccAccountGetBalanceAsOfDate
1870 gnc_numeric
1871 xaccAccountGetBalanceAsOfDate (Account *acc, time64 date)// C: 12 in 7 SCM: 4 in 4*/
1872 static void
1873 test_xaccAccountGetBalanceAsOfDate (Fixture *fixture, gconstpointer pData)
1874 {
1875  gnc_numeric val, bal = gnc_numeric_zero ();
1876  gfloat dval;
1877  gfloat dbal = 0.0;
1878  SetupData *sdata = (SetupData*)pData;
1879  TxnParms* t_arr;
1880  int ind;
1881  gint min_ind = 2;
1882  gint offset = 24 * 3600 * 3; /* 3 days in seconds */
1883  g_assert (sdata != NULL);
1884  t_arr = (TxnParms*)sdata->txns;
1885  for (ind = 0; ind < min_ind; ind++)
1886  {
1887  SplitParms p = t_arr[ind].splits[1];
1888  bal = gnc_numeric_add_fixed (bal, p.amount);
1889  }
1890  dbal = gnc_numeric_to_double (bal);
1891  xaccAccountRecomputeBalance (fixture->acct);
1892  val = xaccAccountGetBalanceAsOfDate (fixture->acct,
1893  (gnc_time (NULL) - offset));
1894  dval = gnc_numeric_to_double (val);
1895  g_assert_cmpfloat (dval, == , dbal);
1896 }
1897 /* xaccAccountGetPresentBalance
1898 gnc_numeric
1899 xaccAccountGetPresentBalance (const Account *acc)// C: 4 in 2 */
1900 static void
1901 test_xaccAccountGetPresentBalance (Fixture *fixture, gconstpointer pData)
1902 {
1903  gnc_numeric val, bal = gnc_numeric_zero ();
1904  gfloat dval;
1905  gfloat dbal = 0.0;
1906  SetupData *sdata = (SetupData*)pData;
1907  TxnParms* t_arr;
1908  int ind;
1909  gint min_ind = 3;
1910  g_assert (sdata != NULL);
1911  t_arr = (TxnParms*)sdata->txns;
1912  for (ind = 0; ind < min_ind; ind++)
1913  {
1914  SplitParms p = t_arr[ind].splits[1];
1915  bal = gnc_numeric_add_fixed (bal, p.amount);
1916  }
1917  dbal = gnc_numeric_to_double (bal);
1918  xaccAccountRecomputeBalance (fixture->acct);
1919  val = xaccAccountGetPresentBalance (fixture->acct);
1920  dval = gnc_numeric_to_double (val);
1921  g_assert_cmpfloat (dval, == , dbal);
1922 }
1923 /*
1924  * xaccAccountConvertBalanceToCurrency
1925  * xaccAccountConvertBalanceToCurrencyAsOfDate are wrappers around
1926  * gnc_pricedb_convert_balance_latest_price and
1927  * gnc_pricedb_convert_balance_nearest_price. Don't test.
1928  *
1929  * The rest of these are convenience functions that wrap
1930  * xaccAccountConvertBalanceToCurrency* with one of the balance getter
1931  * functions tested immediately above and one of the recursion
1932  * functions, tested above those. There's no point in testing them.
1933  *
1934  * xaccAccountGetXxxBalanceInCurrency
1935  * xaccAccountGetXxxBalanceAsOfDateInCurrency
1936  * xaccAccountBalanceHelper
1937  * xaccAccountBalanceAsOfDateHelper
1938  * xaccAccountGetXxxBalanceInCurrencyRecursive
1939  * xaccAccountGetXxxBalanceAsOfDateInCurrencyRecursive
1940  * xaccAccountGetBalanceInCurrency
1941  * xaccAccountGetClearedBalanceInCurrency
1942  * xaccAccountGetReconciledBalanceInCurrency
1943  * xaccAccountGetPresentBalanceInCurrency
1944  * xaccAccountGetProjectedMinimumBalanceInCurrency
1945  * xaccAccountGetBalanceAsOfDateInCurrency
1946  * xaccAccountGetBalanceChangeForPeriod
1947  */
1948 /*
1949  * Yet more getters & setters:
1950  * xaccAccountGetSplitList
1951  * xaccAccountGetLotList
1952  */
1953 /* xaccAccountFindOpenLots
1954 LotList *
1955 xaccAccountFindOpenLots (const Account *acc,// C: 24 in 13 */
1956 
1957 static gboolean
1958 bogus_lot_match_func_true (GNCLot *lot, gpointer p_data)
1959 {
1960  return TRUE;
1961 }
1962 
1963 static gboolean
1964 bogus_lot_match_func_false (GNCLot *lot, gpointer p_data)
1965 {
1966  return FALSE;
1967 }
1968 
1969 static guint count_sorts = 0;
1970 static gint
1971 bogus_lot_sort_func (gconstpointer a, gconstpointer b)
1972 {
1973  ++count_sorts;
1974  return 0;
1975 }
1976 
1977 static void
1978 test_xaccAccountFindOpenLots (Fixture *fixture, gconstpointer pData)
1979 {
1980  Account *root = gnc_account_get_root (fixture->acct);
1981  Account *acct = gnc_account_lookup_by_name (root, "baz");
1982  LotList* lots;
1983 
1984  g_assert (acct);
1985  lots = xaccAccountFindOpenLots (acct, NULL, NULL, NULL);
1986  g_assert (g_list_length (lots) == 2);
1987  if (lots) g_list_free (lots);
1988  lots = xaccAccountFindOpenLots (acct, bogus_lot_match_func_true,
1989  NULL, NULL);
1990  g_assert (g_list_length (lots) == 2);
1991  if (lots) g_list_free (lots);
1992  lots = xaccAccountFindOpenLots (acct, bogus_lot_match_func_false,
1993  NULL, NULL);
1994  g_assert (g_list_length (lots) == 0);
1995  if (lots) g_list_free (lots);
1996  lots = xaccAccountFindOpenLots (acct, NULL, NULL, bogus_lot_sort_func);
1997  g_assert_cmpint (count_sorts, == , 1);
1998  g_assert (g_list_length (lots) == 2);
1999  if (lots) g_list_free (lots);
2000  count_sorts = 0;
2001 }
2002 
2003 static gpointer
2004 bogus_for_each_lot_func (GNCLot *lot, gpointer data)
2005 {
2006  guint *count = data;
2007  ++*count;
2008  return (*count > 4 ? lot : NULL);
2009 }
2010 
2011 /* xaccAccountForEachLot
2012 gpointer
2013 xaccAccountForEachLot (const Account *acc,// C: 2 in 2 */
2014 static void
2015 test_xaccAccountForEachLot (Fixture *fixture, gconstpointer pData)
2016 {
2017  Account *root = gnc_account_get_root (fixture->acct);
2018  Account *acct = gnc_account_lookup_by_name (root, "baz");
2019  guint count_calls = 0;
2020 
2021  g_assert (acct);
2022  xaccAccountForEachLot (acct, bogus_for_each_lot_func, &count_calls);
2023  g_assert_cmpint (count_calls, == , 3);
2024  xaccAccountForEachLot (acct, bogus_for_each_lot_func, &count_calls);
2025  g_assert_cmpint (count_calls, == , 5);
2026 }
2027 /* These getters and setters look in KVP, so I guess their delegators instead:
2028  * xaccAccountGetTaxRelated
2029  * xaccAccountSetTaxRelated
2030  * xaccAccountGetTaxUSCode
2031  * xaccAccountSetTaxUSCode
2032  * xaccAccountGetTaxUSPayerNameSource
2033  * xaccAccountSetTaxUSPayerNameSource
2034  * xaccAccountGetTaxUSCopyNumber
2035  * xaccAccountSetTaxUSCopyNumber
2036  * xaccAccountGetPlaceholder
2037  * xaccAccountSetPlaceholder
2038  * xaccAccountGetDescendantPlaceholder
2039  * xaccAccountGetHidden
2040  * xaccAccountSetHidden
2041  * xaccAccountIsHidden
2042 */
2043 /* xaccAccountHasAncestor
2044 gboolean
2045 xaccAccountHasAncestor (const Account *acc, const Account * ancestor)// C: 5 in 3 */
2046 static void
2047 test_xaccAccountHasAncestor (Fixture *fixture, gconstpointer pData)
2048 {
2049  Account *root = gnc_account_get_root (fixture->acct);
2050  Account *ltcg = gnc_account_lookup_by_name (root, "ltcg");
2051  Account *income = gnc_account_lookup_by_name (root, "income");
2052  Account *expense = gnc_account_lookup_by_name (root, "expense");
2053 
2054  g_assert (root);
2055  g_assert (ltcg);
2056  g_assert (income);
2057  g_assert (expense);
2058  g_assert (xaccAccountHasAncestor (fixture->acct, root));
2059  g_assert (xaccAccountHasAncestor (ltcg, income));
2060  g_assert (!xaccAccountHasAncestor (ltcg, expense));
2061 
2062 }
2063 /* xaccAccountTypeEnumAsString
2064  * xaccAccountStringToType
2065  * xaccAccountStringToEnum
2066  * xaccAccountGetTypeStr
2067  * xaccAccountIsPriced
2068 const char *
2069 xaccAccountTypeEnumAsString (GNCAccountType type)// C: 5 in 3 */
2070 static void
2071 test_xaccAccountType_Stuff (void)
2072 {
2073  GNCAccountType type;
2074  gint loglevel = G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL;
2075  gchar *logdomain = "gnc.account";
2076  gchar *msg1 = g_strdup_printf ("[xaccAccountTypeEnumAsString()] asked to translate unknown account type %d.\n", ACCT_TYPE_LAST);
2077  gchar *msg2 = "[xaccAccountStringToType()] asked to translate unknown account type string (null).\n";
2078  gchar *msg3 = "[xaccAccountStringToType()] asked to translate unknown account type string LAST.\n";
2079  guint loghandler = 0;
2080  TestErrorStruct check1 = { loglevel, logdomain, msg1, 0 };
2081  TestErrorStruct check2 = { loglevel, logdomain, msg2, 0 };
2082  TestErrorStruct check3 = { loglevel, logdomain, msg3, 0 };
2083  Account *acc = g_object_new (GNC_TYPE_ACCOUNT, NULL);
2084 
2085  for (type = ACCT_TYPE_NONE; type < ACCT_TYPE_LAST; type++)
2086  {
2087  const gchar *typename = xaccAccountTypeEnumAsString (type);
2088  const gchar *typestr;
2089  gchar *typestr_uc;
2090 
2091  g_assert (typename);
2092  g_assert_cmpint (xaccAccountStringToEnum (typename), == , type);
2093  if (type < 0 || type >= NUM_ACCOUNT_TYPES)
2094  continue;
2095 
2096  typestr = xaccAccountGetTypeStr (type);
2097  typestr_uc = g_ascii_strup (typestr, strlen (typestr));
2098  if (type == ACCT_TYPE_PAYABLE || type == ACCT_TYPE_RECEIVABLE)
2099  {
2100  gchar *cmpstr = g_strconcat ("A/", typename, NULL);
2101  g_assert_cmpstr (typestr_uc, == , cmpstr);
2102  g_free (cmpstr);
2103  }
2104  else if (type == ACCT_TYPE_CREDIT)
2105  {
2106  gchar *cmpstr = g_strconcat (typename, " CARD", NULL);
2107  g_assert_cmpstr (typestr_uc, == , cmpstr);
2108  g_free (cmpstr);
2109  }
2110  else if (type == ACCT_TYPE_MUTUAL)
2111  {
2112  gchar *cmpstr = g_strconcat (typename, " FUND", NULL);
2113  g_assert_cmpstr (typestr_uc, == , cmpstr);
2114  g_free (cmpstr);
2115  }
2116  else
2117  g_assert_cmpstr (typestr_uc, == , typename);
2118  g_free (typestr_uc);
2119 
2120  g_object_set (acc, "type", type, NULL);
2121  if (type == ACCT_TYPE_STOCK || type == ACCT_TYPE_MUTUAL ||
2122  type == ACCT_TYPE_CURRENCY)
2123  g_assert (xaccAccountIsPriced (acc));
2124  else
2125  g_assert (!xaccAccountIsPriced (acc));
2126 
2127  }
2128  g_object_unref (acc);
2129 
2130  loghandler = g_log_set_handler (logdomain, loglevel,
2131  (GLogFunc)test_null_handler, &check1);
2132  g_test_log_set_fatal_handler ((GTestLogFatalFunc)test_checked_handler, &check1);
2133  g_assert (!xaccAccountTypeEnumAsString (ACCT_TYPE_LAST));
2134  g_assert_cmpint (check1.hits, ==, 1);
2135 
2136  g_log_remove_handler (logdomain, loghandler);
2137  g_free (msg1);
2138  loghandler = g_log_set_handler (logdomain, loglevel,
2139  (GLogFunc)test_null_handler, &check2);
2140  g_test_log_set_fatal_handler ((GTestLogFatalFunc)test_checked_handler, &check2);
2141  g_assert (!xaccAccountStringToType (NULL, &type));
2142  g_assert_cmpint (check2.hits, ==, 1);
2143 
2144  g_log_remove_handler (logdomain, loghandler);
2145  loghandler = g_log_set_handler (logdomain, loglevel,
2146  (GLogFunc)test_null_handler, &check3);
2147  g_test_log_set_fatal_handler ((GTestLogFatalFunc)test_checked_handler, &check3);
2148  g_assert (!xaccAccountStringToType ("LAST", &type));
2149  g_assert_cmpint (check3.hits, ==, 1);
2150 
2151  g_log_remove_handler (logdomain, loghandler);
2152 
2153 
2154 }
2155 /* xaccParentAccountTypesCompatibleWith
2156  * xaccAccountTypesCompatible
2157 guint32
2158 xaccParentAccountTypesCompatibleWith (GNCAccountType type)// C: 5 in 3 */
2159 static void
2160 test_xaccAccountType_Compatibility (void)
2161 {
2162  guint32 bank_compat = ((1 << ACCT_TYPE_BANK) |
2163  (1 << ACCT_TYPE_CASH) |
2164  (1 << ACCT_TYPE_ASSET) |
2165  (1 << ACCT_TYPE_STOCK) |
2166  (1 << ACCT_TYPE_MUTUAL) |
2167  (1 << ACCT_TYPE_CURRENCY) |
2168  (1 << ACCT_TYPE_CREDIT) |
2169  (1 << ACCT_TYPE_LIABILITY) |
2170  (1 << ACCT_TYPE_RECEIVABLE) |
2171  (1 << ACCT_TYPE_PAYABLE) |
2172  (1 << ACCT_TYPE_ROOT));
2173  guint32 expense_compat = ((1 << ACCT_TYPE_INCOME) |
2174  (1 << ACCT_TYPE_EXPENSE) |
2175  (1 << ACCT_TYPE_ROOT));
2176  guint32 equity_compat = ((1 << ACCT_TYPE_EQUITY) | (1 << ACCT_TYPE_ROOT));
2177  guint32 trading_compat = ((1 << ACCT_TYPE_TRADING) | (1 << ACCT_TYPE_ROOT));
2178  guint32 compat;
2179  GNCAccountType type;
2180  gchar *msg1 = g_strdup_printf ("[xaccParentAccountTypesCompatibleWith()] bad account type: %d", ACCT_TYPE_ROOT);
2181  gchar *msg2 = g_strdup_printf ("[xaccParentAccountTypesCompatibleWith()] bad account type: %d", ACCT_TYPE_SAVINGS);
2182  gchar *logdomain = "gnc.account";
2183  guint loglevel = G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL;
2184  TestErrorStruct check1 = { loglevel, logdomain, msg1, 0 };
2185  TestErrorStruct check2 = { loglevel, logdomain, msg2, 0 };
2186  gint loghandler;
2187 
2188  for (type = ACCT_TYPE_BANK; type < NUM_ACCOUNT_TYPES; type++)
2189  {
2190  GNCAccountType child;
2191  if (type == ACCT_TYPE_ROOT)
2192  {
2193  loghandler = g_log_set_handler (logdomain, loglevel,
2194  (GLogFunc)test_null_handler, &check1);
2195  g_test_log_set_fatal_handler ((GTestLogFatalFunc)test_checked_handler,
2196  &check1);
2197  compat = xaccParentAccountTypesCompatibleWith (type);
2198  g_log_remove_handler (logdomain, loghandler);
2199  g_assert_cmpint (compat, == , 0);
2200  g_assert_cmpint (check1.hits, ==, 1);
2201  g_free (msg1);
2202  continue;
2203  }
2204  compat = xaccParentAccountTypesCompatibleWith (type);
2205 
2206  if (type <= ACCT_TYPE_CURRENCY || type == ACCT_TYPE_PAYABLE
2207  || type == ACCT_TYPE_RECEIVABLE)
2208  g_assert_cmpint (compat, == , bank_compat);
2209  else if (type == ACCT_TYPE_INCOME || type == ACCT_TYPE_EXPENSE)
2210  g_assert_cmpint (compat, == , expense_compat);
2211  else if (type == ACCT_TYPE_EQUITY)
2212  g_assert_cmpint (compat, == , equity_compat);
2213  else if (type == ACCT_TYPE_TRADING)
2214  g_assert_cmpint (compat, == , trading_compat);
2215  for (child = ACCT_TYPE_NONE; child < ACCT_TYPE_LAST; child++)
2216  if (1 << child & compat)
2217  g_assert (xaccAccountTypesCompatible (type, child));
2218  else
2219  g_assert (!xaccAccountTypesCompatible (type, child));
2220  }
2221 
2222  loghandler = g_log_set_handler (logdomain, loglevel,
2223  (GLogFunc)test_null_handler, &check2);
2224  g_test_log_set_fatal_handler ((GTestLogFatalFunc)test_checked_handler, &check2);
2225  compat = xaccParentAccountTypesCompatibleWith (++type);
2226  g_log_remove_handler (logdomain, loghandler);
2227  g_assert_cmpint (compat, == , 0);
2228  g_assert_cmpint (check2.hits, ==, 1);
2229  g_free (msg2);
2230 }
2231 /* More KVP getters & setters
2232  * xaccAccountGetReconcileLastDate
2233  * xaccAccountSetReconcileLastDate
2234  * xaccAccountGetReconcilePostponeDate
2235  * xaccAccountSetReconcilePostponeDate
2236  * xaccAccountGetReconcilePostponeBalance
2237  * xaccAccountSetReconcilePostponeBalance
2238  * xaccAccountClearReconcilePostpone
2239  * xaccAccountGetAutoInterestXfer
2240  * xaccAccountSetAutoInterestXfer
2241  * xaccAccountGetLastNum
2242  * xaccAccountSetLastNum
2243  * xaccAccountSetReconcileChildrenStatus
2244  * xaccAccountGetReconcileChildrenStatus
2245  * xaccAccountGetReconcileLastInterval
2246  * xaccAccountSetReconcileLastInterval
2247  * dxaccAccountSetPriceSrc
2248  * dxaccAccountSetQuoteTZ
2249  * dxaccAccountGetQuoteTZ
2250  */
2251 /* finder_help_function
2252 static void
2253 finder_help_function (const Account *acc, const char *description,// 3
2254 Helper function, fully exercised by the following two public functions
2255 */
2256 /* xaccAccountFindSplitByDesc
2257 Split *
2258 xaccAccountFindSplitByDesc (const Account *acc, const char *description)// C: 5 in 3 */
2259 
2260 static void
2261 test_xaccAccountFindSplitByDesc (Fixture *fixture, gconstpointer pData)
2262 {
2263  Account *root = gnc_account_get_root (fixture->acct);
2264  Account *baz = gnc_account_lookup_by_name (root, "baz");
2265  gchar *memo;
2266  Split *split = xaccAccountFindSplitByDesc (baz, "pepper");
2267  g_assert (split);
2268  g_object_get (split, "memo", &memo, NULL);
2269  g_assert_cmpstr (memo, == , "pepper_baz");
2270  g_free (memo);
2271 }
2272 /* xaccAccountFindTransByDesc
2273 Transaction *
2274 xaccAccountFindTransByDesc (const Account *acc, const char *description)// C: 5 in 3 */
2275 static void
2276 test_xaccAccountFindTransByDesc (Fixture *fixture, gconstpointer pData)
2277 {
2278  Account *root = gnc_account_get_root (fixture->acct);
2279  Account *baz = gnc_account_lookup_by_name (root, "baz");
2280  gchar *desc;
2281  Transaction *txn = xaccAccountFindTransByDesc (baz, "pepper");
2282  g_assert (txn);
2283  g_object_get (txn, "description", &desc, NULL);
2284  g_assert_cmpstr (desc, == , "pepper");
2285  g_free (desc);
2286 }
2287 /* gnc_account_join_children
2288 void
2289 gnc_account_join_children (Account *to_parent, Account *from_parent)// C: 4 in 2 SCM: 3 in 3*/
2290 static void
2291 test_gnc_account_join_children (Fixture *fixture, gconstpointer pData)
2292 {
2293  Account *root = gnc_account_get_root (fixture->acct);
2294  Account *broker = gnc_account_lookup_by_name (root, "broker");
2295  Account *income = gnc_account_lookup_by_name (root, "income");
2296  gint broker_desc = gnc_account_n_descendants (broker);
2297  gint income_desc = gnc_account_n_descendants (income);
2298 
2299  g_test_message ("The following should fail because of account type incompatibility. It doesn't, which is a bug.");
2300  gnc_account_join_children (income, broker);
2301  g_assert_cmpint (gnc_account_n_descendants (income), == ,
2302  broker_desc + income_desc);
2303 
2304 
2305 }
2306 /* gnc_account_merge_children
2307 void
2308 gnc_account_merge_children (Account *parent)// C: 4 in 2 SCM: 2 in 2*/
2309 static void
2310 test_gnc_account_merge_children (Fixture *fixture, gconstpointer pData)
2311 {
2312  Account *root = gnc_account_get_root (fixture->acct);
2313  Account *taxable = gnc_account_lookup_by_name (root, "taxable");
2314  Account *expense = gnc_account_lookup_by_name (root, "expense");
2315  Account *div = gnc_account_lookup_by_name (root, "div");
2316  Account *div1 = gnc_account_lookup_by_name (root, "div1");
2317  gint taxable_desc = gnc_account_n_descendants (taxable);
2318  gint expense_desc = gnc_account_n_descendants (expense);
2319  TestSignal sig4, sig5;
2320  /* This segment doesn't test because of problems with resetting
2321  * the accounts on the splits. It will have to be rewritten with a
2322  * mock Split object
2323  Account *stocks = gnc_account_lookup_by_name (root, "stocks");
2324  Account *baz = gnc_account_lookup_by_name (root, "baz");
2325  Account *baz2 = gnc_account_lookup_by_name (root, "baz2");
2326  gint stocks_desc = gnc_account_n_descendants (stocks);
2327  gfloat stocks_balance = gnc_numeric_to_double (
2328  xaccAccountGetBalance (stocks));
2329  gfloat baz_balance = gnc_numeric_to_double (xaccAccountGetBalance (baz));
2330  gfloat baz2_balance = gnc_numeric_to_double (xaccAccountGetBalance (baz2));
2331  TestSignal sig1, sig2, sig3;
2332  gchar *logdomain = "gnc.engine";
2333  gint loglevel = G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL;
2334  gchar *msg = "[xaccSplitCommitEdit ()] Account grabbed split prematurely.";
2335  TestErrorStruct check = { loglevel, logdomain, msg, 0 };
2336  guint hdlr = g_log_set_handler (logdomain, loglevel,
2337  (GLogFunc)test_null_handler, &check);
2338  g_test_log_set_fatal_handler ((GTestLogFatalFunc)test_checked_handler, &check);
2339 
2340  sig1 = test_signal_new (QOF_INSTANCE (baz), QOF_EVENT_MODIFY, NULL);
2341  sig2 = test_signal_new (QOF_INSTANCE (baz2), QOF_EVENT_MODIFY, NULL);
2342  sig3 = test_signal_new (QOF_INSTANCE (baz2), QOF_EVENT_DESTROY, NULL);
2343 
2344  gnc_account_foreach_descendant (stocks, (AccountCb)print_account, NULL);
2345  g_object_set (baz2, "name", "baz", NULL);
2346  gnc_account_merge_children (stocks);
2347  gnc_account_foreach_descendant (stocks, (AccountCb)print_account, NULL);
2348  g_assert_cmpint (gnc_account_n_descendants (stocks), ==, stocks_desc - 1);
2349  g_assert_cmpfloat (gnc_numeric_to_double (xaccAccountGetBalance (stocks)),
2350  ==, stocks_balance);
2351  g_assert_cmpfloat (gnc_numeric_to_double (xaccAccountGetBalance (baz)),
2352  ==, baz_balance + baz2_balance);
2353  test_signal_assert_hits (sig1, 0);
2354  test_signal_assert_hits (sig2, 0);
2355  test_signal_assert_hits (sig3, 1);
2356  test_signal_free (sig1);
2357  test_signal_free (sig2);
2358  test_signal_free (sig3);
2359  g_log_remove_handler (logdomain, hdlr);
2360  g_free (msg);
2361  */
2362  sig4 = test_signal_new (QOF_INSTANCE (div), QOF_EVENT_MODIFY, NULL);
2363  sig5 = test_signal_new (QOF_INSTANCE (div1), QOF_EVENT_MODIFY, NULL);
2364  g_object_set (div1, "name", "div", NULL);
2365  gnc_account_merge_children (taxable);
2366  g_assert_cmpint (gnc_account_n_descendants (taxable), == , taxable_desc - 1);
2367  test_signal_assert_hits (sig4, 1);
2368  test_signal_assert_hits (sig5, 4);
2369  test_signal_free (sig4);
2370  test_signal_free (sig5);
2371  gnc_account_merge_children (expense);
2372  g_assert_cmpint (gnc_account_n_descendants (expense), == , expense_desc);
2373 }
2374 /* xaccSplitsBeginStagedTransactionTraversals
2375  * xaccAccountBeginStagedTransactionTraversals
2376  * gnc_account_tree_begin_staged_transaction_traversals
2377  * xaccAccountStagedTransactionTraversal
2378  * gnc_account_tree_staged_transaction_traversal
2379  * Static helper functions for xaccAccount (Tree)?ForEach ()
2380  */
2381 /* xaccTransactionTraverse
2382 gboolean
2383 xaccTransactionTraverse (Transaction *trans, int stage)// Used only by xaccSplitTransactionTraverses (not used) delete.
2384 */
2385 /* xaccSplitTransactionTraverse
2386 gboolean
2387 xaccSplitTransactionTraverse (Split *split, int stage)// Not used, delete.
2388 */
2389 /* do_one_split
2390  * do_one_account
2391  Trivial helper functions
2392 */
2393 typedef struct
2394 {
2395  guint count;
2396  gchar *name;
2397 } Thunkdata;
2398 
2399 static gint
2400 thunk3 (Transaction *txn, gpointer data)
2401 {
2402  Thunkdata *td = (Thunkdata*)data;
2403  ++(td->count);
2404  if (td->name)
2405  {
2406  gchar *txn_desc;
2407  gboolean result;
2408  g_object_get (txn, "description", &txn_desc, NULL);
2409  result = g_strcmp0 (td->name, txn_desc) == 0;
2410  g_free (txn_desc);
2411  if (result)
2412  return td->count;
2413  }
2414  return 0;
2415 }
2416 
2417 /* xaccAccountTreeForEachTransaction
2418 int
2419 xaccAccountTreeForEachTransaction (Account *acc, TransactionCallback proc,
2420  void *data);// C: 302 in 89 SCM: 1158 in 142*/
2421 static void
2422 test_xaccAccountTreeForEachTransaction (Fixture *fixture, gconstpointer pData )
2423 {
2424  Thunkdata td = {0, NULL};
2425  Account *root = gnc_account_get_root (fixture->acct);
2426  gint result;
2427  result = xaccAccountTreeForEachTransaction (root, thunk3, &td);
2428  g_assert_cmpint (td.count, == , 9);
2429  g_assert_cmpint (result, == , 0);
2430  td.count = 0;
2431  td.name = "pepper";
2432  result = xaccAccountTreeForEachTransaction (root, thunk3, &td);
2433  g_assert_cmpint (td.count, == , result);
2434  g_assert_cmpint (result, < , 9);
2435 }
2436 /* xaccAccountForEachTransaction
2437 gint
2438 xaccAccountForEachTransaction (const Account *acc, TransactionCallback proc,// C: 8 in 4 */
2439 static void
2440 test_xaccAccountForEachTransaction (Fixture *fixture, gconstpointer pData )
2441 {
2442  Thunkdata td = {0, NULL};
2443  Account *root = gnc_account_get_root (fixture->acct);
2444  Account *money = gnc_account_lookup_by_name (root, "money");
2445  gint result;
2446  result = xaccAccountForEachTransaction (root, thunk3, &td);
2447  g_assert_cmpint (td.count, == , 0);
2448  g_assert (money);
2449  result = xaccAccountForEachTransaction (money, thunk3, &td);
2450  g_assert_cmpint (td.count, == , 9);
2451  g_assert_cmpint (result, == , 0);
2452  td.count = 0;
2453  td.name = "pepper";
2454  result = xaccAccountForEachTransaction (money, thunk3, &td);
2455  g_assert_cmpint (td.count, == , result);
2456  g_assert_cmpint (result, < , 9);
2457 }
2458 #endif
2459 
2460 static void
2461 test_gnc_set_budget_name()
2462 {
2463  QofBook *book = qof_book_new();
2464  GncBudget* budget = gnc_budget_new(book);
2465 
2466  g_assert(strcmp(gnc_budget_get_name(budget), "Unnamed Budget") == 0);
2467  gnc_budget_set_name(budget, "New Budget");
2468  g_assert(strcmp(gnc_budget_get_name(budget), "New Budget") == 0);
2469 
2470  gnc_budget_destroy(budget);
2471 }
2472 
2473 static void
2474 test_gnc_set_budget_description()
2475 {
2476  QofBook *book = qof_book_new();
2477  GncBudget* budget = gnc_budget_new(book);
2478 
2479  g_assert(strcmp(gnc_budget_get_description(budget), "") == 0);
2480  gnc_budget_set_description(budget, "New Budget");
2481  g_assert(strcmp(gnc_budget_get_description(budget), "New Budget") == 0);
2482 
2483  gnc_budget_destroy(budget);
2484 }
2485 
2486 static void
2487 test_gnc_set_budget_num_periods()
2488 {
2489  QofBook *book = qof_book_new();
2490  GncBudget* budget = gnc_budget_new(book);
2491 
2492  g_assert_cmpint(gnc_budget_get_num_periods(budget), ==, 12);
2493  gnc_budget_set_num_periods(budget, 20);
2494  g_assert_cmpint(gnc_budget_get_num_periods(budget), ==, 20);
2495 
2496  gnc_budget_destroy(budget);
2497 }
2498 
2499 static void
2500 test_gnc_set_budget_recurrence()
2501 {
2502  QofBook *book = qof_book_new();
2503  GncBudget* budget = gnc_budget_new(book);
2504  Recurrence new_r;
2505  GDate start_date;
2506  const Recurrence* r;
2507  GDate period_start;
2508  GDate period_end;
2509  int i;
2510  typedef struct
2511  {
2512  GDateMonth month;
2513  int end_day;
2514  } PeriodInfo;
2515  PeriodInfo period_info[] = { { G_DATE_JANUARY, 31 }, { G_DATE_FEBRUARY, 29 }, { G_DATE_MARCH, 31 }, { G_DATE_APRIL, 30 }, { G_DATE_MAY, 31 }, { G_DATE_JUNE, 30 },
2516  { G_DATE_JULY, 31 }, { G_DATE_AUGUST, 31 }, { G_DATE_SEPTEMBER, 30 }, { G_DATE_OCTOBER, 31 }, { G_DATE_NOVEMBER, 30 }, { G_DATE_DECEMBER, 31 }
2517  };
2518 
2519  r = gnc_budget_get_recurrence(budget);
2520  g_assert_cmpint(r->ptype, ==, PERIOD_MONTH);
2521  g_assert_cmpint(r->mult, ==, 1);
2522  g_assert_cmpint(r->wadj, ==, WEEKEND_ADJ_NONE);
2523 
2524  g_date_set_dmy(&start_date, 1, G_DATE_JANUARY, 2012);
2525  recurrenceSet(&new_r, 1, PERIOD_MONTH, &start_date, WEEKEND_ADJ_NONE);
2526  gnc_budget_set_recurrence(budget, &new_r);
2527 
2528  r = gnc_budget_get_recurrence(budget);
2529  g_assert_cmpint(r->ptype, ==, PERIOD_MONTH);
2530  g_assert_cmpint(r->mult, ==, 1);
2531  g_assert_cmpint(r->wadj, ==, WEEKEND_ADJ_NONE);
2532 
2533  for (i = 0; i < 12; ++i)
2534  {
2535  period_start = timespec_to_gdate(gnc_budget_get_period_start_date(budget, i));
2536  period_end = timespec_to_gdate(gnc_budget_get_period_end_date(budget, i));
2537 
2538  g_assert_cmpint(g_date_get_day(&period_start), ==, 1);
2539  g_assert_cmpint(g_date_get_day(&period_end), ==, period_info[i].end_day);
2540  g_assert_cmpint(g_date_get_month(&period_start), ==, period_info[i].month);
2541  g_assert_cmpint(g_date_get_month(&period_end), ==, period_info[i].month);
2542  g_assert_cmpint(g_date_get_year(&period_start), ==, 2012);
2543  g_assert_cmpint(g_date_get_year(&period_end), ==, 2012);
2544  }
2545 
2546  gnc_budget_destroy(budget);
2547 }
2548 
2549 static void
2550 test_gnc_set_budget_account_period_value()
2551 {
2552  QofBook *book = qof_book_new();
2553  GncBudget* budget = gnc_budget_new(book);
2554  Account *acc;
2555  gnc_numeric val;
2556 
2557  guint log_level = G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL;
2558  gchar *log_domain = "gnc.engine";
2559  gchar *msg = "[gnc_budget_set_account_period_value()] Period 12 does not exist";
2560  guint hdlr;
2561  TestErrorStruct check = { log_level, log_domain, msg, 0 };
2562  GLogFunc oldlogger;
2563 
2564  acc = gnc_account_create_root(book);
2565 
2566  g_assert(!gnc_budget_is_account_period_value_set(budget, acc, 0));
2567  gnc_budget_set_account_period_value(budget, acc, 0, gnc_numeric_create(100,1));
2568  g_assert(gnc_budget_is_account_period_value_set(budget, acc, 0));
2569  val = gnc_budget_get_account_period_value(budget, acc, 0);
2570  g_assert (gnc_numeric_equal (val, gnc_numeric_create (100, 1)));
2571 
2572  /* Budget has 12 periods by default, numbered from 0 to 11. Setting
2573  * period 12 should throw an error. */
2574  oldlogger = g_log_set_default_handler ((GLogFunc)test_null_handler, &check);
2575  g_test_log_set_fatal_handler ((GTestLogFatalFunc)test_checked_handler, &check);
2576  gnc_budget_set_account_period_value(budget, acc, 12, gnc_numeric_create(100,1));
2577  g_assert_cmpint (check.hits, ==, 1);
2578  g_log_set_default_handler (oldlogger, NULL);
2579 
2580  g_object_unref(book);
2581  g_object_unref(acc);
2582  gnc_budget_destroy(budget);
2583 }
2584 
2585 void
2586 test_suite_budget(void)
2587 {
2588 
2589  GNC_TEST_ADD_FUNC(suitename, "gnc_budget_set_name()", test_gnc_set_budget_name);
2590  GNC_TEST_ADD_FUNC(suitename, "gnc_budget_set_description()", test_gnc_set_budget_description);
2591  GNC_TEST_ADD_FUNC(suitename, "gnc_budget_set_num_periods()", test_gnc_set_budget_num_periods);
2592  GNC_TEST_ADD_FUNC(suitename, "gnc_budget_set_recurrence()", test_gnc_set_budget_recurrence);
2593  GNC_TEST_ADD_FUNC(suitename, "gnc_budget_set_account_period_value()", test_gnc_set_budget_account_period_value);
2594 
2595 #if 0
2596  GNC_TEST_ADD_FUNC (suitename, "gnc set account separator", test_gnc_set_account_separator);
2597  GNC_TEST_ADD_FUNC (suitename, "gnc account name violations errmsg", test_gnc_account_name_violations_errmsg);
2598  GNC_TEST_ADD (suitename, "gnc account list name violations", Fixture, &bad_data, setup, test_gnc_account_list_name_violations, teardown);
2599  GNC_TEST_ADD_FUNC (suitename, "account create and destroy", test_gnc_account_create_and_destroy);
2600  GNC_TEST_ADD (suitename, "book set/get root account", Fixture, NULL, setup, test_gnc_book_set_get_root_account, teardown);
2601  GNC_TEST_ADD_FUNC (suitename, "xaccMallocAccount", test_xaccMallocAccount);
2602 
2603  GNC_TEST_ADD_FUNC (suitename, "gnc account create root", test_gnc_account_create_root);
2604  GNC_TEST_ADD (suitename, "xaccCloneAccount", Fixture, NULL, setup, test_xaccCloneAccount, teardown );
2605  /*Destroys the account, so we have to do the tear down in the test function */
2606  GNC_TEST_ADD (suitename, "xaccFreeAccountChildren", Fixture, &good_data, setup, test_xaccFreeAccountChildren, NULL);
2607  /* See comment at the beginning of test_xaccFreeAccount */
2608  GNC_TEST_ADD (suitename, "xaccFreeAccount", Fixture, &good_data, setup, test_xaccFreeAccount, NULL );
2609  GNC_TEST_ADD (suitename, "xaccAccountCommitEdit", Fixture, &good_data, setup, test_xaccAccountCommitEdit, NULL );
2610 // GNC_TEST_ADD (suitename, "xaccAcctChildrenEqual", Fixture, NULL, setup, test_xaccAcctChildrenEqual, teardown );
2611 // GNC_TEST_ADD (suitename, "xaccAccountEqual", Fixture, NULL, setup, test_xaccAccountEqual, teardown );
2612  GNC_TEST_ADD (suitename, "gnc account insert & remove split", Fixture, NULL, setup, test_gnc_account_insert_remove_split, teardown );
2613  GNC_TEST_ADD (suitename, "xaccAccount Insert and Remove Lot", Fixture, &good_data, setup, test_xaccAccountInsertRemoveLot, teardown );
2614  GNC_TEST_ADD (suitename, "xaccAccountRecomputeBalance", Fixture, &some_data, setup, test_xaccAccountRecomputeBalance, teardown );
2615  GNC_TEST_ADD_FUNC (suitename, "xaccAccountOrder", test_xaccAccountOrder );
2616  GNC_TEST_ADD (suitename, "qofAccountSetParent", Fixture, &some_data, setup, test_qofAccountSetParent, teardown );
2617  GNC_TEST_ADD (suitename, "gnc account append/remove child", Fixture, NULL, setup, test_gnc_account_append_remove_child, teardown );
2618  GNC_TEST_ADD (suitename, "gnc account n descendants", Fixture, &some_data, setup, test_gnc_account_n_descendants, teardown );
2619  GNC_TEST_ADD (suitename, "gnc account get current depth", Fixture, &some_data, setup, test_gnc_account_get_current_depth, teardown );
2620  GNC_TEST_ADD (suitename, "gnc account get tree depth", Fixture, &complex, setup, test_gnc_account_get_tree_depth, teardown );
2621  GNC_TEST_ADD (suitename, "gnc account get descendants", Fixture, &complex, setup, test_gnc_account_get_descendants, teardown );
2622  GNC_TEST_ADD (suitename, "gnc account get descendants sorted", Fixture, &complex, setup, test_gnc_account_get_descendants_sorted, teardown );
2623  GNC_TEST_ADD (suitename, "gnc account lookup by name", Fixture, &complex, setup, test_gnc_account_lookup_by_name, teardown );
2624  GNC_TEST_ADD (suitename, "gnc account lookup by code", Fixture, &complex, setup, test_gnc_account_lookup_by_code, teardown );
2625  GNC_TEST_ADD (suitename, "gnc account lookup by full name helper", Fixture, &complex, setup, test_gnc_account_lookup_by_full_name_helper, teardown );
2626  GNC_TEST_ADD (suitename, "gnc account lookup by full name", Fixture, &complex, setup, test_gnc_account_lookup_by_full_name, teardown );
2627  GNC_TEST_ADD (suitename, "gnc account foreach child", Fixture, &complex, setup, test_gnc_account_foreach_child, teardown );
2628  GNC_TEST_ADD (suitename, "gnc account foreach descendant", Fixture, &complex, setup, test_gnc_account_foreach_descendant, teardown );
2629  GNC_TEST_ADD (suitename, "gnc account foreach descendant until", Fixture, &complex, setup, test_gnc_account_foreach_descendant_until, teardown );
2630  GNC_TEST_ADD (suitename, "gnc account get full name", Fixture, &good_data, setup, test_gnc_account_get_full_name, teardown );
2631  GNC_TEST_ADD (suitename, "xaccAccountGetProjectedMinimumBalance", Fixture, &some_data, setup, test_xaccAccountGetProjectedMinimumBalance, teardown );
2632  GNC_TEST_ADD (suitename, "xaccAccountGetBalanceAsOfDate", Fixture, &some_data, setup, test_xaccAccountGetBalanceAsOfDate, teardown );
2633  GNC_TEST_ADD (suitename, "xaccAccountGetPresentBalance", Fixture, &some_data, setup, test_xaccAccountGetPresentBalance, teardown );
2634  GNC_TEST_ADD (suitename, "xaccAccountFindOpenLots", Fixture, &complex_data, setup, test_xaccAccountFindOpenLots, teardown );
2635  GNC_TEST_ADD (suitename, "xaccAccountForEachLot", Fixture, &complex_data, setup, test_xaccAccountForEachLot, teardown );
2636 
2637  GNC_TEST_ADD (suitename, "xaccAccountHasAncestor", Fixture, &complex, setup, test_xaccAccountHasAncestor, teardown );
2638  GNC_TEST_ADD_FUNC (suitename, "AccountType Stuff", test_xaccAccountType_Stuff );
2639  GNC_TEST_ADD_FUNC (suitename, "AccountType Compatibility", test_xaccAccountType_Compatibility);
2640  GNC_TEST_ADD (suitename, "xaccAccountFindSplitByDesc", Fixture, &complex_data, setup, test_xaccAccountFindSplitByDesc, teardown );
2641  GNC_TEST_ADD (suitename, "xaccAccountFindTransByDesc", Fixture, &complex_data, setup, test_xaccAccountFindTransByDesc, teardown );
2642  GNC_TEST_ADD (suitename, "gnc account join children", Fixture, &complex, setup, test_gnc_account_join_children, teardown );
2643  GNC_TEST_ADD (suitename, "gnc account merge children", Fixture, &complex_data, setup, test_gnc_account_merge_children, teardown );
2644  GNC_TEST_ADD (suitename, "xaccAccountForEachTransaction", Fixture, &complex_data, setup, test_xaccAccountForEachTransaction, teardown );
2645  GNC_TEST_ADD (suitename, "xaccAccountTreeForEachTransaction", Fixture, &complex_data, setup, test_xaccAccountTreeForEachTransaction, teardown );
2646 #endif
2647 
2648 }
void xaccAccountSetType(Account *acc, GNCAccountType tip)
Definition: Account.c:2208
void gnc_budget_set_num_periods(GncBudget *budget, guint num_periods)
Definition: gnc-budget.c:452
Account * gnc_account_get_parent(const Account *acc)
Definition: Account.c:2623
gint xaccAccountForEachTransaction(const Account *acc, TransactionCallback proc, void *data)
Definition: Account.c:4996
int xaccAccountTreeForEachTransaction(Account *acc, TransactionCallback proc, void *data)
Transaction * xaccMallocTransaction(QofBook *book)
Definition: Transaction.c:513
gboolean gnc_numeric_equal(gnc_numeric a, gnc_numeric b)
void gnc_budget_destroy(GncBudget *budget)
Definition: gnc-budget.c:306
Timespec gnc_budget_get_period_end_date(const GncBudget *budget, guint period_num)
Definition: gnc-budget.c:595
GList LotList
Definition: gnc-engine.h:201
void gnc_account_append_child(Account *new_parent, Account *child)
Definition: Account.c:2525
const GncGUID * qof_instance_get_guid(gconstpointer)
gpointer xaccAccountForEachLot(const Account *acc, gpointer(*proc)(GNCLot *lot, gpointer user_data), gpointer user_data)
GList * gnc_account_get_descendants_sorted(const Account *account)
Definition: Account.c:2777
gint gnc_account_n_descendants(const Account *account)
Definition: Account.c:2698
SplitList * xaccAccountGetSplitList(const Account *acc)
Definition: Account.c:3717
void gnc_account_foreach_descendant(const Account *acc, AccountCb thunk, gpointer user_data)
Definition: Account.c:2958
void xaccAccountSetNotes(Account *acc, const char *str)
Definition: Account.c:2368
gboolean xaccAccountIsPriced(const Account *acc)
Definition: Account.c:4249
QofInstance * qof_collection_lookup_entity(const QofCollection *, const GncGUID *)
GnuCash Budgets.
Account * gnc_account_create_root(QofBook *book)
Definition: Account.c:1097
GncBudget * gnc_budget_new(QofBook *book)
Definition: gnc-budget.c:289
gint kvp_frame_compare(const KvpFrame *fa, const KvpFrame *fb)
gboolean gnc_commodity_equal(const gnc_commodity *a, const gnc_commodity *b)
void xaccAccountSetCode(Account *acc, const char *str)
Definition: Account.c:2249
QofBook * qof_book_new(void)
gpointer gnc_account_foreach_descendant_until(const Account *acc, AccountCb2 thunk, gpointer user_data)
Definition: Account.c:2979
void gnc_account_set_policy(Account *acc, GNCPolicy *policy)
Definition: Account.c:1888
void gnc_lot_add_split(GNCLot *lot, Split *split)
Definition: gnc-lot.c:569
void xaccTransSetDescription(Transaction *trans, const char *desc)
Definition: Transaction.c:2085
gboolean gnc_account_remove_split(Account *acc, Split *s)
Definition: Account.c:1756
gboolean gnc_numeric_zero_p(gnc_numeric a)
const char * xaccAccountTypeEnumAsString(GNCAccountType type)
Definition: Account.c:4027
void xaccSplitSetReconcile(Split *split, char recn)
Definition: Split.c:1826
GList * gnc_account_list_name_violations(QofBook *book, const gchar *separator)
Definition: Account.c:196
void xaccAccountInsertLot(Account *acc, GNCLot *lot)
Definition: Account.c:1920
gboolean qof_commit_edit(QofInstance *inst)
void xaccAccountSetLastNum(Account *acc, const char *num)
Definition: Account.c:4481
void xaccTransSetDatePostedGDate(Transaction *trans, GDate date)
Definition: Transaction.c:1928
Definition: guid.h:65
void xaccAccountDestroy(Account *acc)
Definition: Account.c:1400
Account * gnc_account_lookup_by_name(const Account *parent, const char *name)
Definition: Account.c:2803
void gnc_account_remove_child(Account *parent, Account *child)
Definition: Account.c:2587
int xaccAccountOrder(const Account *aa, const Account *ab)
Definition: Account.c:2132
Timespec gnc_budget_get_period_start_date(const GncBudget *budget, guint period_num)
Definition: gnc-budget.c:584
Split * xaccAccountFindSplitByDesc(const Account *acc, const char *description)
Definition: Account.c:4711
GDate timespec_to_gdate(Timespec ts)
gdouble gnc_numeric_to_double(gnc_numeric n)
GNCAccountType xaccAccountStringToEnum(const char *str)
Definition: Account.c:4098
gchar * gnc_account_get_full_name(const Account *account)
Definition: Account.c:3038
gboolean xaccAccountTypesCompatible(GNCAccountType parent_type, GNCAccountType child_type)
Definition: Account.c:4194
gchar * gnc_account_name_violations_errmsg(const gchar *separator, GList *invalid_account_names)
Definition: Account.c:159
void xaccAccountSetColor(Account *acc, const char *str)
Definition: Account.c:2287
Transaction * xaccAccountFindTransByDesc(const Account *acc, const char *description)
Definition: Account.c:4726
void gnc_account_foreach_child(const Account *acc, AccountCb thunk, gpointer user_data)
Definition: Account.c:2940
#define YREC
Definition: Split.h:68
Account * gnc_account_lookup_by_code(const Account *parent, const char *code)
Definition: Account.c:2836
void xaccSplitSetMemo(Split *split, const char *memo)
Definition: Split.c:1774
#define FREC
Definition: Split.h:69
gnc_commodity * gnc_commodity_new(QofBook *book, const char *fullname, const char *name_space, const char *mnemonic, const char *cusip, int fraction)
LotList * xaccAccountGetLotList(const Account *acc)
Definition: Account.c:3744
void xaccAccountRecomputeBalance(Account *acc)
Definition: Account.c:2058
Account * gnc_account_lookup_by_full_name(const Account *any_acc, const gchar *name)
Definition: Account.c:2915
gboolean xaccAccountStringToType(const char *str, GNCAccountType *type)
Definition: Account.c:4064
Additional event handling code.
Account * xaccCloneAccount(const Account *from, QofBook *book)
Definition: Account.c:1114
void xaccTransBeginEdit(Transaction *trans)
Definition: Transaction.c:1380
void gnc_account_join_children(Account *to_parent, Account *from_parent)
Definition: Account.c:4739
gnc_numeric xaccAccountGetBalanceAsOfDate(Account *acc, time64 date)
Definition: Account.c:3288
gboolean gnc_numeric_eq(gnc_numeric a, gnc_numeric b)
#define CREC
Definition: Split.h:67
GNCAccountType
Definition: Account.h:96
Split * xaccMallocSplit(QofBook *book)
Definition: Split.c:582
void gnc_budget_set_name(GncBudget *budget, const gchar *name)
Definition: gnc-budget.c:371
gboolean gnc_account_insert_split(Account *acc, Split *s)
Definition: Account.c:1720
GList * gnc_account_get_descendants(const Account *account)
Definition: Account.c:2755
guint32 xaccParentAccountTypesCompatibleWith(GNCAccountType type)
Definition: Account.c:4147
GList * gnc_account_get_children(const Account *account)
Definition: Account.c:2654
Definition: SplitP.h:71
void xaccAccountBeginEdit(Account *acc)
Definition: Account.c:1280
gboolean xaccAccountHasAncestor(const Account *acc, const Account *ancestor)
Definition: Account.c:4004
gint qof_instance_guid_compare(const gconstpointer ptr1, const gconstpointer ptr2)
gint gnc_account_get_current_depth(const Account *account)
Definition: Account.c:2715
void gnc_budget_set_description(GncBudget *budget, const gchar *description)
Definition: gnc-budget.c:396
Account * xaccMallocAccount(QofBook *book)
Definition: Account.c:1083
time64 gnc_time(time64 *tbuf)
get the current local time
QofCollection * qof_book_get_collection(const QofBook *, QofIdType)
Account * gnc_lot_get_account(const GNCLot *lot)
Definition: gnc-lot.c:386
void xaccAccountSetDescription(Account *acc, const char *str)
Definition: Account.c:2268
LotList * xaccAccountFindOpenLots(const Account *acc, gboolean(*match_func)(GNCLot *lot, gpointer user_data), gpointer user_data, GCompareFunc sort_func)
Definition: Account.c:3751
Account * gnc_account_get_root(Account *acc)
Definition: Account.c:2630
const char * xaccAccountGetTypeStr(GNCAccountType type)
Definition: Account.c:4137
#define GNC_EVENT_ITEM_ADDED
Definition: gnc-event.h:45
void xaccAccountCommitEdit(Account *acc)
Definition: Account.c:1321
void xaccAccountSetName(Account *acc, const char *str)
Definition: Account.c:2229
void gnc_account_merge_children(Account *parent)
Definition: Account.c:4764
void qof_book_destroy(QofBook *book)
void gnc_gdate_set_time64(GDate *gd, time64 time)
void xaccAccountSetCommodity(Account *acc, gnc_commodity *com)
Definition: Account.c:2389
#define NREC
Definition: Split.h:70
gint gnc_account_get_tree_depth(const Account *account)
Definition: Account.c:2734
GNCPolicy * xaccGetFIFOPolicy(void)
Definition: policy.c:178