00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <glib.h>
00026 #include <glib/gprintf.h>
00027 #define _GNU_SOURCE
00028
00029 #include "qof.h"
00030 #include "test-engine-stuff.h"
00031 #include "test-stuff.h"
00032
00033 #define GRAND_MODULE_NAME "recursive-grandparent"
00034 #define PARENT_MODULE_NAME "recursive-parent"
00035 #define CHILD_MODULE_NAME "recursive-child"
00036 #define GRAND_MODULE_DESC "Recursive Grand Parent Test"
00037 #define PARENT_MODULE_DESC "Recursive Parent Test"
00038 #define CHILD_MODULE_DESC "Recursive Child Test"
00039 #define OBJ_NAME "somename"
00040 #define OBJ_AMOUNT "anamount"
00041 #define OBJ_DATE "nottoday"
00042 #define OBJ_DISCOUNT "hefty"
00043 #define OBJ_VERSION "early"
00044 #define OBJ_MINOR "tiny"
00045 #define OBJ_ACTIVE "ofcourse"
00046 #define OBJ_FLAG "tiny_flag"
00047 #define OBJ_RELATIVE "family"
00048 #define OBJ_LIST "descendents"
00049
00050
00051
00052 static gboolean debug = FALSE;
00053
00054
00055 typedef struct child_s
00056 {
00057 QofInstance inst;
00058 gchar *Name;
00059 gchar flag;
00060 gnc_numeric Amount;
00061 Timespec date;
00062 double discount;
00063 gboolean active;
00064 gint32 version;
00065 gint64 minor;
00066 }mychild;
00067
00068
00069 typedef struct parent_s
00070 {
00071 QofInstance inst;
00072 mychild *child;
00073 gchar *Name;
00074 gchar flag;
00075 gnc_numeric Amount;
00076 Timespec date;
00077 double discount;
00078 gboolean active;
00079 gint32 version;
00080 gint64 minor;
00081 }myparent;
00082
00083
00084 typedef struct grand_s
00085 {
00086 QofInstance inst;
00087 myparent *child;
00088 GList *descend;
00089 gchar *Name;
00090 gchar flag;
00091 gnc_numeric Amount;
00092 Timespec date;
00093 double discount;
00094 gboolean active;
00095 gint32 version;
00096 gint64 minor;
00097 }mygrand;
00098
00099 mygrand* grand_create(QofBook*);
00100 myparent* parent_create(QofBook*);
00101 mychild* child_create(QofBook*);
00102
00103 gboolean mygrandRegister (void);
00104 gboolean myparentRegister (void);
00105 gboolean mychildRegister (void);
00106
00107
00108 void grand_setName(mygrand*, gchar*);
00109 void grand_setAmount(mygrand*, gnc_numeric);
00110 void grand_setDate(mygrand*, Timespec h);
00111 void grand_setDiscount(mygrand*, double);
00112 void grand_setActive(mygrand*, gboolean);
00113 void grand_setVersion(mygrand*, gint32);
00114 void grand_setMinor(mygrand*, gint64);
00115 void grand_setFlag(mygrand*, gchar);
00116
00117
00118 gchar* grand_getName(mygrand*);
00119 gnc_numeric grand_getAmount(mygrand*);
00120 Timespec grand_getDate(mygrand*);
00121 double grand_getDiscount(mygrand*);
00122 gboolean grand_getActive(mygrand*);
00123 gint32 grand_getVersion(mygrand*);
00124 gint64 grand_getMinor(mygrand*);
00125 gchar grand_getFlag(mygrand*);
00126
00127
00128 void parent_setName(myparent*, gchar*);
00129 void parent_setAmount(myparent*, gnc_numeric);
00130 void parent_setDate(myparent*, Timespec h);
00131 void parent_setDiscount(myparent*, double);
00132 void parent_setActive(myparent*, gboolean);
00133 void parent_setVersion(myparent*, gint32);
00134 void parent_setMinor(myparent*, gint64);
00135 void parent_setFlag(myparent*, gchar);
00136
00137
00138 gchar* parent_getName(myparent*);
00139 gnc_numeric parent_getAmount(myparent*);
00140 Timespec parent_getDate(myparent*);
00141 double parent_getDiscount(myparent*);
00142 gboolean parent_getActive(myparent*);
00143 gint32 parent_getVersion(myparent*);
00144 gint64 parent_getMinor(myparent*);
00145 gchar parent_getFlag(myparent*);
00146
00147
00148 void child_setName(mychild*, gchar*);
00149 void child_setAmount(mychild*, gnc_numeric);
00150 void child_setDate(mychild*, Timespec h);
00151 void child_setDiscount(mychild*, double);
00152 void child_setActive(mychild*, gboolean);
00153 void child_setVersion(mychild*, gint32);
00154 void child_setMinor(mychild*, gint64);
00155 void child_setFlag(mychild*, gchar);
00156
00157
00158 gchar* child_getName(mychild*);
00159 gnc_numeric child_getAmount(mychild*);
00160 Timespec child_getDate(mychild*);
00161 double child_getDiscount(mychild*);
00162 gboolean child_getActive(mychild*);
00163 gint32 child_getVersion(mychild*);
00164 gint64 child_getMinor(mychild*);
00165 gchar child_getFlag(mychild*);
00166
00167 mygrand*
00168 grand_create(QofBook *book)
00169 {
00170 mygrand *g;
00171
00172 g_return_val_if_fail(book, NULL);
00173 g = g_new0(mygrand, 1);
00174 qof_instance_init (&g->inst, GRAND_MODULE_NAME, book);
00175 g->date = *get_random_timespec();
00176 g->discount = get_random_double();;
00177 g->active = get_random_boolean();
00178 g->version = get_random_int_in_range(1,10000);
00179 g->minor = get_random_int_in_range(100001,99999999);
00180 g->flag = get_random_character();
00181 g->Name = get_random_string();
00182 g->Amount = get_random_gnc_numeric();
00183 g->child = NULL;
00184 g->descend = NULL;
00185 gnc_engine_gen_event(&g->inst.entity, GNC_EVENT_CREATE);
00186 return g;
00187 }
00188
00189 myparent*
00190 parent_create(QofBook *book)
00191 {
00192 myparent *g;
00193
00194 g_return_val_if_fail(book, NULL);
00195 g = g_new0(myparent, 1);
00196 qof_instance_init (&g->inst, PARENT_MODULE_NAME, book);
00197 g->date = *get_random_timespec();
00198 g->discount = get_random_double();
00199 g->active = get_random_boolean();
00200 g->version = get_random_int_in_range(1,10000);
00201 g->minor = get_random_int_in_range(100001,99999999);
00202 g->flag = get_random_character();
00203 g->Name = get_random_string();
00204 g->Amount = get_random_gnc_numeric();
00205 g->child = NULL;
00206 gnc_engine_gen_event(&g->inst.entity, GNC_EVENT_CREATE);
00207 return g;
00208 }
00209
00210 mychild*
00211 child_create(QofBook *book)
00212 {
00213 mychild *g;
00214
00215 g_return_val_if_fail(book, NULL);
00216 g = g_new0(mychild, 1);
00217 qof_instance_init (&g->inst, CHILD_MODULE_NAME, book);
00218 g->date = *get_random_timespec();
00219 g->discount = get_random_double();
00220 g->active = get_random_boolean();
00221 g->version = get_random_int_in_range(1,10000);
00222 g->minor = get_random_int_in_range(100001,99999999);
00223 g->flag = get_random_character();
00224 g->Name = get_random_string();
00225 g->Amount = get_random_gnc_numeric();
00226 gnc_engine_gen_event(&g->inst.entity, GNC_EVENT_CREATE);
00227 return g;
00228 }
00229
00230 static void
00231 descend_cb (QofEntity *ent, gpointer user_data)
00232 {
00233 mygrand *g = (mygrand*)user_data;
00234
00235 g_return_if_fail(g || ent);
00236 g->descend = g_list_prepend(g->descend, (mychild*)ent);
00237 }
00238
00239 static void
00240 grand_setDescend(mygrand *g, QofCollection *coll)
00241 {
00242 g_return_if_fail(g || coll);
00243 if(0 != safe_strcmp(qof_collection_get_type(coll), CHILD_MODULE_NAME))
00244 {
00245 return;
00246 }
00247 qof_collection_foreach(coll, descend_cb, g);
00248 }
00249
00250 static QofCollection*
00251 grand_getDescend(mygrand *g)
00252 {
00253 QofCollection *col;
00254 QofEntity *ent;
00255 GList *list;
00256
00257 g_return_val_if_fail(g, NULL);
00258 col = qof_collection_new(CHILD_MODULE_NAME);
00259 for(list = g_list_copy(g->descend);list;list=list->next)
00260 {
00261 ent = (QofEntity*)list->data;
00262 if(!ent) { break; }
00263 do_test(0 == safe_strcmp(ent->e_type, CHILD_MODULE_NAME), "wrong entity");
00264 qof_collection_add_entity(col, ent);
00265 }
00266 return col;
00267 }
00268
00269 static void
00270 grand_setChild(mygrand *g, myparent *p)
00271 {
00272 g_return_if_fail(g || p);
00273 g->child = p;
00274 }
00275
00276 static myparent*
00277 grand_getChild(mygrand *g)
00278 {
00279 g_return_val_if_fail(g, NULL);
00280 return g->child;
00281 }
00282
00283 void
00284 grand_setFlag(mygrand *g, gchar f)
00285 {
00286 g_return_if_fail(g);
00287 g->flag = f;
00288 }
00289
00290 gchar
00291 grand_getFlag(mygrand *g)
00292 {
00293 g_return_val_if_fail(g, 'n');
00294 return g->flag;
00295 }
00296
00297 void
00298 grand_setMinor(mygrand *g, gint64 h)
00299 {
00300 g_return_if_fail(g != NULL);
00301 g->minor = h;
00302 }
00303
00304 gint64
00305 grand_getMinor(mygrand *g)
00306 {
00307 g_return_val_if_fail((g != NULL),0);
00308 return g->minor;
00309 }
00310
00311 void
00312 grand_setVersion(mygrand *g, gint32 h)
00313 {
00314 g_return_if_fail(g != NULL);
00315 g->version = h;
00316 }
00317
00318 gint32
00319 grand_getVersion(mygrand *g)
00320 {
00321 if(!g) return 0;
00322 return g->version;
00323 }
00324
00325 void
00326 grand_setActive(mygrand *g, gboolean h)
00327 {
00328 if(!g) return;
00329 g->active = h;
00330 }
00331
00332 gboolean
00333 grand_getActive(mygrand *g)
00334 {
00335 if(!g) return FALSE;
00336 return g->active;
00337 }
00338
00339 void
00340 grand_setDiscount(mygrand *g, double h)
00341 {
00342 if(!g) return;
00343 g->discount = h;
00344 }
00345
00346 double
00347 grand_getDiscount(mygrand *g)
00348 {
00349 if(!g) return 0;
00350 return g->discount;
00351 }
00352
00353 void
00354 grand_setDate(mygrand *g, Timespec h)
00355 {
00356 if(!g) return;
00357 g->date = h;
00358 }
00359
00360 Timespec
00361 grand_getDate(mygrand *g)
00362 {
00363 Timespec ts;
00364 ts.tv_sec = 0;
00365 ts.tv_nsec = 0;
00366 if(!g) return ts;
00367 ts = g->date;
00368 return ts;
00369 }
00370
00371 void
00372 grand_setName(mygrand* g, gchar* h)
00373 {
00374 if(!g || !h) return;
00375 g->Name = strdup(h);
00376 }
00377
00378 gchar*
00379 grand_getName(mygrand *g)
00380 {
00381 if(!g) return NULL;
00382 return g->Name;
00383 }
00384
00385 void
00386 grand_setAmount(mygrand *g, gnc_numeric h)
00387 {
00388 if(!g) return;
00389 g->Amount = h;
00390 }
00391
00392 gnc_numeric
00393 grand_getAmount(mygrand *g)
00394 {
00395 if(!g) return gnc_numeric_zero();
00396 return g->Amount;
00397 }
00398
00399 static void
00400 parent_setChild(myparent *p, mychild *c)
00401 {
00402 g_return_if_fail(p || c);
00403 p->child = c;
00404 }
00405
00406 static mychild*
00407 parent_getChild(myparent* p)
00408 {
00409 g_return_val_if_fail(p, NULL);
00410 return p->child;
00411 }
00412
00413 void
00414 parent_setFlag(myparent *p, gchar f)
00415 {
00416 g_return_if_fail(p);
00417 p->flag = f;
00418 }
00419
00420 gchar
00421 parent_getFlag(myparent *p)
00422 {
00423 g_return_val_if_fail(p, 'n');
00424 return p->flag;
00425 }
00426
00427 void
00428 parent_setMinor(myparent *p, gint64 h)
00429 {
00430 g_return_if_fail(p != NULL);
00431 p->minor = h;
00432 }
00433
00434 gint64
00435 parent_getMinor(myparent *p)
00436 {
00437 g_return_val_if_fail((p != NULL),0);
00438 return p->minor;
00439 }
00440
00441 void
00442 parent_setVersion(myparent *p, gint32 h)
00443 {
00444 g_return_if_fail(p != NULL);
00445 p->version = h;
00446 }
00447
00448 gint32
00449 parent_getVersion(myparent *p)
00450 {
00451 if(!p) return 0;
00452 return p->version;
00453 }
00454
00455 void
00456 parent_setActive(myparent *p, gboolean h)
00457 {
00458 if(!p) return;
00459 p->active = h;
00460 }
00461
00462 gboolean
00463 parent_getActive(myparent *p)
00464 {
00465 if(!p) return FALSE;
00466 return p->active;
00467 }
00468
00469 void
00470 parent_setDiscount(myparent *p, double h)
00471 {
00472 if(!p) return;
00473 p->discount = h;
00474 }
00475
00476 double
00477 parent_getDiscount(myparent *p)
00478 {
00479 if(!p) return 0;
00480 return p->discount;
00481 }
00482
00483 void
00484 parent_setDate(myparent *p, Timespec h)
00485 {
00486 if(!p) return;
00487 p->date = h;
00488 }
00489
00490 Timespec
00491 parent_getDate(myparent *p)
00492 {
00493 Timespec ts;
00494 ts.tv_sec = 0;
00495 ts.tv_nsec = 0;
00496 if(!p) return ts;
00497 ts = p->date;
00498 return ts;
00499 }
00500
00501 void
00502 parent_setName(myparent* p, gchar* h)
00503 {
00504 if(!p || !h) return;
00505 p->Name = strdup(h);
00506 }
00507
00508 gchar*
00509 parent_getName(myparent *p)
00510 {
00511 if(!p) return NULL;
00512 return p->Name;
00513 }
00514
00515 void
00516 parent_setAmount(myparent *p, gnc_numeric h)
00517 {
00518 if(!p) return;
00519 p->Amount = h;
00520 }
00521
00522 gnc_numeric
00523 parent_getAmount(myparent *p)
00524 {
00525 if(!p) return gnc_numeric_zero();
00526 return p->Amount;
00527 }
00528
00529 void
00530 child_setFlag(mychild *c, gchar f)
00531 {
00532 g_return_if_fail(c);
00533 c->flag = f;
00534 }
00535
00536 gchar
00537 child_getFlag(mychild *c)
00538 {
00539 g_return_val_if_fail(c, 'n');
00540 return c->flag;
00541 }
00542
00543 void
00544 child_setMinor(mychild *c, gint64 h)
00545 {
00546 g_return_if_fail(c != NULL);
00547 c->minor = h;
00548 }
00549
00550 gint64
00551 child_getMinor(mychild *c)
00552 {
00553 g_return_val_if_fail((c != NULL),0);
00554 return c->minor;
00555 }
00556
00557 void
00558 child_setVersion(mychild *c, gint32 h)
00559 {
00560 g_return_if_fail(c != NULL);
00561 c->version = h;
00562 }
00563
00564 gint32
00565 child_getVersion(mychild *c)
00566 {
00567 if(!c) return 0;
00568 return c->version;
00569 }
00570
00571 void
00572 child_setActive(mychild *c, gboolean h)
00573 {
00574 if(!c) return;
00575 c->active = h;
00576 }
00577
00578 gboolean
00579 child_getActive(mychild *c)
00580 {
00581 if(!c) return FALSE;
00582 return c->active;
00583 }
00584
00585 void
00586 child_setDiscount(mychild *c, double h)
00587 {
00588 if(!c) return;
00589 c->discount = h;
00590 }
00591
00592 double
00593 child_getDiscount(mychild *c)
00594 {
00595 if(!c) return 0;
00596 return c->discount;
00597 }
00598
00599 void
00600 child_setDate(mychild *c, Timespec h)
00601 {
00602 if(!c) return;
00603 c->date = h;
00604 }
00605
00606 Timespec
00607 child_getDate(mychild *c)
00608 {
00609 Timespec ts;
00610 ts.tv_sec = 0;
00611 ts.tv_nsec = 0;
00612 if(!c) return ts;
00613 ts = c->date;
00614 return ts;
00615 }
00616
00617 void
00618 child_setName(mychild* c, gchar* h)
00619 {
00620 if(!c || !h) return;
00621 c->Name = strdup(h);
00622 }
00623
00624 gchar*
00625 child_getName(mychild *c)
00626 {
00627 if(!c) return NULL;
00628 return c->Name;
00629 }
00630
00631 void
00632 child_setAmount(mychild *c, gnc_numeric h)
00633 {
00634 if(!c) return;
00635 c->Amount = h;
00636 }
00637
00638 gnc_numeric
00639 child_getAmount(mychild *c)
00640 {
00641 if(!c) return gnc_numeric_zero();
00642 return c->Amount;
00643 }
00644
00645 static QofObject grand_object_def = {
00646 interface_version: QOF_OBJECT_VERSION,
00647 e_type: GRAND_MODULE_NAME,
00648 type_label: GRAND_MODULE_DESC,
00649 create: (gpointer)grand_create,
00650 book_begin: NULL,
00651 book_end: NULL,
00652 is_dirty: qof_collection_is_dirty,
00653 mark_clean: qof_collection_mark_clean,
00654 foreach: qof_collection_foreach,
00655 printable: NULL,
00656 version_cmp: (int (*)(gpointer,gpointer)) qof_instance_version_cmp,
00657 };
00658
00659 gboolean mygrandRegister (void)
00660 {
00661 static QofParam params[] = {
00662 { OBJ_NAME, QOF_TYPE_STRING, (QofAccessFunc)grand_getName,
00663 (QofSetterFunc)grand_setName },
00664 { OBJ_AMOUNT, QOF_TYPE_NUMERIC, (QofAccessFunc)grand_getAmount,
00665 (QofSetterFunc)grand_setAmount },
00666 { OBJ_DATE, QOF_TYPE_DATE, (QofAccessFunc)grand_getDate,
00667 (QofSetterFunc)grand_setDate },
00668 { OBJ_DISCOUNT, QOF_TYPE_DOUBLE, (QofAccessFunc)grand_getDiscount,
00669 (QofSetterFunc)grand_setDiscount },
00670 { OBJ_ACTIVE, QOF_TYPE_BOOLEAN, (QofAccessFunc)grand_getActive,
00671 (QofSetterFunc)grand_setActive },
00672 { OBJ_VERSION, QOF_TYPE_INT32, (QofAccessFunc)grand_getVersion,
00673 (QofSetterFunc)grand_setVersion },
00674 { OBJ_MINOR, QOF_TYPE_INT64, (QofAccessFunc)grand_getMinor,
00675 (QofSetterFunc)grand_setMinor },
00676 { OBJ_FLAG, QOF_TYPE_CHAR, (QofAccessFunc)grand_getFlag,
00677 (QofSetterFunc)grand_setFlag },
00678 { OBJ_RELATIVE, PARENT_MODULE_NAME, (QofAccessFunc)grand_getChild,
00679 (QofSetterFunc)grand_setChild },
00680 { OBJ_LIST, QOF_TYPE_COLLECT, (QofAccessFunc)grand_getDescend,
00681 (QofSetterFunc)grand_setDescend },
00682 { QOF_PARAM_BOOK, QOF_ID_BOOK, (QofAccessFunc)qof_instance_get_book, NULL },
00683 { QOF_PARAM_GUID, QOF_TYPE_GUID, (QofAccessFunc)qof_instance_get_guid, NULL },
00684 { NULL },
00685 };
00686
00687 qof_class_register (GRAND_MODULE_NAME, NULL, params);
00688
00689
00690 return qof_object_register (&grand_object_def);
00691 }
00692
00693 static QofObject parent_object_def = {
00694 interface_version: QOF_OBJECT_VERSION,
00695 e_type: PARENT_MODULE_NAME,
00696 type_label: PARENT_MODULE_DESC,
00697 create: (gpointer)parent_create,
00698 book_begin: NULL,
00699 book_end: NULL,
00700 is_dirty: qof_collection_is_dirty,
00701 mark_clean: qof_collection_mark_clean,
00702 foreach: qof_collection_foreach,
00703 printable: NULL,
00704 version_cmp: (int (*)(gpointer,gpointer)) qof_instance_version_cmp,
00705 };
00706
00707 gboolean myparentRegister (void)
00708 {
00709 static QofParam params[] = {
00710 { OBJ_NAME, QOF_TYPE_STRING, (QofAccessFunc)parent_getName,
00711 (QofSetterFunc)parent_setName },
00712 { OBJ_AMOUNT, QOF_TYPE_NUMERIC, (QofAccessFunc)parent_getAmount,
00713 (QofSetterFunc)parent_setAmount },
00714 { OBJ_DATE, QOF_TYPE_DATE, (QofAccessFunc)parent_getDate,
00715 (QofSetterFunc)parent_setDate },
00716 { OBJ_DISCOUNT, QOF_TYPE_DOUBLE, (QofAccessFunc)parent_getDiscount,
00717 (QofSetterFunc)parent_setDiscount },
00718 { OBJ_ACTIVE, QOF_TYPE_BOOLEAN, (QofAccessFunc)parent_getActive,
00719 (QofSetterFunc)parent_setActive },
00720 { OBJ_VERSION, QOF_TYPE_INT32, (QofAccessFunc)parent_getVersion,
00721 (QofSetterFunc)parent_setVersion },
00722 { OBJ_MINOR, QOF_TYPE_INT64, (QofAccessFunc)parent_getMinor,
00723 (QofSetterFunc)parent_setMinor },
00724 { OBJ_FLAG, QOF_TYPE_CHAR, (QofAccessFunc)parent_getFlag,
00725 (QofSetterFunc)parent_setFlag },
00726 { OBJ_RELATIVE, CHILD_MODULE_NAME, (QofAccessFunc)parent_getChild,
00727 (QofSetterFunc)parent_setChild },
00728 { QOF_PARAM_BOOK, QOF_ID_BOOK, (QofAccessFunc)qof_instance_get_book, NULL },
00729 { QOF_PARAM_GUID, QOF_TYPE_GUID, (QofAccessFunc)qof_instance_get_guid, NULL },
00730 { NULL },
00731 };
00732
00733 qof_class_register (PARENT_MODULE_NAME, NULL, params);
00734
00735 return qof_object_register (&parent_object_def);
00736 }
00737
00738 static QofObject child_object_def = {
00739 interface_version: QOF_OBJECT_VERSION,
00740 e_type: CHILD_MODULE_NAME,
00741 type_label: CHILD_MODULE_DESC,
00742 create: (gpointer)child_create,
00743 book_begin: NULL,
00744 book_end: NULL,
00745 is_dirty: qof_collection_is_dirty,
00746 mark_clean: qof_collection_mark_clean,
00747 foreach: qof_collection_foreach,
00748 printable: NULL,
00749 version_cmp: (int (*)(gpointer,gpointer)) qof_instance_version_cmp,
00750 };
00751
00752 gboolean mychildRegister (void)
00753 {
00754 static QofParam params[] = {
00755 { OBJ_NAME, QOF_TYPE_STRING, (QofAccessFunc)child_getName,
00756 (QofSetterFunc)child_setName },
00757 { OBJ_AMOUNT, QOF_TYPE_NUMERIC, (QofAccessFunc)child_getAmount,
00758 (QofSetterFunc)child_setAmount },
00759 { OBJ_DATE, QOF_TYPE_DATE, (QofAccessFunc)child_getDate,
00760 (QofSetterFunc)child_setDate },
00761 { OBJ_DISCOUNT, QOF_TYPE_DOUBLE, (QofAccessFunc)child_getDiscount,
00762 (QofSetterFunc)child_setDiscount },
00763 { OBJ_ACTIVE, QOF_TYPE_BOOLEAN, (QofAccessFunc)child_getActive,
00764 (QofSetterFunc)child_setActive },
00765 { OBJ_VERSION, QOF_TYPE_INT32, (QofAccessFunc)child_getVersion,
00766 (QofSetterFunc)child_setVersion },
00767 { OBJ_MINOR, QOF_TYPE_INT64, (QofAccessFunc)child_getMinor,
00768 (QofSetterFunc)child_setMinor },
00769 { OBJ_FLAG, QOF_TYPE_CHAR, (QofAccessFunc)child_getFlag,
00770 (QofSetterFunc)child_setFlag },
00771 { QOF_PARAM_BOOK, QOF_ID_BOOK, (QofAccessFunc)qof_instance_get_book, NULL },
00772 { QOF_PARAM_GUID, QOF_TYPE_GUID, (QofAccessFunc)qof_instance_get_guid, NULL },
00773 { NULL },
00774 };
00775
00776 qof_class_register (CHILD_MODULE_NAME, NULL, params);
00777
00778 return qof_object_register (&child_object_def);
00779 }
00780
00781 static void
00782 create_data (QofSession *original, guint counter)
00783 {
00784 QofCollection *coll;
00785 QofBook *start;
00786 mygrand *grand1;
00787 myparent *parent1;
00788 mychild *child1;
00789
00790 start = qof_session_get_book(original);
00791 grand1 = (mygrand*)qof_object_new_instance(GRAND_MODULE_NAME, start);
00792 do_test ((NULL != &grand1->inst), "instance init");
00793 switch (counter)
00794 {
00795 case 0 : {
00796 do_test((grand1 != NULL), "empty tree check");
00797 coll = qof_book_get_collection(start, GRAND_MODULE_NAME);
00798 do_test((qof_collection_count(coll) == 1),
00799 "Too many grandparents found - should be 1");
00800 coll = qof_book_get_collection(start, CHILD_MODULE_NAME);
00801 do_test((qof_collection_count(coll) == 0),
00802 "child found, should be empty");
00803 coll = qof_book_get_collection(start, PARENT_MODULE_NAME);
00804 do_test((qof_collection_count(coll) == 0),
00805 "tree not empty: parent found");
00806 break;
00807 }
00808 case 1 : {
00809 parent1 = (myparent*)qof_object_new_instance(PARENT_MODULE_NAME, start);
00810 grand_setChild(grand1, parent1);
00811 do_test((parent1 != NULL), "single parent check");
00812 do_test((grand_getChild(grand1) == parent1), "set child in grandparent");
00813 coll = qof_book_get_collection(start, GRAND_MODULE_NAME);
00814 do_test((qof_collection_count(coll) == 1),
00815 "Wrong number of grandparents, should be 1");
00816 coll = qof_book_get_collection(start, CHILD_MODULE_NAME);
00817 do_test((qof_collection_count(coll) == 0),
00818 "Should be no child entities this iteration.");
00819 coll = qof_book_get_collection(start, PARENT_MODULE_NAME);
00820 do_test((qof_collection_count(coll) == 1),
00821 "Wrong number of parents found, should be 1");
00822 break;
00823 }
00824 case 2 : {
00825 parent1 = (myparent*)qof_object_new_instance(PARENT_MODULE_NAME, start);
00826 grand_setChild(grand1, parent1);
00827 child1 = (mychild*)qof_object_new_instance(CHILD_MODULE_NAME, start);
00828 parent1 = grand_getChild(grand1);
00829 parent_setChild(parent1, child1);
00830 do_test((child1 != NULL), "one parent with one related child");
00831 do_test((child1 == parent_getChild(parent1)), "child of single parent");
00832 coll = qof_book_get_collection(start, GRAND_MODULE_NAME);
00833 do_test((qof_collection_count(coll) == 1),
00834 "Wrong number of grandparents. Should be 1");
00835 coll = qof_book_get_collection(start, CHILD_MODULE_NAME);
00836 do_test((qof_collection_count(coll) == 1),
00837 "Wrong number of child entities, should be 1");
00838 coll = qof_book_get_collection(start, PARENT_MODULE_NAME);
00839 do_test((qof_collection_count(coll) == 1),
00840 "Wrong number of parents. Should be 1");
00841 break;
00842 }
00843 case 3 : {
00844 child1 = (mychild*)qof_object_new_instance(CHILD_MODULE_NAME, start);
00845 parent1 = (myparent*)qof_object_new_instance(PARENT_MODULE_NAME, start);
00846 grand_setChild(grand1, parent1);
00847 parent_setChild(parent1, child1);
00848 do_test((parent1 == grand_getChild(grand1)), "same grandparent, new parent");
00849 do_test((child1 == parent_getChild(parent1)), "new parent, same child");
00850 coll = qof_book_get_collection(start, GRAND_MODULE_NAME);
00851 do_test((qof_collection_count(coll) == 1),
00852 "Wrong number of grandparents. Should be 1, Iteration 3.");
00853 coll = qof_book_get_collection(start, CHILD_MODULE_NAME);
00854 do_test((qof_collection_count(coll) == 1),
00855 "Wrong number of child entities, should be 1. Iteration 3.");
00856 coll = qof_book_get_collection(start, PARENT_MODULE_NAME);
00857 do_test((qof_collection_count(coll) == 1),
00858 "Wrong number of parents. Should be 1. Iteration 3.");
00859 break;
00860 }
00861 case 4 : {
00862 grand1 = (mygrand*)qof_object_new_instance(GRAND_MODULE_NAME, start);
00863 parent1 = (myparent*)qof_object_new_instance(PARENT_MODULE_NAME, start);
00864 child1 = (mychild*)qof_object_new_instance(CHILD_MODULE_NAME, start);
00865 parent_setChild(parent1, child1);
00866 do_test((NULL == grand_getChild(grand1)), "new grand, unrelated parent");
00867 do_test((child1 == parent_getChild(parent1)), "child unrelated to grand");
00868 coll = grand_getDescend(grand1);
00869 do_test((coll != NULL), "grandparent not valid");
00870 if(coll)
00871 {
00872 QofEntity *ent;
00873
00874 ent = (QofEntity*)child1;
00875 qof_collection_add_entity(coll, ent);
00876 grand_setDescend(grand1, coll);
00877 qof_collection_destroy(coll);
00878 do_test((g_list_length(grand1->descend) > 0), "entity not added");
00879 do_test((qof_collection_count(grand_getDescend(grand1)) > 0),
00880 "empty collection returned");
00881 }
00882 break;
00883 }
00884 }
00885 }
00886
00887 struct tally
00888 {
00889 guint nulls, total, collect;
00890 QofBook *book;
00891 };
00892
00893 static void
00894 check_cb (QofEntity *ent, gpointer data)
00895 {
00896 QofEntity *parent, *child;
00897 QofCollection *coll;
00898 struct tally *c;
00899 const QofParam *param;
00900 mygrand *testg;
00901 myparent *testp;
00902 mychild *testc;
00903
00904 c = (struct tally*)data;
00905
00906
00907 testg = (mygrand*)ent;
00908
00909 do_test((testg != NULL), "grandparent not found");
00910 c->total++;
00911 param = qof_class_get_parameter(GRAND_MODULE_NAME, OBJ_LIST);
00912 coll = (QofCollection*)param->param_getfcn(ent, param);
00913 c->collect = qof_collection_count(coll);
00914 if(c->book) { qof_book_set_references(c->book); }
00915 param = qof_class_get_parameter(GRAND_MODULE_NAME, OBJ_RELATIVE);
00916 parent = (QofEntity*)param->param_getfcn(ent, param);
00917 testp = grand_getChild((mygrand*)ent);
00918
00919 if(!parent) { c->nulls++; return; }
00920 do_test((0 == safe_strcmp(parent_getName(testp),
00921 parent_getName((myparent*)parent))), "parent copy test");
00922 param = qof_class_get_parameter(PARENT_MODULE_NAME, OBJ_RELATIVE);
00923 child = param->param_getfcn(parent, param);
00924 testc = parent_getChild((myparent*)parent);
00925 if(!child) { c->nulls++; return; }
00926 do_test((0 == safe_strcmp(child_getName(testc),
00927 child_getName((mychild*)child))), "child copy test");
00928 }
00929
00930 static void
00931 test_recursion (QofSession *original, guint counter)
00932 {
00933 QofSession *copy;
00934 QofCollection *grand_coll;
00935 struct tally c;
00936 QofBook *book;
00937 guint d, e, f;
00938
00939 c.nulls = 0;
00940 c.total = 0;
00941 c.collect = 0;
00942 c.book = NULL;
00943 book = qof_session_get_book(original);
00944 grand_coll = qof_book_get_collection(book, GRAND_MODULE_NAME);
00945 copy = qof_session_new();
00946 if(debug) { qof_session_begin(copy, QOF_STDOUT, TRUE, FALSE); }
00947
00948 qof_entity_copy_coll_r(copy, grand_coll);
00949
00950 qof_object_foreach(GRAND_MODULE_NAME, book, check_cb, &c);
00951 book = qof_session_get_book(copy);
00952
00953 d = c.nulls;
00954 e = c.total;
00955 f = c.collect;
00956 c.nulls = 0;
00957 c.total = 0;
00958 c.collect = 0;
00959 c.book = book;
00960 qof_object_foreach(GRAND_MODULE_NAME, book, check_cb, &c);
00961 do_test((d == c.nulls), "Null parents do not match");
00962 do_test((e == c.total), "Total parents do not match");
00963 do_test((f == c.collect), "Number of children in descendents does not match");
00964 if(counter == 4 && debug == TRUE) {
00965 qof_session_save(copy, NULL);
00966 qof_session_save(original, NULL);
00967 }
00968 qof_session_end(copy);
00969 copy = NULL;
00970 }
00971
00972 int
00973 main (int argc, const char *argv[])
00974 {
00975 QofSession *original;
00976 guint counter;
00977
00978 qof_init ();
00979 mygrandRegister();
00980 myparentRegister();
00981 mychildRegister();
00982 for(counter = 0; counter < 35; counter++)
00983 {
00984 original = qof_session_new();
00985 if(debug) { qof_session_begin(original, QOF_STDOUT, TRUE, FALSE); }
00986 create_data(original, (counter % 5));
00987 test_recursion(original, (counter % 5));
00988 qof_session_end(original);
00989 }
00990 print_test_results();
00991 qof_close();
00992 return EXIT_SUCCESS;
00993 }