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     gnc_numeric Amount;
00060     QofTime *date;
00061     double 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     gnc_numeric Amount;
00075     QofTime *date;
00076     double 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     gnc_numeric Amount;
00091     QofTime *date;
00092     double 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 *, gnc_numeric);
00109 void grand_setDate (mygrand *, QofTime *h);
00110 void grand_setDiscount (mygrand *, double);
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 gnc_numeric grand_getAmount (mygrand *);
00119 QofTime *grand_getDate (mygrand *);
00120 double 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 *, gnc_numeric);
00129 void parent_setDate (myparent *, QofTime *h);
00130 void parent_setDiscount (myparent *, double);
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 gnc_numeric parent_getAmount (myparent *);
00139 QofTime *parent_getDate (myparent *);
00140 double 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 *, gnc_numeric);
00149 void child_setDate (mychild *, QofTime *h);
00150 void child_setDiscount (mychild *, double);
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 gnc_numeric child_getAmount (mychild *);
00159 QofTime *child_getDate (mychild *);
00160 double 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_gnc_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_gnc_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_gnc_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, gnc_numeric h)
00396 {
00397     if (!g)
00398         return;
00399     g->Amount = h;
00400 }
00401 
00402 gnc_numeric
00403 grand_getAmount (mygrand * g)
00404 {
00405     if (!g)
00406         return gnc_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, gnc_numeric h)
00533 {
00534     if (!p)
00535         return;
00536     p->Amount = h;
00537 }
00538 
00539 gnc_numeric
00540 parent_getAmount (myparent * p)
00541 {
00542     if (!p)
00543         return gnc_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, gnc_numeric h)
00656 {
00657     if (!c)
00658         return;
00659     c->Amount = h;
00660 }
00661 
00662 gnc_numeric
00663 child_getAmount (mychild * c)
00664 {
00665     if (!c)
00666         return gnc_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:(int (*)(gpointer, gpointer)) qof_instance_version_cmp,
00682 };
00683 
00684 gboolean
00685 mygrandRegister (void)
00686 {
00687     static QofParam params[] = {
00688         {OBJ_NAME, QOF_TYPE_STRING, (QofAccessFunc) grand_getName,
00689          (QofSetterFunc) grand_setName},
00690         {OBJ_AMOUNT, QOF_TYPE_NUMERIC, (QofAccessFunc) grand_getAmount,
00691          (QofSetterFunc) grand_setAmount},
00692         {OBJ_DATE, QOF_TYPE_TIME, (QofAccessFunc) grand_getDate,
00693          (QofSetterFunc) grand_setDate},
00694         {OBJ_DISCOUNT, QOF_TYPE_DOUBLE, (QofAccessFunc) grand_getDiscount,
00695          (QofSetterFunc) grand_setDiscount},
00696         {OBJ_ACTIVE, QOF_TYPE_BOOLEAN, (QofAccessFunc) grand_getActive,
00697          (QofSetterFunc) grand_setActive},
00698         {OBJ_VERSION, QOF_TYPE_INT32, (QofAccessFunc) grand_getVersion,
00699          (QofSetterFunc) grand_setVersion},
00700         {OBJ_MINOR, QOF_TYPE_INT64, (QofAccessFunc) grand_getMinor,
00701          (QofSetterFunc) grand_setMinor},
00702         {OBJ_FLAG, QOF_TYPE_CHAR, (QofAccessFunc) grand_getFlag,
00703          (QofSetterFunc) grand_setFlag},
00704         {OBJ_RELATIVE, PARENT_MODULE_NAME, (QofAccessFunc) grand_getChild,
00705          (QofSetterFunc) grand_setChild},
00706         {OBJ_LIST, QOF_TYPE_COLLECT, (QofAccessFunc) grand_getDescend,
00707          (QofSetterFunc) grand_setDescend},
00708         {QOF_PARAM_BOOK, QOF_ID_BOOK, (QofAccessFunc) qof_instance_get_book,
00709          NULL},
00710         {QOF_PARAM_GUID, QOF_TYPE_GUID, (QofAccessFunc) qof_instance_get_guid,
00711          NULL},
00712         {NULL},
00713     };
00714 
00715     qof_class_register (GRAND_MODULE_NAME, NULL, params);
00716 /*  if(!qof_choice_create(GRAND_MODULE_NAME)) { return FALSE; }*/
00717 
00718     return qof_object_register (&grand_object_def);
00719 }
00720 
00721 static QofObject parent_object_def = {
00722   interface_version:QOF_OBJECT_VERSION,
00723   e_type:PARENT_MODULE_NAME,
00724   type_label:PARENT_MODULE_DESC,
00725   create:(gpointer) parent_create,
00726   book_begin:NULL,
00727   book_end:NULL,
00728   is_dirty:qof_collection_is_dirty,
00729   mark_clean:qof_collection_mark_clean,
00730   foreach:qof_collection_foreach,
00731   printable:NULL,
00732   version_cmp:(int (*)(gpointer, gpointer)) qof_instance_version_cmp,
00733 };
00734 
00735 gboolean
00736 myparentRegister (void)
00737 {
00738     static QofParam params[] = {
00739         {OBJ_NAME, QOF_TYPE_STRING, (QofAccessFunc) parent_getName,
00740          (QofSetterFunc) parent_setName},
00741         {OBJ_AMOUNT, QOF_TYPE_NUMERIC, (QofAccessFunc) parent_getAmount,
00742          (QofSetterFunc) parent_setAmount},
00743         {OBJ_DATE, QOF_TYPE_TIME, (QofAccessFunc) parent_getDate,
00744          (QofSetterFunc) parent_setDate},
00745         {OBJ_DISCOUNT, QOF_TYPE_DOUBLE, (QofAccessFunc) parent_getDiscount,
00746          (QofSetterFunc) parent_setDiscount},
00747         {OBJ_ACTIVE, QOF_TYPE_BOOLEAN, (QofAccessFunc) parent_getActive,
00748          (QofSetterFunc) parent_setActive},
00749         {OBJ_VERSION, QOF_TYPE_INT32, (QofAccessFunc) parent_getVersion,
00750          (QofSetterFunc) parent_setVersion},
00751         {OBJ_MINOR, QOF_TYPE_INT64, (QofAccessFunc) parent_getMinor,
00752          (QofSetterFunc) parent_setMinor},
00753         {OBJ_FLAG, QOF_TYPE_CHAR, (QofAccessFunc) parent_getFlag,
00754          (QofSetterFunc) parent_setFlag},
00755         {OBJ_RELATIVE, CHILD_MODULE_NAME, (QofAccessFunc) parent_getChild,
00756          (QofSetterFunc) parent_setChild},
00757         {QOF_PARAM_BOOK, QOF_ID_BOOK, (QofAccessFunc) qof_instance_get_book,
00758          NULL},
00759         {QOF_PARAM_GUID, QOF_TYPE_GUID, (QofAccessFunc) qof_instance_get_guid,
00760          NULL},
00761         {NULL},
00762     };
00763 
00764     qof_class_register (PARENT_MODULE_NAME, NULL, params);
00765 
00766     return qof_object_register (&parent_object_def);
00767 }
00768 
00769 static QofObject child_object_def = {
00770   interface_version:QOF_OBJECT_VERSION,
00771   e_type:CHILD_MODULE_NAME,
00772   type_label:CHILD_MODULE_DESC,
00773   create:(gpointer) child_create,
00774   book_begin:NULL,
00775   book_end:NULL,
00776   is_dirty:qof_collection_is_dirty,
00777   mark_clean:qof_collection_mark_clean,
00778   foreach:qof_collection_foreach,
00779   printable:NULL,
00780   version_cmp:(int (*)(gpointer, gpointer)) qof_instance_version_cmp,
00781 };
00782 
00783 gboolean
00784 mychildRegister (void)
00785 {
00786     static QofParam params[] = {
00787         {OBJ_NAME, QOF_TYPE_STRING, (QofAccessFunc) child_getName,
00788          (QofSetterFunc) child_setName},
00789         {OBJ_AMOUNT, QOF_TYPE_NUMERIC, (QofAccessFunc) child_getAmount,
00790          (QofSetterFunc) child_setAmount},
00791         {OBJ_DATE, QOF_TYPE_TIME, (QofAccessFunc) child_getDate,
00792          (QofSetterFunc) child_setDate},
00793         {OBJ_DISCOUNT, QOF_TYPE_DOUBLE, (QofAccessFunc) child_getDiscount,
00794          (QofSetterFunc) child_setDiscount},
00795         {OBJ_ACTIVE, QOF_TYPE_BOOLEAN, (QofAccessFunc) child_getActive,
00796          (QofSetterFunc) child_setActive},
00797         {OBJ_VERSION, QOF_TYPE_INT32, (QofAccessFunc) child_getVersion,
00798          (QofSetterFunc) child_setVersion},
00799         {OBJ_MINOR, QOF_TYPE_INT64, (QofAccessFunc) child_getMinor,
00800          (QofSetterFunc) child_setMinor},
00801         {OBJ_FLAG, QOF_TYPE_CHAR, (QofAccessFunc) child_getFlag,
00802          (QofSetterFunc) child_setFlag},
00803         {QOF_PARAM_BOOK, QOF_ID_BOOK, (QofAccessFunc) qof_instance_get_book,
00804          NULL},
00805         {QOF_PARAM_GUID, QOF_TYPE_GUID, (QofAccessFunc) qof_instance_get_guid,
00806          NULL},
00807         {NULL},
00808     };
00809 
00810     qof_class_register (CHILD_MODULE_NAME, NULL, params);
00811 
00812     return qof_object_register (&child_object_def);
00813 }
00814 
00815 static void
00816 create_data (QofSession * original, guint counter)
00817 {
00818     QofCollection *coll;
00819     QofBook *start;
00820     mygrand *grand1;
00821     myparent *parent1;
00822     mychild *child1;
00823 
00824     start = qof_session_get_book (original);
00825     grand1 = (mygrand *) qof_object_new_instance (GRAND_MODULE_NAME, start);
00826     do_test ((NULL != &grand1->inst), "instance init");
00827     switch (counter)
00828     {
00829     case 0:
00830         {                       /* NULL tree */
00831             do_test ((grand1 != NULL), "empty tree check");
00832             coll = qof_book_get_collection (start, GRAND_MODULE_NAME);
00833             do_test ((qof_collection_count (coll) == 1),
00834                      "Too many grandparents found - should be 1");
00835             coll = qof_book_get_collection (start, CHILD_MODULE_NAME);
00836             do_test ((qof_collection_count (coll) == 0),
00837                      "child found, should be empty");
00838             coll = qof_book_get_collection (start, PARENT_MODULE_NAME);
00839             do_test ((qof_collection_count (coll) == 0),
00840                      "tree not empty: parent found");
00841             break;
00842         }
00843     case 1:
00844         {                       /* one parent, no child */
00845             parent1 =
00846                 (myparent *) qof_object_new_instance (PARENT_MODULE_NAME,
00847                                                       start);
00848             grand_setChild (grand1, parent1);
00849             do_test ((parent1 != NULL), "single parent check");
00850             do_test ((grand_getChild (grand1) == parent1),
00851                      "set child in grandparent");
00852             coll = qof_book_get_collection (start, GRAND_MODULE_NAME);
00853             do_test ((qof_collection_count (coll) == 1),
00854                      "Wrong number of grandparents, should be 1");
00855             coll = qof_book_get_collection (start, CHILD_MODULE_NAME);
00856             do_test ((qof_collection_count (coll) == 0),
00857                      "Should be no child entities this iteration.");
00858             coll = qof_book_get_collection (start, PARENT_MODULE_NAME);
00859             do_test ((qof_collection_count (coll) == 1),
00860                      "Wrong number of parents found, should be 1");
00861             break;
00862         }
00863     case 2:
00864         {                       /* one parent, one child */
00865             parent1 =
00866                 (myparent *) qof_object_new_instance (PARENT_MODULE_NAME,
00867                                                       start);
00868             grand_setChild (grand1, parent1);
00869             child1 =
00870                 (mychild *) qof_object_new_instance (CHILD_MODULE_NAME,
00871                                                      start);
00872             parent1 = grand_getChild (grand1);
00873             parent_setChild (parent1, child1);
00874             do_test ((child1 != NULL), "one parent with one related child");
00875             do_test ((child1 == parent_getChild (parent1)),
00876                      "child of single parent");
00877             coll = qof_book_get_collection (start, GRAND_MODULE_NAME);
00878             do_test ((qof_collection_count (coll) == 1),
00879                      "Wrong number of grandparents. Should be 1");
00880             coll = qof_book_get_collection (start, CHILD_MODULE_NAME);
00881             do_test ((qof_collection_count (coll) == 1),
00882                      "Wrong number of child entities, should be 1");
00883             coll = qof_book_get_collection (start, PARENT_MODULE_NAME);
00884             do_test ((qof_collection_count (coll) == 1),
00885                      "Wrong number of parents. Should be 1");
00886             break;
00887         }
00888     case 3:
00889         {                       /* same grand, new parent, same child */
00890             child1 =
00891                 (mychild *) qof_object_new_instance (CHILD_MODULE_NAME,
00892                                                      start);
00893             parent1 =
00894                 (myparent *) qof_object_new_instance (PARENT_MODULE_NAME,
00895                                                       start);
00896             grand_setChild (grand1, parent1);
00897             parent_setChild (parent1, child1);
00898             do_test ((parent1 == grand_getChild (grand1)),
00899                      "same grandparent, new parent");
00900             do_test ((child1 == parent_getChild (parent1)),
00901                      "new parent, same child");
00902             coll = qof_book_get_collection (start, GRAND_MODULE_NAME);
00903             do_test ((qof_collection_count (coll) == 1),
00904                      "Wrong number of grandparents. Should be 1, Iteration 3.");
00905             coll = qof_book_get_collection (start, CHILD_MODULE_NAME);
00906             do_test ((qof_collection_count (coll) == 1),
00907                      "Wrong number of child entities, should be 1. Iteration 3.");
00908             coll = qof_book_get_collection (start, PARENT_MODULE_NAME);
00909             do_test ((qof_collection_count (coll) == 1),
00910                      "Wrong number of parents. Should be 1. Iteration 3.");
00911             break;
00912         }
00913     case 4:
00914         {                       /* new grand, unrelated parent, child unrelated to grand */
00915             grand1 =
00916                 (mygrand *) qof_object_new_instance (GRAND_MODULE_NAME,
00917                                                      start);
00918             parent1 =
00919                 (myparent *) qof_object_new_instance (PARENT_MODULE_NAME,
00920                                                       start);
00921             child1 =
00922                 (mychild *) qof_object_new_instance (CHILD_MODULE_NAME,
00923                                                      start);
00924             parent_setChild (parent1, child1);
00925             do_test ((NULL == grand_getChild (grand1)),
00926                      "new grand, unrelated parent");
00927             do_test ((child1 == parent_getChild (parent1)),
00928                      "child unrelated to grand");
00929             coll = grand_getDescend (grand1);
00930             do_test ((coll != NULL), "grandparent not valid");
00931             if (coll)
00932             {
00933                 QofEntity *ent;
00934 
00935                 ent = (QofEntity *) child1;
00936                 qof_collection_add_entity (coll, ent);
00937                 grand_setDescend (grand1, coll);
00938                 qof_collection_destroy (coll);
00939                 do_test ((g_list_length (grand1->descend) > 0),
00940                          "entity not added");
00941                 do_test ((qof_collection_count (grand_getDescend (grand1)) >
00942                           0), "empty collection returned");
00943             }
00944             break;
00945         }
00946     }
00947 }
00948 
00949 struct tally
00950 {
00951     guint nulls, total, collect;
00952     QofBook *book;
00953 };
00954 
00955 static void
00956 check_cb (QofEntity * ent, gpointer data)
00957 {
00958     QofEntity *parent, *child;
00959     QofCollection *coll;
00960     struct tally *c;
00961     const QofParam *param;
00962     mygrand *testg;
00963     myparent *testp;
00964     mychild *testc;
00965 
00966     c = (struct tally *) data;
00967     /* check the same number and type of entities
00968        exist in the copied book */
00969     testg = (mygrand *) ent;
00970     /* we always have a grandparent */
00971     do_test ((testg != NULL), "grandparent not found");
00972     c->total++;
00973     param = qof_class_get_parameter (GRAND_MODULE_NAME, OBJ_LIST);
00974     coll = (QofCollection *) param->param_getfcn (ent, param);
00975     c->collect = qof_collection_count (coll);
00976     if (c->book)
00977     {
00978         qof_book_set_references (c->book);
00979     }
00980     param = qof_class_get_parameter (GRAND_MODULE_NAME, OBJ_RELATIVE);
00981     parent = (QofEntity *) param->param_getfcn (ent, param);
00982     testp = grand_getChild ((mygrand *) ent);
00983     /* not all grandparents have family so just keep count. */
00984     if (!parent)
00985     {
00986         c->nulls++;
00987         return;
00988     }
00989     do_test ((0 == safe_strcmp (parent_getName (testp),
00990                                 parent_getName ((myparent *) parent))),
00991              "parent copy test");
00992     param = qof_class_get_parameter (PARENT_MODULE_NAME, OBJ_RELATIVE);
00993     child = param->param_getfcn (parent, param);
00994     testc = parent_getChild ((myparent *) parent);
00995     if (!child)
00996     {
00997         c->nulls++;
00998         return;
00999     }
01000     do_test ((0 == safe_strcmp (child_getName (testc),
01001                                 child_getName ((mychild *) child))),
01002              "child copy test");
01003 }
01004 
01005 static void
01006 test_recursion (QofSession * original, guint counter)
01007 {
01008     QofSession *copy;
01009     QofCollection *grand_coll;
01010     struct tally c;
01011     QofBook *book;
01012     guint d, e, f;
01013 
01014     c.nulls = 0;
01015     c.total = 0;
01016     c.collect = 0;
01017     c.book = NULL;
01018     book = qof_session_get_book (original);
01019     grand_coll = qof_book_get_collection (book, GRAND_MODULE_NAME);
01020     copy = qof_session_new ();
01021     if (debug)
01022     {
01023         qof_session_begin (copy, QOF_STDOUT, TRUE, FALSE);
01024     }
01025     /* TODO: implement QOF_TYPE_CHOICE testing. */
01026     qof_entity_copy_coll_r (copy, grand_coll);
01027     /* test the original */
01028     qof_object_foreach (GRAND_MODULE_NAME, book, check_cb, &c);
01029     book = qof_session_get_book (copy);
01030     /* test the copy */
01031     d = c.nulls;
01032     e = c.total;
01033     f = c.collect;
01034     c.nulls = 0;
01035     c.total = 0;
01036     c.collect = 0;
01037     c.book = book;
01038     qof_object_foreach (GRAND_MODULE_NAME, book, check_cb, &c);
01039     do_test ((d == c.nulls), "Null parents do not match");
01040     do_test ((e == c.total), "Total parents do not match");
01041     do_test ((f == c.collect),
01042              "Number of children in descendents does not match");
01043     if (counter == 4 && debug == TRUE)
01044     {
01045         qof_session_save (copy, NULL);
01046         qof_session_save (original, NULL);
01047     }
01048     qof_session_end (copy);
01049     copy = NULL;
01050 }
01051 
01052 int
01053 main (int argc, const char *argv[])
01054 {
01055     QofSession *original;
01056     guint counter;
01057 
01058     qof_init ();
01059     mygrandRegister ();
01060     myparentRegister ();
01061     mychildRegister ();
01062     for (counter = 0; counter < 35; counter++)
01063     {
01064         original = qof_session_new ();
01065         if (debug)
01066         {
01067             qof_session_begin (original, QOF_STDOUT, TRUE, FALSE);
01068         }
01069         create_data (original, (counter % 5));
01070         test_recursion (original, (counter % 5));
01071         qof_session_end (original);
01072     }
01073     print_test_results ();
01074     qof_close ();
01075     return EXIT_SUCCESS;
01076 }

Generated on Fri Sep 1 15:37:32 2006 for QOF by  doxygen 1.4.6