mirror of
https://github.com/Gnucash/gnucash.git
synced 2024-12-02 05:29:20 -06:00
1238b9d8cd
This will avoid a ninja-build from picking up a config.h generated by the autotools build (in the root build directory). Picking up the wrong config.h may lead to all kinds of subtle issues if the autotools run was done with different options than the cmake run.
943 lines
37 KiB
C
943 lines
37 KiB
C
/********************************************************************
|
|
* test_qofbook.c: GLib g_test test suite for qofbook. *
|
|
* Copyright 2011 John Ralls <jralls@ceridwen.us> *
|
|
* *
|
|
* 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, contact: *
|
|
* *
|
|
* Free Software Foundation Voice: +1-617-542-5942 *
|
|
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
|
|
* Boston, MA 02110-1301, USA gnu@gnu.org *
|
|
\********************************************************************/
|
|
#ifdef __cplusplus
|
|
extern "C"
|
|
{
|
|
#endif
|
|
|
|
#include <config.h>
|
|
#include <string.h>
|
|
#include <glib.h>
|
|
#include <inttypes.h>
|
|
#include <unittest-support.h>
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#include "../qof.h"
|
|
#include "../qofbook-p.h"
|
|
#include "../qofbookslots.h"
|
|
|
|
static const gchar *suitename = "/qof/qofbook";
|
|
void test_suite_qofbook ( void );
|
|
|
|
typedef struct
|
|
{
|
|
QofBook *book;
|
|
} Fixture;
|
|
|
|
static struct
|
|
{
|
|
guint param;
|
|
gpointer data;
|
|
gboolean called;
|
|
gchar* msg;
|
|
} test_struct;
|
|
|
|
static struct
|
|
{
|
|
gboolean col1_called;
|
|
gboolean col2_called;
|
|
gpointer data;
|
|
} col_struct;
|
|
|
|
static void
|
|
setup( Fixture *fixture, gconstpointer pData )
|
|
{
|
|
fixture->book = qof_book_new();
|
|
}
|
|
|
|
static void
|
|
teardown( Fixture *fixture, gconstpointer pData )
|
|
{
|
|
qof_book_destroy( fixture->book );
|
|
}
|
|
|
|
/* use g_free on test_struct.msg after this function been called */
|
|
static gboolean
|
|
handle_faults ( const char * log_domain, GLogLevelFlags log_level, const gchar *msg, gpointer user_data)
|
|
{
|
|
test_struct.msg = (gchar *) g_strdup( msg );
|
|
return FALSE;
|
|
}
|
|
|
|
/* mock dirty callback function */
|
|
static void
|
|
mock_dirty_cb (QofBook *book, gboolean dirty, gpointer user_data)
|
|
{
|
|
test_struct.called = TRUE;
|
|
g_test_message( "Checking if book is valid" );
|
|
g_assert( book );
|
|
g_assert( QOF_IS_BOOK( book ) );
|
|
g_test_message( "Checking parameters" );
|
|
g_assert( dirty );
|
|
g_assert( user_data == test_struct.data );
|
|
}
|
|
|
|
/* mock callback for qof_book_foreach_collection testing */
|
|
static void
|
|
mock_foreach_collection (QofCollection *col, gpointer user_data)
|
|
{
|
|
g_test_message( "Checking if collection and data passed correctly" );
|
|
g_assert( col );
|
|
g_assert( user_data == col_struct.data );
|
|
if ( g_strcmp0( qof_collection_get_type(col), "my_type" ) == 0 )
|
|
col_struct.col1_called = TRUE;
|
|
else if ( g_strcmp0( qof_collection_get_type(col), "my_type2" ) == 0 )
|
|
col_struct.col2_called = TRUE;
|
|
}
|
|
|
|
/* mock final callback function */
|
|
static void
|
|
mock_final_cb (QofBook *book, gpointer key, gpointer user_data)
|
|
{
|
|
test_struct.called = TRUE;
|
|
g_assert( book );
|
|
g_assert( QOF_IS_BOOK( book ) );
|
|
g_test_message( "Checking parameters" );
|
|
g_assert_cmpstr( (gchar*)key, == , "key" );
|
|
g_assert_cmpstr( (gchar*)user_data, == , "data" );
|
|
}
|
|
|
|
static void
|
|
test_book_readonly( Fixture *fixture, gconstpointer pData )
|
|
{
|
|
g_assert( fixture->book != NULL );
|
|
g_assert( !qof_book_is_readonly( fixture->book ) );
|
|
qof_book_mark_readonly( fixture->book );
|
|
g_assert( qof_book_is_readonly( fixture->book ) );
|
|
}
|
|
static void
|
|
test_book_normalize_counter( void )
|
|
{
|
|
gchar *r, *err_msg = NULL;
|
|
g_test_bug("644036");
|
|
g_test_bug("728722");
|
|
|
|
/* Test for detection of missing format conversion */
|
|
r = qof_book_normalize_counter_format("This string is missing the conversion specifier", &err_msg);
|
|
g_assert(!r);
|
|
g_assert(err_msg);
|
|
if (!r && g_test_verbose())
|
|
{
|
|
g_test_message("Counter format normalization correctly failed: %s", err_msg);
|
|
}
|
|
g_free(err_msg);
|
|
err_msg = NULL;
|
|
|
|
/* Test the usual Linux/Unix G_GINT64_FORMAT */
|
|
r = qof_book_normalize_counter_format("Test - %li", &err_msg);
|
|
if (!r && g_test_verbose())
|
|
{
|
|
g_test_message("Counter format normalization erroneously failed: %s", err_msg);
|
|
}
|
|
g_assert_cmpstr( r, == , "Test - %" PRIi64);
|
|
g_assert(err_msg == NULL);
|
|
g_free(r);
|
|
|
|
/* Test the Windows G_GINT64_FORMAT */
|
|
r = qof_book_normalize_counter_format("Test - %I64i", &err_msg);
|
|
if (!r && g_test_verbose())
|
|
{
|
|
g_test_message("Counter format normalization erroneously failed: %s", err_msg);
|
|
}
|
|
g_assert_cmpstr( r, == , "Test - %" PRIi64);
|
|
g_assert(err_msg == NULL);
|
|
g_free(r);
|
|
|
|
/* Test the system's G_INT64_FORMAT */
|
|
r = qof_book_normalize_counter_format("Test - %" G_GINT64_FORMAT, &err_msg);
|
|
if (!r && g_test_verbose())
|
|
{
|
|
g_test_message("Counter format normalization erroneously failed: %s", err_msg);
|
|
}
|
|
g_assert_cmpstr( r, == , "Test - %" PRIi64);
|
|
g_assert(err_msg == NULL);
|
|
g_free(r);
|
|
|
|
/* Test the posix' PRIi64 */
|
|
r = qof_book_normalize_counter_format("Test - %" PRIi64, &err_msg);
|
|
if (!r && g_test_verbose())
|
|
{
|
|
g_test_message("Counter format normalization erroneously failed: %s", err_msg);
|
|
}
|
|
g_assert_cmpstr( r, == , "Test - %" PRIi64);
|
|
g_assert(err_msg == NULL);
|
|
g_free(r);
|
|
|
|
/* Test the posix' PRIi64 with precision field */
|
|
r = qof_book_normalize_counter_format("Test - %.3" PRIi64, &err_msg);
|
|
if (!r && g_test_verbose())
|
|
{
|
|
g_test_message("Counter format normalization erroneously failed: %s", err_msg);
|
|
}
|
|
g_assert_cmpstr( r, == , "Test - %.3" PRIi64);
|
|
g_assert(err_msg == NULL);
|
|
g_free(r);
|
|
|
|
/* Test the posix' PRIi64 with width field */
|
|
r = qof_book_normalize_counter_format("Test - %5" PRIi64, &err_msg);
|
|
if (!r && g_test_verbose())
|
|
{
|
|
g_test_message("Counter format normalization erroneously failed: %s", err_msg);
|
|
}
|
|
g_assert_cmpstr( r, == , "Test - %5" PRIi64);
|
|
g_assert(err_msg == NULL);
|
|
g_free(r);
|
|
|
|
/* Test the posix' PRIi64 with width and precision field */
|
|
r = qof_book_normalize_counter_format("Test - %5.4" PRIi64, &err_msg);
|
|
if (!r && g_test_verbose())
|
|
{
|
|
g_test_message("Counter format normalization erroneously failed: %s", err_msg);
|
|
}
|
|
g_assert_cmpstr( r, == , "Test - %5.4" PRIi64);
|
|
g_assert(err_msg == NULL);
|
|
g_free(r);
|
|
|
|
/* Test the usual Linux/Unix G_GINT64_FORMAT */
|
|
r = qof_book_normalize_counter_format_internal("Test - %li", "li", &err_msg);
|
|
if (!r && g_test_verbose())
|
|
{
|
|
g_test_message("Counter format normalization erroneously failed: %s", err_msg);
|
|
}
|
|
g_assert_cmpstr( r, == , "Test - %" PRIi64);
|
|
g_assert(err_msg == NULL);
|
|
g_free(r);
|
|
|
|
/* Test the Windows G_GINT64_FORMAT */
|
|
r = qof_book_normalize_counter_format_internal("Test - %I64i", "I64i", &err_msg);
|
|
if (!r && g_test_verbose())
|
|
{
|
|
g_test_message("Counter format normalization erroneously failed: %s", err_msg);
|
|
}
|
|
g_assert_cmpstr( r, == , "Test - %" PRIi64);
|
|
g_assert(err_msg == NULL);
|
|
g_free(r);
|
|
|
|
/* Test an erroneous Windows G_GINT64_FORMAT */
|
|
r = qof_book_normalize_counter_format_internal("Test - %li", "I64i", &err_msg);
|
|
g_assert(!r);
|
|
g_assert(err_msg);
|
|
if (!r && g_test_verbose())
|
|
{
|
|
g_test_message("Counter format normalization correctly failed: %s", err_msg);
|
|
}
|
|
g_free(err_msg);
|
|
err_msg = NULL;
|
|
|
|
/* Test an erroneous Linux G_GINT64_FORMAT */
|
|
r = qof_book_normalize_counter_format_internal("Test - %I64i", "li", &err_msg);
|
|
g_assert(!r);
|
|
g_assert(err_msg);
|
|
if (!r && g_test_verbose())
|
|
{
|
|
g_test_message("Counter format normalization correctly failed: %s", err_msg);
|
|
}
|
|
g_free(err_msg);
|
|
}
|
|
|
|
static void
|
|
test_book_get_string_option( Fixture *fixture, gconstpointer pData )
|
|
{
|
|
const char *opt_name = "Option Name";
|
|
const char *opt_value = "Option Value";
|
|
const char *opt_name_notset = "Not Set";
|
|
g_assert( fixture->book != NULL );
|
|
qof_book_set_string_option( fixture->book, opt_name, opt_value);
|
|
g_assert_cmpstr( qof_book_get_string_option( fixture->book, opt_name ), == , opt_value);
|
|
g_assert_cmpstr( qof_book_get_string_option( fixture->book, opt_name_notset ), == , NULL );
|
|
}
|
|
|
|
static void
|
|
test_book_set_string_option( Fixture *fixture, gconstpointer pData )
|
|
{
|
|
const char *opt_name = "Option Name";
|
|
const char *opt_value = "Option Value";
|
|
g_assert( fixture->book != NULL );
|
|
qof_book_set_string_option( fixture->book, opt_name, opt_value);
|
|
g_assert( qof_instance_is_dirty (QOF_INSTANCE (fixture->book)) );
|
|
}
|
|
|
|
static void
|
|
test_book_session_not_saved( Fixture *fixture, gconstpointer pData )
|
|
{
|
|
g_assert( fixture->book != NULL );
|
|
g_assert( !qof_book_session_not_saved( fixture->book ) );
|
|
qof_book_mark_session_saved( fixture->book );
|
|
g_assert( !qof_book_session_not_saved( fixture->book ) );
|
|
qof_book_mark_session_dirty( fixture-> book );
|
|
g_assert( qof_book_session_not_saved( fixture->book ) );
|
|
}
|
|
|
|
static void
|
|
test_book_mark_session_saved( Fixture *fixture, gconstpointer pData )
|
|
{
|
|
time64 dirty_time, clean_time;
|
|
|
|
qof_book_mark_session_dirty( fixture-> book );
|
|
g_assert( qof_book_session_not_saved( fixture->book ) );
|
|
dirty_time = qof_book_get_session_dirty_time( fixture->book );
|
|
qof_book_mark_session_saved( fixture->book );
|
|
clean_time = qof_book_get_session_dirty_time( fixture->book );
|
|
g_assert( !qof_book_session_not_saved( fixture->book ) );
|
|
g_assert( dirty_time != clean_time );
|
|
g_assert( clean_time == 0);
|
|
}
|
|
|
|
static void
|
|
test_book_get_counter( Fixture *fixture, gconstpointer pData )
|
|
{
|
|
const char *counter_name = "Counter name";
|
|
const char *err_no_book = "No book";
|
|
const char *err_invalid_cnt = "Invalid counter name";
|
|
gint64 counter;
|
|
|
|
/* need this as long as we have fatal warnings enabled */
|
|
g_test_log_set_fatal_handler ( ( GTestLogFatalFunc )handle_faults, NULL );
|
|
|
|
counter = qof_book_get_counter( NULL, counter_name );
|
|
g_assert_cmpint( counter, == , -1 );
|
|
g_assert( g_strrstr( test_struct.msg, err_no_book ) != NULL );
|
|
g_free( test_struct.msg );
|
|
|
|
counter = qof_book_get_counter( fixture->book, NULL );
|
|
g_assert_cmpint( counter, == , -1 );
|
|
g_assert( g_strrstr( test_struct.msg, err_invalid_cnt ) != NULL );
|
|
g_free( test_struct.msg );
|
|
|
|
counter = qof_book_get_counter( fixture->book, NULL );
|
|
g_assert_cmpint( counter, == , -1 );
|
|
g_assert( g_strrstr( test_struct.msg, err_invalid_cnt ) != NULL );
|
|
g_free( test_struct.msg );
|
|
|
|
counter = qof_book_get_counter( fixture->book, counter_name );
|
|
g_assert_cmpint( counter, == , 0 );
|
|
|
|
qof_book_increment_and_format_counter( fixture->book, counter_name );
|
|
counter = qof_book_get_counter( fixture->book, counter_name );
|
|
g_assert_cmpint( counter, == , 1 );
|
|
}
|
|
|
|
static void
|
|
test_book_get_counter_format ( Fixture *fixture, gconstpointer pData )
|
|
{
|
|
const char *counter_name = "Counter name";
|
|
const char *err_no_book = "No book";
|
|
const char *err_invalid_cnt = "Invalid counter name";
|
|
const char *r;
|
|
|
|
/* need this as long as we have fatal warnings enabled */
|
|
g_test_log_set_fatal_handler ( ( GTestLogFatalFunc )handle_faults, NULL );
|
|
|
|
g_test_message( "Testing counter format when book is null" );
|
|
r = qof_book_get_counter_format( NULL, counter_name );
|
|
g_assert_cmpstr( r, == , NULL );
|
|
g_assert( g_strrstr( test_struct.msg, err_no_book ) != NULL );
|
|
g_free( test_struct.msg );
|
|
|
|
g_test_message( "Testing counter format when counter name is null" );
|
|
r = qof_book_get_counter_format( fixture->book, NULL );
|
|
g_assert_cmpstr( r, == , NULL );
|
|
g_assert( g_strrstr( test_struct.msg, err_invalid_cnt ) != NULL );
|
|
g_free( test_struct.msg );
|
|
|
|
g_test_message( "Testing counter format when counter name is empty string" );
|
|
r = qof_book_get_counter_format( fixture->book, "" );
|
|
g_assert_cmpstr( r, == , NULL );
|
|
g_assert( g_strrstr( test_struct.msg, err_invalid_cnt ) != NULL );
|
|
g_free( test_struct.msg );
|
|
|
|
g_test_message( "Testing counter format with existing counter" );
|
|
r = qof_book_get_counter_format( fixture->book, counter_name );
|
|
g_assert_cmpstr( r, == , "%.6" PRIi64);
|
|
|
|
g_test_message( "Testing counter format for default value" );
|
|
r = qof_book_get_counter_format( fixture->book, counter_name );
|
|
g_assert_cmpstr( r, == , "%.6" PRIi64);
|
|
}
|
|
|
|
static void
|
|
test_book_increment_and_format_counter ( Fixture *fixture, gconstpointer pData )
|
|
{
|
|
const char *counter_name = "Counter name";
|
|
const char *err_no_book = "No book";
|
|
const char *err_invalid_cnt = "Invalid counter name";
|
|
const char *format;
|
|
char *r;
|
|
gint64 counter;
|
|
|
|
/* need this as long as we have fatal warnings enabled */
|
|
g_test_log_set_fatal_handler ( ( GTestLogFatalFunc )handle_faults, NULL );
|
|
|
|
g_test_message( "Testing increment and format when book is null" );
|
|
r = qof_book_increment_and_format_counter( NULL, counter_name );
|
|
g_assert_cmpstr( r, == , NULL );
|
|
g_free( r );
|
|
g_assert( g_strrstr( test_struct.msg, err_no_book ) != NULL );
|
|
g_free( test_struct.msg );
|
|
|
|
g_test_message( "Testing increment and format when counter name is null" );
|
|
r = qof_book_increment_and_format_counter( fixture->book, NULL );
|
|
g_assert_cmpstr( r, == , NULL );
|
|
g_free( r );
|
|
g_assert( g_strrstr( test_struct.msg, err_invalid_cnt ) != NULL );
|
|
g_free( test_struct.msg );
|
|
|
|
g_test_message( "Testing increment and format when counter name is empty string" );
|
|
r = qof_book_increment_and_format_counter( fixture->book, "" );
|
|
g_assert_cmpstr( r, == , NULL );
|
|
g_free( r );
|
|
g_assert( g_strrstr( test_struct.msg, err_invalid_cnt ) != NULL );
|
|
g_free( test_struct.msg );
|
|
|
|
g_test_message( "Testing increment and format with new counter" );
|
|
r = qof_book_increment_and_format_counter( fixture->book, counter_name );
|
|
counter = qof_book_get_counter( fixture->book, counter_name );
|
|
format = qof_book_get_counter_format( fixture->book, counter_name );
|
|
g_assert_cmpint( counter, == , 1 );
|
|
g_assert( qof_instance_is_dirty (QOF_INSTANCE (fixture->book)) );
|
|
g_assert_cmpstr( r, == , g_strdup_printf( format, counter ));
|
|
g_free( r );
|
|
|
|
g_test_message( "Testing increment and format with existing counter" );
|
|
r = qof_book_increment_and_format_counter( fixture->book, counter_name );
|
|
counter = qof_book_get_counter( fixture->book, counter_name );
|
|
format = qof_book_get_counter_format( fixture->book, counter_name );
|
|
g_assert_cmpint( counter, == , 2 );
|
|
g_assert_cmpstr( r, == , g_strdup_printf( format, counter ));
|
|
g_free( r );
|
|
}
|
|
|
|
static void
|
|
test_book_use_trading_accounts( Fixture *fixture, gconstpointer pData )
|
|
{
|
|
g_assert( qof_book_use_trading_accounts( fixture-> book ) == FALSE );
|
|
|
|
g_test_message( "Testing with existing trading accounts set to true - t" );
|
|
qof_book_begin_edit (fixture->book);
|
|
qof_instance_set (QOF_INSTANCE (fixture->book),
|
|
"trading-accts", "t",
|
|
NULL);
|
|
g_assert( qof_book_use_trading_accounts( fixture-> book ) == TRUE );
|
|
|
|
g_test_message( "Testing with existing trading accounts and incorrect value - tt" );
|
|
qof_instance_set (QOF_INSTANCE (fixture->book),
|
|
"trading-accts", "tt",
|
|
NULL);
|
|
g_assert( qof_book_use_trading_accounts( fixture-> book ) == FALSE );
|
|
qof_book_commit_edit (fixture->book);
|
|
|
|
}
|
|
|
|
static void
|
|
test_book_use_book_currency( Fixture *fixture, gconstpointer pData )
|
|
{
|
|
const gchar *cur;
|
|
const gchar *pol;
|
|
GncGUID *acct;
|
|
const GncGUID *acct2;
|
|
|
|
cur = qof_book_get_book_currency_name( fixture-> book );
|
|
g_assert_cmpstr( cur, == , NULL );
|
|
pol = qof_book_get_default_gains_policy( fixture-> book );
|
|
g_assert_cmpstr( pol, == , NULL );
|
|
acct2 = qof_book_get_default_gain_loss_acct_guid( fixture-> book );
|
|
g_assert (acct2 == NULL );
|
|
|
|
g_test_message( "Testing with existing trading accounts set to true - t" );
|
|
qof_book_begin_edit (fixture->book);
|
|
qof_instance_set (QOF_INSTANCE (fixture->book),
|
|
"trading-accts", "t",
|
|
NULL);
|
|
cur = qof_book_get_book_currency_name( fixture-> book );
|
|
g_assert_cmpstr( cur, == , NULL );
|
|
pol = qof_book_get_default_gains_policy( fixture-> book );
|
|
g_assert_cmpstr( pol, == , NULL );
|
|
acct2 = qof_book_get_default_gain_loss_acct_guid( fixture-> book );
|
|
g_assert (acct2 == NULL );
|
|
qof_book_commit_edit (fixture->book);
|
|
|
|
qof_book_destroy( fixture->book );
|
|
fixture->book = qof_book_new();
|
|
|
|
g_test_message( "Testing with book-currency set and no default-gains-policy or account" );
|
|
qof_book_begin_edit (fixture->book);
|
|
qof_instance_set (QOF_INSTANCE (fixture->book),
|
|
"book-currency", "USD",
|
|
NULL);
|
|
cur = qof_book_get_book_currency_name( fixture-> book );
|
|
g_assert_cmpstr( cur, == , "USD" );
|
|
pol = qof_book_get_default_gains_policy( fixture-> book );
|
|
g_assert_cmpstr( pol, == , NULL );
|
|
acct2 = qof_book_get_default_gain_loss_acct_guid( fixture-> book );
|
|
g_assert (acct2 == NULL );
|
|
qof_book_commit_edit (fixture->book);
|
|
|
|
qof_book_destroy( fixture->book );
|
|
fixture->book = qof_book_new();
|
|
|
|
g_test_message( "Testing with default-gains-policy set and no book-currency" );
|
|
qof_book_begin_edit (fixture->book);
|
|
qof_instance_set (QOF_INSTANCE (fixture->book),
|
|
"default-gains-policy", "fifo",
|
|
NULL);
|
|
cur = qof_book_get_book_currency_name( fixture-> book );
|
|
g_assert_cmpstr( cur, == , NULL );
|
|
pol = qof_book_get_default_gains_policy( fixture-> book );
|
|
g_assert_cmpstr( pol, == , "fifo" );
|
|
acct2 = qof_book_get_default_gain_loss_acct_guid( fixture-> book );
|
|
g_assert (acct2 == NULL );
|
|
qof_book_commit_edit (fixture->book);
|
|
|
|
qof_book_destroy( fixture->book );
|
|
fixture->book = qof_book_new();
|
|
|
|
g_test_message( "Testing with book-currency and default-gains-policy set to nonsense" );
|
|
qof_book_begin_edit (fixture->book);
|
|
qof_instance_set (QOF_INSTANCE (fixture->book),
|
|
"book-currency", "myMoney",
|
|
NULL);
|
|
qof_instance_set (QOF_INSTANCE (fixture->book),
|
|
"default-gains-policy", "random",
|
|
NULL);
|
|
cur = qof_book_get_book_currency_name( fixture-> book );
|
|
g_assert_cmpstr( cur, == , "myMoney" );
|
|
pol = qof_book_get_default_gains_policy( fixture-> book );
|
|
g_assert_cmpstr( pol, == , "random" );
|
|
acct2 = qof_book_get_default_gain_loss_acct_guid( fixture-> book );
|
|
g_assert (acct2 == NULL );
|
|
qof_book_commit_edit (fixture->book);
|
|
|
|
qof_book_destroy( fixture->book );
|
|
fixture->book = qof_book_new();
|
|
|
|
g_test_message( "Testing with book-currency, default-gains-policy and default-gains-account set to valid values" );
|
|
qof_book_begin_edit (fixture->book);
|
|
qof_instance_set (QOF_INSTANCE (fixture->book),
|
|
"book-currency", "USD",
|
|
NULL);
|
|
qof_instance_set (QOF_INSTANCE (fixture->book),
|
|
"default-gains-policy", "fifo",
|
|
NULL);
|
|
acct = guid_new();
|
|
qof_instance_set (QOF_INSTANCE (fixture->book),
|
|
"default-gain-loss-account-guid", acct,
|
|
NULL);
|
|
cur = qof_book_get_book_currency_name( fixture-> book );
|
|
g_assert_cmpstr( cur, == , "USD" );
|
|
pol = qof_book_get_default_gains_policy( fixture-> book );
|
|
g_assert_cmpstr( pol, == , "fifo" );
|
|
acct2 = qof_book_get_default_gain_loss_acct_guid( fixture-> book );
|
|
g_assert_cmpstr( guid_to_string (acct), == , guid_to_string (acct2) );
|
|
g_assert (guid_equal(acct, acct2));
|
|
guid_free (acct);
|
|
qof_book_commit_edit (fixture->book);
|
|
}
|
|
|
|
static void
|
|
test_book_get_num_days_autofreeze( Fixture *fixture, gconstpointer pData )
|
|
{
|
|
g_test_message( "Testing default: No auto-freeze days are set" );
|
|
g_assert( qof_book_uses_autoreadonly( fixture-> book ) == FALSE );
|
|
g_assert( qof_book_get_num_days_autoreadonly( fixture-> book ) == 0 );
|
|
|
|
g_assert( qof_book_uses_autoreadonly( fixture-> book ) == FALSE );
|
|
g_assert( qof_book_get_num_days_autoreadonly( fixture-> book ) == 0 );
|
|
|
|
qof_book_begin_edit (fixture->book);
|
|
qof_instance_set (QOF_INSTANCE (fixture->book),
|
|
"autoreadonly-days", (gdouble)17,
|
|
NULL);
|
|
g_assert( qof_book_uses_autoreadonly( fixture-> book ) == TRUE );
|
|
g_assert( qof_book_get_num_days_autoreadonly( fixture-> book ) == 17 );
|
|
|
|
g_test_message( "Testing when setting this correctly to zero again" );
|
|
|
|
qof_instance_set (QOF_INSTANCE (fixture->book),
|
|
"autoreadonly-days", (gdouble)0,
|
|
NULL);
|
|
g_assert( qof_book_uses_autoreadonly( fixture-> book ) == FALSE );
|
|
g_assert( qof_book_get_num_days_autoreadonly( fixture-> book ) == 0 );
|
|
|
|
qof_instance_set (QOF_INSTANCE (fixture->book),
|
|
"autoreadonly-days", (gdouble)32,
|
|
NULL);
|
|
g_assert( qof_book_uses_autoreadonly( fixture-> book ) == TRUE );
|
|
g_assert( qof_book_get_num_days_autoreadonly( fixture-> book ) == 32 );
|
|
|
|
qof_book_commit_edit (fixture->book);
|
|
}
|
|
|
|
static void
|
|
test_book_use_split_action_for_num_field( Fixture *fixture, gconstpointer pData )
|
|
{
|
|
g_test_message( "Testing default: No selection has been specified" );
|
|
g_assert( qof_book_use_split_action_for_num_field( fixture-> book ) == FALSE );
|
|
|
|
g_test_message( "Testing with existing use split action for num set to true - t" );
|
|
|
|
qof_book_begin_edit (fixture->book);
|
|
qof_instance_set (QOF_INSTANCE (fixture->book),
|
|
"split-action-num-field", "t",
|
|
NULL);
|
|
g_assert( qof_book_use_split_action_for_num_field( fixture-> book ) == TRUE );
|
|
|
|
g_test_message( "Testing with existing use split action for num and incorrect value - tt" );
|
|
qof_instance_set (QOF_INSTANCE (fixture->book),
|
|
"split-action-num-field", "tt",
|
|
NULL);
|
|
g_assert( qof_book_use_split_action_for_num_field( fixture-> book ) == FALSE );
|
|
qof_book_commit_edit (fixture->book);
|
|
}
|
|
|
|
static void
|
|
test_book_mark_session_dirty( Fixture *fixture, gconstpointer pData )
|
|
{
|
|
QofBook *_empty = NULL;
|
|
time64 before, after;
|
|
guint param = (guint) g_test_rand_int();
|
|
|
|
g_test_message( "Testing when book is NULL" );
|
|
qof_book_mark_session_dirty( _empty );
|
|
g_assert( _empty == NULL );
|
|
|
|
g_test_message( "Testing when book is not dirty and dirty_cb is null" );
|
|
g_assert_cmpint( qof_book_get_session_dirty_time( fixture->book ), == , 0);
|
|
g_assert( fixture->book->dirty_cb == NULL );
|
|
g_assert( qof_book_session_not_saved( fixture->book ) == FALSE );
|
|
before = gnc_time (NULL);
|
|
qof_book_mark_session_dirty( fixture->book );
|
|
after = gnc_time (NULL);
|
|
g_assert_cmpint( qof_book_get_session_dirty_time( fixture->book ), >= , before);
|
|
g_assert_cmpint( qof_book_get_session_dirty_time( fixture->book ), <= , after);
|
|
g_assert( qof_book_session_not_saved( fixture->book ) == TRUE );
|
|
|
|
g_test_message( "Testing when book is not dirty and dirty_cb is not null" );
|
|
/* prepare conditions */
|
|
qof_book_mark_session_saved( fixture->book );
|
|
qof_book_set_dirty_cb( fixture->book, mock_dirty_cb, (gpointer) (¶m) );
|
|
test_struct.data = (gpointer) (¶m);
|
|
test_struct.called = FALSE;
|
|
g_assert( fixture->book->dirty_cb != NULL );
|
|
g_assert_cmpint( qof_book_get_session_dirty_time( fixture->book ), == , 0);
|
|
g_assert( qof_book_session_not_saved( fixture->book ) == FALSE );
|
|
/* run FUT */
|
|
before = gnc_time (NULL);
|
|
qof_book_mark_session_dirty( fixture->book );
|
|
after = gnc_time (NULL);
|
|
/* test output */
|
|
g_assert_cmpint( qof_book_get_session_dirty_time( fixture->book ), >= , before);
|
|
g_assert_cmpint( qof_book_get_session_dirty_time( fixture->book ), <= , after);
|
|
g_assert( qof_book_session_not_saved( fixture->book ) == TRUE );
|
|
g_assert( test_struct.called );
|
|
|
|
g_test_message( "Testing when book is dirty" );
|
|
g_assert( qof_book_session_not_saved( fixture->book ) == TRUE );
|
|
before = qof_book_get_session_dirty_time( fixture->book );
|
|
qof_book_mark_session_dirty( fixture->book );
|
|
g_assert( qof_book_session_not_saved( fixture->book ) == TRUE );
|
|
after = qof_book_get_session_dirty_time( fixture->book );
|
|
g_assert_cmpint( before, == , after );
|
|
}
|
|
|
|
static void
|
|
test_book_get_session_dirty_time( Fixture *fixture, gconstpointer pData )
|
|
{
|
|
time64 before, after;
|
|
|
|
g_test_message( "Testing time on saved book = 0" );
|
|
g_assert( qof_book_session_not_saved( fixture->book ) == FALSE );
|
|
g_assert_cmpint( qof_book_get_session_dirty_time( fixture->book ), == , 0);
|
|
|
|
g_test_message( "Testing time on dirty book is correct" );
|
|
before = gnc_time (NULL);
|
|
qof_book_mark_session_dirty( fixture->book );
|
|
after = gnc_time (NULL);
|
|
g_assert_cmpint( qof_book_get_session_dirty_time( fixture->book ), >= , before);
|
|
g_assert_cmpint( qof_book_get_session_dirty_time( fixture->book ), <= , after);
|
|
|
|
}
|
|
|
|
static void
|
|
test_book_set_dirty_cb( Fixture *fixture, gconstpointer pData )
|
|
{
|
|
const char * error_msg = "Already existing callback";
|
|
|
|
g_test_message( "Testing when callback is previously not set" );
|
|
g_assert( fixture->book->dirty_cb == NULL );
|
|
qof_book_set_dirty_cb( fixture->book, mock_dirty_cb, (gpointer) (&test_struct) );
|
|
g_assert( fixture->book->dirty_cb == mock_dirty_cb );
|
|
g_assert( fixture->book->dirty_data == &test_struct );
|
|
|
|
/* need this as long as we have fatal warnings enabled */
|
|
g_test_log_set_fatal_handler ( ( GTestLogFatalFunc )handle_faults, NULL );
|
|
|
|
g_test_message( "Testing when callback was previously set" );
|
|
g_assert( fixture->book->dirty_cb != NULL );
|
|
qof_book_set_dirty_cb( fixture->book, NULL, NULL );
|
|
g_assert( g_strrstr( test_struct.msg, error_msg ) != NULL );
|
|
g_assert( fixture->book->dirty_cb == NULL );
|
|
g_assert( fixture->book->dirty_data == NULL );
|
|
g_free( test_struct.msg );
|
|
}
|
|
|
|
static void
|
|
test_book_shutting_down( Fixture *fixture, gconstpointer pData )
|
|
{
|
|
g_test_message( "Testing when book is null" );
|
|
g_assert( qof_book_shutting_down( NULL ) == FALSE );
|
|
g_test_message( "Testing when shutting down is true" );
|
|
fixture->book->shutting_down = TRUE;
|
|
g_assert( qof_book_shutting_down( fixture->book ) == TRUE );
|
|
g_test_message( "Testing when shutting down is false" );
|
|
fixture->book->shutting_down = FALSE;
|
|
g_assert( qof_book_shutting_down( fixture->book ) == FALSE );
|
|
}
|
|
|
|
static void
|
|
test_book_set_get_data( Fixture *fixture, gconstpointer pData )
|
|
{
|
|
const char *key = "key";
|
|
const char *data = "data";
|
|
|
|
g_assert( fixture->book->data_tables != NULL );
|
|
g_test_message( "Testing when book is null" );
|
|
qof_book_set_data( NULL, key, (gpointer) data );
|
|
g_assert( qof_book_get_data( NULL, key ) == NULL );
|
|
|
|
g_test_message( "Testing when key is null" );
|
|
qof_book_set_data( fixture->book, NULL, (gpointer) data );
|
|
g_assert( qof_book_get_data( fixture->book, NULL) == NULL );
|
|
|
|
g_test_message( "Testing with book key not null, data null" );
|
|
qof_book_set_data( fixture->book, key, NULL );
|
|
g_assert( qof_book_get_data( fixture->book, key ) == NULL );
|
|
|
|
g_test_message( "Testing with book key data not null" );
|
|
qof_book_set_data( fixture->book, key, (gpointer) data );
|
|
g_assert_cmpstr( (const char *)qof_book_get_data( fixture->book, key ), == , data );
|
|
}
|
|
|
|
static void
|
|
test_book_get_collection( Fixture *fixture, gconstpointer pData )
|
|
{
|
|
QofIdType my_type = "my type";
|
|
QofCollection *m_col, *m_col2;
|
|
|
|
g_test_message( "Testing when book is null" );
|
|
g_assert( qof_book_get_collection( NULL, my_type ) == NULL );
|
|
|
|
g_test_message( "Testing when entity type is null" );
|
|
g_assert( qof_book_get_collection( fixture->book, NULL ) == NULL );
|
|
|
|
g_test_message( "Testing when collection does not exist" );
|
|
g_assert( fixture->book->hash_of_collections != NULL );
|
|
g_assert( g_hash_table_lookup ( fixture->book->hash_of_collections, my_type ) == NULL );
|
|
m_col = qof_book_get_collection( fixture->book, my_type );
|
|
g_assert( m_col != NULL );
|
|
|
|
g_test_message( "Testing with existing collection" );
|
|
g_assert( g_hash_table_lookup ( fixture->book->hash_of_collections, my_type ) != NULL );
|
|
m_col2 = qof_book_get_collection( fixture->book, my_type );
|
|
g_assert( m_col2 != NULL );
|
|
g_assert( m_col == m_col2 );
|
|
}
|
|
|
|
static void
|
|
test_book_foreach_collection( Fixture *fixture, gconstpointer pData )
|
|
{
|
|
G_GNUC_UNUSED QofCollection *m_col, *m_col2;
|
|
QofIdType my_type = "my_type", my_type2 = "my_type2";
|
|
guint param = (guint) g_test_rand_int();
|
|
/* GLib assertion messages which aren't filtered to make clang's output like gcc's */
|
|
#if defined(__clang__)
|
|
#define _func "void qof_book_foreach_collection(const QofBook *, QofCollectionForeachCB, gpointer)"
|
|
#else
|
|
#define _func "void qof_book_foreach_collection(const QofBook*, QofCollectionForeachCB, gpointer)"
|
|
//#define _func "qof_book_foreach_collection"
|
|
#endif
|
|
gchar *msg1 = _func ": assertion 'book' failed";
|
|
gchar *msg2 = _func ": assertion 'cb' failed";
|
|
#undef _func
|
|
gchar *log_domain = "qof";
|
|
guint loglevel = G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL, hdlr;
|
|
TestErrorStruct check1 = { loglevel, log_domain, msg1 };
|
|
TestErrorStruct check2 = { loglevel, log_domain, msg2 };
|
|
|
|
/* need this as long as we have fatal warnings enabled */
|
|
g_test_log_set_fatal_handler ( ( GTestLogFatalFunc )handle_faults, NULL );
|
|
test_add_error (&check1);
|
|
test_add_error (&check2);
|
|
hdlr = g_log_set_handler (log_domain, loglevel,
|
|
(GLogFunc)test_list_handler, NULL);
|
|
|
|
g_test_message( "Testing when book is null" );
|
|
m_col = qof_book_get_collection( fixture->book, my_type );
|
|
m_col2 = qof_book_get_collection( fixture->book, my_type2 );
|
|
col_struct.col1_called = FALSE;
|
|
col_struct.col2_called = FALSE;
|
|
col_struct.data = (gpointer) (¶m);
|
|
/* launch foreach make sure callback was not called and check warning msg */
|
|
qof_book_foreach_collection( NULL, mock_foreach_collection, (gpointer)(¶m) );
|
|
g_assert( !col_struct.col1_called );
|
|
g_assert( !col_struct.col2_called );
|
|
g_assert_cmpstr( test_struct.msg, == , msg1);
|
|
g_free( test_struct.msg );
|
|
|
|
g_test_message( "Testing when cb is null" );
|
|
/* launching with empty cb should still fail and produce warning */
|
|
qof_book_foreach_collection( fixture->book, NULL, (gpointer)(¶m) );
|
|
g_assert( !col_struct.col1_called );
|
|
g_assert( !col_struct.col2_called );
|
|
g_assert_cmpstr( test_struct.msg, == , msg2);
|
|
g_free( test_struct.msg );
|
|
g_log_remove_handler (log_domain, hdlr);
|
|
test_clear_error_list ();
|
|
|
|
g_test_message( "Testing when book and cb not null, user_data provided" );
|
|
/* both cols have to be called */
|
|
qof_book_foreach_collection( fixture->book, mock_foreach_collection, (gpointer)(¶m) );
|
|
g_assert( col_struct.col1_called );
|
|
g_assert( col_struct.col2_called );
|
|
}
|
|
|
|
static void
|
|
test_book_set_data_fin( void )
|
|
{
|
|
QofBook *book;
|
|
const char *key = "key";
|
|
const char *data = "data";
|
|
|
|
/* init */
|
|
book = qof_book_new();
|
|
g_assert_cmpint( g_hash_table_size( book->data_tables ), == , 0 );
|
|
g_assert_cmpint( g_hash_table_size( book->data_table_finalizers ), == , 0 );
|
|
|
|
g_test_message( "Testing when book is null" );
|
|
qof_book_set_data_fin( NULL, key, (gpointer) data, mock_final_cb );
|
|
/* assert nothing was set */
|
|
g_assert_cmpint( g_hash_table_size( book->data_tables ), == , 0 );
|
|
g_assert_cmpint( g_hash_table_size( book->data_table_finalizers ), == , 0 );
|
|
|
|
g_test_message( "Testing when key is null" );
|
|
qof_book_set_data_fin( book, NULL, (gpointer) data, mock_final_cb );
|
|
/* nothing set as well */
|
|
g_assert_cmpint( g_hash_table_size( book->data_tables ), == , 0 );
|
|
g_assert_cmpint( g_hash_table_size( book->data_table_finalizers ), == , 0 );
|
|
|
|
g_test_message( "Testing with book key not null, cb null" );
|
|
qof_book_set_data_fin( book, key, (gpointer) data, NULL );
|
|
/* now data is set cb not set */
|
|
g_assert_cmpint( g_hash_table_size( book->data_tables ), == , 1 );
|
|
g_assert_cmpint( g_hash_table_size( book->data_table_finalizers ), == , 0 );
|
|
g_assert_cmpstr( (const char *)qof_book_get_data( book, key ), == , data );
|
|
|
|
g_test_message( "Testing with all data set" );
|
|
qof_book_set_data_fin( book, key, (gpointer) data, mock_final_cb );
|
|
/* now we have all set */
|
|
g_assert_cmpint( g_hash_table_size( book->data_tables ), == , 1 );
|
|
g_assert_cmpint( g_hash_table_size( book->data_table_finalizers ), == , 1 );
|
|
g_assert_cmpstr( (const char *)qof_book_get_data( book, key ), == , data );
|
|
g_assert( g_hash_table_lookup ( book->data_table_finalizers, (gpointer)key ) == mock_final_cb );
|
|
|
|
/* get rid of book make sure final cb is called */
|
|
test_struct.called = FALSE;
|
|
qof_book_destroy( book );
|
|
g_assert( test_struct.called );
|
|
}
|
|
|
|
static void
|
|
test_book_mark_closed( Fixture *fixture, gconstpointer pData )
|
|
{
|
|
g_test_message( "Testing when book is null" );
|
|
g_assert_cmpstr( &fixture->book->book_open, == , "y" );
|
|
qof_book_mark_closed( NULL );
|
|
g_assert_cmpstr( &fixture->book->book_open, == , "y" );
|
|
|
|
g_test_message( "Testing when book is not null" );
|
|
qof_book_mark_closed( fixture->book );
|
|
g_assert_cmpstr( &fixture->book->book_open, == , "n" );
|
|
}
|
|
|
|
static void
|
|
test_book_new_destroy( void )
|
|
{
|
|
QofBook *book;
|
|
const char *key = "key";
|
|
const char *data = "data";
|
|
|
|
g_test_message( "Testing book creation and initial setup" );
|
|
book = qof_book_new();
|
|
g_assert( book );
|
|
g_assert( QOF_IS_BOOK( book ) );
|
|
|
|
g_test_message( "Testing book initial setup" );
|
|
g_assert( book->hash_of_collections );
|
|
g_assert( book->data_tables );
|
|
g_assert( book->data_table_finalizers );
|
|
g_assert_cmpint( g_hash_table_size( book->hash_of_collections ), == , 1 );
|
|
g_assert( g_hash_table_lookup ( book->hash_of_collections, QOF_ID_BOOK ) != NULL );
|
|
g_assert_cmpint( g_hash_table_size( book->data_tables ), == , 0 );
|
|
g_assert_cmpint( g_hash_table_size( book->data_table_finalizers ), == , 0 );
|
|
g_assert_cmpstr( &book->book_open, == , "y");
|
|
g_assert( !book->read_only );
|
|
g_assert_cmpint( book->version, == , 0 );
|
|
|
|
/* set finalizer */
|
|
qof_book_set_data_fin( book, key, (gpointer) data, mock_final_cb );
|
|
test_struct.called = FALSE;
|
|
|
|
g_test_message( "Testing book destroy" );
|
|
qof_book_destroy( book );
|
|
g_assert( qof_book_shutting_down( book ) );
|
|
g_assert( test_struct.called );
|
|
}
|
|
|
|
void
|
|
test_suite_qofbook ( void )
|
|
{
|
|
GNC_TEST_ADD( suitename, "readonly", Fixture, NULL, setup, test_book_readonly, teardown );
|
|
GNC_TEST_ADD_FUNC( suitename, "validate counter", test_book_normalize_counter );
|
|
GNC_TEST_ADD( suitename, "get string option", Fixture, NULL, setup, test_book_get_string_option, teardown );
|
|
GNC_TEST_ADD( suitename, "set string option", Fixture, NULL, setup, test_book_set_string_option, teardown );
|
|
GNC_TEST_ADD( suitename, "session not saved", Fixture, NULL, setup, test_book_session_not_saved, teardown );
|
|
GNC_TEST_ADD( suitename, "session mark saved", Fixture, NULL, setup, test_book_mark_session_saved, teardown );
|
|
GNC_TEST_ADD( suitename, "get counter", Fixture, NULL, setup, test_book_get_counter, teardown );
|
|
GNC_TEST_ADD( suitename, "get counter format", Fixture, NULL, setup, test_book_get_counter_format, teardown );
|
|
GNC_TEST_ADD( suitename, "increment and format counter", Fixture, NULL, setup, test_book_increment_and_format_counter, teardown );
|
|
GNC_TEST_ADD( suitename, "use trading accounts", Fixture, NULL, setup, test_book_use_trading_accounts, teardown );
|
|
GNC_TEST_ADD( suitename, "use book-currency", Fixture, NULL, setup, test_book_use_book_currency, teardown );
|
|
GNC_TEST_ADD( suitename, "get autofreeze days", Fixture, NULL, setup, test_book_get_num_days_autofreeze, teardown );
|
|
GNC_TEST_ADD( suitename, "use split action for num field", Fixture, NULL, setup, test_book_use_split_action_for_num_field, teardown );
|
|
GNC_TEST_ADD( suitename, "mark session dirty", Fixture, NULL, setup, test_book_mark_session_dirty, teardown );
|
|
GNC_TEST_ADD( suitename, "session dirty time", Fixture, NULL, setup, test_book_get_session_dirty_time, teardown );
|
|
GNC_TEST_ADD( suitename, "set dirty callback", Fixture, NULL, setup, test_book_set_dirty_cb, teardown );
|
|
GNC_TEST_ADD( suitename, "shutting down", Fixture, NULL, setup, test_book_shutting_down, teardown );
|
|
GNC_TEST_ADD( suitename, "set get data", Fixture, NULL, setup, test_book_set_get_data, teardown );
|
|
GNC_TEST_ADD( suitename, "get collection", Fixture, NULL, setup, test_book_get_collection, teardown );
|
|
GNC_TEST_ADD( suitename, "foreach collection", Fixture, NULL, setup, test_book_foreach_collection, teardown );
|
|
GNC_TEST_ADD_FUNC( suitename, "set data finalizers", test_book_set_data_fin );
|
|
GNC_TEST_ADD( suitename, "mark closed", Fixture, NULL, setup, test_book_mark_closed, teardown );
|
|
GNC_TEST_ADD_FUNC( suitename, "book new and destroy", test_book_new_destroy );
|
|
}
|