GnuCash 2.4.99
test-xml-account.c
00001 /***************************************************************************
00002  *            test-xml-account.c
00003  *
00004  *  Sun Oct  9 15:37:26 2005
00005  *  Copyright  2005  Neil Williams
00006  *  linux@codehelp.co.uk
00007  ****************************************************************************/
00008 /*
00009  *  This program is free software; you can redistribute it and/or modify
00010  *  it under the terms of the GNU General Public License as published by
00011  *  the Free Software Foundation; either version 2 of the License, or
00012  *  (at your option) any later version.
00013  *
00014  *  This program is distributed in the hope that it will be useful,
00015  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  *  GNU General Public License for more details.
00018  *
00019  *  You should have received a copy of the GNU General Public License
00020  *  along with this program; if not, write to the Free Software
00021  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00022  *  02110-1301, USA.
00023  */
00024 
00025 #include "config.h"
00026 
00027 #include <glib.h>
00028 #include <glib/gstdio.h>
00029 #include <stdlib.h>
00030 #include <unistd.h>
00031 
00032 #include "../gnc-xml-helper.h"
00033 #include "../gnc-xml.h"
00034 #include <gnc-engine.h>
00035 #include <cashobjects.h>
00036 #include "../sixtp-parsers.h"
00037 #include "../sixtp-dom-parsers.h"
00038 
00039 #include <test-stuff.h>
00040 #include <test-engine-stuff.h>
00041 #include <test-file-stuff.h>
00042 #include <unittest-support.h>
00043 
00044 #include "Account.h"
00045 #include "Scrub.h"
00046 
00047 #define GNC_V2_STRING "gnc-v2"
00048 const gchar *gnc_v2_xml_version_string = GNC_V2_STRING;
00049 
00050 static QofBook *sixbook;
00051 
00052 static gchar*
00053 node_and_account_equal(xmlNodePtr node, Account *act)
00054 {
00055     xmlNodePtr mark;
00056 
00057     while (safe_strcmp ((char*)node->name, "text") == 0)
00058     {
00059         node = node->next;
00060     }
00061 
00062     if (!check_dom_tree_version(node, "2.0.0"))
00063     {
00064         return g_strdup("version wrong.  Not 2.0.0 or not there");
00065     }
00066 
00067     if (!node->name || safe_strcmp((char*)node->name, "gnc:account"))
00068     {
00069         return g_strdup("Name of toplevel node is bad");
00070     }
00071 
00072     for (mark = node->xmlChildrenNode; mark; mark = mark->next)
00073     {
00074         if (safe_strcmp((char*)mark->name, "text") == 0)
00075         {
00076         }
00077         else if (safe_strcmp((char*)mark->name, "act:name") == 0)
00078         {
00079             if (!equals_node_val_vs_string(mark, xaccAccountGetName(act)))
00080             {
00081                 return g_strdup("names differ");
00082             }
00083         }
00084         else if (safe_strcmp((char*)mark->name, "act:id") == 0)
00085         {
00086             if (!equals_node_val_vs_guid(mark, xaccAccountGetGUID(act)))
00087             {
00088                 return g_strdup("ids differ");
00089             }
00090         }
00091         else if (safe_strcmp((char*)mark->name, "act:type") == 0)
00092         {
00093             gchar *txt;
00094             int type;
00095 
00096             txt = dom_tree_to_text(mark);
00097 
00098             if (!txt)
00099             {
00100                 return g_strdup("couldn't get type string");
00101             }
00102             else if (!xaccAccountStringToType(txt, &type))
00103             {
00104                 g_free(txt);
00105                 return g_strdup("couldn't convert type string to int");
00106             }
00107             else if (type != xaccAccountGetType(act))
00108             {
00109                 g_free(txt);
00110                 return g_strdup("types differ");
00111             }
00112             else
00113             {
00114                 g_free(txt);
00115             }
00116         }
00117         else if (safe_strcmp((char*)mark->name, "act:commodity") == 0)
00118         {
00119             /* This is somewhat BS, because if the commodity isn't a
00120                currency (and therefore built in) there isn't a
00121                corresponding currency in the XML, skip the test. jralls
00122                2010-11-02 */
00123             if (xaccAccountGetCommodity(act) == NULL) continue;
00124             if (!equals_node_val_vs_commodity(
00125                         mark, xaccAccountGetCommodity(act),
00126                         gnc_account_get_book(act)))
00127             {
00128                 return g_strdup("commodities differ");
00129             }
00130         }
00131         else if (safe_strcmp((char*)mark->name, "act:code") == 0)
00132         {
00133             if (!equals_node_val_vs_string(mark, xaccAccountGetCode(act)))
00134             {
00135                 return g_strdup("codes differ");
00136             }
00137         }
00138         else if (safe_strcmp((char*)mark->name, "act:description") == 0)
00139         {
00140             if (!equals_node_val_vs_string(
00141                         mark, xaccAccountGetDescription(act)))
00142             {
00143                 return g_strdup("descriptions differ");
00144             }
00145         }
00146         else if (safe_strcmp((char*)mark->name, "act:slots") == 0)
00147         {
00148             /* xaccAccountDeleteOldData (act); */
00149 
00150             if (!equals_node_val_vs_kvp_frame(mark, xaccAccountGetSlots(act)))
00151             {
00152                 return g_strdup("slots differ");
00153             }
00154         }
00155         else if (safe_strcmp((char*)mark->name, "act:parent") == 0)
00156         {
00157             if (!equals_node_val_vs_guid(
00158                         mark, xaccAccountGetGUID(gnc_account_get_parent(act))))
00159             {
00160                 return g_strdup("parent ids differ");
00161             }
00162         }
00163         else if (safe_strcmp((char*)mark->name, "act:commodity-scu") == 0)
00164         {
00165             if (!equals_node_val_vs_int(mark, xaccAccountGetCommoditySCU(act)))
00166             {
00167                 return g_strdup("commodity scus differ");
00168             }
00169         }
00170         else if (safe_strcmp((char*)mark->name, "act:hidden") == 0)
00171         {
00172             if (!equals_node_val_vs_boolean(mark, xaccAccountGetHidden(act)))
00173             {
00174                 return g_strdup("Hidden flags differ");
00175             }
00176         }
00177         else if (safe_strcmp((char*)mark->name, "act:placeholder") == 0)
00178         {
00179             if (!equals_node_val_vs_boolean(mark, xaccAccountGetPlaceholder(act)))
00180             {
00181                 return g_strdup("Placeholder flags differ");
00182             }
00183         }
00184         else if (safe_strcmp((char*)mark->name, "act:security") == 0)
00185         {
00186             return NULL; // This tag is ignored.
00187         }
00188         else
00189         {
00190             return g_strdup_printf("unknown node in dom tree: %s", mark->name);
00191         }
00192     }
00193 
00194     return NULL;
00195 }
00196 
00197 static void
00198 delete_random_account(Account *act)
00199 {
00200     xaccAccountBeginEdit(act);
00201     xaccAccountDestroy(act);
00202 }
00203 
00204 struct act_data_struct
00205 {
00206     Account *act;
00207     int value;
00208 };
00209 typedef struct act_data_struct act_data;
00210 
00211 static gboolean
00212 test_add_account(const char *tag, gpointer globaldata, gpointer data)
00213 {
00214     Account *account = data;
00215     act_data *gdata = (act_data*)globaldata;
00216     gnc_commodity * com;
00217     gnc_commodity * new_com;
00218     gnc_commodity_table *t;
00219 
00220     com = xaccAccountGetCommodity (account);
00221 
00222     t = gnc_commodity_table_get_table (sixbook);
00223 
00224     new_com = gnc_commodity_table_lookup (t,
00225                                           gnc_commodity_get_namespace (com),
00226                                           gnc_commodity_get_mnemonic (com));
00227 
00228     if (new_com)
00229     {
00230         xaccAccountSetCommodity (account, new_com);
00231     }
00232 
00233     do_test_args(xaccAccountEqual((Account*)account, (Account*)(gdata->act),
00234                                   TRUE),
00235                  "gnc_account_sixtp_parser_create",
00236                  __FILE__, __LINE__, "%d", gdata->value );
00237 
00238     return TRUE;
00239 }
00240 
00241 static void
00242 test_account(int i, Account *test_act)
00243 {
00244     xmlNodePtr test_node;
00245     gchar *filename1;
00246     gchar *compare_msg;
00247     int fd;
00248 
00249     test_node = gnc_account_dom_tree_create(test_act, FALSE, TRUE);
00250 
00251     if (!test_node)
00252     {
00253         failure_args("account_xml", __FILE__, __LINE__,
00254                      "gnc_account_dom_tree_create returned NULL");
00255         return;
00256     }
00257 
00258     if ((compare_msg = node_and_account_equal(test_node, test_act)) != NULL)
00259     {
00260         failure_args("account_xml", __FILE__, __LINE__,
00261                      "node and account were not equal: %s", compare_msg);
00262         xmlElemDump(stdout, NULL, test_node);
00263         fprintf(stdout, "\n");
00264         xmlFreeNode(test_node);
00265         g_free(compare_msg);
00266         return;
00267     }
00268     else
00269     {
00270         success("account_xml");
00271     }
00272 
00273     filename1 = g_strdup_printf("test_file_XXXXXX");
00274 
00275     fd = g_mkstemp(filename1);
00276 
00277     write_dom_node_to_file(test_node, fd);
00278 
00279     close(fd);
00280 
00281     {
00282         sixtp *parser;
00283         act_data data;
00284 
00285         data.act = test_act;
00286         data.value = i;
00287 
00288         parser = gnc_account_sixtp_parser_create();
00289 
00290         if (!gnc_xml_parse_file(parser, filename1, test_add_account,
00291                                 &data, sixbook))
00292         {
00293             failure_args("gnc_xml_parse_file returned FALSE",
00294                          __FILE__, __LINE__, "%d", i);
00295         }
00296 
00297         /* no handling of circular data structures.  We'll do that later */
00298         /* sixtp_destroy(parser); */
00299     }
00300 
00301 
00302     g_unlink(filename1);
00303     g_free(filename1);
00304     xmlFreeNode(test_node);
00305 }
00306 
00307 static void
00308 test_generation()
00309 {
00310     int i;
00311 
00312     for (i = 0; i < 20; i++)
00313     {
00314         Account *ran_act;
00315 
00316         ran_act = get_random_account(sixbook);
00317 
00318         test_account(i, ran_act);
00319 
00320         delete_random_account(ran_act);
00321     }
00322 
00323     {
00324         /* empty some things. */
00325         Account *act;
00326         gchar *msg = "xaccAccountSetCommodity: assertion `GNC_IS_COMMODITY(com)' failed";
00327         gchar *logdomain = "gnc.engine";
00328         guint loglevel = G_LOG_LEVEL_CRITICAL;
00329         TestErrorStruct check = { loglevel, logdomain, msg };
00330         g_log_set_handler (logdomain, loglevel,
00331                            (GLogFunc)test_checked_handler, &check);
00332 
00333         act = get_random_account(sixbook);
00334 
00335         xaccAccountSetCode(act, "");
00336         xaccAccountSetDescription(act, "");
00337 
00338         xaccAccountSetCommodity(act, NULL);
00339 
00340         test_account(-1, act);
00341 
00342         delete_random_account(act);
00343     }
00344 
00345     /*     { */
00346     /*         Account *act1; */
00347     /*         Account *act2; */
00348 
00349     /*         act1 = get_random_account(); */
00350     /*         act2 = get_random_account(); */
00351 
00352     /*         gnc_account_append_child(act1, act2); */
00353 
00354     /*         test_account(-1, act2); */
00355     /*         test_account(-1, act1); */
00356 
00357     /*         delete_random_account(act2); */
00358     /*         delete_random_account(act1); */
00359     /*     } */
00360 
00361 }
00362 
00363 static gboolean
00364 test_real_account(const char *tag, gpointer global_data, gpointer data)
00365 {
00366     char *msg;
00367     Account *act = (Account*)data;
00368 
00369     if (!gnc_account_get_parent(act))
00370     {
00371         gnc_account_append_child(gnc_book_get_root_account(sixbook), act);
00372     }
00373 
00374     msg = node_and_account_equal((xmlNodePtr)global_data, act);
00375     do_test_args(msg == NULL, "test_real_account",
00376                  __FILE__, __LINE__, msg);
00377 
00378     g_free(msg);
00379     return TRUE;
00380 }
00381 
00382 int
00383 main (int argc, char ** argv)
00384 {
00385     QofSession *session;
00386 
00387     qof_init();
00388     cashobjects_register();
00389     session = qof_session_new();
00390     sixbook = qof_session_get_book (session);
00391     if (argc > 1)
00392     {
00393         test_files_in_dir(argc, argv, test_real_account,
00394                           gnc_account_sixtp_parser_create(),
00395                           "gnc:account", sixbook);
00396     }
00397     else
00398     {
00399         test_generation();
00400     }
00401 
00402     qof_session_destroy(session);
00403     print_test_results();
00404     qof_close();
00405     exit(get_rv());
00406 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines