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