GnuCash  2.6.99
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
test-qofinstance.c
1 /********************************************************************
2  * test_qofinstance.c: GLib g_test test suite for qofinstance. *
3  * Copyright 2011 John Ralls <[email protected]> *
4  * *
5  * This program is free software; you can redistribute it and/or *
6  * modify it under the terms of the GNU General Public License as *
7  * published by the Free Software Foundation; either version 2 of *
8  * the License, or (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License*
16  * along with this program; if not, contact: *
17  * *
18  * Free Software Foundation Voice: +1-617-542-5942 *
19  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
20  * Boston, MA 02110-1301, USA [email protected] *
21 \********************************************************************/
22 #include <config.h>
23 #include <glib.h>
24 #include <unittest-support.h>
25 #include "../qof.h"
26 #include "../qofbackend-p.h"
27 
28 static const gchar *suitename = "/qof/qofinstance";
29 void test_suite_qofinstance ( void );
30 static gchar* error_message;
31 static gboolean is_called;
32 
33 #ifdef HAVE_GLIB_2_38
34 #define _Q "'"
35 #else
36 #define _Q "`"
37 #endif
38 
39 typedef struct
40 {
41  QofInstance *inst;
42 } Fixture;
43 
44 /* use g_free on error_message after this function been called */
45 static gboolean
46 fatal_handler ( const char * log_domain,
47  GLogLevelFlags log_level,
48  const gchar *msg,
49  gpointer user_data)
50 {
51  error_message = (gchar *) g_strdup( msg );
52  return FALSE;
53 }
54 
55 static void
56 setup( Fixture *fixture, gconstpointer pData )
57 {
58  fixture->inst = g_object_new(QOF_TYPE_INSTANCE, NULL);
59 }
60 
61 static void
62 teardown( Fixture *fixture, gconstpointer pData )
63 {
64  g_object_unref(fixture->inst);
65 }
66 
67 static void
68 test_instance_set_get_book( Fixture *fixture, gconstpointer pData )
69 {
70  QofBook *book;
71 
72  /* set up */
73  book = qof_book_new();
74 
75  g_assert( QOF_IS_INSTANCE( fixture->inst ) );
76 
77  g_test_message( "Setting and getting book" );
78  qof_instance_set_book( fixture->inst, book );
79  g_assert( book == qof_instance_get_book( fixture->inst ) );
80 
81  g_test_message( "Getting book when instance is null" );
82  g_assert( qof_instance_get_book( NULL ) == NULL );
83 
84  /* Clean up */
85  qof_book_destroy( book );
86 }
87 
88 static void
89 test_instance_set_get_guid( Fixture *fixture, gconstpointer pData )
90 {
91  GncGUID *gncGuid;
92 
93  /* on null instance deprecated getter returns empty guid
94  * while instance_get_guid returns null
95  */
96  g_assert( !qof_instance_get_guid( NULL ) );
97  g_assert( qof_entity_get_guid( NULL ) == guid_null() );
98 
99  /* set up */
100  gncGuid = guid_new();
101  g_assert( QOF_IS_INSTANCE( fixture->inst ) );
102  g_assert( gncGuid );
103 
104  /* guid already exists after instance init */
105  g_test_message( "Setting new guid" );
106  g_assert( qof_instance_get_guid( fixture->inst ) );
107  g_assert( !guid_equal( gncGuid, qof_instance_get_guid( fixture->inst ) ) );
108  qof_instance_set_guid( fixture->inst, gncGuid );
109  g_assert( guid_equal( gncGuid, qof_instance_get_guid( fixture->inst ) ) );
110  g_assert( guid_equal( gncGuid, qof_entity_get_guid( fixture->inst ) ) );
111 
112  /* Clean up */
113  guid_free( gncGuid );
114 }
115 
116 static void
117 test_instance_new_destroy( void )
118 {
119  /* qofinstance var */
120  QofInstance *inst;
121  QofInstanceClass *klass;
122  /* test var */
123  Timespec *timespec_priv;
124  gchar *msg1 = "qof_instance_get_collection: assertion " _Q "QOF_IS_INSTANCE(ptr)' failed";
125  gchar *msg2 = "qof_instance_get_editlevel: assertion " _Q "QOF_IS_INSTANCE(ptr)' failed";
126  gchar *msg3 = "qof_instance_get_destroying: assertion " _Q "QOF_IS_INSTANCE(ptr)' failed";
127  gchar *msg4 = "qof_instance_get_dirty_flag: assertion " _Q "QOF_IS_INSTANCE(ptr)' failed";
128  gchar *log_domain = "qof";
129  guint loglevel = G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL, hdlr;
130  TestErrorStruct check = { loglevel, log_domain, msg1 };
131 
132  g_test_message( "Testing qofinstance object initialization" );
133  inst = g_object_new(QOF_TYPE_INSTANCE, NULL);
134  g_assert( QOF_IS_INSTANCE( inst ) );
135  /* test class fields */
136  klass = QOF_INSTANCE_GET_CLASS( inst );
137  g_assert( QOF_IS_INSTANCE_CLASS( klass ) );
138  g_assert( klass->get_display_name == NULL );
139  g_assert( klass->refers_to_object == NULL );
140  g_assert( klass->get_typed_referring_object_list == NULL );
141  /* testing initial values */
142  g_assert( qof_instance_get_guid( inst ) );
143  g_assert( !qof_instance_get_collection( inst ) );
144  g_assert( qof_instance_get_book( inst ) == NULL );
145  g_assert( inst->kvp_data );
146  g_object_get( inst, "last-update", &timespec_priv, NULL);
147  g_assert_cmpint( timespec_priv->tv_sec, == , 0 );
148  g_assert_cmpint( timespec_priv->tv_nsec, == , -1 );
149  g_assert_cmpint( qof_instance_get_editlevel( inst ), == , 0 );
150  g_assert( !qof_instance_get_destroying( inst ) );
151  g_assert( !qof_instance_get_dirty_flag( inst ) );
152  g_assert( qof_instance_get_infant( inst ) );
153  g_assert_cmpint( qof_instance_get_version( inst ), == , 0 );
154  g_assert_cmpint( qof_instance_get_version_check( inst ), == , 0 );
155  g_assert_cmpint( qof_instance_get_idata( inst ), == , 0 );
156 
157  g_test_message( "Testing object destruction" );
158  g_object_unref( inst );
159  /* test fields were deinitialized */
160  g_assert( inst );
161  g_assert( !QOF_IS_INSTANCE( inst ) );
162  /* set fatal handler */
163  g_test_log_set_fatal_handler ( ( GTestLogFatalFunc )fatal_handler, NULL );
164  hdlr = g_log_set_handler (log_domain, loglevel,
165  (GLogFunc)test_checked_handler, &check);
166  g_assert( qof_instance_get_collection( inst ) == NULL );
167  g_assert( g_strrstr( error_message, "assertion " _Q "QOF_IS_INSTANCE(ptr)' failed" ) != NULL );
168  g_free( error_message );
169 
170  check.msg = msg2;
171  g_assert_cmpint( qof_instance_get_editlevel( inst ), == , 0 );
172  g_assert( g_strrstr( error_message, "assertion " _Q "QOF_IS_INSTANCE(ptr)' failed" ) != NULL );
173  g_free( error_message );
174 
175  check.msg = msg3;
176  g_assert( !qof_instance_get_destroying( inst ) );
177  g_assert( g_strrstr( error_message, "assertion " _Q "QOF_IS_INSTANCE(ptr)' failed" ) != NULL );
178  g_free( error_message );
179 
180  check.msg = msg4;
181  g_assert( !qof_instance_get_dirty_flag( inst ) );
182  g_assert( g_strrstr( error_message, "assertion " _Q "QOF_IS_INSTANCE(ptr)' failed" ) != NULL );
183  g_free( error_message );
184  g_log_remove_handler (log_domain, hdlr);
185 }
186 
187 static void
188 test_instance_init_data( void )
189 {
190  QofInstance *inst;
191  QofIdType test_type = "test type";
192  QofBook *book;
193  QofCollection *col;
194  const GncGUID *gncguid;
195  char guid_id_before[GUID_ENCODING_LENGTH + 1];
196  char guid_id_after[GUID_ENCODING_LENGTH + 1];
197 
198  /* set up */
199  inst = g_object_new( QOF_TYPE_INSTANCE, NULL );
200  g_assert( QOF_IS_INSTANCE( inst ) );
201  book = qof_book_new();
202  g_assert( QOF_IS_BOOK( book ) );
203  /* set fatal handler */
204  g_test_log_set_fatal_handler ( ( GTestLogFatalFunc )fatal_handler, NULL );
205 
206  g_test_message( "Running test with correct initial data" );
207  gncguid = qof_instance_get_guid( inst );
208  g_assert( gncguid );
209  guid_to_string_buff( gncguid, guid_id_before );
210  g_assert( qof_instance_get_book( inst ) == NULL );
211  g_assert( qof_instance_get_collection( inst ) == NULL );
212  /* run init */
213  qof_instance_init_data( inst, test_type, book );
214 
215  g_assert( qof_instance_get_book( inst ) == book );
216  guid_to_string_buff( gncguid, guid_id_after );
217  g_assert_cmpstr( guid_id_before, != , guid_id_after );
218  g_assert( qof_instance_get_collection( inst ) != NULL );
219  col = qof_book_get_collection( book, test_type );
220  g_assert( col );
221  g_assert( col == qof_instance_get_collection( inst ) );
222  g_assert_cmpstr( inst->e_type, == , test_type );
223  g_assert( qof_collection_lookup_entity( qof_instance_get_collection( inst ), gncguid ) == inst );
224 
225  /* clean up */
226  g_object_unref( inst );
227  qof_book_destroy( book );
228 }
229 
230 static void
231 test_instance_get_set_slots( Fixture *fixture, gconstpointer pData )
232 {
233  KvpFrame *kvp_frame, *kvp_frame2;
234 
235  /* set up */
236  g_assert( fixture->inst );
237  kvp_frame = qof_instance_get_slots( fixture->inst );
238  g_assert( kvp_frame );
239 
240  g_test_message( "Test when kvp frame is the same" );
241  qof_instance_set_slots( fixture->inst, kvp_frame );
242  g_assert( kvp_frame == qof_instance_get_slots( fixture->inst ) );
243  g_assert( qof_instance_get_dirty_flag( fixture->inst ) );
244 
245  g_test_message( "Test when kvp frame is not the same" );
246  kvp_frame2 = kvp_frame_new();
247  g_assert( kvp_frame != kvp_frame2 );
248  qof_instance_set_slots( fixture->inst, kvp_frame2 );
249  g_assert( kvp_frame2 == qof_instance_get_slots( fixture->inst ) );
250  g_assert( qof_instance_get_dirty_flag( fixture->inst ) );
251 
252  g_test_message( "Test when kvp frame is null" );
253  qof_instance_set_slots( fixture->inst, NULL );
254  g_assert( NULL == qof_instance_get_slots( fixture->inst ) );
255  g_assert( qof_instance_get_dirty_flag( fixture->inst ) );
256 
257 }
258 
259 static void
260 test_instance_version_cmp( void )
261 {
262  QofInstance *left, *right;
263  int result;
264  Timespec timespec_left, timespec_right;
265 
266  /* set up*/
267  left = g_object_new( QOF_TYPE_INSTANCE, NULL );
268  right = g_object_new( QOF_TYPE_INSTANCE, NULL );
269 
270  g_test_message( "Test both null" );
271  result = qof_instance_version_cmp( NULL, NULL );
272  g_assert_cmpint( result, == , 0 );
273 
274  g_test_message( "Test left null" );
275  result = qof_instance_version_cmp( NULL, right );
276  g_assert_cmpint( result, == , -1 );
277 
278  g_test_message( "Test right null" );
279  result = qof_instance_version_cmp( left, NULL );
280  g_assert_cmpint( result, == , 1 );
281 
282  g_test_message( "Test left tv_sec lesser than right" );
283  timespec_left.tv_sec = 0;
284  timespec_right.tv_sec = 1;
285  qof_instance_set_last_update( left, timespec_left );
286  qof_instance_set_last_update( right, timespec_right );
287  result = qof_instance_version_cmp( left, right );
288  g_assert_cmpint( result, == , -1 );
289 
290  g_test_message( "Test right tv_sec lesser than left" );
291  timespec_left.tv_sec = 1;
292  timespec_right.tv_sec = 0;
293  qof_instance_set_last_update( left, timespec_left );
294  qof_instance_set_last_update( right, timespec_right );
295  result = qof_instance_version_cmp( left, right );
296  g_assert_cmpint( result, == , 1 );
297 
298  g_test_message( "Test left tv_nsec lesser than right" );
299  timespec_left.tv_sec = 1;
300  timespec_left.tv_nsec = 0;
301  timespec_right.tv_sec = 1;
302  timespec_right.tv_nsec = 1;
303  qof_instance_set_last_update( left, timespec_left );
304  qof_instance_set_last_update( right, timespec_right );
305  result = qof_instance_version_cmp( left, right );
306  g_assert_cmpint( result, == , -1 );
307 
308  g_test_message( "Test right tv_sec lesser than left" );
309  timespec_left.tv_sec = 1;
310  timespec_left.tv_nsec = 1;
311  timespec_right.tv_sec = 1;
312  timespec_right.tv_nsec = 0;
313  qof_instance_set_last_update( left, timespec_left );
314  qof_instance_set_last_update( right, timespec_right );
315  result = qof_instance_version_cmp( left, right );
316  g_assert_cmpint( result, == , 1 );
317 
318  g_test_message( "Test both equal" );
319  timespec_left.tv_sec = 1;
320  timespec_left.tv_nsec = 1;
321  timespec_right.tv_sec = 1;
322  timespec_right.tv_nsec = 1;
323  qof_instance_set_last_update( left, timespec_left );
324  qof_instance_set_last_update( right, timespec_right );
325  result = qof_instance_version_cmp( left, right );
326  g_assert_cmpint( result, == , 0 );
327 
328  /* clear */
329  g_object_unref( left );
330  g_object_unref( right );
331 }
332 
333 static void
334 test_instance_get_set_dirty( Fixture *fixture, gconstpointer pData )
335 {
336  QofIdType type = "test type";
337  QofCollection *col;
338 
339  /* setup */
340  col = qof_collection_new ( type );
341  qof_instance_set_collection( fixture->inst, col );
342  g_assert( qof_instance_get_collection( fixture->inst ) );
343 
344  g_test_message( "Test get_dirty on empty instance returns false" );
345  g_assert( qof_instance_get_dirty( NULL ) == FALSE );
346 
347  g_test_message( "Test dirty in normal mode" );
348  g_assert( !qof_get_alt_dirty_mode() );
349  g_assert( !qof_instance_get_dirty_flag( fixture->inst ) );
350  g_assert( !qof_collection_is_dirty( col ) );
351  g_assert( !qof_instance_get_dirty( fixture->inst ) );
352  qof_instance_set_dirty( fixture->inst );
353  g_assert( qof_instance_get_dirty_flag( fixture->inst ) );
354  g_assert( qof_collection_is_dirty( col ) );
355  g_assert( qof_instance_get_dirty( fixture->inst ) );
356 
357 
358  g_test_message( "Test dirty in alternate mode" );
359  qof_set_alt_dirty_mode ( TRUE );
360  /* restore */
362  qof_instance_set_dirty_flag( fixture->inst, FALSE );
363 
364  g_assert( qof_get_alt_dirty_mode() );
365  g_assert( !qof_instance_get_dirty_flag( fixture->inst ) );
366  g_assert( !qof_collection_is_dirty( col ) );
367  g_assert( !qof_instance_get_dirty( fixture->inst ) );
368  qof_instance_set_dirty( fixture->inst );
369  g_assert( qof_instance_get_dirty_flag( fixture->inst ) );
370  g_assert( !qof_collection_is_dirty( col ) );
371  g_assert( qof_instance_get_dirty( fixture->inst ) );
372 
373  /* clean up */
374  qof_instance_set_collection( fixture->inst, NULL );
375  qof_collection_destroy( col );
376 }
377 
378 /* mock display name function */
379 static gchar*
380 mock_get_display_name(const QofInstance* inst)
381 {
382  gchar *display_name;
383 
384  g_assert( inst );
385  g_assert( QOF_INSTANCE_GET_CLASS( inst )->get_display_name == mock_get_display_name );
386  is_called = TRUE;
387  display_name = g_strdup_printf("Mock display name %p", inst );
388  return display_name;
389 }
390 
391 static void
392 test_instance_display_name( Fixture *fixture, gconstpointer pData )
393 {
394  QofIdType type = "test type";
395  QofCollection *col;
396  gchar *display_name, *default_display_name, *mock_display_name;
397 
398  /* setup */
399  g_assert( fixture->inst );
400  is_called = FALSE;
401  col = qof_collection_new ( type );
402  g_assert( col );
403  qof_instance_set_collection( fixture->inst, col );
404  g_assert( qof_instance_get_collection( fixture->inst ) );
405  default_display_name = g_strdup_printf( "Object %s %p", type, fixture->inst );
406  mock_display_name = g_strdup_printf( "Mock display name %p", fixture->inst );
407 
408  g_test_message( "Test instance when display name not set" );
409  g_assert( QOF_INSTANCE_GET_CLASS( fixture->inst )->get_display_name == NULL );
410  display_name = qof_instance_get_display_name( fixture->inst );
411  g_assert( !is_called );
412  g_assert_cmpstr( display_name, == , default_display_name );
413  g_free( display_name );
414 
415  g_test_message( "Test instance when display name is set" );
416  QOF_INSTANCE_GET_CLASS( fixture->inst )->get_display_name = mock_get_display_name;
417  display_name = qof_instance_get_display_name( fixture->inst );
418  g_assert( is_called );
419  g_assert_cmpstr( display_name, == , mock_display_name );
420  g_free( display_name );
421 
422  /* clean up */
423  g_free( default_display_name );
424  g_free( mock_display_name );
425  qof_instance_set_collection( fixture->inst, NULL );
426  qof_collection_destroy( col );
427 }
428 
429 static void
430 mock_backend_begin( QofBackend *be, QofInstance *inst )
431 {
432  g_assert( be );
433  g_assert( inst );
434  g_assert( be->begin == mock_backend_begin );
435  g_assert_cmpstr( inst->e_type, == , "test type" );
436  is_called = TRUE;
437 }
438 
439 static void
440 test_instance_begin_edit( Fixture *fixture, gconstpointer pData )
441 {
442  QofBackend *be;
443  QofBook *book;
444  gboolean result;
445 
446  /* setup */
447  be = g_new0( QofBackend, 1 );
448  g_assert( be );
449  qof_backend_init( be );
450  book = qof_book_new();
451  g_assert( book );
452  g_assert( QOF_IS_BOOK( book ) );
453  qof_book_set_backend( book, be );
454  g_assert( fixture->inst );
455  fixture->inst->e_type = "test type";
456  g_assert( qof_instance_get_dirty_flag( fixture->inst ) == FALSE );
457  g_assert_cmpint( qof_instance_get_editlevel( fixture->inst ), == , 0 );
458 
459  g_test_message( "Test when instance is null" );
460  result = qof_begin_edit( NULL );
461  g_assert( result == FALSE );
462 
463  g_test_message( "Test when instance's editlevel is >= 1" );
464  qof_instance_increase_editlevel( fixture->inst );
465  result = qof_begin_edit( fixture->inst );
466  g_assert( result == FALSE );
467  g_assert_cmpint( qof_instance_get_editlevel( fixture->inst ), == , 2 );
468 
469  g_test_message( "Test when instance's editlevel is <= 0 and backend not set" );
470  qof_instance_reset_editlevel( fixture->inst );
471  result = qof_begin_edit( fixture->inst );
472  g_assert( result == TRUE );
473  g_assert_cmpint( qof_instance_get_editlevel( fixture->inst ), == , 1 );
474  g_assert( qof_instance_get_dirty_flag( fixture->inst ) == TRUE );
475 
476  g_test_message( "Test when instance's editlevel is <= 0 and backend is set" );
477  result = FALSE;
478  is_called = FALSE;
479  qof_instance_reset_editlevel( fixture->inst );
480  qof_instance_set_dirty_flag( fixture->inst, FALSE );
481  qof_instance_set_book( fixture->inst, book );
482  be->begin = mock_backend_begin;
483  result = qof_begin_edit( fixture->inst );
484  g_assert( result == TRUE );
485  g_assert_cmpint( qof_instance_get_editlevel( fixture->inst ), == , 1 );
486  g_assert( qof_instance_get_dirty_flag( fixture->inst ) == FALSE );
487  g_assert( is_called );
488 
489  /* clean up */
490  qof_book_set_backend( book, NULL );
491  qof_book_destroy( book );
492  qof_backend_destroy( be );
493  g_free( be );
494 }
495 
496 static void
497 test_instance_commit_edit( Fixture *fixture, gconstpointer pData )
498 {
499  gboolean result;
500  gchar *msg = "[qof_commit_edit()] unbalanced call - resetting (was -2)";
501  gchar *log_domain = "qof.engine";
502  guint loglevel = G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL, hdlr;
503  TestErrorStruct check = { loglevel, log_domain, msg };
504 
505  g_test_message( "Test when instance set to null" );
506  result = qof_commit_edit( NULL );
507  g_assert( !result );
508 
509  g_test_message( "Test when instance's editlevel >= 2" );
510  qof_instance_increase_editlevel( fixture->inst );
511  qof_instance_increase_editlevel( fixture->inst );
512  g_assert_cmpint( qof_instance_get_editlevel( fixture->inst ), == , 2 );
513  result = qof_commit_edit( fixture->inst );
514  g_assert_cmpint( qof_instance_get_editlevel( fixture->inst ), == , 1 );
515  g_assert( !result );
516 
517  g_test_message( "Test when instance's editlevel = 1" );
518  result = qof_commit_edit( fixture->inst );
519  g_assert_cmpint( qof_instance_get_editlevel( fixture->inst ), == , 0 );
520  g_assert( result );
521 
522  g_test_message( "Test when instance's editlevel < 0" );
523  g_test_log_set_fatal_handler ( ( GTestLogFatalFunc )fatal_handler, NULL );
524  hdlr = g_log_set_handler (log_domain, loglevel,
525  (GLogFunc)test_checked_handler, &check);
526  qof_instance_decrease_editlevel( fixture->inst );
527  g_assert_cmpint( qof_instance_get_editlevel( fixture->inst ), == , -1 );
528  result = qof_commit_edit( fixture->inst );
529  g_assert_cmpint( qof_instance_get_editlevel( fixture->inst ), == , 0 );
530  g_assert_cmpstr( error_message, == , "[qof_commit_edit()] unbalanced call - resetting (was -2)" );
531  g_free( error_message );
532  g_log_remove_handler (log_domain, hdlr);
533 }
534 
535 /* backend commit test start */
536 
537 static struct
538 {
539  gpointer inst;
540  gpointer be;
541 
542  gboolean commit_called;
543  gboolean commit_with_err_called;
544  gboolean on_error_called;
545  gboolean on_free_called;
546  gboolean on_done_called;
547  QofBackendError err;
548 } commit_test_part2;
549 
550 static void
551 mock_backend_commit( QofBackend *be, QofInstance *inst )
552 {
553  g_assert( inst );
554  g_assert( be );
555  g_assert( QOF_IS_INSTANCE( inst ) );
556  g_assert( commit_test_part2.inst == inst );
557  g_assert( commit_test_part2.be == be );
558  commit_test_part2.commit_called = TRUE;
559 }
560 
561 static void
562 mock_backend_commit_with_error( QofBackend *be, QofInstance *inst )
563 {
564  g_assert( inst );
565  g_assert( be );
566  g_assert( QOF_IS_INSTANCE( inst ) );
567  g_assert( commit_test_part2.inst == inst );
568  g_assert( commit_test_part2.be == be );
570  commit_test_part2.err = ERR_BACKEND_NO_HANDLER;
571  commit_test_part2.commit_with_err_called = TRUE;
572 }
573 
574 
575 static void
576 mock_on_error( QofInstance *inst, QofBackendError be_error )
577 {
578  g_assert( inst );
579  g_assert( QOF_IS_INSTANCE( inst ) );
580  g_assert( commit_test_part2.err == be_error );
581  commit_test_part2.on_error_called = TRUE;
582 }
583 
584 static void
585 mock_on_done( QofInstance *inst )
586 {
587  g_assert( inst );
588  g_assert( QOF_IS_INSTANCE( inst ) );
589  g_assert( commit_test_part2.inst == inst );
590  commit_test_part2.on_done_called = TRUE;
591 }
592 
593 static void
594 mock_on_free( QofInstance *inst )
595 {
596  g_assert( inst );
597  g_assert( QOF_IS_INSTANCE( inst ) );
598  g_assert( commit_test_part2.inst == inst );
599  commit_test_part2.on_free_called = TRUE;
600 }
601 
602 static void
603 test_instance_commit_edit_part2( Fixture *fixture, gconstpointer pData )
604 {
605  QofBackend *be;
606  QofBook *book;
607  gboolean result;
608 
609  /* setup */
610  be = g_new0( QofBackend, 1 );
611  g_assert( be );
612  qof_backend_init( be );
613  book = qof_book_new();
614  g_assert( book );
615  g_assert( QOF_IS_BOOK( book ) );
616  qof_book_set_backend( book, be );
617 
618  /* init */
619  result = FALSE;
620  commit_test_part2.commit_called = FALSE;
621  commit_test_part2.commit_with_err_called = FALSE;
622  commit_test_part2.on_error_called = FALSE;
623  commit_test_part2.on_free_called = FALSE;
624  commit_test_part2.on_done_called = FALSE;
625  commit_test_part2.inst = fixture->inst;
626  commit_test_part2.be = be;
627  qof_instance_set_dirty_flag( fixture->inst, TRUE );
628 
629  g_test_message( "Test when instance's backend not set, callbacks not set" );
630  g_assert( qof_instance_get_infant( fixture->inst ) );
631  g_assert( !qof_instance_get_destroying( fixture->inst ) );
632  result = qof_commit_edit_part2( fixture->inst, NULL, NULL, NULL );
633  g_assert( result );
634  g_assert( qof_instance_get_dirty_flag( fixture->inst ) );
635  g_assert( !qof_instance_get_infant( fixture->inst ) );
636  g_assert( !commit_test_part2.commit_called );
637  g_assert( !commit_test_part2.commit_with_err_called );
638  g_assert( !commit_test_part2.on_error_called );
639  g_assert( !commit_test_part2.on_free_called );
640  g_assert( !commit_test_part2.on_done_called );
641 
642  g_test_message( "Test when instance's backend not set, do_free is true" );
643  qof_instance_set_destroying( fixture->inst, TRUE );
644  result = qof_commit_edit_part2( fixture->inst, mock_on_error, mock_on_done, mock_on_free );
645  g_assert( result );
646  g_assert( qof_instance_get_dirty_flag( fixture->inst ) );
647  g_assert( !commit_test_part2.commit_called );
648  g_assert( !commit_test_part2.commit_with_err_called );
649  g_assert( !commit_test_part2.on_error_called );
650  g_assert( commit_test_part2.on_free_called );
651  g_assert( !commit_test_part2.on_done_called );
652 
653  g_test_message( "Test when instance's backend not set, do_free is false" );
654  qof_instance_set_destroying( fixture->inst, FALSE );
655  commit_test_part2.on_free_called = FALSE;
656  result = qof_commit_edit_part2( fixture->inst, mock_on_error, mock_on_done, mock_on_free );
657  g_assert( result );
658  g_assert( qof_instance_get_dirty_flag( fixture->inst ) );
659  g_assert( !commit_test_part2.commit_called );
660  g_assert( !commit_test_part2.commit_with_err_called );
661  g_assert( !commit_test_part2.on_error_called );
662  g_assert( !commit_test_part2.on_free_called );
663  g_assert( commit_test_part2.on_done_called );
664 
665  g_test_message( "Test when instance's backend is set, all cb set, no error produced" );
666  qof_instance_set_book( fixture->inst, book );
667  qof_instance_set_destroying( fixture->inst, FALSE );
668  commit_test_part2.on_done_called = FALSE;
669  be->commit = mock_backend_commit;
670  result = qof_commit_edit_part2( fixture->inst, mock_on_error, mock_on_done, mock_on_free );
671  g_assert( result );
672  g_assert( !qof_instance_get_dirty_flag( fixture->inst ) );
673  g_assert( commit_test_part2.commit_called );
674  g_assert( !commit_test_part2.commit_with_err_called );
675  g_assert( !commit_test_part2.on_error_called );
676  g_assert( !commit_test_part2.on_free_called );
677  g_assert( commit_test_part2.on_done_called );
678 
679  g_test_message( "Test when instance's backend is set, all cb set, error produced" );
680  commit_test_part2.commit_called = FALSE;
681  commit_test_part2.on_done_called = FALSE;
682  be->commit = mock_backend_commit_with_error;
683  qof_instance_set_dirty_flag( fixture->inst, TRUE );
684  qof_instance_set_destroying( fixture->inst, TRUE );
685  result = qof_commit_edit_part2( fixture->inst, mock_on_error, mock_on_done, mock_on_free );
686  g_assert( !result );
687  g_assert( qof_instance_get_dirty_flag( fixture->inst ) );
688  g_assert( !qof_instance_get_destroying( fixture->inst ) );
689  g_assert( !commit_test_part2.commit_called );
690  g_assert( commit_test_part2.commit_with_err_called );
691  g_assert( commit_test_part2.on_error_called );
692  g_assert( !commit_test_part2.on_free_called );
693  g_assert( !commit_test_part2.on_done_called );
694 
695  /* clean up */
696  qof_book_set_backend( book, NULL );
697  qof_book_destroy( book );
698  qof_backend_destroy( be );
699  g_free( be );
700 }
701 
702 /* backend commit test end */
703 
704 /* object reference tests */
705 
706 static struct
707 {
708  gpointer inst;
709  gpointer ref;
710 
711  gboolean refers_to_object_called;
712 } refers_test_struct;
713 
714 static gboolean
715 mock_refers_to_object( const QofInstance* inst, const QofInstance* ref )
716 {
717  g_assert( inst );
718  g_assert( ref );
719  g_assert( refers_test_struct.inst == inst );
720  g_assert( refers_test_struct.ref == ref );
721  refers_test_struct.refers_to_object_called = TRUE;
722  return TRUE;
723 }
724 
725 static void
726 test_instance_refers_to_object( Fixture *fixture, gconstpointer pData )
727 {
728  QofInstance * ref;
729 
730  ref = g_object_new( QOF_TYPE_INSTANCE, NULL );
731  g_assert( fixture->inst );
732  g_assert( ref );
733  g_assert( QOF_INSTANCE_GET_CLASS( fixture->inst )->refers_to_object == NULL );
734  refers_test_struct.refers_to_object_called = FALSE;
735  refers_test_struct.inst = fixture->inst;
736  refers_test_struct.ref = ref;
737 
738  g_test_message( "Test when refers to object not set" );
739  g_assert( !qof_instance_refers_to_object( fixture->inst, ref ) );
740  g_assert( !refers_test_struct.refers_to_object_called );
741 
742  g_test_message( "Test when refers to object set" );
743  QOF_INSTANCE_GET_CLASS( fixture->inst )->refers_to_object = mock_refers_to_object;
744  g_assert( qof_instance_refers_to_object( fixture->inst, ref ) );
745  g_assert( refers_test_struct.refers_to_object_called );
746 
747  g_object_unref( ref );
748 }
749 
750 static struct
751 {
752  GList *list;
753  gpointer ref;
754  guint call_count;
755 } refers_test_struct_from_col;
756 
757 static gboolean
758 mock_refers_to_object_from_col( const QofInstance* inst, const QofInstance* ref )
759 {
760  g_assert( inst );
761  g_assert( ref );
762  g_assert( g_list_find( refers_test_struct_from_col.list, inst ) );
763  g_assert( refers_test_struct_from_col.ref == ref );
764  refers_test_struct_from_col.call_count++;
765  refers_test_struct.refers_to_object_called = TRUE;
766  return TRUE;
767 }
768 
769 static void
770 test_instance_get_referring_object_list_from_collection( void )
771 {
772  QofIdType type = "test type";
773  QofBook *book;
774  GList *inst_list = NULL;
775  GList *result = NULL;
776  QofCollection *coll;
777  QofInstance *ref;
778  /* randomly init number of entities >=0 and < 10 */
779  gint32 list_length = g_test_rand_int_range( 0, 10 );
780  int i;
781 
782  /* setup book and ref instance */
783  book = qof_book_new();
784  g_assert( book );
785  g_assert( QOF_IS_BOOK( book ) );
786  ref = g_object_new( QOF_TYPE_INSTANCE, NULL );
787  g_assert( ref );
788  g_assert( QOF_IS_INSTANCE( ref ) );
789  QOF_INSTANCE_GET_CLASS( ref )->refers_to_object = NULL;
790  refers_test_struct_from_col.call_count = 0;
791  /* init list of entities of one type,
792  * put them into book collection and
793  * save in the list
794  */
795  for (i = 0; i < list_length; i++ )
796  {
797  QofInstance *inst = g_object_new( QOF_TYPE_INSTANCE, NULL );
798  g_assert( inst );
799  qof_instance_init_data( inst, type, book );
800  inst_list = g_list_append ( inst_list, inst );
801  g_assert_cmpint( g_list_length( inst_list ), == , (i + 1) );
802  }
803  g_assert_cmpint( list_length, == , g_list_length( inst_list ) );
804 
805  g_test_message( "Test when refers to object not set" );
806  coll = qof_book_get_collection( book, type );
807  g_assert( coll );
809  g_assert( !result );
810  g_assert_cmpint( refers_test_struct_from_col.call_count, == , 0 );
811 
812  g_test_message( "Test when refers to object is set" );
813  QOF_INSTANCE_GET_CLASS( ref )->refers_to_object = mock_refers_to_object_from_col;
814  refers_test_struct_from_col.list = inst_list;
815  refers_test_struct_from_col.ref = ref;
817  if ( list_length == 0 )
818  g_assert( !result );
819  else
820  g_assert( result );
821  g_assert_cmpint( g_list_length( inst_list ), == , g_list_length( result ) );
822  g_assert_cmpint( g_list_length( inst_list ), == , refers_test_struct_from_col.call_count );
823 
824  /* clean up list and destroy book */
825  g_list_foreach( inst_list, (GFunc) g_object_unref, NULL );
826  g_list_free( inst_list );
827  g_list_free( result );
828  qof_book_destroy( book );
829  g_object_unref( ref );
830 }
831 
832 static struct
833 {
834  gpointer inst;
835  gpointer ref;
836 
837  gboolean get_typed_referring_object_list_called;
838 } get_typed_referring_object_list_struct;
839 
840 static GList*
841 mock_get_typed_referring_object_list( const QofInstance* inst, const QofInstance* ref )
842 {
843  GList* result = NULL;
844 
845  g_assert( inst );
846  g_assert( ref );
847  g_assert( get_typed_referring_object_list_struct.inst == inst );
848  g_assert( get_typed_referring_object_list_struct.ref == ref );
849  get_typed_referring_object_list_struct.get_typed_referring_object_list_called = TRUE;
850  return g_list_append( result, (gpointer) inst );
851 }
852 
853 static void
854 test_instance_get_typed_referring_object_list( void )
855 {
856  QofInstance *inst;
857  QofInstance *ref;
858  QofBook *book;
859  GList* result = NULL;
860 
861  /* setup */
862  inst = g_object_new( QOF_TYPE_INSTANCE, NULL );
863  ref = g_object_new( QOF_TYPE_INSTANCE, NULL );
864  book = qof_book_new();
865  g_assert( inst );
866  g_assert( ref );
867  g_assert( book );
868  QOF_INSTANCE_GET_CLASS( inst )->refers_to_object = NULL;
869  QOF_INSTANCE_GET_CLASS( inst )->get_typed_referring_object_list = NULL;
870  qof_instance_init_data( inst, "test type", book );
871  get_typed_referring_object_list_struct.get_typed_referring_object_list_called = FALSE;
872 
873  /*
874  * cases when refers to object is set are not tested in current function
875  * as they are checked in the previous tests
876  */
877  g_test_message( "Test when get typed referring object list is not set" );
878  result = qof_instance_get_typed_referring_object_list( inst, ref );
879  g_assert( !result );
880  g_assert( !get_typed_referring_object_list_struct.get_typed_referring_object_list_called );
881  g_list_free( result );
882 
883  g_test_message( "Test when get typed referring object list is set" );
884  QOF_INSTANCE_GET_CLASS( inst )->get_typed_referring_object_list = mock_get_typed_referring_object_list;
885  get_typed_referring_object_list_struct.inst = inst;
886  get_typed_referring_object_list_struct.ref = ref;
887  result = qof_instance_get_typed_referring_object_list( inst, ref );
888  g_assert( result );
889  g_assert_cmpint( g_list_length( result ), == , 1 );
890  g_assert( get_typed_referring_object_list_struct.get_typed_referring_object_list_called );
891  g_list_free( result );
892 
893  /* clean */
894  g_object_unref( inst );
895  g_object_unref( ref );
896  qof_book_destroy( book );
897 }
898 
899 static struct
900 {
901  guint refers_to_object_call_count;
902  guint get_typed_referring_object_list_count;
903 } get_referring_object_list_struct;
904 
905 static gboolean
906 mock_simple_refers_to_object( const QofInstance* inst, const QofInstance* ref )
907 {
908  g_assert( inst );
909  g_assert( ref );
910  if ( inst->e_type == ref->e_type )
911  {
912  get_referring_object_list_struct.refers_to_object_call_count++;
913  return TRUE;
914  }
915  return FALSE;
916 }
917 
918 static GList*
919 mock_simple_get_typed_referring_object_list(const QofInstance* inst, const QofInstance* ref)
920 {
921  g_assert( inst );
922  g_assert( ref );
923  get_referring_object_list_struct.get_typed_referring_object_list_count++;
925 }
926 
927 static void
928 test_instance_get_referring_object_list( void )
929 {
930  /* walk through the book's each collection's each instance */
931  QofInstance *ref1;
932  QofInstance *ref2;
933  QofBook *book;
934  QofIdType type1 = "type1";
935  QofIdType type2 = "type2";
936  gint32 col1_length = g_test_rand_int_range( 0, 10 );
937  gint32 col2_length = g_test_rand_int_range( 0, 10 );
938  GList* inst_list1 = NULL;
939  GList* inst_list2 = NULL;
940  GList* result = NULL;
941  int i, j;
942 
943  /* setup */
944  book = qof_book_new();
945  g_assert( book );
946  g_assert( QOF_IS_BOOK( book ) );
947  ref1 = g_object_new( QOF_TYPE_INSTANCE, NULL );
948  g_assert( ref1 );
949  ref2 = g_object_new( QOF_TYPE_INSTANCE, NULL );
950  g_assert( ref2 );
951  qof_instance_init_data( ref1, type1, book );
952  qof_instance_init_data( ref2, type2, book );
953  QOF_INSTANCE_GET_CLASS( ref1 )->refers_to_object = NULL;
954  QOF_INSTANCE_GET_CLASS( ref1 )->get_typed_referring_object_list = NULL;
955  g_assert_cmpint( qof_collection_count( qof_book_get_collection( book, type1 ) ), == , 1 );
956  g_assert_cmpint( qof_collection_count( qof_book_get_collection( book, type2 ) ), == , 1 );
957  get_referring_object_list_struct.refers_to_object_call_count = 0;
958  get_referring_object_list_struct.get_typed_referring_object_list_count = 0;
959  /*
960  * fill two collections with different types
961  * and random number of elements
962  */
963  for (i = 0; i < col1_length; i++ )
964  {
965  QofInstance *inst = g_object_new( QOF_TYPE_INSTANCE, NULL );
966  g_assert( inst );
967  qof_instance_init_data( inst, type1, book );
968  inst_list1 = g_list_append ( inst_list1, inst );
969  g_assert_cmpint( g_list_length( inst_list1 ), == , (i + 1) );
970  }
971  g_assert_cmpint( qof_collection_count( qof_book_get_collection( book, type1 ) ), == , col1_length + 1 );
972  g_assert_cmpint( g_list_length( inst_list1 ), == , col1_length );
973 
974  for (j = 0; j < col2_length; j++ )
975  {
976  QofInstance *inst = g_object_new( QOF_TYPE_INSTANCE, NULL );
977  g_assert( inst );
978  qof_instance_init_data( inst, type2, book );
979  inst_list2 = g_list_append ( inst_list2, inst );
980  g_assert_cmpint( g_list_length( inst_list2 ), == , (j + 1) );
981  }
982  g_assert_cmpint( qof_collection_count( qof_book_get_collection( book, type2 ) ), == , col2_length + 1 );
983  g_assert_cmpint( g_list_length( inst_list2 ), == , col2_length );
984 
985  g_test_message( "Test object list returned for ref1 instance by default" );
987  g_assert( !result );
988  g_assert_cmpint( get_referring_object_list_struct.refers_to_object_call_count, == , 0 );
989 
990  g_test_message( "Test object list returned for ref2 instance by default" );
992  g_assert( !result );
993  g_assert_cmpint( get_referring_object_list_struct.refers_to_object_call_count, == , 0 );
994 
995  /*
996  * refers to object is made simple as it is tested enough
997  * it checks if instance types are equal
998  * that is for ref1 we should get all elements from collection with type1
999  * for ref2 we should get all elements from collection with type2
1000  */
1001  g_test_message( "Test object list returned for ref1 instance when refers_to_object is set" );
1002  QOF_INSTANCE_GET_CLASS( ref1 )->refers_to_object = mock_simple_refers_to_object;
1003  result = qof_instance_get_referring_object_list( ref1 );
1004  g_assert( result );
1005  g_assert_cmpint( g_list_length( result ), == , col1_length + 1 );
1006  g_assert_cmpint( get_referring_object_list_struct.refers_to_object_call_count, == , col1_length + 1 );
1007  g_list_free( result );
1008 
1009  g_test_message( "Test object list returned for ref2 instance when refers_to_object is set" );
1010  get_referring_object_list_struct.refers_to_object_call_count = 0;
1011  result = qof_instance_get_referring_object_list( ref2 );
1012  g_assert( result );
1013  g_assert_cmpint( g_list_length( result ), == , col2_length + 1 );
1014  g_assert_cmpint( get_referring_object_list_struct.refers_to_object_call_count, == , col2_length + 1 );
1015  g_list_free( result );
1016 
1017  g_test_message( "Test object list returned for ref1 instance when refers_to_object is set and get typed set" );
1018  QOF_INSTANCE_GET_CLASS( ref1 )->get_typed_referring_object_list = mock_simple_get_typed_referring_object_list;
1019  get_referring_object_list_struct.refers_to_object_call_count = 0;
1020  get_referring_object_list_struct.get_typed_referring_object_list_count = 0;
1021  result = qof_instance_get_referring_object_list( ref1 );
1022  g_assert( result );
1023  g_assert_cmpint( g_list_length( result ), == , col1_length + 1 );
1024  g_assert_cmpint( get_referring_object_list_struct.refers_to_object_call_count, == , col1_length + 1 );
1025  g_assert_cmpint( get_referring_object_list_struct.get_typed_referring_object_list_count, == , 2 );
1026  g_list_free( result );
1027 
1028  g_test_message( "Test object list returned for ref2 instance when refers_to_object is set and get typed set" );
1029  get_referring_object_list_struct.refers_to_object_call_count = 0;
1030  get_referring_object_list_struct.get_typed_referring_object_list_count = 0;
1031  result = qof_instance_get_referring_object_list( ref2 );
1032  g_assert( result );
1033  g_assert_cmpint( g_list_length( result ), == , col2_length + 1 );
1034  g_assert_cmpint( get_referring_object_list_struct.refers_to_object_call_count, == , col2_length + 1 );
1035  g_assert_cmpint( get_referring_object_list_struct.get_typed_referring_object_list_count, == , 2 );
1036  g_list_free( result );
1037 
1038  /* clean */
1039  g_object_unref( ref1 );
1040  g_object_unref( ref2 );
1041  g_list_foreach( inst_list1, (GFunc) g_object_unref, NULL );
1042  g_list_foreach( inst_list2, (GFunc) g_object_unref, NULL );
1043  g_list_free( inst_list1 );
1044  g_list_free( inst_list2 );
1045  qof_book_destroy( book );
1046 }
1047 
1048 void
1049 test_suite_qofinstance ( void )
1050 {
1051  GNC_TEST_ADD( suitename, "set get book", Fixture, NULL, setup, test_instance_set_get_book, teardown );
1052  GNC_TEST_ADD( suitename, "set get guid", Fixture, NULL, setup, test_instance_set_get_guid, teardown );
1053  GNC_TEST_ADD_FUNC( suitename, "instance new and destroy", test_instance_new_destroy );
1054  GNC_TEST_ADD_FUNC( suitename, "init data", test_instance_init_data );
1055  GNC_TEST_ADD( suitename, "get set slots", Fixture, NULL, setup, test_instance_get_set_slots, teardown );
1056  GNC_TEST_ADD_FUNC( suitename, "version compare", test_instance_version_cmp );
1057  GNC_TEST_ADD( suitename, "get set dirty", Fixture, NULL, setup, test_instance_get_set_dirty, teardown );
1058  GNC_TEST_ADD( suitename, "display name", Fixture, NULL, setup, test_instance_display_name, teardown );
1059  GNC_TEST_ADD( suitename, "begin edit", Fixture, NULL, setup, test_instance_begin_edit, teardown );
1060  GNC_TEST_ADD( suitename, "commit edit", Fixture, NULL, setup, test_instance_commit_edit, teardown );
1061  GNC_TEST_ADD( suitename, "commit edit part 2", Fixture, NULL, setup, test_instance_commit_edit_part2, teardown );
1062  GNC_TEST_ADD( suitename, "instance refers to object", Fixture, NULL, setup, test_instance_refers_to_object, teardown );
1063  GNC_TEST_ADD_FUNC( suitename, "instance get referring object list from collection", test_instance_get_referring_object_list_from_collection );
1064  GNC_TEST_ADD_FUNC( suitename, "instance get typed referring object list", test_instance_get_typed_referring_object_list);
1065  GNC_TEST_ADD_FUNC( suitename, "instance get referring object list", test_instance_get_referring_object_list );
1066 }
int qof_instance_version_cmp(const QofInstance *left, const QofInstance *right)
QofIdType e_type
Definition: qofinstance.h:69
void qof_backend_set_error(QofBackend *be, QofBackendError err)
const GncGUID * qof_instance_get_guid(gconstpointer)
QofBook * qof_instance_get_book(gconstpointer)
gboolean qof_collection_is_dirty(const QofCollection *col)
QofInstance * qof_collection_lookup_entity(const QofCollection *, const GncGUID *)
QofBackendError
The errors that can be reported to the GUI & other front-end users.
Definition: qofbackend.h:59
void qof_set_alt_dirty_mode(gboolean enabled)
GList * qof_instance_get_referring_object_list_from_collection(const QofCollection *coll, const QofInstance *ref)
gboolean qof_instance_get_destroying(gconstpointer ptr)
GncGUID * guid_new(void)
QofBook * qof_book_new(void)
Use a 64-bit unsigned int timespec.
Definition: gnc-date.h:299
QofCollection * qof_instance_get_collection(gconstpointer inst)
gchar * guid_to_string_buff(const GncGUID *guid, gchar *buff)
gboolean qof_commit_edit(QofInstance *inst)
Definition: guid.h:65
const gchar * QofIdType
Definition: qofid.h:85
void qof_instance_init_data(QofInstance *, QofIdType, QofBook *)
gboolean qof_begin_edit(QofInstance *inst)
guint32 qof_instance_get_idata(gconstpointer inst)
gboolean guid_equal(const GncGUID *guid_1, const GncGUID *guid_2)
#define GUID_ENCODING_LENGTH
Definition: guid.h:74
gboolean qof_instance_get_dirty_flag(gconstpointer ptr)
GList * qof_instance_get_typed_referring_object_list(const QofInstance *inst, const QofInstance *ref)
gboolean qof_commit_edit_part2(QofInstance *inst, void(*on_error)(QofInstance *, QofBackendError), void(*on_done)(QofInstance *), void(*on_free)(QofInstance *))
void qof_collection_mark_clean(QofCollection *)
const GncGUID * qof_entity_get_guid(gconstpointer)
void qof_collection_destroy(QofCollection *col)
GList * qof_instance_get_referring_object_list(const QofInstance *inst)
const GncGUID * guid_null(void)
void qof_instance_set_book(gconstpointer inst, QofBook *book)
struct KvpFrameImpl KvpFrame
Definition: kvp_frame.h:76
KvpFrame * kvp_frame_new(void)
QofCollection * qof_book_get_collection(const QofBook *, QofIdType)
guint qof_collection_count(const QofCollection *col)
gboolean qof_instance_refers_to_object(const QofInstance *inst, const QofInstance *ref)
gboolean qof_get_alt_dirty_mode(void)
void qof_book_destroy(QofBook *book)
QofCollection * qof_collection_new(QofIdType type)
gchar * qof_instance_get_display_name(const QofInstance *inst)