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

Generated on Thu Jan 31 22:50:26 2008 for QOF by  doxygen 1.5.4