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