test-recursive.c

00001 /***************************************************************************
00002  *            test-recursive.c
00003  *
00004  *  Wed Feb  1 21:54:49 2006
00005  *  Copyright  2006  Neil Williams
00006  *  linux@codehelp.co.uk
00007  ****************************************************************************/
00008 /*
00009  *  This program is free software; you can redistribute it and/or modify
00010  *  it under the terms of the GNU General Public License as published by
00011  *  the Free Software Foundation; either version 2 of the License, or
00012  *  (at your option) any later version.
00013  *
00014  *  This program is distributed in the hope that it will be useful,
00015  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  *  GNU General Public License for more details.
00018  *
00019  *  You should have received a copy of the GNU General Public License
00020  *  along with this program; if not, write to the Free Software
00021  *  Foundation, Inc., 51 Franklin Street, Fifth Floor
00022  *  Boston, MA  02110-1301,  USA 
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 /* set to TRUE to get QSF XML output
00051  * requires QSF available (i.e. make install) */
00052 static gboolean debug = FALSE;
00053 
00054 /* simple object structure */
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; /* cheap pun, I know. */
00063         gboolean    active;
00064         gint32      version;
00065         gint64      minor;
00066 }mychild;
00067 
00068 /* simple object structure */
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; /* cheap pun, I know. */
00078         gboolean    active;
00079         gint32      version;
00080         gint64      minor;
00081 }myparent;
00082 
00083         /* simple object structure */
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; /* cheap pun, I know. */
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 /* obvious setter functions */
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 /* obvious getter functions */
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 /* obvious setter functions */
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 /* obvious getter functions */
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 /* obvious setter functions */
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 /* obvious getter functions */
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 /*  if(!qof_choice_create(GRAND_MODULE_NAME)) { return FALSE; }*/
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 : { /* NULL tree */
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 : { /* one parent, no child */ 
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 : { /* one parent, one child */ 
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 : { /* same grand, new parent, same child */
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 : { /* new grand, unrelated parent, child unrelated to grand */
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         /* check the same number and type of entities
00906         exist in the copied book */
00907         testg = (mygrand*)ent;
00908         /* we always have a grandparent */
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         /* not all grandparents have family so just keep count. */
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         /* TODO: implement QOF_TYPE_CHOICE testing. */
00948         qof_entity_copy_coll_r(copy, grand_coll);
00949         /* test the original */
00950         qof_object_foreach(GRAND_MODULE_NAME, book, check_cb, &c);
00951         book = qof_session_get_book(copy);
00952         /* test the copy */
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 }

Generated on Fri May 12 18:00:33 2006 for QOF by  doxygen 1.4.4