GnuCash  2.6.99
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
test-qofobject.c
1 /********************************************************************
2  * test-qofobject.c: GLib g_test test suite for qofobject.c. *
3  * Copyright 2011 Muslim Chochlov <[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 #ifdef __cplusplus
23 extern "C"
24 {
25 #endif
26 
27 #include "config.h"
28 #include <string.h>
29 #include <glib.h>
30 #include <unittest-support.h>
31 #ifdef __cplusplus
32 }
33 #endif
34 
35 #include "../qof.h"
36 #include "../qofobject-p.h"
37 
38 static const gchar *suitename = "/qof/qofobject";
39 void test_suite_qofobject ( void );
40 
41 typedef struct
42 {
43  QofObject *qofobject;
44 } Fixture;
45 
46 typedef enum
47 {
48  MOCK_OBJECT_BOOK_BEGIN = 1,
49  MOCK_OBJECT_BOOK_END,
50  MOCK_OBJECT_DIRTY,
51  MOCK_OBJECT_MARK_CLEAN,
52  EMPTY
53 } MockFields;
54 
55 static void mock_object_book_begin( QofBook *book );
56 static gboolean mock_object_dirty( const QofCollection *col );
57 static void mock_object_mark_clean( QofCollection *col );
58 
59 static QofObject*
60 new_object( QofIdType e_type, const char *type_label, MockFields field)
61 {
62  QofObject *object = NULL;
63 
64  object = g_new0( QofObject, 1 );
65  g_assert( object );
66  object->interface_version = QOF_OBJECT_VERSION;
67  object->e_type = e_type;
68  object->type_label = type_label;
69  switch ( field )
70  {
71  case MOCK_OBJECT_BOOK_BEGIN:
72  object->book_begin = mock_object_book_begin;
73  break;
74  case MOCK_OBJECT_BOOK_END:
75  object->book_end = mock_object_book_begin;
76  break;
77  case MOCK_OBJECT_DIRTY:
78  object->is_dirty = mock_object_dirty;
79  break;
80  case MOCK_OBJECT_MARK_CLEAN:
81  object->mark_clean = mock_object_mark_clean;
82  case EMPTY:
83  break;
84  }
85  return object;
86 }
87 
88 #ifdef __cplusplus
89 extern "C"
90 {
91 #endif
92 
93 extern gboolean get_object_is_initialized( void );
94 extern GList* get_object_modules( void );
95 extern GList* get_book_list( void );
96 extern GHashTable* get_backend_data( void );
97 
98 #ifdef __cplusplus
99 }
100 #endif
101 
102 static void
103 setup( Fixture *fixture, gconstpointer pData )
104 {
105  qof_object_initialize();
106  fixture->qofobject = new_object( "my type object", "object desc", EMPTY );
107 }
108 
109 static void
110 teardown( Fixture *fixture, gconstpointer pData )
111 {
112  g_free( fixture->qofobject );
113  qof_object_shutdown();
114 }
115 
116 /*
117  * Safely generates objects and registers them
118  *
119  * Input: min_objects - minimum number of objects to be generated (should be between 0 and 5)
120  * mock_filed - function in qofobject to be mocked
121  * Output: number of generated objects
122  */
123 static gint32
124 generate_and_register_objects( guint min_objects, MockFields mock_field )
125 {
126  gint32 list_length = g_test_rand_int_range( min_objects, 5 );
127  const char *types[5] = {"type1", "type2", "type3", "type4", "type5"};
128  int i;
129 
130  g_assert_cmpint( min_objects, >= , 0 );
131  g_assert_cmpint( min_objects, < , 5 );
132  for (i = 0; i < list_length; i++ )
133  {
134  QofObject *object = new_object( types[i], "desc", mock_field );
135  g_assert( object );
136  g_assert( qof_object_register( object ) );
137  g_assert_cmpint( g_list_length( get_object_modules() ), == , (i + 1) );
138  }
139  g_assert_cmpint( list_length, == , g_list_length( get_object_modules() ) );
140 
141  return list_length;
142 }
143 
144 /*
145  * TESTS
146  */
147 static struct
148 {
149  GList *books;
150  guint call_count;
151 } book_begin_struct;
152 
153 static void
154 mock_book_begin( QofBook *book )
155 {
156  g_assert( book );
157  g_assert( book == book_begin_struct.books->data );
158  book_begin_struct.books = book_begin_struct.books->next;
159  book_begin_struct.call_count++;
160 }
161 
162 static void
163 test_qof_object_register( Fixture *fixture, gconstpointer pData )
164 {
165  GList *books = NULL;
166  gint32 list_length = g_test_rand_int_range( 0, 5 );
167  int i;
168  QofObject *simple_object = NULL;
169 
170  for (i = 0; i < list_length; i++ )
171  {
172  QofBook *book = qof_book_new();
173  g_assert( book );
174  books = g_list_prepend ( books, book );
175  g_assert_cmpint( g_list_length( books ), == , (i + 1) );
176  }
177  g_assert_cmpint( list_length, == , g_list_length( books ) );
178 
179  g_test_message( "Test null check" );
180  g_assert( qof_object_register( NULL ) == FALSE );
181 
182  g_test_message( "Test new object register with book_begin specified" );
183  fixture->qofobject->book_begin = mock_book_begin;
184  book_begin_struct.books = books;
185  book_begin_struct.call_count = 0;
186  g_assert( qof_object_register( fixture->qofobject ) == TRUE );
187  g_assert( qof_object_lookup( "my type object" ) == fixture->qofobject );
188  g_assert_cmpint( book_begin_struct.call_count, == , list_length );
189 
190  g_test_message( "Test registering the same object one more time" );
191  book_begin_struct.call_count = 0;
192  g_assert( qof_object_register( fixture->qofobject ) == FALSE );
193  g_assert( qof_object_lookup( "my type object" ) == fixture->qofobject );
194  g_assert_cmpint( book_begin_struct.call_count, == , 0 );
195 
196  g_test_message( "Test new object register without book_begin specified" );
197  simple_object = new_object( "my type simple", "simple desc", EMPTY );
198  g_assert( qof_object_register( simple_object ) == TRUE );
199  g_assert( qof_object_lookup( "my type simple" ) == simple_object );
200  g_assert_cmpint( book_begin_struct.call_count, == , 0 );
201 
202  g_test_message( "Test register simple object one more time" );
203  g_assert( qof_object_register( simple_object ) == FALSE );
204  g_assert( qof_object_lookup( "my type simple" ) == simple_object );
205 
206  g_test_message( "Test book begin is called only one time when object is registered" );
207  simple_object->book_begin = mock_book_begin;
208  book_begin_struct.books = books;
209  book_begin_struct.call_count = 0;
210  g_assert( qof_object_register( simple_object ) == FALSE );
211  g_assert_cmpint( book_begin_struct.call_count, == , 0 );
212 
213  g_list_foreach( books, (GFunc) qof_book_destroy, NULL );
214  g_list_free( books );
215  g_free( simple_object );
216 }
217 
218 static void
219 test_qof_object_lookup( Fixture *fixture, gconstpointer pData )
220 {
221  g_test_message( "Test null check" );
222  g_assert( qof_object_lookup( NULL ) == NULL );
223 
224  g_test_message( "Test existing object lookup" );
225  g_assert( qof_object_register( fixture->qofobject ) == TRUE );
226  g_assert( qof_object_lookup( "my type object" ) == fixture->qofobject );
227 
228  g_test_message( "Test non existing object lookup" );
229  g_assert( qof_object_lookup( "anytype" ) == NULL );
230 }
231 
232 static struct
233 {
234  gpointer data1;
235  gpointer data2;
236 } be_data;
237 
238 static void
239 test_qof_object_backend_register_lookup( Fixture *fixture, gconstpointer pData )
240 {
241  g_test_message( "Test register and lookup null checks" );
242  g_assert( qof_object_register_backend( NULL, "test", &be_data ) == FALSE );
243  g_assert( qof_object_register_backend( "", "test", &be_data ) == FALSE );
244  g_assert( qof_object_register_backend( "test", NULL, &be_data ) == FALSE );
245  g_assert( qof_object_register_backend( "test", "", &be_data ) == FALSE );
246  g_assert( qof_object_register_backend( "test", "test", NULL ) == FALSE );
247  g_assert( qof_object_lookup_backend( NULL, "test" ) == NULL );
248  g_assert( qof_object_lookup_backend( "", "test" ) == NULL );
249  g_assert( qof_object_lookup_backend( "test", NULL ) == NULL );
250  g_assert( qof_object_lookup_backend( "test", "" ) == NULL );
251 
252  g_test_message( "Test new backend and type insert" );
253  g_assert( qof_object_lookup_backend( "type", "backend" ) == NULL );
254  g_assert( qof_object_register_backend( "type", "backend", &be_data.data1 ) == TRUE );
255  g_assert( qof_object_lookup_backend( "type", "backend" ) == &be_data.data1 );
256 
257  g_test_message( "Test type insert into existing backend" );
258  g_assert( qof_object_register_backend( "type2", "backend", &be_data.data2 ) == TRUE );
259  g_assert( qof_object_lookup_backend( "type", "backend" ) == &be_data.data1 );
260  g_assert( qof_object_lookup_backend( "type2", "backend" ) == &be_data.data2 );
261 }
262 
263 static void
264 test_qof_object_get_type_label( Fixture *fixture, gconstpointer pData )
265 {
266  g_assert( qof_object_get_type_label( NULL ) == NULL );
267 
268  g_test_message( "Test with non existing object" );
269  g_assert( qof_object_get_type_label( "anytype" ) == NULL );
270 
271  g_test_message( "Test with existing registered object" );
272  g_assert( qof_object_register( fixture->qofobject ) == TRUE );
273  g_assert_cmpstr( qof_object_get_type_label( "my type object" ), == , "object desc" );
274 }
275 
276 static struct
277 {
278  gpointer param;
279 } printable_struct;
280 
281 static const char *
282 mock_printable( gpointer instance )
283 {
284  g_assert( instance );
285  g_assert( instance == printable_struct.param );
286  return "printable was called";
287 }
288 
289 static void
290 test_qof_object_printable( Fixture *fixture, gconstpointer pData )
291 {
292  gint param;
293 
294  g_test_message( "Test null checks" );
295  g_assert( qof_object_printable( NULL, (gpointer)&param ) == NULL );
296  g_assert( qof_object_printable( "test", NULL ) == NULL );
297 
298  g_test_message( "Test with non registered object" );
299  g_assert( qof_object_printable( "test", (gpointer)&param ) == NULL );
300 
301  g_test_message( "Test with registered object and printable not set" );
302  g_assert( qof_object_register( fixture->qofobject ) == TRUE );
303  g_assert( qof_object_printable( "my type object", (gpointer)&param ) == NULL );
304 
305  g_test_message( "Test with registered object and printable set" );
306  fixture->qofobject->printable = mock_printable;
307  printable_struct.param = (gpointer)&param;
308  g_assert_cmpstr( qof_object_printable( "my type object", (gpointer)&param ), == , "printable was called" );
309 }
310 
311 static struct
312 {
313  QofBook *book;
314  guint call_count;
315 } object_book_begin_struct;
316 
317 static void
318 mock_object_book_begin( QofBook *book )
319 {
320  g_assert( book );
321  g_assert( book == object_book_begin_struct.book );
322  object_book_begin_struct.call_count++;
323 }
324 
325 static void
326 test_qof_object_book_begin( Fixture *fixture, gconstpointer pData )
327 {
328  QofBook *book = NULL, *book2 = NULL;
329  gint32 list_length;
330 
331  g_test_message( "Test book begin with no objects" );
332  g_assert_cmpint( 0, == , g_list_length( get_book_list() ) );
333  object_book_begin_struct.call_count = 0;
334  book = g_object_new(QOF_TYPE_BOOK, NULL);
335  g_assert( book );
336  qof_object_book_begin( book );
337  g_assert_cmpint( 1, == , g_list_length( get_book_list() ) );
338  g_assert_cmpint( g_list_index( get_book_list(), (gconstpointer) book), != , -1 );
339  g_assert_cmpint( object_book_begin_struct.call_count, == , 0 );
340 
341  qof_book_destroy( book );
342 
343  list_length = generate_and_register_objects( 1, MOCK_OBJECT_BOOK_BEGIN );
344 
345  g_test_message( "Test book begin with random objects registered and book begin set up" );
346  g_assert_cmpint( 0, == , g_list_length( get_book_list() ) );
347  book2 = g_object_new(QOF_TYPE_BOOK, NULL);
348  g_assert( book2 );
349  object_book_begin_struct.book = book2;
350  qof_object_book_begin( book2 );
351  g_assert_cmpint( 1, == , g_list_length( get_book_list() ) );
352  g_assert_cmpint( g_list_index( get_book_list(), (gconstpointer) book2 ), != , -1 );
353  g_assert_cmpint( object_book_begin_struct.call_count, == , list_length );
354 
355  qof_book_destroy( book2 );
356 }
357 
358 static void
359 test_qof_object_book_end( Fixture *fixture, gconstpointer pData )
360 {
361  QofBook *book = NULL, *book2 = NULL;
362  gint32 list_length;
363 
364  g_test_message( "Test book with no objects" );
365  book = qof_book_new();
366  g_assert( book );
367  object_book_begin_struct.call_count = 0;
368  g_assert_cmpint( 1, == , g_list_length( get_book_list() ) );
369  g_assert_cmpint( g_list_index( get_book_list(), (gconstpointer) book), != , -1 );
370  qof_book_destroy( book ); /* calls object_book_end */
371  g_assert_cmpint( object_book_begin_struct.call_count, == , 0 );
372  g_assert_cmpint( 0, == , g_list_length( get_book_list() ) );
373 
374  list_length = generate_and_register_objects( 1, MOCK_OBJECT_BOOK_END );
375 
376  g_test_message( "Test book end with random objects registered and book end set up" );
377  book2 = qof_book_new();
378  g_assert( book2 );
379  object_book_begin_struct.book = book2;
380  g_assert_cmpint( 1, == , g_list_length( get_book_list() ) );
381  g_assert_cmpint( g_list_index( get_book_list(), (gconstpointer) book2 ), != , -1 );
382  qof_book_destroy( book2 ); /* calls object_book_end */
383  g_assert_cmpint( object_book_begin_struct.call_count, == , list_length );
384  g_assert_cmpint( 0, == , g_list_length( get_book_list() ) );
385 }
386 
387 static struct
388 {
389  GList *objects;
390  guint call_count;
391  gboolean result;
392 } object_dirty_struct;
393 
394 static gboolean
395 mock_object_dirty( const QofCollection *col )
396 {
397  QofObject *obj = NULL;
398 
399  g_assert( col );
400  obj = object_dirty_struct.objects->data;
401  object_dirty_struct.objects = object_dirty_struct.objects->next;
402  g_assert( obj );
403  g_assert_cmpstr( qof_collection_get_type( col ), == , obj->e_type );
404  object_dirty_struct.call_count++;
405  return object_dirty_struct.result;
406 }
407 
408 static void
409 test_qof_object_is_dirty( Fixture *fixture, gconstpointer pData )
410 {
411  QofBook *book = NULL;
412  gint32 list_length;
413 
414  g_test_message( "Test null check returns false" );
415  g_assert( qof_object_is_dirty( NULL ) == FALSE );
416 
417  g_test_message( "Test with no objects" );
418  book = qof_book_new();
419  g_assert( book );
420  object_dirty_struct.call_count = 0;
421  g_assert( qof_object_is_dirty( book ) == FALSE );
422  g_assert_cmpint( object_dirty_struct.call_count, == , 0 );
423 
424  list_length = generate_and_register_objects( 1, MOCK_OBJECT_DIRTY );
425 
426  g_test_message( "Test with registered objects and suppose all collections are clean" );
427  object_dirty_struct.objects = get_object_modules();
428  object_dirty_struct.result = FALSE;
429  g_assert( qof_object_is_dirty( book ) == FALSE );
430  g_assert_cmpint( object_dirty_struct.call_count, == , list_length );
431 
432  g_test_message( "Test with registered objects and suppose first collection is dirty" );
433  object_dirty_struct.objects = get_object_modules();
434  object_dirty_struct.result = TRUE;
435  object_dirty_struct.call_count = 0;
436  g_assert( qof_object_is_dirty( book ) == TRUE );
437  g_assert_cmpint( object_dirty_struct.call_count, == , 1 ); /* should break on first */
438 
439  qof_book_destroy( book );
440 }
441 
442 static struct
443 {
444  GList *objects;
445  guint call_count;
446 } object_mark_clean_struct;
447 
448 static void
449 mock_object_mark_clean( QofCollection *col )
450 {
451  QofObject *obj = NULL;
452 
453  g_assert( col );
454  obj = object_mark_clean_struct.objects->data;
455  object_mark_clean_struct.objects = object_mark_clean_struct.objects->next;
456  g_assert( obj );
457  g_assert_cmpstr( qof_collection_get_type( col ), == , obj->e_type );
458  object_mark_clean_struct.call_count++;
459 }
460 
461 static void
462 test_qof_object_mark_clean( Fixture *fixture, gconstpointer pData )
463 {
464  QofBook *book = NULL;
465  gint32 list_length;
466 
467  g_test_message( "Test with no objects" );
468  book = qof_book_new();
469  g_assert( book );
470  object_mark_clean_struct.call_count = 0;
471  g_assert_cmpint( g_list_length( get_object_modules() ), == , 0 );
472  qof_object_mark_clean( book );
473  g_assert_cmpint( object_mark_clean_struct.call_count, == , 0 );
474 
475  list_length = generate_and_register_objects( 1, MOCK_OBJECT_MARK_CLEAN );
476 
477  g_test_message( "Test with registered objects and mark clean set up" );
478  object_mark_clean_struct.objects = get_object_modules();
479  qof_object_mark_clean( book );
480  g_assert_cmpint( object_mark_clean_struct.call_count, == , list_length );
481 
482  qof_book_destroy( book );
483 }
484 
485 static struct
486 {
487  QofBook *book;
488  QofInstance *inst;
489  gboolean is_called;
490 } object_create_struct;
491 
492 static gpointer
493 mock_object_create( QofBook *book )
494 {
495  QofInstance *inst = NULL;
496 
497  inst = g_object_new(QOF_TYPE_INSTANCE, NULL);
498  g_assert( inst );
499  g_assert( QOF_IS_INSTANCE( inst ) );
500  g_assert( book );
501  g_assert( book == object_create_struct.book );
502  object_create_struct.is_called = TRUE;
503  object_create_struct.inst = inst;
504  return inst;
505 }
506 
507 static void
508 test_qof_object_new_instance( Fixture *fixture, gconstpointer pData )
509 {
510  QofBook *book = NULL;
511  QofInstance *inst = NULL;
512 
513  book = qof_book_new();
514  g_assert( book );
515 
516  g_test_message( "Test null check" );
517  g_assert( qof_object_new_instance( NULL, book ) == NULL );
518 
519  g_test_message( "Test non existing object type" );
520  g_assert( qof_object_new_instance( "non existing type", book ) == NULL );
521 
522  g_test_message( "Test with registered object type and create not set" );
523  g_assert( qof_object_register( fixture->qofobject ) );
524  g_assert( qof_object_new_instance( fixture->qofobject->e_type, book ) == NULL );
525 
526  g_test_message( "Test with registered object type and create set" );
527  object_create_struct.is_called = FALSE;
528  object_create_struct.book = book;
529  object_create_struct.inst = NULL;
530  fixture->qofobject->create = mock_object_create;
531  inst = qof_object_new_instance( fixture->qofobject->e_type, book );
532  g_assert( inst );
533  g_assert( object_create_struct.is_called == TRUE );
534  g_assert( object_create_struct.inst == inst );
535 
536  g_object_unref( inst );
537  qof_book_destroy( book );
538 }
539 
540 static void
541 mock_object_foreach( const QofCollection *col, QofInstanceForeachCB cb, gpointer data)
542 {
543 }
544 
545 static void
546 test_qof_object_compliance( Fixture *fixture, gconstpointer pData )
547 {
548  g_assert( qof_object_register( fixture->qofobject ) );
549 
550  g_test_message( "Test when neither create nor foreach set" );
551  g_assert( qof_object_compliance( fixture->qofobject->e_type, FALSE ) == FALSE );
552  g_assert( qof_object_compliance( fixture->qofobject->e_type, TRUE ) == FALSE );
553 
554  g_test_message( "Test when only create set" );
555  fixture->qofobject->create = mock_object_create;
556  g_assert( qof_object_compliance( fixture->qofobject->e_type, FALSE ) == FALSE );
557  g_assert( qof_object_compliance( fixture->qofobject->e_type, TRUE ) == FALSE );
558 
559  g_test_message( "Test when only foreach set" );
560  fixture->qofobject->create = NULL;
561  fixture->qofobject->foreach = mock_object_foreach;
562  g_assert( qof_object_compliance( fixture->qofobject->e_type, FALSE ) == FALSE );
563  g_assert( qof_object_compliance( fixture->qofobject->e_type, TRUE ) == FALSE );
564 
565  g_test_message( "Test when both set" );
566  fixture->qofobject->create = mock_object_create;
567  fixture->qofobject->foreach = mock_object_foreach;
568  g_assert( qof_object_compliance( fixture->qofobject->e_type, FALSE ) == TRUE );
569  g_assert( qof_object_compliance( fixture->qofobject->e_type, TRUE ) == TRUE );
570 }
571 
572 static struct
573 {
574  GList *objects;
575  gpointer user_data;
576  guint call_count;
577 } foreach_type_cb_struct;
578 
579 static void
580 mock_foreach_type_cb( QofObject *object, gpointer user_data )
581 {
582  g_assert( object );
583  g_assert( user_data );
584  g_assert( object == foreach_type_cb_struct.objects->data );
585  g_assert( user_data == foreach_type_cb_struct.user_data );
586  foreach_type_cb_struct.objects = foreach_type_cb_struct.objects->next;
587  foreach_type_cb_struct.call_count++;
588 }
589 
590 static void
591 test_qof_object_foreach_type( Fixture *fixture, gconstpointer pData )
592 {
593  gint user_data;
594  gint32 list_length;
595 
596  g_test_message( "Test with no objects" );
597  foreach_type_cb_struct.call_count = 0;
598  g_assert_cmpint( g_list_length( get_object_modules() ), == , 0 );
599  qof_object_foreach_type( mock_foreach_type_cb, ( gpointer ) &user_data );
600  g_assert_cmpint( foreach_type_cb_struct.call_count, == , 0 );
601 
602  list_length = generate_and_register_objects( 1, EMPTY );
603 
604  g_test_message( "Test foreach cb" );
605  foreach_type_cb_struct.objects = get_object_modules();
606  foreach_type_cb_struct.user_data = ( gpointer ) &user_data;
607  foreach_type_cb_struct.call_count = 0;
608  qof_object_foreach_type( mock_foreach_type_cb, ( gpointer ) &user_data );
609  g_assert_cmpint( foreach_type_cb_struct.call_count, == , list_length );
610 }
611 
612 static struct
613 {
614  gpointer user_data;
616  QofCollection *col;
617  gboolean is_called;
618 } foreach_cb_struct;
619 
620 static void
621 mock_instance_foreach_cb( QofInstance *inst, gpointer user_data )
622 {
623 }
624 
625 static void
626 mock_foreach( const QofCollection *col, QofInstanceForeachCB cb, gpointer user_data )
627 {
628  g_assert( col );
629  g_assert( cb );
630  g_assert( user_data );
631  g_assert( col == foreach_cb_struct.col );
632  g_assert( user_data == foreach_cb_struct.user_data );
633  g_assert( cb == foreach_cb_struct.cb );
634  foreach_cb_struct.is_called = TRUE;
635 }
636 
637 static void
638 test_qof_object_foreach( Fixture *fixture, gconstpointer pData )
639 {
640  gint user_data;
641  QofBook *book = NULL;
642  QofCollection *col = NULL;
643 
644  /* setup */
645  book = qof_book_new();
646  g_assert( book );
647  g_assert_cmpint( g_list_length( get_object_modules() ), == , 0 );
648  qof_object_register( fixture->qofobject );
649  g_assert_cmpint( g_list_length( get_object_modules() ), == , 1 );
650  col = qof_book_get_collection( book, fixture->qofobject->e_type ); /* make col already exist */
651  g_assert( col );
652 
653  g_test_message( "Test foreach and data" );
654  foreach_cb_struct.user_data = ( gpointer ) &user_data;
655  foreach_cb_struct.is_called = FALSE;
656  foreach_cb_struct.col = col;
657  foreach_cb_struct.cb = mock_instance_foreach_cb;
658  fixture->qofobject->foreach = mock_foreach;
659  qof_object_foreach( fixture->qofobject->e_type, book, mock_instance_foreach_cb, ( gpointer ) &user_data );
660  g_assert( foreach_cb_struct.is_called == TRUE );
661 
662  qof_book_destroy( book );
663 }
664 
665 static struct
666 {
667  GList *instances;
668  gpointer user_data;
669  guint call_count;
670 } foreach_for_sorted_struct;
671 
672 static void
673 mock_foreach_for_sorted( const QofCollection *col, QofInstanceForeachCB cb, gpointer user_data )
674 {
675  GList *iter;
676 
677  g_assert( col );
678  g_assert( cb );
679  g_assert( user_data );
680 
681  for (iter = foreach_for_sorted_struct.instances; iter; iter = iter->next)
682  {
683  cb( iter->data, user_data );
684  }
685 }
686 
687 static void
688 mock_instance_foreach_cb_for_sorted( QofInstance *inst, gpointer user_data )
689 {
690  g_assert( inst );
691  g_assert( user_data );
692  g_assert_cmpint( g_list_index( foreach_for_sorted_struct.instances, (gconstpointer) inst ), != , -1 );
693  g_assert( user_data == foreach_for_sorted_struct.user_data );
694  foreach_for_sorted_struct.call_count++;
695 }
696 
697 static void
698 test_qof_object_foreach_sorted( Fixture *fixture, gconstpointer pData )
699 {
700  int i;
701  gint32 list_length = g_test_rand_int_range( 0, 5 );
702  gint user_data;
703  QofBook *book = NULL;
704  QofCollection *col = NULL;
705  foreach_for_sorted_struct.instances = NULL;
706 
707  /* setup */
708  book = qof_book_new();
709  g_assert( book );
710  g_assert_cmpint( g_list_length( get_object_modules() ), == , 0 );
711  qof_object_register( fixture->qofobject );
712  g_assert_cmpint( g_list_length( get_object_modules() ), == , 1 );
713 
714  fixture->qofobject->foreach = mock_foreach_for_sorted;
715  /* init instances */
716  col = qof_book_get_collection( book, fixture->qofobject->e_type );
717  for (i = 0; i < list_length; i++ )
718  {
719  QofInstance * inst = g_object_new( QOF_TYPE_INSTANCE, NULL );
720  g_assert( QOF_IS_INSTANCE( inst ) );
721  foreach_for_sorted_struct.instances = g_list_append( foreach_for_sorted_struct.instances, inst );
722  qof_collection_insert_entity( col, inst );
723  }
724  g_assert_cmpint( list_length, == , g_list_length( foreach_for_sorted_struct.instances ) );
725 
726  foreach_for_sorted_struct.call_count = 0;
727  foreach_for_sorted_struct.user_data = &user_data;
728  qof_object_foreach_sorted( fixture->qofobject->e_type, book, mock_instance_foreach_cb_for_sorted, ( gpointer ) &user_data );
729  g_assert_cmpint( list_length, == , foreach_for_sorted_struct.call_count );
730 
731  qof_book_destroy( book );
732  g_list_free( foreach_for_sorted_struct.instances );
733 }
734 
735 static struct
736 {
737  QofIdTypeConst type;
738  gpointer backend_data;
739  gpointer user_data;
740  guint call_count;
741 } foreach_backend_struct;
742 
743 static void
744 mock_foreach_backend( QofIdTypeConst type, gpointer backend_data, gpointer user_data)
745 {
746  g_assert( type );
747  g_assert( backend_data );
748  g_assert( user_data );
749  g_assert_cmpstr( type, == , foreach_backend_struct.type );
750  g_assert( backend_data == foreach_backend_struct.backend_data );
751  g_assert( user_data == foreach_backend_struct.user_data );
752  foreach_backend_struct.call_count++;
753 }
754 
755 static void
756 test_qof_object_foreach_backend( Fixture *fixture, gconstpointer pData )
757 {
758  gint backend_data;
759  gint user_data;
760 
761  g_assert_cmpint( g_hash_table_size( get_backend_data() ), == , 0 );
762  qof_object_register_backend( "type1", "backend", (gpointer) &backend_data ); /* register backend */
763  g_assert_cmpint( g_hash_table_size( get_backend_data() ), == , 1 );
764 
765  foreach_backend_struct.call_count = 0;
766  foreach_backend_struct.backend_data = (gpointer) &backend_data;
767  foreach_backend_struct.user_data = (gpointer) &user_data;
768  foreach_backend_struct.type = "type1";
769  qof_object_foreach_backend ( "backend", mock_foreach_backend, (gpointer) &user_data);
770  g_assert_cmpint( foreach_backend_struct.call_count, == , 1 );
771 }
772 
773 void
774 test_suite_qofobject (void)
775 {
776  GNC_TEST_ADD( suitename, "qof object register", Fixture, NULL, setup, test_qof_object_register, teardown );
777  GNC_TEST_ADD( suitename, "qof object lookup", Fixture, NULL, setup, test_qof_object_lookup, teardown );
778  GNC_TEST_ADD( suitename, "qof object register and lookup backend", Fixture, NULL, setup, test_qof_object_backend_register_lookup, teardown );
779  GNC_TEST_ADD( suitename, "qof object get type label", Fixture, NULL, setup, test_qof_object_get_type_label, teardown );
780  GNC_TEST_ADD( suitename, "qof object printable", Fixture, NULL, setup, test_qof_object_printable, teardown );
781  GNC_TEST_ADD( suitename, "qof object book begin", Fixture, NULL, setup, test_qof_object_book_begin, teardown );
782  GNC_TEST_ADD( suitename, "qof object book end", Fixture, NULL, setup, test_qof_object_book_end, teardown );
783  GNC_TEST_ADD( suitename, "qof object is dirty", Fixture, NULL, setup, test_qof_object_is_dirty, teardown );
784  GNC_TEST_ADD( suitename, "qof object mark clean", Fixture, NULL, setup, test_qof_object_mark_clean, teardown );
785  GNC_TEST_ADD( suitename, "qof object new instance", Fixture, NULL, setup, test_qof_object_new_instance, teardown );
786  GNC_TEST_ADD( suitename, "qof object compliance", Fixture, NULL, setup, test_qof_object_compliance, teardown );
787  GNC_TEST_ADD( suitename, "qof object foreach type", Fixture, NULL, setup, test_qof_object_foreach_type, teardown );
788  GNC_TEST_ADD( suitename, "qof object foreach", Fixture, NULL, setup, test_qof_object_foreach, teardown );
789  GNC_TEST_ADD( suitename, "qof object foreach sorted", Fixture, NULL, setup, test_qof_object_foreach_sorted, teardown );
790  GNC_TEST_ADD( suitename, "qof object foreach backend", Fixture, NULL, setup, test_qof_object_foreach_backend, teardown );
791 }
gboolean qof_object_register_backend(QofIdTypeConst type_name, const char *backend_name, gpointer be_data)
const char * qof_object_get_type_label(QofIdTypeConst type_name)
void qof_object_book_begin(QofBook *book)
const gchar * QofIdTypeConst
Definition: qofid.h:87
gboolean qof_object_compliance(QofIdTypeConst type_name, gboolean warn)
check an object can be created and supports iteration
QofBook * qof_book_new(void)
gpointer(* create)(QofBook *)
Definition: qofobject.h:87
#define QOF_OBJECT_VERSION
Definition: qofobject.h:64
void qof_object_foreach_type(QofForeachTypeCB cb, gpointer user_data)
void qof_object_foreach_sorted(QofIdTypeConst type_name, QofBook *book, QofInstanceForeachCB cb, gpointer user_data)
const gchar * QofIdType
Definition: qofid.h:85
const QofObject * qof_object_lookup(QofIdTypeConst type_name)
void qof_object_foreach(QofIdTypeConst type_name, QofBook *book, QofInstanceForeachCB cb, gpointer user_data)
void qof_collection_insert_entity(QofCollection *, QofInstance *)
void(* book_begin)(QofBook *)
Definition: qofobject.h:92
gpointer qof_object_new_instance(QofIdTypeConst type_name, QofBook *book)
const char *(* printable)(gpointer instance)
Definition: qofobject.h:116
void(* QofInstanceForeachCB)(QofInstance *, gpointer user_data)
Definition: qofid.h:186
QofIdType qof_collection_get_type(const QofCollection *)
void(* foreach)(const QofCollection *, QofInstanceForeachCB, gpointer)
Definition: qofobject.h:112
const char * qof_object_printable(QofIdTypeConst type_name, gpointer instance)
QofCollection * qof_book_get_collection(const QofBook *, QofIdType)
gboolean qof_object_register(const QofObject *object)
void qof_book_destroy(QofBook *book)