r18958 - gnucash/trunk/src/backend/dbi/test - Update dbi tests - more object types are now saved and loaded
Phil Longstaff
plongstaff at code.gnucash.org
Tue Mar 23 17:43:05 EDT 2010
Author: plongstaff
Date: 2010-03-23 17:43:05 -0400 (Tue, 23 Mar 2010)
New Revision: 18958
Trac: http://svn.gnucash.org/trac/changeset/18958
Modified:
gnucash/trunk/src/backend/dbi/test/test-dbi-basic.c
gnucash/trunk/src/backend/dbi/test/test-dbi-stuff.c
gnucash/trunk/src/backend/dbi/test/test-dbi.c
Log:
Update dbi tests - more object types are now saved and loaded
Modified: gnucash/trunk/src/backend/dbi/test/test-dbi-basic.c
===================================================================
--- gnucash/trunk/src/backend/dbi/test/test-dbi-basic.c 2010-03-23 18:34:17 UTC (rev 18957)
+++ gnucash/trunk/src/backend/dbi/test/test-dbi-basic.c 2010-03-23 21:43:05 UTC (rev 18958)
@@ -31,6 +31,7 @@
#include "test-dbi-stuff.h"
#include "Account.h"
+#include "Transaction.h"
#include "Split.h"
#include "gnc-commodity.h"
@@ -43,16 +44,26 @@
QofSession* session = qof_session_new();
QofBook* book = qof_session_get_book( session );
Account* root = gnc_book_get_root_account( book );
- Account* a;
+ Account* acct1;
+ Account* acct2;
KvpFrame* frame;
+ Transaction* tx;
+ Split* spl1;
+ Split* spl2;
Timespec ts;
struct timeval tv;
+ gnc_commodity_table* table;
+ gnc_commodity* currency;
+
+ table = gnc_commodity_table_get_table( book );
+ currency = gnc_commodity_table_lookup( table, GNC_COMMODITY_NS_CURRENCY, "CAD" );
- a = xaccMallocAccount( book );
- xaccAccountSetType( a, ACCT_TYPE_BANK );
- xaccAccountSetName( a, "Bank" );
+ acct1 = xaccMallocAccount( book );
+ xaccAccountSetType( acct1, ACCT_TYPE_BANK );
+ xaccAccountSetName( acct1, "Bank 1" );
+ xaccAccountSetCommodity( acct1, currency );
- frame = qof_instance_get_slots( QOF_INSTANCE(a) );
+ frame = qof_instance_get_slots( QOF_INSTANCE(acct1) );
kvp_frame_set_gint64( frame, "int64-val", 100 );
kvp_frame_set_double( frame, "double-val", 3.14159 );
kvp_frame_set_numeric( frame, "numeric-val", gnc_numeric_zero() );
@@ -64,10 +75,24 @@
kvp_frame_set_timespec( frame, "timespec-val", ts );
kvp_frame_set_string( frame, "string-val", "abcdefghijklmnop" );
- kvp_frame_set_guid( frame, "guid-val", qof_instance_get_guid( QOF_INSTANCE(a) ) );
+ kvp_frame_set_guid( frame, "guid-val", qof_instance_get_guid( QOF_INSTANCE(acct1) ) );
- gnc_account_append_child( root, a );
+ gnc_account_append_child( root, acct1 );
+ acct2 = xaccMallocAccount( book );
+ xaccAccountSetType( acct2, ACCT_TYPE_BANK );
+ xaccAccountSetName( acct2, "Bank 1" );
+
+ tx = xaccMallocTransaction( book );
+ xaccTransBeginEdit( tx );
+ xaccTransSetCurrency( tx, currency );
+ spl1 = xaccMallocSplit( book );
+ xaccTransAppendSplit( tx, spl1 );
+ spl2 = xaccMallocSplit( book );
+ xaccTransAppendSplit( tx, spl2 );
+ xaccTransCommitEdit( tx );
+
+
return session;
}
@@ -85,6 +110,7 @@
filename = tempnam( "/tmp", "test-sqlite3-" );
printf( "Using filename: %s\n", filename );
test_dbi_store_and_reload( "sqlite3", session_1, filename );
+ #if 0
printf( "TEST_MYSQL_URL='%s'\n", TEST_MYSQL_URL );
if ( strlen( TEST_MYSQL_URL ) > 0 )
{
@@ -97,6 +123,7 @@
session_1 = create_session();
test_dbi_store_and_reload( "pgsql", session_1, TEST_PGSQL_URL );
}
+ #endif
print_test_results();
qof_close();
exit(get_rv());
Modified: gnucash/trunk/src/backend/dbi/test/test-dbi-stuff.c
===================================================================
--- gnucash/trunk/src/backend/dbi/test/test-dbi-stuff.c 2010-03-23 18:34:17 UTC (rev 18957)
+++ gnucash/trunk/src/backend/dbi/test/test-dbi-stuff.c 2010-03-23 21:43:05 UTC (rev 18958)
@@ -32,12 +32,341 @@
#include "Account.h"
#include "Split.h"
+#include "Transaction.h"
#include "gnc-commodity.h"
static gboolean testAccountEqual(const Account *aa, const Account *ab, gboolean check_guids);
static QofLogModule log_module = "test-dbi";
+static gboolean testTransEqual(const Transaction *ta, const Transaction *tb,
+ gboolean check_guids, gboolean check_splits,
+ gboolean check_balances, gboolean assume_ordered);
+static gboolean test_commodity_equal(const gnc_commodity * a, const gnc_commodity * b);
+
+/*
+ * Helper routine for testSplitEqual.
+ */
static gboolean
+testSplitEqualCheckBal (const char *tag, gnc_numeric a, gnc_numeric b)
+{
+ char *str_a, *str_b;
+
+ if (gnc_numeric_equal (a, b))
+ return TRUE;
+
+ str_a = gnc_numeric_to_string (a);
+ str_b = gnc_numeric_to_string (b);
+
+ PWARN ("%sbalances differ: %s vs %s", tag, str_a, str_b);
+
+ g_free (str_a);
+ g_free (str_b);
+
+ return FALSE;
+}
+
+static gboolean
+testSplitEqual(const Split *sa, const Split *sb,
+ gboolean check_guids,
+ gboolean check_balances,
+ gboolean check_txn_splits)
+{
+ Timespec ts1, ts2;
+
+ if (!sa && !sb) return TRUE; /* Arguable. FALSE is better, methinks */
+
+ if (!sa || !sb)
+ {
+ PWARN ("one is NULL");
+ return FALSE;
+ }
+
+ if (sa == sb) return TRUE;
+
+ if (check_guids)
+ {
+ if (qof_instance_guid_compare(sa, sb) != 0)
+ {
+ PWARN ("GUIDs differ");
+ return FALSE;
+ }
+ }
+
+ /* Since these strings are cached we can just use pointer equality */
+ if (strcmp(xaccSplitGetMemo(sa), xaccSplitGetMemo(sb)) != 0)
+ {
+ const gchar* memo_a = xaccSplitGetMemo(sa);
+ const gchar* memo_b = xaccSplitGetMemo(sb);
+
+ PWARN ("memos differ: (%p)%s vs (%p)%s",
+ memo_a, memo_a, memo_b, memo_b);
+ return FALSE;
+ }
+
+ if (strcmp(xaccSplitGetAction(sa), xaccSplitGetAction(sb)) != 0)
+ {
+ PWARN ("actions differ: %s vs %s", xaccSplitGetAction(sa), xaccSplitGetAction(sb));
+ return FALSE;
+ }
+
+ if (kvp_frame_compare(qof_instance_get_slots(QOF_INSTANCE(sa)), qof_instance_get_slots(QOF_INSTANCE(sb))) != 0)
+ {
+ char *frame_a;
+ char *frame_b;
+
+ frame_a = kvp_frame_to_string (qof_instance_get_slots(QOF_INSTANCE(sa)));
+ frame_b = kvp_frame_to_string (qof_instance_get_slots(QOF_INSTANCE(sb)));
+
+ PWARN ("kvp frames differ:\n%s\n\nvs\n\n%s", frame_a, frame_b);
+
+ g_free (frame_a);
+ g_free (frame_b);
+
+ return FALSE;
+ }
+
+ if (xaccSplitGetReconcile(sa) != xaccSplitGetReconcile(sb))
+ {
+ PWARN ("reconcile flags differ: %c vs %c", xaccSplitGetReconcile(sa), xaccSplitGetReconcile(sb));
+ return FALSE;
+ }
+
+ ts1 = xaccSplitRetDateReconciledTS(sa);
+ ts2 = xaccSplitRetDateReconciledTS(sb);
+ if (timespec_cmp(&ts1, &ts2))
+ {
+ PWARN ("reconciled date differs");
+ return FALSE;
+ }
+
+ if (!gnc_numeric_eq(xaccSplitGetAmount (sa), xaccSplitGetAmount (sb)))
+ {
+ char *str_a;
+ char *str_b;
+
+ str_a = gnc_numeric_to_string (xaccSplitGetAmount (sa));
+ str_b = gnc_numeric_to_string (xaccSplitGetAmount (sb));
+
+ PWARN ("amounts differ: %s vs %s", str_a, str_b);
+
+ g_free (str_a);
+ g_free (str_b);
+
+ return FALSE;
+ }
+
+ if (!gnc_numeric_eq(xaccSplitGetValue (sa), xaccSplitGetValue (sb)))
+ {
+ char *str_a;
+ char *str_b;
+
+ str_a = gnc_numeric_to_string (xaccSplitGetValue (sa));
+ str_b = gnc_numeric_to_string (xaccSplitGetValue (sb));
+
+ PWARN ("values differ: %s vs %s", str_a, str_b);
+
+ g_free (str_a);
+ g_free (str_b);
+
+ return FALSE;
+ }
+
+ if (check_balances)
+ {
+ gnc_numeric bal1, bal2;
+
+ bal1 = xaccSplitGetBalance(sa);
+ bal2 = xaccSplitGetBalance(sb);
+ if (!testSplitEqualCheckBal ("", bal1, bal2))
+ return FALSE;
+ bal1 = xaccSplitGetClearedBalance(sa);
+ bal2 = xaccSplitGetClearedBalance(sb);
+ if (!testSplitEqualCheckBal ("cleared ", bal1, bal2))
+ return FALSE;
+ bal1 = xaccSplitGetReconciledBalance(sa);
+ bal2 = xaccSplitGetReconciledBalance(sb);
+ if (!testSplitEqualCheckBal ("reconciled ", bal1, bal2))
+ return FALSE;
+ }
+
+ if (!testTransEqual(xaccSplitGetParent(sa), xaccSplitGetParent(sb), check_guids, check_txn_splits,
+ check_balances, FALSE))
+ {
+ PWARN ("transactions differ");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static gint
+compare_split_guids (gconstpointer a, gconstpointer b)
+{
+ const Split *sa = a;
+ const Split *sb = b;
+
+ if (sa == sb) return 0;
+ if (!sa || !sb) return 1;
+
+ return guid_compare (xaccSplitGetGUID (sa), xaccSplitGetGUID (sb));
+}
+
+static gboolean
+testTransEqual(const Transaction *ta, const Transaction *tb,
+ gboolean check_guids,
+ gboolean check_splits,
+ gboolean check_balances,
+ gboolean assume_ordered)
+{
+ Timespec ts1, ts2;
+
+ if (!ta && !tb) return TRUE; /* Arguable. FALSE may be better. */
+
+ if (!ta || !tb)
+ {
+ PWARN ("one is NULL");
+ return FALSE;
+ }
+
+ if (ta == tb) return TRUE;
+
+ if (check_guids)
+ {
+ if (qof_instance_guid_compare(ta, tb) != 0)
+ {
+ PWARN ("GUIDs differ");
+ return FALSE;
+ }
+ }
+
+ if (!test_commodity_equal(xaccTransGetCurrency(ta), xaccTransGetCurrency(tb)))
+ {
+ PWARN ("commodities differ %s vs %s",
+ gnc_commodity_get_unique_name (xaccTransGetCurrency(ta)),
+ gnc_commodity_get_unique_name (xaccTransGetCurrency(tb)));
+ return FALSE;
+ }
+
+ ts1 = xaccTransRetDateEnteredTS(ta);
+ ts2 = xaccTransRetDateEnteredTS(tb);
+ ts1.tv_nsec = ts2.tv_nsec = 0;
+ if (timespec_cmp(&ts1, &ts2))
+ {
+ char buf1[100];
+ char buf2[100];
+
+ (void)gnc_timespec_to_iso8601_buff(ts1, buf1);
+ (void)gnc_timespec_to_iso8601_buff(ts2, buf2);
+ PWARN ("date entered differs: '%s' vs '%s'", buf1, buf2);
+ return FALSE;
+ }
+
+ ts1 = xaccTransRetDatePostedTS(ta);
+ ts2 = xaccTransRetDatePostedTS(tb);
+ ts1.tv_nsec = ts2.tv_nsec = 0;
+ if (timespec_cmp(&ts1, &ts2))
+ {
+ char buf1[100];
+ char buf2[100];
+
+ (void)gnc_timespec_to_iso8601_buff(ts1, buf1);
+ (void)gnc_timespec_to_iso8601_buff(ts2, buf2);
+ PWARN ("date posted differs: '%s' vs '%s'", buf1, buf2);
+ return FALSE;
+ }
+
+ if (strcmp(xaccTransGetNum(ta), xaccTransGetNum(tb)) != 0)
+ {
+ PWARN ("num differs: %s vs %s", xaccTransGetNum(ta), xaccTransGetNum(tb));
+ return FALSE;
+ }
+
+ if (strcmp(xaccTransGetDescription(ta), xaccTransGetDescription(tb)) != 0)
+ {
+ PWARN ("descriptions differ: %s vs %s", xaccTransGetDescription(ta), xaccTransGetDescription(tb));
+ return FALSE;
+ }
+
+ if (kvp_frame_compare(qof_instance_get_slots(QOF_INSTANCE(ta)), qof_instance_get_slots(QOF_INSTANCE(tb))) != 0)
+ {
+ char *frame_a;
+ char *frame_b;
+
+ frame_a = kvp_frame_to_string (qof_instance_get_slots(QOF_INSTANCE(ta)));
+ frame_b = kvp_frame_to_string (qof_instance_get_slots(QOF_INSTANCE(tb)));
+
+ PWARN ("kvp frames differ:\n%s\n\nvs\n\n%s", frame_a, frame_b);
+
+ g_free (frame_a);
+ g_free (frame_b);
+
+ return FALSE;
+ }
+
+ if (check_splits)
+ {
+ GList* splits1;
+ GList* splits2;
+
+ splits1 = xaccTransGetSplitList(ta);
+ splits2 = xaccTransGetSplitList(tb);
+ if ((!splits1 && splits2) || (!splits2 && splits1))
+ {
+ PWARN ("only one has splits");
+ return FALSE;
+ }
+
+ if (splits1 && splits2)
+ {
+ GList *node_a, *node_b;
+
+ for (node_a = splits1, node_b = splits2;
+ node_a;
+ node_a = node_a->next, node_b = node_b->next)
+ {
+ Split *split_a = node_a->data;
+ Split *split_b;
+
+ /* don't presume that the splits are in the same order */
+ if (!assume_ordered)
+ node_b = g_list_find_custom (splits2, split_a,
+ compare_split_guids);
+
+ if (!node_b)
+ {
+ PWARN ("first has split %s and second does not",
+ guid_to_string (xaccSplitGetGUID (split_a)));
+ return FALSE;
+ }
+
+ split_b = node_b->data;
+
+ if (!testSplitEqual (split_a, split_b, check_guids, check_balances,
+ FALSE))
+ {
+ char str_a[GUID_ENCODING_LENGTH+1];
+ char str_b[GUID_ENCODING_LENGTH+1];
+
+ guid_to_string_buff (xaccSplitGetGUID (split_a), str_a);
+ guid_to_string_buff (xaccSplitGetGUID (split_b), str_b);
+
+ PWARN ("splits %s and %s differ", str_a, str_b);
+ return FALSE;
+ }
+ }
+
+ if (g_list_length (splits1) != g_list_length (splits2))
+ {
+ PWARN ("different number of splits");
+ return FALSE;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+static gboolean
test_commodity_equal(const gnc_commodity * a, const gnc_commodity * b)
{
if (a == b) return TRUE;
@@ -318,7 +647,7 @@
Split *sa = (Split *) la->data;
Split *sb = (Split *) lb->data;
- if (!xaccSplitEqual(sa, sb, check_guids, TRUE, FALSE))
+ if (!testSplitEqual(sa, sb, check_guids, TRUE, FALSE))
{
PWARN ("splits differ");
return(FALSE);
@@ -354,28 +683,114 @@
do_test( testAccountEqual( root_1, root_2, TRUE ), "Accounts trees match" );
}
+typedef struct
+{
+ QofBook* book_1;
+ QofBook* book_2;
+ gboolean result;
+} CompareInfoStruct;
+
static void
compare_pricedbs( QofBook* book_1, QofBook* book_2 )
{
}
static void
+compare_single_tx( QofInstance* inst, gpointer user_data )
+{
+ CompareInfoStruct* info = (CompareInfoStruct*)user_data;
+ Transaction* tx_1 = GNC_TRANS(inst);
+ Transaction* tx_2 = xaccTransLookup( qof_instance_get_guid(inst), info->book_2 );
+
+ if (!testTransEqual( tx_1, tx_2, TRUE, TRUE, TRUE, FALSE ))
+ {
+ info->result = FALSE;
+ }
+}
+
+static void
compare_txs( QofBook* book_1, QofBook* book_2 )
{
+ CompareInfoStruct info;
+ QofCollection* coll;
+
+ coll = qof_book_get_collection( book_1, GNC_ID_TRANS );
+ info.book_1 = book_1;
+ info.book_2 = book_2;
+ info.result = TRUE;
+ qof_collection_foreach(coll, compare_single_tx, &info);
+
+ do_test( info.result, "Transaction lists match" );
}
static void
+compare_single_sx( QofInstance* inst, gpointer user_data )
+{
+#if 0
+ CompareInfoStruct* info = (CompareInfoStruct*)user_data;
+ Transaction* tx_1 = GNC_TRANS(inst);
+ Transaction* tx_2 = xaccTransLookup( qof_instance_get_guid(inst), info->book_2 );
+
+ if (!testTransEqual( tx_1, tx_2, TRUE, TRUE, TRUE, FALSE ))
+ {
+ info->result = FALSE;
+ }
+#endif
+}
+
+static void
compare_sxs( QofBook* book_1, QofBook* book_2 )
{
+ QofCollection* coll;
+ CompareInfoStruct info;
+
+ coll = qof_book_get_collection( book_1, GNC_ID_SCHEDXACTION );
+ info.book_1 = book_1;
+ info.book_2 = book_2;
+ info.result = TRUE;
+ qof_collection_foreach(coll, compare_single_sx, &info);
+
+ do_test( info.result, "Scheduled transaction lists match" );
}
static void
+compare_single_lot( QofInstance* inst, gpointer user_data )
+{
+#if 0
+ CompareInfoStruct* info = (CompareInfoStruct*)user_data;
+ Transaction* tx_1 = GNC_TRANS(inst);
+ Transaction* tx_2 = xaccTransLookup( qof_instance_get_guid(inst), info->book_2 );
+
+ if (!testTransEqual( tx_1, tx_2, TRUE, TRUE, TRUE, FALSE ))
+ {
+ info->result = FALSE;
+ }
+#endif
+}
+
+static void
+compare_lots( QofBook* book_1, QofBook* book_2 )
+{
+ QofCollection* coll;
+ CompareInfoStruct info;
+
+ coll = qof_book_get_collection( book_1, GNC_ID_LOT );
+ info.book_1 = book_1;
+ info.book_2 = book_2;
+ info.result = TRUE;
+ qof_collection_foreach(coll, compare_single_sx, &info);
+
+ do_test( info.result, "Lot lists match" );
+}
+
+static void
compare_books( QofBook* book_1, QofBook* book_2 )
{
compare_accounts( book_1, book_2 );
compare_pricedbs( book_1, book_2 );
compare_txs( book_1, book_2 );
compare_sxs( book_1, book_2 );
+ compare_lots( book_1, book_2 );
}
void
Modified: gnucash/trunk/src/backend/dbi/test/test-dbi.c
===================================================================
--- gnucash/trunk/src/backend/dbi/test/test-dbi.c 2010-03-23 18:34:17 UTC (rev 18957)
+++ gnucash/trunk/src/backend/dbi/test/test-dbi.c 2010-03-23 21:43:05 UTC (rev 18958)
@@ -1,7 +1,8 @@
/***************************************************************************
* test-dbi.c
*
- * Tests saving and loading to a dbi/sqlite3 db
+ * Tests saving and loading to a dbi/sqlite3 db. The contents of an XML
+ * file are read and saved to sqlite3, then the results read back and compared.
*
* Copyright (C) 2009 Phil Longstaff <plongstaff at rogers.com>
****************************************************************************/
More information about the gnucash-changes
mailing list