Files
gnucash/libgnucash/backend/xml/test/test-xml-account.cpp
John Ralls 8ff5af4c19 Decouple QofBook creation from QofSession.
So that we don't create two books when loading a session.
Step 1 to not having a dirty book when we think we should have no
book at all.
2020-05-08 15:59:41 -07:00

410 lines
11 KiB
C++

/***************************************************************************
* test-xml-account.c
*
* Sun Oct 9 15:37:26 2005
* Copyright 2005 Neil Williams
* linux@codehelp.co.uk
****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
extern "C"
{
#include <config.h>
#include <glib.h>
#include <glib/gstdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <gnc-engine.h>
#include <cashobjects.h>
#include <test-engine-stuff.h>
#include <unittest-support.h>
#include "Account.h"
#include "Scrub.h"
}
#include "../gnc-xml-helper.h"
#include "../gnc-xml.h"
#include "../sixtp-parsers.h"
#include "../sixtp-dom-parsers.h"
#include "test-file-stuff.h"
#include <test-stuff.h>
static QofBook* sixbook;
static gchar*
node_and_account_equal (xmlNodePtr node, Account* act)
{
xmlNodePtr mark;
while (g_strcmp0 ((char*)node->name, "text") == 0)
{
node = node->next;
}
if (!check_dom_tree_version (node, "2.0.0"))
{
return g_strdup ("version wrong. Not 2.0.0 or not there");
}
if (!node->name || g_strcmp0 ((char*)node->name, "gnc:account"))
{
return g_strdup ("Name of toplevel node is bad");
}
for (mark = node->xmlChildrenNode; mark; mark = mark->next)
{
if (g_strcmp0 ((char*)mark->name, "text") == 0)
{
}
else if (g_strcmp0 ((char*)mark->name, "act:name") == 0)
{
if (!equals_node_val_vs_string (mark, xaccAccountGetName (act)))
{
return g_strdup ("names differ");
}
}
else if (g_strcmp0 ((char*)mark->name, "act:id") == 0)
{
if (!equals_node_val_vs_guid (mark, xaccAccountGetGUID (act)))
{
return g_strdup ("ids differ");
}
}
else if (g_strcmp0 ((char*)mark->name, "act:type") == 0)
{
gchar* txt;
GNCAccountType type;
txt = dom_tree_to_text (mark);
if (!txt)
{
return g_strdup ("couldn't get type string");
}
else if (!xaccAccountStringToType (txt, &type))
{
g_free (txt);
return g_strdup ("couldn't convert type string to int");
}
else if (type != xaccAccountGetType (act))
{
g_free (txt);
return g_strdup ("types differ");
}
else
{
g_free (txt);
}
}
else if (g_strcmp0 ((char*)mark->name, "act:commodity") == 0)
{
/* This is somewhat BS, because if the commodity isn't a
currency (and therefore built in) there isn't a
corresponding currency in the XML, skip the test. jralls
2010-11-02 */
if (xaccAccountGetCommodity (act) == NULL) continue;
if (!equals_node_val_vs_commodity (
mark, xaccAccountGetCommodity (act),
gnc_account_get_book (act)))
{
return g_strdup ("commodities differ");
}
}
else if (g_strcmp0 ((char*)mark->name, "act:code") == 0)
{
if (!equals_node_val_vs_string (mark, xaccAccountGetCode (act)))
{
return g_strdup ("codes differ");
}
}
else if (g_strcmp0 ((char*)mark->name, "act:description") == 0)
{
if (!equals_node_val_vs_string (
mark, xaccAccountGetDescription (act)))
{
return g_strdup ("descriptions differ");
}
}
else if (g_strcmp0 ((char*)mark->name, "act:slots") == 0)
{
/* xaccAccountDeleteOldData (act); */
if (!equals_node_val_vs_kvp_frame (mark,
qof_instance_get_slots (QOF_INSTANCE (act))))
{
return g_strdup ("slots differ");
}
}
else if (g_strcmp0 ((char*)mark->name, "act:parent") == 0)
{
if (!equals_node_val_vs_guid (
mark, xaccAccountGetGUID (gnc_account_get_parent (act))))
{
return g_strdup ("parent ids differ");
}
}
else if (g_strcmp0 ((char*)mark->name, "act:commodity-scu") == 0)
{
if (!equals_node_val_vs_int (mark, xaccAccountGetCommoditySCU (act)))
{
return g_strdup ("commodity scus differ");
}
}
else if (g_strcmp0 ((char*)mark->name, "act:hidden") == 0)
{
if (!equals_node_val_vs_boolean (mark, xaccAccountGetHidden (act)))
{
return g_strdup ("Hidden flags differ");
}
}
else if (g_strcmp0 ((char*)mark->name, "act:placeholder") == 0)
{
if (!equals_node_val_vs_boolean (mark, xaccAccountGetPlaceholder (act)))
{
return g_strdup ("Placeholder flags differ");
}
}
else if (g_strcmp0 ((char*)mark->name, "act:security") == 0)
{
return NULL; // This tag is ignored.
}
else
{
return g_strdup_printf ("unknown node in dom tree: %s", mark->name);
}
}
return NULL;
}
static void
delete_random_account (Account* act)
{
xaccAccountBeginEdit (act);
xaccAccountDestroy (act);
}
struct act_data_struct
{
Account* act;
int value;
};
typedef struct act_data_struct act_data;
static gboolean
test_add_account (const char* tag, gpointer globaldata, gpointer data)
{
Account* account = static_cast<decltype (account)> (data);
act_data* gdata = (act_data*)globaldata;
gnc_commodity* com;
gnc_commodity* new_com;
gnc_commodity_table* t;
com = xaccAccountGetCommodity (account);
t = gnc_commodity_table_get_table (sixbook);
new_com = gnc_commodity_table_lookup (t,
gnc_commodity_get_namespace (com),
gnc_commodity_get_mnemonic (com));
if (new_com)
{
xaccAccountSetCommodity (account, new_com);
}
do_test_args (xaccAccountEqual ((Account*)account, (Account*) (gdata->act),
TRUE),
"gnc_account_sixtp_parser_create",
__FILE__, __LINE__, "%d", gdata->value);
return TRUE;
}
static void
test_account (int i, Account* test_act)
{
xmlNodePtr test_node;
gchar* filename1;
gchar* compare_msg;
int fd;
test_node = gnc_account_dom_tree_create (test_act, FALSE, TRUE);
if (!test_node)
{
failure_args ("account_xml", __FILE__, __LINE__,
"gnc_account_dom_tree_create returned NULL");
return;
}
if ((compare_msg = node_and_account_equal (test_node, test_act)) != NULL)
{
failure_args ("account_xml", __FILE__, __LINE__,
"node and account were not equal: %s", compare_msg);
xmlElemDump (stdout, NULL, test_node);
fprintf (stdout, "\n");
xmlFreeNode (test_node);
g_free (compare_msg);
return;
}
else
{
success ("account_xml");
}
filename1 = g_strdup_printf ("test_file_XXXXXX");
fd = g_mkstemp (filename1);
write_dom_node_to_file (test_node, fd);
close (fd);
{
sixtp* parser;
act_data data;
data.act = test_act;
data.value = i;
parser = gnc_account_sixtp_parser_create ();
if (!gnc_xml_parse_file (parser, filename1, test_add_account,
&data, sixbook))
{
failure_args ("gnc_xml_parse_file returned FALSE",
__FILE__, __LINE__, "%d", i);
}
/* no handling of circular data structures. We'll do that later */
/* sixtp_destroy(parser); */
}
g_unlink (filename1);
g_free (filename1);
xmlFreeNode (test_node);
}
static void
test_generation ()
{
int i;
for (i = 0; i < 20; i++)
{
Account* ran_act;
ran_act = get_random_account (sixbook);
test_account (i, ran_act);
delete_random_account (ran_act);
}
{
/* empty some things. */
Account* act;
const char* msg =
"xaccAccountSetCommodity: assertion `GNC_IS_COMMODITY(com)' failed";
const char* logdomain = "gnc.engine";
GLogLevelFlags loglevel = static_cast<decltype (loglevel)>
(G_LOG_LEVEL_CRITICAL);
TestErrorStruct check = { loglevel, const_cast<char*> (logdomain),
const_cast<char*> (msg)
};
g_log_set_handler (logdomain, loglevel,
(GLogFunc)test_checked_handler, &check);
act = get_random_account (sixbook);
xaccAccountSetCode (act, "");
xaccAccountSetDescription (act, "");
xaccAccountSetCommodity (act, NULL);
test_account (-1, act);
delete_random_account (act);
}
/* { */
/* Account *act1; */
/* Account *act2; */
/* act1 = get_random_account(); */
/* act2 = get_random_account(); */
/* gnc_account_append_child(act1, act2); */
/* test_account(-1, act2); */
/* test_account(-1, act1); */
/* delete_random_account(act2); */
/* delete_random_account(act1); */
/* } */
}
static gboolean
test_real_account (const char* tag, gpointer global_data, gpointer data)
{
char* msg;
Account* act = (Account*)data;
if (!gnc_account_get_parent (act))
{
gnc_account_append_child (gnc_book_get_root_account (sixbook), act);
}
msg = node_and_account_equal ((xmlNodePtr)global_data, act);
do_test_args (msg == NULL, "test_real_account",
__FILE__, __LINE__, msg);
g_free (msg);
return TRUE;
}
int
main (int argc, char** argv)
{
qof_init ();
cashobjects_register ();
sixbook = qof_book_new ();
auto session = qof_session_new (sixbook);
if (argc > 1)
{
test_files_in_dir (argc, argv, test_real_account,
gnc_account_sixtp_parser_create (),
"gnc:account", sixbook);
}
else
{
test_generation ();
}
qof_session_destroy (session);
print_test_results ();
qof_close ();
exit (get_rv ());
}