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