QOF 0.7.5
|
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 }