gnucash stable: Multiple changes pushed

Christopher Lam clam at code.gnucash.org
Tue Jun 9 23:59:45 EDT 2026


Updated	 via  https://github.com/Gnucash/gnucash/commit/13112ab8 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/63917e08 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/8b6d93eb (commit)
	from  https://github.com/Gnucash/gnucash/commit/db6cac5b (commit)



commit 13112ab809ac16dfd2ec7a9040ce83eddbbb78d9
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Tue Jun 9 20:45:18 2026 +0800

    rename gmock-qofbook.h and gmock-Split.h to .hpp

diff --git a/gnucash/import-export/test/gtest-import-backend.cpp b/gnucash/import-export/test/gtest-import-backend.cpp
index cca303c106..11226e4118 100644
--- a/gnucash/import-export/test/gtest-import-backend.cpp
+++ b/gnucash/import-export/test/gtest-import-backend.cpp
@@ -38,10 +38,10 @@
 #include <gnc-ui-util.h>
 
 #include "gmock-gnc-prefs.h"
-#include "gmock-qofbook.h"
+#include "gmock-qofbook.hpp"
 #include "gmock-Account.h"
 #include "gmock-Transaction.h"
-#include "gmock-Split.h"
+#include "gmock-Split.hpp"
 
 
 
diff --git a/libgnucash/engine/mocks/CMakeLists.txt b/libgnucash/engine/mocks/CMakeLists.txt
index 85262f66f5..48fc68cd59 100644
--- a/libgnucash/engine/mocks/CMakeLists.txt
+++ b/libgnucash/engine/mocks/CMakeLists.txt
@@ -3,12 +3,12 @@ set(engine_mocks_SOURCES
     gmock-Account.h
     gmock-gobject.h
     gmock-qofbook.cpp
-    gmock-qofbook.h
+    gmock-qofbook.hpp
     gmock-qofinstance.cpp
     fake-qofquery.cpp
     fake-qofquery.h
     gmock-Split.cpp
-    gmock-Split.h
+    gmock-Split.hpp
     gmock-Transaction.cpp
     gmock-Transaction.h
 )
diff --git a/libgnucash/engine/mocks/gmock-Split.cpp b/libgnucash/engine/mocks/gmock-Split.cpp
index 6ce632562b..523d99a6d9 100644
--- a/libgnucash/engine/mocks/gmock-Split.cpp
+++ b/libgnucash/engine/mocks/gmock-Split.cpp
@@ -3,8 +3,8 @@
 #include <Transaction.h>
 #include <Account.h>
 
-#include "gmock-Split.h"
-#include "gmock-qofbook.h"
+#include "gmock-Split.hpp"
+#include "gmock-qofbook.hpp"
 
 
 struct _MockSplitClass
diff --git a/libgnucash/engine/mocks/gmock-Split.h b/libgnucash/engine/mocks/gmock-Split.hpp
similarity index 99%
rename from libgnucash/engine/mocks/gmock-Split.h
rename to libgnucash/engine/mocks/gmock-Split.hpp
index fc69dd0eef..b2667d3381 100644
--- a/libgnucash/engine/mocks/gmock-Split.h
+++ b/libgnucash/engine/mocks/gmock-Split.hpp
@@ -10,7 +10,7 @@
 #include <Split.h>
 #include <SplitP.hpp>
 
-#include "gmock-qofbook.h"
+#include "gmock-qofbook.hpp"
 #include "gmock-gobject.h"
 
 
diff --git a/libgnucash/engine/mocks/gmock-qofbook.cpp b/libgnucash/engine/mocks/gmock-qofbook.cpp
index 73c50b04ae..fcb42216a9 100644
--- a/libgnucash/engine/mocks/gmock-qofbook.cpp
+++ b/libgnucash/engine/mocks/gmock-qofbook.cpp
@@ -1,4 +1,4 @@
-#include "gmock-qofbook.h"
+#include "gmock-qofbook.hpp"
 
 struct _QofMockBookClass
 {
diff --git a/libgnucash/engine/mocks/gmock-qofbook.h b/libgnucash/engine/mocks/gmock-qofbook.hpp
similarity index 100%
rename from libgnucash/engine/mocks/gmock-qofbook.h
rename to libgnucash/engine/mocks/gmock-qofbook.hpp

commit 63917e082430275cec9f4699902478863c8dc5ba
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sun Jun 7 08:40:24 2026 +0800

    [qofbook.cpp] move _QofBook definition from qofbook.h to qofbook-p.hpp
    
    to make it opaque
    
    and change:
    - qofbook.h to .hpp
    - test-qofbook.c to test-qofbook.cpp

diff --git a/libgnucash/engine/CMakeLists.txt b/libgnucash/engine/CMakeLists.txt
index 4797652a9d..9bc5a18d54 100644
--- a/libgnucash/engine/CMakeLists.txt
+++ b/libgnucash/engine/CMakeLists.txt
@@ -22,7 +22,7 @@ set(engine_noinst_HEADERS
   gnc-optiondb-impl.hpp
   gnc-pricedb-p.h
   policy-p.h
-  qofbook-p.h
+  qofbook-p.hpp
   qofclass-p.h
   qofevent-p.h
   qofobject-p.h
diff --git a/libgnucash/engine/mocks/gmock-qofbook.h b/libgnucash/engine/mocks/gmock-qofbook.h
index 3662877b2d..04619ad6c6 100644
--- a/libgnucash/engine/mocks/gmock-qofbook.h
+++ b/libgnucash/engine/mocks/gmock-qofbook.h
@@ -8,7 +8,7 @@
 
 
 #include <qofbook.h>
-#include <qofbook-p.h>
+#include <qofbook-p.hpp>
 #include <Split.h>
 
 #include "gmock-gobject.h"
diff --git a/libgnucash/engine/qofbook-p.h b/libgnucash/engine/qofbook-p.hpp
similarity index 55%
rename from libgnucash/engine/qofbook-p.h
rename to libgnucash/engine/qofbook-p.hpp
index 939387c509..e63b357dfa 100644
--- a/libgnucash/engine/qofbook-p.h
+++ b/libgnucash/engine/qofbook-p.hpp
@@ -41,10 +41,92 @@
 #include "qofid.h"
 #include "qofid-p.h"
 #include "qofinstance-p.h"
-#ifdef __cplusplus
-extern "C"
+
+
+struct QofBook
 {
-#endif
+    QofInstance   inst;     /* Unique guid for this book. */
+
+    /* Boolean indicates that the session is dirty -- that is, it has
+     * not yet been written out to disk after the last time the
+     * backend ran commit_edit(). This is distinct from the inherited
+     * QofInstance::dirty, which indicates that some persistent
+     * property of the book object itself has been edited and not
+     * committed. Some backends write data out as part of
+     * commit_edit() and so don't use this flag.
+     */
+    gboolean session_dirty;
+
+    /* The time when the book was first dirtied.  This is a secondary
+     * indicator. It should only be used when session_saved is FALSE. */
+    time64 dirty_time;
+
+    /* This callback function is called any time the book dirty flag
+     * changes state. Both clean->dirty and dirty->clean transitions
+     * trigger a callback. */
+    QofBookDirtyCB dirty_cb;
+
+    /* This is the user supplied data that is returned in the dirty
+     * callback function.*/
+    gpointer dirty_data;
+
+    /* The entity table associates the GUIDs of all the objects
+     * belonging to this book, with their pointers to the respective
+     * objects.  This allows a lookup of objects based on their guid.
+     */
+    GHashTable * hash_of_collections;
+
+    /* In order to store arbitrary data, for extensibility, add a table
+     * that will be used to hold arbitrary pointers.
+     */
+    GHashTable *data_tables;
+
+    /* Hash table of destroy callbacks for the data table. */
+    GHashTable *data_table_finalizers;
+
+    /* Boolean indicates whether book is safe to write to (true means
+     * that it isn't). The usual reason will be a database version
+     * mismatch with the running instance of Gnucash.
+     */
+    gboolean read_only;
+
+    /* state flag: 'y' means 'open for editing',
+     * 'n' means 'book is closed'
+     * xxxxx shouldn't this be replaced by the instance editlevel ???
+     */
+    char book_open;
+
+    /* a flag denoting whether the book is closing down, used to
+     * help the QOF objects shut down cleanly without maintaining
+     * internal consistency.
+     * XXX shouldn't this be replaced by instance->do_free ???
+     */
+    gboolean shutting_down;
+
+    /* version number, used for tracking multiuser updates */
+    gint32  version;
+
+    /* To be technically correct, backends belong to sessions and
+     * not books.  So the pointer below "really shouldn't be here",
+     * except that it provides a nice convenience, avoiding a lookup
+     * from the session.  Better solutions welcome ... */
+    QofBackend *backend;
+
+    /* A cached value of the OPTION_NAME_NUM_FIELD_SOURCE option value
+     * because it is queried quite a lot, so we want to avoid a KVP
+     * lookup on each query */
+    gboolean cached_num_field_source;
+    /* Whether the above cached value is valid. */
+    gboolean cached_num_field_source_isvalid;
+
+    /* A cahed value of the "autoreadonly-days" option value because
+     * it is queried quite a lot, so we want to avoid a KVP lookup on
+     * each query */
+    gint cached_num_days_autoreadonly;
+    /* Whether the above cached value is valid. */
+    gboolean cached_num_days_autoreadonly_isvalid;
+};
+
 
 /* Structure for accessing static functions for testing */
 typedef struct
@@ -96,8 +178,5 @@ void qof_book_print_dirty (const QofBook *book);
 /* @} */
 /* @} */
 /* @} */
-#ifdef __cplusplus
-}
-#endif
 
 #endif /* QOF_BOOK_P_H */
diff --git a/libgnucash/engine/qofbook.cpp b/libgnucash/engine/qofbook.cpp
index c19e62e6d3..364aadb36f 100644
--- a/libgnucash/engine/qofbook.cpp
+++ b/libgnucash/engine/qofbook.cpp
@@ -49,7 +49,7 @@
 #include "qof.h"
 #include "qofevent-p.h"
 #include "qofbackend.h"
-#include "qofbook-p.h"
+#include "qofbook-p.hpp"
 #include "qofid-p.h"
 #include "qofobject-p.h"
 #include "qofbookslots.h"
diff --git a/libgnucash/engine/qofbook.h b/libgnucash/engine/qofbook.h
index 6a5ce8d0c8..5165160f33 100644
--- a/libgnucash/engine/qofbook.h
+++ b/libgnucash/engine/qofbook.h
@@ -82,91 +82,6 @@ typedef void (*QofBookDirtyCB) (QofBook *, gboolean dirty, gpointer user_data);
 typedef void (*GncOptionSave) (GncOptionDB*, QofBook*, gboolean);
 typedef void (*GncOptionLoad) (GncOptionDB*, QofBook*);
 
-/* Book structure */
-struct _QofBook
-{
-    QofInstance   inst;     /* Unique guid for this book. */
-
-    /* Boolean indicates that the session is dirty -- that is, it has
-     * not yet been written out to disk after the last time the
-     * backend ran commit_edit(). This is distinct from the inherited
-     * QofInstance::dirty, which indicates that some persistent
-     * property of the book object itself has been edited and not
-     * committed. Some backends write data out as part of
-     * commit_edit() and so don't use this flag.
-     */
-    gboolean session_dirty;
-
-    /* The time when the book was first dirtied.  This is a secondary
-     * indicator. It should only be used when session_saved is FALSE. */
-    time64 dirty_time;
-
-    /* This callback function is called any time the book dirty flag
-     * changes state. Both clean->dirty and dirty->clean transitions
-     * trigger a callback. */
-    QofBookDirtyCB dirty_cb;
-
-    /* This is the user supplied data that is returned in the dirty
-     * callback function.*/
-    gpointer dirty_data;
-
-    /* The entity table associates the GUIDs of all the objects
-     * belonging to this book, with their pointers to the respective
-     * objects.  This allows a lookup of objects based on their guid.
-     */
-    GHashTable * hash_of_collections;
-
-    /* In order to store arbitrary data, for extensibility, add a table
-     * that will be used to hold arbitrary pointers.
-     */
-    GHashTable *data_tables;
-
-    /* Hash table of destroy callbacks for the data table. */
-    GHashTable *data_table_finalizers;
-
-    /* Boolean indicates whether book is safe to write to (true means
-     * that it isn't). The usual reason will be a database version
-     * mismatch with the running instance of Gnucash.
-     */
-    gboolean read_only;
-
-    /* state flag: 'y' means 'open for editing',
-     * 'n' means 'book is closed'
-     * xxxxx shouldn't this be replaced by the instance editlevel ???
-     */
-    char book_open;
-
-    /* a flag denoting whether the book is closing down, used to
-     * help the QOF objects shut down cleanly without maintaining
-     * internal consistency.
-     * XXX shouldn't this be replaced by instance->do_free ???
-     */
-    gboolean shutting_down;
-
-    /* version number, used for tracking multiuser updates */
-    gint32  version;
-
-    /* To be technically correct, backends belong to sessions and
-     * not books.  So the pointer below "really shouldn't be here",
-     * except that it provides a nice convenience, avoiding a lookup
-     * from the session.  Better solutions welcome ... */
-    QofBackend *backend;
-
-    /* A cached value of the OPTION_NAME_NUM_FIELD_SOURCE option value
-     * because it is queried quite a lot, so we want to avoid a KVP
-     * lookup on each query */
-    gboolean cached_num_field_source;
-    /* Whether the above cached value is valid. */
-    gboolean cached_num_field_source_isvalid;
-
-    /* A cahed value of the "autoreadonly-days" option value because
-     * it is queried quite a lot, so we want to avoid a KVP lookup on
-     * each query */
-    gint cached_num_days_autoreadonly;
-    /* Whether the above cached value is valid. */
-    gboolean cached_num_days_autoreadonly_isvalid;
-};
-
 struct _QofBookClass
 {
     QofInstanceClass parent_class;
diff --git a/libgnucash/engine/qofinstance.cpp b/libgnucash/engine/qofinstance.cpp
index 707ca743b7..555a57d321 100644
--- a/libgnucash/engine/qofinstance.cpp
+++ b/libgnucash/engine/qofinstance.cpp
@@ -36,7 +36,7 @@
 #include <cstdint>
 #include <utility>
 #include "qof.h"
-#include "qofbook-p.h"
+#include "qofbook-p.hpp"
 #include "qofid-p.h"
 #include "kvp-frame.hpp"
 #include "qofinstance-p.h"
diff --git a/libgnucash/engine/qofinstance.h b/libgnucash/engine/qofinstance.h
index 37dfe310dc..ddafa8f28c 100644
--- a/libgnucash/engine/qofinstance.h
+++ b/libgnucash/engine/qofinstance.h
@@ -41,7 +41,7 @@ typedef struct _QofInstanceClass QofInstanceClass;
 typedef struct QofInstance_s QofInstance;
 
 /** \brief QofBook reference */
-typedef struct _QofBook       QofBook;
+typedef struct QofBook       QofBook;
 
 #include "qofid.h"
 #include "guid.h"
diff --git a/libgnucash/engine/qofquery.cpp b/libgnucash/engine/qofquery.cpp
index 2a1be5e6c7..0ee62807f5 100644
--- a/libgnucash/engine/qofquery.cpp
+++ b/libgnucash/engine/qofquery.cpp
@@ -31,7 +31,7 @@
 
 #include "qof.h"
 #include "qof-backend.hpp"
-#include "qofbook-p.h"
+#include "qofbook-p.hpp"
 #include "qofclass-p.h"
 #include "qofquery-p.h"
 #include "qofquerycore-p.h"
diff --git a/libgnucash/engine/qofsession.cpp b/libgnucash/engine/qofsession.cpp
index b7f43a1d29..0afd47f791 100644
--- a/libgnucash/engine/qofsession.cpp
+++ b/libgnucash/engine/qofsession.cpp
@@ -51,7 +51,7 @@
 
 static QofLogModule log_module = QOF_MOD_SESSION;
 
-#include "qofbook-p.h"
+#include "qofbook-p.hpp"
 #include "qof-backend.hpp"
 #include "qofsession.hpp"
 #include "gnc-backend-prov.hpp"
diff --git a/libgnucash/engine/test/CMakeLists.txt b/libgnucash/engine/test/CMakeLists.txt
index 6d5b073694..11d40cb655 100644
--- a/libgnucash/engine/test/CMakeLists.txt
+++ b/libgnucash/engine/test/CMakeLists.txt
@@ -24,7 +24,7 @@ add_engine_test(test-commodities test-commodities.cpp)
 set(test_qof_SOURCES
   test-gnc-date.c
   test-qof.c
-  test-qofbook.c
+  test-qofbook.cpp
   test-qofinstance.cpp
   test-qofobject.c
   test-qof-string-cache.c
@@ -243,7 +243,7 @@ set(test_engine_SOURCES_DIST
         test-object.c
         test-qof.c
         test-qofid.cpp
-        test-qofbook.c
+        test-qofbook.cpp
         test-qofinstance.cpp
         test-qofobject.c
         test-qofsession.cpp
diff --git a/libgnucash/engine/test/test-qofbook.c b/libgnucash/engine/test/test-qofbook.cpp
similarity index 98%
rename from libgnucash/engine/test/test-qofbook.c
rename to libgnucash/engine/test/test-qofbook.cpp
index 9cc86bd290..eb90406251 100644
--- a/libgnucash/engine/test/test-qofbook.c
+++ b/libgnucash/engine/test/test-qofbook.cpp
@@ -27,13 +27,13 @@
 
 #include "../qof.h"
 #include "../gnc-features.h"
-#include "../qofbook-p.h"
+#include "../qofbook-p.hpp"
 #include "../qofbookslots.h"
 /* For gnc_account_create_root() */
 #include "../Account.h"
 
 static const gchar *suitename = "/qof/qofbook";
-void test_suite_qofbook ( void );
+extern "C" void test_suite_qofbook ( void );
 
 typedef struct
 {
@@ -842,15 +842,15 @@ test_book_foreach_collection( Fixture *fixture, gconstpointer pData )
 #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";
+    const char* msg1 = _func ": assertion 'book' failed";
+    const char* 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 };
+    const gchar *log_domain = "qof";
+    auto loglevel = static_cast<GLogLevelFlags>(G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL);
+    guint hdlr;
+    TestErrorStruct check1 = { loglevel, const_cast<char*>(log_domain), const_cast<char*>(msg1) };
+    TestErrorStruct check2 = { loglevel, const_cast<char*>(log_domain), const_cast<char*>(msg2) };
 
     /* need this as long as we have fatal warnings enabled */
     g_test_log_set_fatal_handler ( ( GTestLogFatalFunc )handle_faults, NULL );
@@ -985,7 +985,7 @@ test_book_new_destroy( void )
     g_free (test_funcs);
 }
 
-void
+extern "C" void
 test_suite_qofbook ( void )
 {
     GNC_TEST_ADD( suitename, "readonly", Fixture, NULL, setup, test_book_readonly, teardown );

commit 8b6d93eb87177378d1d96f474035407fe4ac0543
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Mon Jun 8 11:53:12 2026 +0800

    [test-qofbook.c] use getters instead of accessing QofBook members

diff --git a/libgnucash/engine/qofbook-p.h b/libgnucash/engine/qofbook-p.h
index 80a79f7bea..939387c509 100644
--- a/libgnucash/engine/qofbook-p.h
+++ b/libgnucash/engine/qofbook-p.h
@@ -46,6 +46,23 @@ extern "C"
 {
 #endif
 
+/* Structure for accessing static functions for testing */
+typedef struct
+{
+    gboolean (*get_session_dirty)(const QofBook*);
+    gboolean (*get_read_only)(const QofBook*);
+    QofBookDirtyCB (*get_dirty_cb)(const QofBook*);
+    void (*set_shutting_down)(QofBook*, gboolean);
+    gpointer (*get_dirty_data)(const QofBook*);
+    GHashTable* (*get_collections)(const QofBook*);
+    GHashTable* (*get_data_tables)(const QofBook*);
+    GHashTable* (*get_data_table_finalizers)(const QofBook*);
+    char (*get_book_open)(const QofBook*);
+    int (*get_version)(const QofBook*);
+} QofBookTestFunctions;
+
+QofBookTestFunctions* _utest_qofbook_fill_functions (void);
+
 /*
  *    qof_book_set_backend() is used by backends to
  *    initialize the pointers in the book structure to
diff --git a/libgnucash/engine/qofbook.cpp b/libgnucash/engine/qofbook.cpp
index 67cccfc854..c19e62e6d3 100644
--- a/libgnucash/engine/qofbook.cpp
+++ b/libgnucash/engine/qofbook.cpp
@@ -1426,4 +1426,37 @@ gboolean qof_book_register (void)
     return TRUE;
 }
 
+
+
+static gboolean get_session_dirty(const QofBook *book){ return book->session_dirty; }
+static gboolean get_read_only(const QofBook *book){ return book->read_only; }
+static QofBookDirtyCB get_dirty_cb(const QofBook *book){ return book->dirty_cb; }
+static void set_shutting_down(QofBook *book, gboolean state){ book->shutting_down = state; }
+static gpointer get_dirty_data(const QofBook *book){ return book->dirty_data; }
+static GHashTable* get_collections(const QofBook *book){ return book->hash_of_collections; }
+static GHashTable* get_data_tables(const QofBook *book){ return book->data_tables; }
+static GHashTable* get_data_table_finalizers(const QofBook *book){ return book->data_table_finalizers; }
+static char get_book_open(const QofBook *book){ return book->book_open; }
+static int get_version(const QofBook *book){ return book->version; }
+
+
+QofBookTestFunctions*
+_utest_qofbook_fill_functions (void)
+{
+    QofBookTestFunctions *func = g_new (QofBookTestFunctions, 1);
+
+    func->get_session_dirty = get_session_dirty;
+    func->get_read_only = get_read_only;
+    func->get_dirty_cb = get_dirty_cb;
+    func->set_shutting_down = set_shutting_down;
+    func->get_dirty_data = get_dirty_data;
+    func->get_collections = get_collections;
+    func->get_data_tables = get_data_tables;
+    func->get_data_table_finalizers = get_data_table_finalizers;
+    func->get_book_open = get_book_open;
+    func->get_version = get_version;
+    return func;
+}
+
+
 /* ========================== END OF FILE =============================== */
diff --git a/libgnucash/engine/test/test-qofbook.c b/libgnucash/engine/test/test-qofbook.c
index e74d37a7e7..9cc86bd290 100644
--- a/libgnucash/engine/test/test-qofbook.c
+++ b/libgnucash/engine/test/test-qofbook.c
@@ -633,6 +633,7 @@ test_book_mark_session_dirty( Fixture *fixture, gconstpointer pData )
     QofBook *_empty = NULL;
     time64 before, after;
     guint param = (guint) g_test_rand_int();
+    QofBookTestFunctions* test_funcs = _utest_qofbook_fill_functions ();
 
     g_test_message( "Testing when book is NULL" );
     qof_book_mark_session_dirty( _empty );
@@ -640,7 +641,7 @@ test_book_mark_session_dirty( Fixture *fixture, gconstpointer pData )
 
     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_true( fixture->book->dirty_cb == NULL );
+    g_assert_true( test_funcs->get_dirty_cb (fixture->book) == NULL );
     g_assert_true( qof_book_session_not_saved( fixture->book ) == FALSE );
     before = gnc_time (NULL);
     gnc_account_create_root (fixture->book);
@@ -656,7 +657,7 @@ test_book_mark_session_dirty( Fixture *fixture, gconstpointer pData )
     qof_book_set_dirty_cb( fixture->book, mock_dirty_cb, (gpointer) (&param) );
     test_struct.data = (gpointer) (&param);
     test_struct.called = FALSE;
-    g_assert_true( fixture->book->dirty_cb != NULL );
+    g_assert_true( test_funcs->get_dirty_cb (fixture->book) != NULL );
     g_assert_cmpint( qof_book_get_session_dirty_time( fixture->book ), == , 0);
     g_assert_true( qof_book_session_not_saved( fixture->book ) == FALSE );
     /* run FUT */
@@ -676,6 +677,8 @@ test_book_mark_session_dirty( Fixture *fixture, gconstpointer pData )
     g_assert_true( qof_book_session_not_saved( fixture->book ) == TRUE );
     after = qof_book_get_session_dirty_time( fixture->book );
     g_assert_cmpint( before, == , after );
+
+    g_free (test_funcs);
 }
 
 static void
@@ -700,36 +703,40 @@ static void
 test_book_set_dirty_cb( Fixture *fixture, gconstpointer pData )
 {
     const char * error_msg = "Already existing callback";
+    QofBookTestFunctions* test_funcs = _utest_qofbook_fill_functions ();
 
     g_test_message( "Testing when callback is previously not set" );
-    g_assert_true( fixture->book->dirty_cb == NULL );
+    g_assert_true( test_funcs->get_dirty_cb (fixture->book) == NULL );
     qof_book_set_dirty_cb( fixture->book, mock_dirty_cb, (gpointer) (&test_struct) );
-    g_assert_true( fixture->book->dirty_cb == mock_dirty_cb );
-    g_assert_true( fixture->book->dirty_data == &test_struct );
+    g_assert_true( test_funcs->get_dirty_cb (fixture->book) == mock_dirty_cb );
+    g_assert_true( test_funcs->get_dirty_data (fixture->book) == &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_true( fixture->book->dirty_cb != NULL );
+    g_assert_true( test_funcs->get_dirty_cb (fixture->book) != NULL );
     qof_book_set_dirty_cb( fixture->book, NULL, NULL );
     g_assert_true( g_strrstr( test_struct.msg, error_msg ) != NULL );
-    g_assert_true( fixture->book->dirty_cb == NULL );
-    g_assert_true( fixture->book->dirty_data == NULL );
+    g_assert_true( test_funcs->get_dirty_cb (fixture->book) == NULL );
+    g_assert_true( test_funcs->get_dirty_data (fixture->book) == NULL );
     g_free( test_struct.msg );
+    g_free (test_funcs);
 }
 
 static void
 test_book_shutting_down( Fixture *fixture, gconstpointer pData )
 {
+    QofBookTestFunctions* test_funcs = _utest_qofbook_fill_functions ();
     g_test_message( "Testing when book is null" );
     g_assert_true( qof_book_shutting_down( NULL ) == FALSE );
     g_test_message( "Testing when shutting down is true" );
-    fixture->book->shutting_down = TRUE;
+    test_funcs->set_shutting_down (fixture->book, TRUE);
     g_assert_true( qof_book_shutting_down( fixture->book ) == TRUE );
     g_test_message( "Testing when shutting down is false" );
-    fixture->book->shutting_down = FALSE;
+    test_funcs->set_shutting_down (fixture->book, FALSE);
     g_assert_true( qof_book_shutting_down( fixture->book ) == FALSE );
+    g_free (test_funcs);
 }
 
 static void
@@ -737,8 +744,9 @@ test_book_set_get_data( Fixture *fixture, gconstpointer pData )
 {
     const char *key = "key";
     const char *data = "data";
+    QofBookTestFunctions* test_funcs = _utest_qofbook_fill_functions ();
 
-    g_assert_true( fixture->book->data_tables != NULL );
+    g_assert_true( test_funcs->get_data_tables (fixture->book) != NULL );
     g_test_message( "Testing when book is null" );
     qof_book_set_data( NULL, key, (gpointer) data );
     g_assert_true( qof_book_get_data( NULL, key ) == NULL );
@@ -754,6 +762,8 @@ test_book_set_get_data( Fixture *fixture, gconstpointer pData )
     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 );
+
+    g_free (test_funcs);
 }
 
 static void
@@ -761,6 +771,7 @@ test_book_get_collection( Fixture *fixture, gconstpointer pData )
 {
     QofIdType my_type = "my type";
     QofCollection *m_col, *m_col2;
+    QofBookTestFunctions* test_funcs = _utest_qofbook_fill_functions ();
 
     g_test_message( "Testing when book is null" );
     g_assert_true( qof_book_get_collection( NULL, my_type ) == NULL );
@@ -769,16 +780,18 @@ test_book_get_collection( Fixture *fixture, gconstpointer pData )
     g_assert_true( qof_book_get_collection( fixture->book, NULL ) == NULL );
 
     g_test_message( "Testing when collection does not exist" );
-    g_assert_true( fixture->book->hash_of_collections != NULL );
-    g_assert_true( g_hash_table_lookup ( fixture->book->hash_of_collections, my_type ) == NULL );
+    g_assert_true (test_funcs->get_collections (fixture->book) != NULL );
+    g_assert_true (g_hash_table_lookup (test_funcs->get_collections (fixture->book), my_type ) == NULL);
     m_col = qof_book_get_collection( fixture->book, my_type );
     g_assert_true( m_col != NULL );
 
     g_test_message( "Testing with existing collection" );
-    g_assert_true( g_hash_table_lookup ( fixture->book->hash_of_collections, my_type ) != NULL );
+    g_assert_true (g_hash_table_lookup (test_funcs->get_collections (fixture->book), my_type ) != NULL);
     m_col2 = qof_book_get_collection( fixture->book, my_type );
     g_assert_true( m_col2 != NULL );
     g_assert_true( m_col == m_col2 );
+
+    g_free (test_funcs);
 }
 
 
@@ -882,56 +895,60 @@ test_book_set_data_fin( void )
     QofBook *book;
     const char *key = "key";
     const char *data = "data";
+    QofBookTestFunctions* test_funcs = _utest_qofbook_fill_functions ();
 
     /* 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_assert_cmpint( g_hash_table_size( test_funcs->get_data_tables (book) ), == , 0 );
+    g_assert_cmpint( g_hash_table_size( test_funcs->get_data_table_finalizers (book) ), == , 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_assert_cmpint( g_hash_table_size( test_funcs->get_data_tables (book) ), == , 0 );
+    g_assert_cmpint( g_hash_table_size( test_funcs->get_data_table_finalizers (book) ), == , 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_assert_cmpint( g_hash_table_size( test_funcs->get_data_tables (book) ), == , 0 );
+    g_assert_cmpint( g_hash_table_size( test_funcs->get_data_table_finalizers (book) ), == , 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_cmpint( g_hash_table_size( test_funcs->get_data_tables (book) ), == , 1 );
+    g_assert_cmpint( g_hash_table_size( test_funcs->get_data_table_finalizers (book) ), == , 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_cmpint( g_hash_table_size( test_funcs->get_data_tables (book) ), == , 1 );
+    g_assert_cmpint( g_hash_table_size( test_funcs->get_data_table_finalizers (book) ), == , 1 );
     g_assert_cmpstr( (const char *)qof_book_get_data( book, key ), == , data );
-    g_assert_true( g_hash_table_lookup ( book->data_table_finalizers, (gpointer)key ) == mock_final_cb );
+    g_assert_true( g_hash_table_lookup ( test_funcs->get_data_table_finalizers (book), (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_true( test_struct.called );
+    g_free (test_funcs);
 }
 
 static void
 test_book_mark_closed( Fixture *fixture, gconstpointer pData )
 {
+    QofBookTestFunctions* test_funcs = _utest_qofbook_fill_functions ();
     g_test_message( "Testing when book is null" );
-    g_assert_cmpstr( &fixture->book->book_open, == , "y" );
+    g_assert_true (qof_book_is_open (fixture->book));
     qof_book_mark_closed( NULL );
-    g_assert_cmpstr( &fixture->book->book_open, == , "y" );
+    g_assert_cmpint (test_funcs->get_book_open (fixture->book), == , 'y' );
 
     g_test_message( "Testing when book is not null" );
     qof_book_mark_closed( fixture->book );
-    g_assert_cmpstr( &fixture->book->book_open, == , "n" );
+    g_assert_false (qof_book_is_open (fixture->book));
+    g_free (test_funcs);
 }
 
 static void
@@ -940,6 +957,7 @@ test_book_new_destroy( void )
     QofBook *book;
     const char *key = "key";
     const char *data = "data";
+    QofBookTestFunctions* test_funcs = _utest_qofbook_fill_functions ();
 
     g_test_message( "Testing book creation and initial setup" );
     book = qof_book_new();
@@ -947,22 +965,24 @@ test_book_new_destroy( void )
     g_assert_true( QOF_IS_BOOK( book ) );
 
     g_test_message( "Testing book initial setup" );
-    g_assert_true( book->hash_of_collections );
-    g_assert_true( book->data_tables );
-    g_assert_true( book->data_table_finalizers );
-    g_assert_cmpint( g_hash_table_size( book->hash_of_collections ), == , 1 );
-    g_assert_true( 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_true( !book->read_only );
-    g_assert_cmpint( book->version, == , 0 );
+    g_assert_true (test_funcs->get_collections (book) != NULL);
+    g_assert_true( test_funcs->get_data_tables (book) );
+    g_assert_true( test_funcs->get_data_table_finalizers (book) );
+    g_assert_cmpint( g_hash_table_size( test_funcs->get_collections (book) ), == , 1 );
+    g_assert_true( g_hash_table_lookup (test_funcs->get_collections (book), QOF_ID_BOOK ) != NULL );
+    g_assert_cmpint( g_hash_table_size( test_funcs->get_data_tables (book) ), == , 0 );
+    g_assert_cmpint( g_hash_table_size( test_funcs->get_data_table_finalizers (book) ), == , 0 );
+    g_assert_true (qof_book_is_open(book));
+    g_assert_true (!qof_book_is_readonly(book));
+    g_assert_cmpint (test_funcs->get_version (book), == , 0);
 
     /* set finalizer */
     qof_book_set_data_fin( book, key, (gpointer) data, mock_final_cb );
     test_struct.called = FALSE;
 
     qof_book_destroy( book );
+
+    g_free (test_funcs);
 }
 
 void



Summary of changes:
 .../import-export/test/gtest-import-backend.cpp    |   4 +-
 libgnucash/engine/CMakeLists.txt                   |   2 +-
 libgnucash/engine/mocks/CMakeLists.txt             |   4 +-
 libgnucash/engine/mocks/gmock-Split.cpp            |   4 +-
 .../mocks/{gmock-Split.h => gmock-Split.hpp}       |   2 +-
 libgnucash/engine/mocks/gmock-qofbook.cpp          |   2 +-
 .../mocks/{gmock-qofbook.h => gmock-qofbook.hpp}   |   2 +-
 libgnucash/engine/qofbook-p.h                      |  86 ----------
 libgnucash/engine/qofbook-p.hpp                    | 182 +++++++++++++++++++++
 libgnucash/engine/qofbook.cpp                      |  35 +++-
 libgnucash/engine/qofbook.h                        |  85 ----------
 libgnucash/engine/qofinstance.cpp                  |   2 +-
 libgnucash/engine/qofinstance.h                    |   2 +-
 libgnucash/engine/qofquery.cpp                     |   2 +-
 libgnucash/engine/qofsession.cpp                   |   2 +-
 libgnucash/engine/test/CMakeLists.txt              |   4 +-
 .../test/{test-qofbook.c => test-qofbook.cpp}      | 116 +++++++------
 17 files changed, 300 insertions(+), 236 deletions(-)
 rename libgnucash/engine/mocks/{gmock-Split.h => gmock-Split.hpp} (99%)
 rename libgnucash/engine/mocks/{gmock-qofbook.h => gmock-qofbook.hpp} (98%)
 delete mode 100644 libgnucash/engine/qofbook-p.h
 create mode 100644 libgnucash/engine/qofbook-p.hpp
 rename libgnucash/engine/test/{test-qofbook.c => test-qofbook.cpp} (89%)



More information about the gnucash-changes mailing list