QOF: test-recursive.c Source File

QOF 0.7.5

test-recursive.c
1 /***************************************************************************
2 * test-recursive.c
3 *
4 * Wed Feb 1 21:54:49 2006
5 * Copyright 2006 Neil Williams
6 * linux@codehelp.co.uk
7 ****************************************************************************/
8 /*
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor
22 * Boston, MA 02110-1301, USA
23 */
24
25 #include <glib.h>
26 #include <glib/gprintf.h>
27 #include "config.h"
28 #include "qof.h"
29 #include "test-engine-stuff.h"
30 #include "test-stuff.h"
31
32 #define GRAND_MODULE_NAME "recursive-grandparent"
33 #define PARENT_MODULE_NAME "recursive-parent"
34 #define CHILD_MODULE_NAME "recursive-child"
35 #define GRAND_MODULE_DESC "Recursive Grand Parent Test"
36 #define PARENT_MODULE_DESC "Recursive Parent Test"
37 #define CHILD_MODULE_DESC "Recursive Child Test"
38 #define OBJ_NAME "somename"
39 #define OBJ_AMOUNT "anamount"
40 #define OBJ_DATE "nottoday"
41 #define OBJ_DISCOUNT "hefty"
42 #define OBJ_VERSION "early"
43 #define OBJ_MINOR "tiny"
44 #define OBJ_ACTIVE "ofcourse"
45 #define OBJ_FLAG "tiny_flag"
46 #define OBJ_RELATIVE "family"
47 #define OBJ_LIST "descendents"
48
49 /* set to TRUE to get QSF XML output
50 * requires QSF available (i.e. make install) */
51 static gboolean debug = FALSE;
52
53 /* simple object structure */
54 typedef struct child_s
55 {
56 QofInstance inst;
57 gchar *Name;
58 gchar flag;
59 QofNumeric Amount;
60 QofTime *date;
61 gdouble discount; /* cheap pun, I know. */
62 gboolean active;
63 gint32 version;
64 gint64 minor;
65 } mychild;
66
67 /* simple object structure */
68 typedef struct parent_s
69 {
70 QofInstance inst;
71 mychild *child;
72 gchar *Name;
73 gchar flag;
74 QofNumeric Amount;
75 QofTime *date;
76 gdouble discount; /* cheap pun, I know. */
77 gboolean active;
78 gint32 version;
79 gint64 minor;
80 } myparent;
81
82 /* simple object structure */
83 typedef struct grand_s
84 {
85 QofInstance inst;
86 myparent *child;
87 GList *descend;
88 gchar *Name;
89 gchar flag;
90 QofNumeric Amount;
91 QofTime *date;
92 gdouble discount; /* cheap pun, I know. */
93 gboolean active;
94 gint32 version;
95 gint64 minor;
96 } mygrand;
97
98 mygrand *grand_create (QofBook *);
99 myparent *parent_create (QofBook *);
100 mychild *child_create (QofBook *);
101
102 gboolean mygrandRegister (void);
103 gboolean myparentRegister (void);
104 gboolean mychildRegister (void);
105
106 /* obvious setter functions */
107 void grand_setName (mygrand *, gchar *);
108 void grand_setAmount (mygrand *, QofNumeric);
109 void grand_setDate (mygrand *, QofTime *h);
110 void grand_setDiscount (mygrand *, gdouble);
111 void grand_setActive (mygrand *, gboolean);
112 void grand_setVersion (mygrand *, gint32);
113 void grand_setMinor (mygrand *, gint64);
114 void grand_setFlag (mygrand *, gchar);
115
116 /* obvious getter functions */
117 gchar *grand_getName (mygrand *);
118 QofNumeric grand_getAmount (mygrand *);
119 QofTime *grand_getDate (mygrand *);
120 gdouble grand_getDiscount (mygrand *);
121 gboolean grand_getActive (mygrand *);
122 gint32 grand_getVersion (mygrand *);
123 gint64 grand_getMinor (mygrand *);
124 gchar grand_getFlag (mygrand *);
125
126 /* obvious setter functions */
127 void parent_setName (myparent *, gchar *);
128 void parent_setAmount (myparent *, QofNumeric);
129 void parent_setDate (myparent *, QofTime *h);
130 void parent_setDiscount (myparent *, gdouble);
131 void parent_setActive (myparent *, gboolean);
132 void parent_setVersion (myparent *, gint32);
133 void parent_setMinor (myparent *, gint64);
134 void parent_setFlag (myparent *, gchar);
135
136 /* obvious getter functions */
137 gchar *parent_getName (myparent *);
138 QofNumeric parent_getAmount (myparent *);
139 QofTime *parent_getDate (myparent *);
140 gdouble parent_getDiscount (myparent *);
141 gboolean parent_getActive (myparent *);
142 gint32 parent_getVersion (myparent *);
143 gint64 parent_getMinor (myparent *);
144 gchar parent_getFlag (myparent *);
145
146 /* obvious setter functions */
147 void child_setName (mychild *, gchar *);
148 void child_setAmount (mychild *, QofNumeric);
149 void child_setDate (mychild *, QofTime *h);
150 void child_setDiscount (mychild *, gdouble);
151 void child_setActive (mychild *, gboolean);
152 void child_setVersion (mychild *, gint32);
153 void child_setMinor (mychild *, gint64);
154 void child_setFlag (mychild *, gchar);
155
156 /* obvious getter functions */
157 gchar *child_getName (mychild *);
158 QofNumeric child_getAmount (mychild *);
159 QofTime *child_getDate (mychild *);
160 gdouble child_getDiscount (mychild *);
161 gboolean child_getActive (mychild *);
162 gint32 child_getVersion (mychild *);
163 gint64 child_getMinor (mychild *);
164 gchar child_getFlag (mychild *);
165
166 mygrand *
167 grand_create (QofBook * book)
168 {
169 mygrand *g;
170
171 g_return_val_if_fail (book, NULL);
172 g = g_new0 (mygrand, 1);
173 qof_instance_init (&g->inst, GRAND_MODULE_NAME, book);
174 /* implement qof_time_random? */
175 g->date = qof_time_get_current ();
176 g->discount = get_random_double ();;
177 g->active = get_random_boolean ();
178 g->version = get_random_int_in_range (1, 10000);
179 g->minor = get_random_int_in_range (100001, 99999999);
180 g->flag = get_random_character ();
181 g->Name = get_random_string ();
182 g->Amount = get_random_qof_numeric ();
183 g->child = NULL;
184 g->descend = NULL;
185 qof_event_gen (&g->inst.entity, QOF_EVENT_CREATE, NULL);
186 return g;
187 }
188
189 myparent *
190 parent_create (QofBook * book)
191 {
192 myparent *g;
193
194 g_return_val_if_fail (book, NULL);
195 g = g_new0 (myparent, 1);
196 qof_instance_init (&g->inst, PARENT_MODULE_NAME, book);
197 g->date = qof_time_get_current ();
198 g->discount = get_random_double ();
199 g->active = get_random_boolean ();
200 g->version = get_random_int_in_range (1, 10000);
201 g->minor = get_random_int_in_range (100001, 99999999);
202 g->flag = get_random_character ();
203 g->Name = get_random_string ();
204 g->Amount = get_random_qof_numeric ();
205 g->child = NULL;
206 qof_event_gen (&g->inst.entity, QOF_EVENT_CREATE, NULL);
207 return g;
208 }
209
210 mychild *
211 child_create (QofBook * book)
212 {
213 mychild *g;
214
215 g_return_val_if_fail (book, NULL);
216 g = g_new0 (mychild, 1);
217 qof_instance_init (&g->inst, CHILD_MODULE_NAME, book);
218 g->date = qof_time_get_current ();
219 g->discount = get_random_double ();
220 g->active = get_random_boolean ();
221 g->version = get_random_int_in_range (1, 10000);
222 g->minor = get_random_int_in_range (100001, 99999999);
223 g->flag = get_random_character ();
224 g->Name = get_random_string ();
225 g->Amount = get_random_qof_numeric ();
226 qof_event_gen (&g->inst.entity, QOF_EVENT_CREATE, NULL);
227 return g;
228 }
229
230 static void
231 descend_cb (QofEntity * ent, gpointer user_data)
232 {
233 mygrand *g = (mygrand *) user_data;
234
235 g_return_if_fail (g || ent);
236 g->descend = g_list_prepend (g->descend, (mychild *) ent);
237 }
238
239 static void
240 grand_setDescend (mygrand * g, QofCollection * coll)
241 {
242 g_return_if_fail (g || coll);
243 if (0 != safe_strcmp (qof_collection_get_type (coll), CHILD_MODULE_NAME))
244 {
245 return;
246 }
247 qof_collection_foreach (coll, descend_cb, g);
248 }
249
250 static QofCollection *
251 grand_getDescend (mygrand * g)
252 {
253 QofCollection *col;
254 QofEntity *ent;
255 GList *list;
256
257 g_return_val_if_fail (g, NULL);
258 col = qof_collection_new (CHILD_MODULE_NAME);
259 for (list = g_list_copy (g->descend); list; list = list->next)
260 {
261 ent = (QofEntity *) list->data;
262 if (!ent)
263 {
264 break;
265 }
266 do_test (0 == safe_strcmp (ent->e_type, CHILD_MODULE_NAME),
267 "wrong entity");
268 qof_collection_add_entity (col, ent);
269 }
270 return col;
271 }
272
273 static void
274 grand_setChild (mygrand * g, myparent * p)
275 {
276 g_return_if_fail (g || p);
277 g->child = p;
278 }
279
280 static myparent *
281 grand_getChild (mygrand * g)
282 {
283 g_return_val_if_fail (g, NULL);
284 return g->child;
285 }
286
287 void
288 grand_setFlag (mygrand * g, gchar f)
289 {
290 g_return_if_fail (g);
291 g->flag = f;
292 }
293
294 gchar
295 grand_getFlag (mygrand * g)
296 {
297 g_return_val_if_fail (g, 'n');
298 return g->flag;
299 }
300
301 void
302 grand_setMinor (mygrand * g, gint64 h)
303 {
304 g_return_if_fail (g != NULL);
305 g->minor = h;
306 }
307
308 gint64
309 grand_getMinor (mygrand * g)
310 {
311 g_return_val_if_fail ((g != NULL), 0);
312 return g->minor;
313 }
314
315 void
316 grand_setVersion (mygrand * g, gint32 h)
317 {
318 g_return_if_fail (g != NULL);
319 g->version = h;
320 }
321
322 gint32
323 grand_getVersion (mygrand * g)
324 {
325 if (!g)
326 return 0;
327 return g->version;
328 }
329
330 void
331 grand_setActive (mygrand * g, gboolean h)
332 {
333 if (!g)
334 return;
335 g->active = h;
336 }
337
338 gboolean
339 grand_getActive (mygrand * g)
340 {
341 if (!g)
342 return FALSE;
343 return g->active;
344 }
345
346 void
347 grand_setDiscount (mygrand * g, double h)
348 {
349 if (!g)
350 return;
351 g->discount = h;
352 }
353
354 double
355 grand_getDiscount (mygrand * g)
356 {
357 if (!g)
358 return 0;
359 return g->discount;
360 }
361
362 void
363 grand_setDate (mygrand * g, QofTime *h)
364 {
365 if (!g)
366 return;
367 g->date = h;
368 }
369
370 QofTime*
371 grand_getDate (mygrand * g)
372 {
373 if (!g)
374 return NULL;
375 return g->date;
376 }
377
378 void
379 grand_setName (mygrand * g, gchar * h)
380 {
381 if (!g || !h)
382 return;
383 g->Name = strdup (h);
384 }
385
386 gchar *
387 grand_getName (mygrand * g)
388 {
389 if (!g)
390 return NULL;
391 return g->Name;
392 }
393
394 void
395 grand_setAmount (mygrand * g, QofNumeric h)
396 {
397 if (!g)
398 return;
399 g->Amount = h;
400 }
401
402 QofNumeric
403 grand_getAmount (mygrand * g)
404 {
405 if (!g)
406 return qof_numeric_zero ();
407 return g->Amount;
408 }
409
410 static void
411 parent_setChild (myparent * p, mychild * c)
412 {
413 g_return_if_fail (p || c);
414 p->child = c;
415 }
416
417 static mychild *
418 parent_getChild (myparent * p)
419 {
420 g_return_val_if_fail (p, NULL);
421 return p->child;
422 }
423
424 void
425 parent_setFlag (myparent * p, gchar f)
426 {
427 g_return_if_fail (p);
428 p->flag = f;
429 }
430
431 gchar
432 parent_getFlag (myparent * p)
433 {
434 g_return_val_if_fail (p, 'n');
435 return p->flag;
436 }
437
438 void
439 parent_setMinor (myparent * p, gint64 h)
440 {
441 g_return_if_fail (p != NULL);
442 p->minor = h;
443 }
444
445 gint64
446 parent_getMinor (myparent * p)
447 {
448 g_return_val_if_fail ((p != NULL), 0);
449 return p->minor;
450 }
451
452 void
453 parent_setVersion (myparent * p, gint32 h)
454 {
455 g_return_if_fail (p != NULL);
456 p->version = h;
457 }
458
459 gint32
460 parent_getVersion (myparent * p)
461 {
462 if (!p)
463 return 0;
464 return p->version;
465 }
466
467 void
468 parent_setActive (myparent * p, gboolean h)
469 {
470 if (!p)
471 return;
472 p->active = h;
473 }
474
475 gboolean
476 parent_getActive (myparent * p)
477 {
478 if (!p)
479 return FALSE;
480 return p->active;
481 }
482
483 void
484 parent_setDiscount (myparent * p, double h)
485 {
486 if (!p)
487 return;
488 p->discount = h;
489 }
490
491 double
492 parent_getDiscount (myparent * p)
493 {
494 if (!p)
495 return 0;
496 return p->discount;
497 }
498
499 void
500 parent_setDate (myparent * p, QofTime *h)
501 {
502 if (!p)
503 return;
504 p->date = h;
505 }
506
507 QofTime *
508 parent_getDate (myparent * p)
509 {
510 if (!p)
511 return NULL;
512 return p->date;
513 }
514
515 void
516 parent_setName (myparent * p, gchar * h)
517 {
518 if (!p || !h)
519 return;
520 p->Name = strdup (h);
521 }
522
523 gchar *
524 parent_getName (myparent * p)
525 {
526 if (!p)
527 return NULL;
528 return p->Name;
529 }
530
531 void
532 parent_setAmount (myparent * p, QofNumeric h)
533 {
534 if (!p)
535 return;
536 p->Amount = h;
537 }
538
539 QofNumeric
540 parent_getAmount (myparent * p)
541 {
542 if (!p)
543 return qof_numeric_zero ();
544 return p->Amount;
545 }
546
547 void
548 child_setFlag (mychild * c, gchar f)
549 {
550 g_return_if_fail (c);
551 c->flag = f;
552 }
553
554 gchar
555 child_getFlag (mychild * c)
556 {
557 g_return_val_if_fail (c, 'n');
558 return c->flag;
559 }
560
561 void
562 child_setMinor (mychild * c, gint64 h)
563 {
564 g_return_if_fail (c != NULL);
565 c->minor = h;
566 }
567
568 gint64
569 child_getMinor (mychild * c)
570 {
571 g_return_val_if_fail ((c != NULL), 0);
572 return c->minor;
573 }
574
575 void
576 child_setVersion (mychild * c, gint32 h)
577 {
578 g_return_if_fail (c != NULL);
579 c->version = h;
580 }
581
582 gint32
583 child_getVersion (mychild * c)
584 {
585 if (!c)
586 return 0;
587 return c->version;
588 }
589
590 void
591 child_setActive (mychild * c, gboolean h)
592 {
593 if (!c)
594 return;
595 c->active = h;
596 }
597
598 gboolean
599 child_getActive (mychild * c)
600 {
601 if (!c)
602 return FALSE;
603 return c->active;
604 }
605
606 void
607 child_setDiscount (mychild * c, double h)
608 {
609 if (!c)
610 return;
611 c->discount = h;
612 }
613
614 double
615 child_getDiscount (mychild * c)
616 {
617 if (!c)
618 return 0;
619 return c->discount;
620 }
621
622 void
623 child_setDate (mychild * c, QofTime *h)
624 {
625 if (!c)
626 return;
627 c->date = h;
628 }
629
630 QofTime*
631 child_getDate (mychild * c)
632 {
633 if (!c)
634 return NULL;
635 return c->date;
636 }
637
638 void
639 child_setName (mychild * c, gchar * h)
640 {
641 if (!c || !h)
642 return;
643 c->Name = strdup (h);
644 }
645
646 gchar *
647 child_getName (mychild * c)
648 {
649 if (!c)
650 return NULL;
651 return c->Name;
652 }
653
654 void
655 child_setAmount (mychild * c, QofNumeric h)
656 {
657 if (!c)
658 return;
659 c->Amount = h;
660 }
661
662 QofNumeric
663 child_getAmount (mychild * c)
664 {
665 if (!c)
666 return qof_numeric_zero ();
667 return c->Amount;
668 }
669
670 static QofObject grand_object_def = {
671 .interface_version = QOF_OBJECT_VERSION,
672 .e_type = GRAND_MODULE_NAME,
673 .type_label = GRAND_MODULE_DESC,
674 .create = (gpointer) grand_create,
675 .book_begin = NULL,
676 .book_end = NULL,
677 .is_dirty = qof_collection_is_dirty,
678 .mark_clean = qof_collection_mark_clean,
679 .foreach = qof_collection_foreach,
680 .printable = NULL,
681 .version_cmp = (gint (*)(gpointer, gpointer))
682 qof_instance_version_cmp,
683 };
684
685 gboolean
686 mygrandRegister (void)
687 {
688 static QofParam params[] = {
689 {OBJ_NAME, QOF_TYPE_STRING, (QofAccessFunc) grand_getName,
690 (QofSetterFunc) grand_setName, NULL},
691 {OBJ_AMOUNT, QOF_TYPE_NUMERIC, (QofAccessFunc) grand_getAmount,
692 (QofSetterFunc) grand_setAmount, NULL},
693 {OBJ_DATE, QOF_TYPE_TIME, (QofAccessFunc) grand_getDate,
694 (QofSetterFunc) grand_setDate, NULL},
695 {OBJ_DISCOUNT, QOF_TYPE_DOUBLE, (QofAccessFunc) grand_getDiscount,
696 (QofSetterFunc) grand_setDiscount, NULL},
697 {OBJ_ACTIVE, QOF_TYPE_BOOLEAN, (QofAccessFunc) grand_getActive,
698 (QofSetterFunc) grand_setActive, NULL},
699 {OBJ_VERSION, QOF_TYPE_INT32, (QofAccessFunc) grand_getVersion,
700 (QofSetterFunc) grand_setVersion, NULL},
701 {OBJ_MINOR, QOF_TYPE_INT64, (QofAccessFunc) grand_getMinor,
702 (QofSetterFunc) grand_setMinor, NULL},
703 {OBJ_FLAG, QOF_TYPE_CHAR, (QofAccessFunc) grand_getFlag,
704 (QofSetterFunc) grand_setFlag, NULL},
705 {OBJ_RELATIVE, PARENT_MODULE_NAME, (QofAccessFunc) grand_getChild,
706 (QofSetterFunc) grand_setChild, NULL},
707 {OBJ_LIST, QOF_TYPE_COLLECT, (QofAccessFunc) grand_getDescend,
708 (QofSetterFunc) grand_setDescend, NULL},
709 {QOF_PARAM_BOOK, QOF_ID_BOOK, (QofAccessFunc) qof_instance_get_book,
710 NULL, NULL},
711 {QOF_PARAM_GUID, QOF_TYPE_GUID, (QofAccessFunc) qof_instance_get_guid,
712 NULL, NULL},
713 {NULL, NULL, NULL, NULL, NULL},
714 };
715
716 qof_class_register (GRAND_MODULE_NAME, NULL, params);
717 /* if(!qof_choice_create(GRAND_MODULE_NAME)) { return FALSE; }*/
718
719 return qof_object_register (&grand_object_def);
720 }
721
722 static QofObject parent_object_def = {
723 .interface_version = QOF_OBJECT_VERSION,
724 .e_type = PARENT_MODULE_NAME,
725 .type_label = PARENT_MODULE_DESC,
726 .create = (gpointer) parent_create,
727 .book_begin = NULL,
728 .book_end = NULL,
729 .is_dirty = qof_collection_is_dirty,
730 .mark_clean = qof_collection_mark_clean,
731 .foreach = qof_collection_foreach,
732 .printable = NULL,
733 .version_cmp = (gint (*)(gpointer, gpointer))
734 qof_instance_version_cmp,
735 };
736
737 gboolean
738 myparentRegister (void)
739 {
740 static QofParam params[] = {
741 {OBJ_NAME, QOF_TYPE_STRING, (QofAccessFunc) parent_getName,
742 (QofSetterFunc) parent_setName, NULL},
743 {OBJ_AMOUNT, QOF_TYPE_NUMERIC, (QofAccessFunc) parent_getAmount,
744 (QofSetterFunc) parent_setAmount, NULL},
745 {OBJ_DATE, QOF_TYPE_TIME, (QofAccessFunc) parent_getDate,
746 (QofSetterFunc) parent_setDate, NULL},
747 {OBJ_DISCOUNT, QOF_TYPE_DOUBLE, (QofAccessFunc) parent_getDiscount,
748 (QofSetterFunc) parent_setDiscount, NULL},
749 {OBJ_ACTIVE, QOF_TYPE_BOOLEAN, (QofAccessFunc) parent_getActive,
750 (QofSetterFunc) parent_setActive, NULL},
751 {OBJ_VERSION, QOF_TYPE_INT32, (QofAccessFunc) parent_getVersion,
752 (QofSetterFunc) parent_setVersion, NULL},
753 {OBJ_MINOR, QOF_TYPE_INT64, (QofAccessFunc) parent_getMinor,
754 (QofSetterFunc) parent_setMinor, NULL},
755 {OBJ_FLAG, QOF_TYPE_CHAR, (QofAccessFunc) parent_getFlag,
756 (QofSetterFunc) parent_setFlag, NULL},
757 {OBJ_RELATIVE, CHILD_MODULE_NAME, (QofAccessFunc) parent_getChild,
758 (QofSetterFunc) parent_setChild, NULL},
759 {QOF_PARAM_BOOK, QOF_ID_BOOK, (QofAccessFunc) qof_instance_get_book,
760 NULL, NULL},
761 {QOF_PARAM_GUID, QOF_TYPE_GUID, (QofAccessFunc) qof_instance_get_guid,
762 NULL, NULL},
763 {NULL, NULL, NULL, NULL, NULL},
764 };
765
766 qof_class_register (PARENT_MODULE_NAME, NULL, params);
767
768 return qof_object_register (&parent_object_def);
769 }
770
771 static QofObject child_object_def = {
772 .interface_version = QOF_OBJECT_VERSION,
773 .e_type = CHILD_MODULE_NAME,
774 .type_label = CHILD_MODULE_DESC,
775 .create = (gpointer) child_create,
776 .book_begin = NULL,
777 .book_end = NULL,
778 .is_dirty = qof_collection_is_dirty,
779 .mark_clean = qof_collection_mark_clean,
780 .foreach = qof_collection_foreach,
781 .printable = NULL,
782 .version_cmp = (gint (*)(gpointer, gpointer))
783 qof_instance_version_cmp,
784 };
785
786 gboolean
787 mychildRegister (void)
788 {
789 static QofParam params[] = {
790 {OBJ_NAME, QOF_TYPE_STRING, (QofAccessFunc) child_getName,
791 (QofSetterFunc) child_setName, NULL},
792 {OBJ_AMOUNT, QOF_TYPE_NUMERIC, (QofAccessFunc) child_getAmount,
793 (QofSetterFunc) child_setAmount, NULL},
794 {OBJ_DATE, QOF_TYPE_TIME, (QofAccessFunc) child_getDate,
795 (QofSetterFunc) child_setDate, NULL},
796 {OBJ_DISCOUNT, QOF_TYPE_DOUBLE, (QofAccessFunc) child_getDiscount,
797 (QofSetterFunc) child_setDiscount, NULL},
798 {OBJ_ACTIVE, QOF_TYPE_BOOLEAN, (QofAccessFunc) child_getActive,
799 (QofSetterFunc) child_setActive, NULL},
800 {OBJ_VERSION, QOF_TYPE_INT32, (QofAccessFunc) child_getVersion,
801 (QofSetterFunc) child_setVersion, NULL},
802 {OBJ_MINOR, QOF_TYPE_INT64, (QofAccessFunc) child_getMinor,
803 (QofSetterFunc) child_setMinor, NULL},
804 {OBJ_FLAG, QOF_TYPE_CHAR, (QofAccessFunc) child_getFlag,
805 (QofSetterFunc) child_setFlag, NULL},
806 {QOF_PARAM_BOOK, QOF_ID_BOOK, (QofAccessFunc) qof_instance_get_book,
807 NULL, NULL},
808 {QOF_PARAM_GUID, QOF_TYPE_GUID, (QofAccessFunc) qof_instance_get_guid,
809 NULL, NULL},
810 {NULL, NULL, NULL, NULL, NULL},
811 };
812
813 qof_class_register (CHILD_MODULE_NAME, NULL, params);
814
815 return qof_object_register (&child_object_def);
816 }
817
818 static void
819 create_data (QofSession * original, guint counter)
820 {
821 QofCollection *coll;
822 QofBook *start;
823 mygrand *grand1;
824 myparent *parent1;
825 mychild *child1;
826
827 start = qof_session_get_book (original);
828 grand1 = (mygrand *) qof_object_new_instance (GRAND_MODULE_NAME, start);
829 do_test ((NULL != &grand1->inst), "instance init");
830 switch (counter)
831 {
832 case 0:
833 { /* NULL tree */
834 do_test ((grand1 != NULL), "empty tree check");
835 coll = qof_book_get_collection (start, GRAND_MODULE_NAME);
836 do_test ((qof_collection_count (coll) == 1),
837 "Too many grandparents found - should be 1");
838 coll = qof_book_get_collection (start, CHILD_MODULE_NAME);
839 do_test ((qof_collection_count (coll) == 0),
840 "child found, should be empty");
841 coll = qof_book_get_collection (start, PARENT_MODULE_NAME);
842 do_test ((qof_collection_count (coll) == 0),
843 "tree not empty: parent found");
844 break;
845 }
846 case 1:
847 { /* one parent, no child */
848 parent1 =
849 (myparent *) qof_object_new_instance (PARENT_MODULE_NAME,
850 start);
851 grand_setChild (grand1, parent1);
852 do_test ((parent1 != NULL), "single parent check");
853 do_test ((grand_getChild (grand1) == parent1),
854 "set child in grandparent");
855 coll = qof_book_get_collection (start, GRAND_MODULE_NAME);
856 do_test ((qof_collection_count (coll) == 1),
857 "Wrong number of grandparents, should be 1");
858 coll = qof_book_get_collection (start, CHILD_MODULE_NAME);
859 do_test ((qof_collection_count (coll) == 0),
860 "Should be no child entities this iteration.");
861 coll = qof_book_get_collection (start, PARENT_MODULE_NAME);
862 do_test ((qof_collection_count (coll) == 1),
863 "Wrong number of parents found, should be 1");
864 break;
865 }
866 case 2:
867 { /* one parent, one child */
868 parent1 =
869 (myparent *) qof_object_new_instance (PARENT_MODULE_NAME,
870 start);
871 grand_setChild (grand1, parent1);
872 child1 =
873 (mychild *) qof_object_new_instance (CHILD_MODULE_NAME,
874 start);
875 parent1 = grand_getChild (grand1);
876 parent_setChild (parent1, child1);
877 do_test ((child1 != NULL), "one parent with one related child");
878 do_test ((child1 == parent_getChild (parent1)),
879 "child of single parent");
880 coll = qof_book_get_collection (start, GRAND_MODULE_NAME);
881 do_test ((qof_collection_count (coll) == 1),
882 "Wrong number of grandparents. Should be 1");
883 coll = qof_book_get_collection (start, CHILD_MODULE_NAME);
884 do_test ((qof_collection_count (coll) == 1),
885 "Wrong number of child entities, should be 1");
886 coll = qof_book_get_collection (start, PARENT_MODULE_NAME);
887 do_test ((qof_collection_count (coll) == 1),
888 "Wrong number of parents. Should be 1");
889 break;
890 }
891 case 3:
892 { /* same grand, new parent, same child */
893 child1 =
894 (mychild *) qof_object_new_instance (CHILD_MODULE_NAME,
895 start);
896 parent1 =
897 (myparent *) qof_object_new_instance (PARENT_MODULE_NAME,
898 start);
899 grand_setChild (grand1, parent1);
900 parent_setChild (parent1, child1);
901 do_test ((parent1 == grand_getChild (grand1)),
902 "same grandparent, new parent");
903 do_test ((child1 == parent_getChild (parent1)),
904 "new parent, same child");
905 coll = qof_book_get_collection (start, GRAND_MODULE_NAME);
906 do_test ((qof_collection_count (coll) == 1),
907 "Wrong number of grandparents. Should be 1, Iteration 3.");
908 coll = qof_book_get_collection (start, CHILD_MODULE_NAME);
909 do_test ((qof_collection_count (coll) == 1),
910 "Wrong number of child entities, should be 1. Iteration 3.");
911 coll = qof_book_get_collection (start, PARENT_MODULE_NAME);
912 do_test ((qof_collection_count (coll) == 1),
913 "Wrong number of parents. Should be 1. Iteration 3.");
914 break;
915 }
916 case 4:
917 { /* new grand, unrelated parent, child unrelated to grand */
918 grand1 =
919 (mygrand *) qof_object_new_instance (GRAND_MODULE_NAME,
920 start);
921 parent1 =
922 (myparent *) qof_object_new_instance (PARENT_MODULE_NAME,
923 start);
924 child1 =
925 (mychild *) qof_object_new_instance (CHILD_MODULE_NAME,
926 start);
927 parent_setChild (parent1, child1);
928 do_test ((NULL == grand_getChild (grand1)),
929 "new grand, unrelated parent");
930 do_test ((child1 == parent_getChild (parent1)),
931 "child unrelated to grand");
932 coll = grand_getDescend (grand1);
933 do_test ((coll != NULL), "grandparent not valid");
934 if (coll)
935 {
936 QofEntity *ent;
937
938 ent = (QofEntity *) child1;
939 qof_collection_add_entity (coll, ent);
940 grand_setDescend (grand1, coll);
941 qof_collection_destroy (coll);
942 do_test ((g_list_length (grand1->descend) > 0),
943 "entity not added");
944 do_test ((qof_collection_count (grand_getDescend (grand1)) >
945 0), "empty collection returned");
946 }
947 break;
948 }
949 }
950 }
951
952 struct tally
953 {
954 guint nulls, total, collect;
955 QofBook *book;
956 };
957
958 static void
959 check_cb (QofEntity * ent, gpointer data)
960 {
961 QofEntity *parent, *child;
962 QofCollection *coll;
963 struct tally *c;
964 const QofParam *param;
965 mygrand *testg;
966 myparent *testp;
967 mychild *testc;
968
969 c = (struct tally *) data;
970 /* check the same number and type of entities
971 exist in the copied book */
972 testg = (mygrand *) ent;
973 /* we always have a grandparent */
974 do_test ((testg != NULL), "grandparent not found");
975 c->total++;
976 param = qof_class_get_parameter (GRAND_MODULE_NAME, OBJ_LIST);
977 coll = (QofCollection *) param->param_getfcn (ent, param);
978 c->collect = qof_collection_count (coll);
979 if (c->book)
980 {
981 qof_book_set_references (c->book);
982 }
983 param = qof_class_get_parameter (GRAND_MODULE_NAME, OBJ_RELATIVE);
984 parent = (QofEntity *) param->param_getfcn (ent, param);
985 testp = grand_getChild ((mygrand *) ent);
986 /* not all grandparents have family so just keep count. */
987 if (!parent)
988 {
989 c->nulls++;
990 return;
991 }
992 do_test ((0 == safe_strcmp (parent_getName (testp),
993 parent_getName ((myparent *) parent))),
994 "parent copy test");
995 param = qof_class_get_parameter (PARENT_MODULE_NAME, OBJ_RELATIVE);
996 child = param->param_getfcn (parent, param);
997 testc = parent_getChild ((myparent *) parent);
998 if (!child)
999 {
1000 c->nulls++;
1001 return;
1002 }
1003 do_test ((0 == safe_strcmp (child_getName (testc),
1004 child_getName ((mychild *) child))),
1005 "child copy test");
1006 }
1007
1008 static void
1009 test_recursion (QofSession * original, guint counter)
1010 {
1011 QofSession *copy;
1012 QofCollection *grand_coll;
1013 struct tally c;
1014 QofBook *book;
1015 guint d, e, f;
1016
1017 c.nulls = 0;
1018 c.total = 0;
1019 c.collect = 0;
1020 c.book = NULL;
1021 book = qof_session_get_book (original);
1022 grand_coll = qof_book_get_collection (book, GRAND_MODULE_NAME);
1023 copy = qof_session_new ();
1024 if (debug)
1025 {
1026 qof_session_begin (copy, QOF_STDOUT, TRUE, FALSE);
1027 }
1028 /* TODO: implement QOF_TYPE_CHOICE testing. */
1029 qof_entity_copy_coll_r (copy, grand_coll);
1030 /* test the original */
1031 qof_object_foreach (GRAND_MODULE_NAME, book, check_cb, &c);
1032 book = qof_session_get_book (copy);
1033 /* test the copy */
1034 d = c.nulls;
1035 e = c.total;
1036 f = c.collect;
1037 c.nulls = 0;
1038 c.total = 0;
1039 c.collect = 0;
1040 c.book = book;
1041 qof_object_foreach (GRAND_MODULE_NAME, book, check_cb, &c);
1042 do_test ((d == c.nulls), "Null parents do not match");
1043 do_test ((e == c.total), "Total parents do not match");
1044 do_test ((f == c.collect),
1045 "Number of children in descendents does not match");
1046 if (counter == 4 && debug == TRUE)
1047 {
1048 qof_session_save (copy, NULL);
1049 qof_session_save (original, NULL);
1050 }
1051 qof_session_end (copy);
1052 copy = NULL;
1053 }
1054
1055 int
1056 main (void)
1057 {
1058 QofSession *original;
1059 guint counter;
1060
1061 qof_init ();
1062 mygrandRegister ();
1063 myparentRegister ();
1064 mychildRegister ();
1065 for (counter = 0; counter < 35; counter++)
1066 {
1067 original = qof_session_new ();
1068 if (debug)
1069 {
1070 qof_session_begin (original, QOF_STDOUT, TRUE, FALSE);
1071 }
1072 create_data (original, (counter % 5));
1073 test_recursion (original, (counter % 5));
1074 qof_session_end (original);
1075 }
1076 print_test_results ();
1077 qof_close ();
1078 return EXIT_SUCCESS;
1079 }
qof_collection_add_entity
gboolean qof_collection_add_entity(QofCollection *coll, QofEntity *ent)
Add an entity to a QOF_TYPE_COLLECT.
Definition: qofid.c:211
qof_object_new_instance
gpointer qof_object_new_instance(QofIdTypeConst type_name, QofBook *book)
Definition: qofobject.c:42
QOF_TYPE_COLLECT
#define QOF_TYPE_COLLECT
Definition: qofclass.h:93
QofInstance_s
Definition: qofinstance-p.h:35
qof_book_get_collection
QofCollection * qof_book_get_collection(QofBook *book, QofIdType entity_type)
Definition: qofbook.c:220
qof_collection_is_dirty
gboolean qof_collection_is_dirty(QofCollection *col)
Definition: qofid.c:362
_QofParam
Definition: qofclass.h:195
QOF_OBJECT_VERSION
#define QOF_OBJECT_VERSION
Definition: qofobject.h:57
_QofSession
Definition: qofsession-p.h:35
QofEntity_s
Definition: qofid.h:147
qof_object_foreach
void qof_object_foreach(QofIdTypeConst type_name, QofBook *book, QofEntityForeachCB cb, gpointer user_data)
Definition: qofobject.c:174
qof_class_register
void qof_class_register(QofIdTypeConst obj_name, QofSortFunc default_sort_function, const QofParam *params)
registers a new object class with the Qof subsystem.
Definition: qofclass.c:93
test-engine-stuff.h
This file declares testing functions for the engine.
qof_instance_get_book
QofBook * qof_instance_get_book(QofInstance *inst)
Definition: qofinstance.c:87
QOF_PARAM_BOOK
#define QOF_PARAM_BOOK
Definition: qofquery.h:104
qof_event_gen
void qof_event_gen(QofEntity *entity, QofEventId event_id, gpointer event_data)
Invoke all registered event handlers using the given arguments.
Definition: qofevent.c:292
QofSetterFunc
void(* QofSetterFunc)(gpointer, gpointer)
Definition: qofclass.h:176
qof_time_get_current
QofTime * qof_time_get_current(void)
Get the current QofTime.
Definition: qoftime.c:362
QofCollection
struct QofCollection_s QofCollection
Definition: qofid.h:138
qof_class_get_parameter
const QofParam * qof_class_get_parameter(QofIdTypeConst obj_name, const gchar *parameter)
Definition: qofclass.c:146
QOF_EVENT_CREATE
#define QOF_EVENT_CREATE
Definition: qofevent.h:71
qof_instance_get_guid
const GUID * qof_instance_get_guid(QofInstance *inst)
Definition: qofinstance.c:79
qof_entity_copy_coll_r
gboolean qof_entity_copy_coll_r(QofSession *new_session, QofCollection *coll)
Recursively copy a collection of entities to a session.
Definition: qofsession.c:884
qof_book_set_references
void qof_book_set_references(QofBook *book)
Read QofEntityReference data for this book and set values.
Definition: qofreference.c:177
qof_session_begin
void qof_session_begin(QofSession *session, const gchar *book_id, gboolean ignore_lock, gboolean create_if_nonexistent)
Definition: qofsession.c:1057
qof_collection_count
guint qof_collection_count(QofCollection *col)
Definition: qofid.c:351
qof_collection_foreach
void qof_collection_foreach(QofCollection *col, QofEntityForeachCB cb_func, gpointer user_data)
Definition: qofid.c:421
_QofObject
Definition: qofobject.h:70
_QofNumeric
Definition: qofnumeric.h:52
QofAccessFunc
gpointer(* QofAccessFunc)(gpointer object, const QofParam *param)
Definition: qofclass.h:169
qof_collection_mark_clean
void qof_collection_mark_clean(QofCollection *)
Definition: qofid.c:368
qof_collection_get_type
QofIdType qof_collection_get_type(QofCollection *col)
Definition: qofid.c:175
qof_object_register
gboolean qof_object_register(const QofObject *object)
Definition: qofobject.c:278
qof_close
void qof_close(void)
Safely close down the Query Object Framework.
Definition: qofutil.c:844
QOF_STDOUT
#define QOF_STDOUT
Allow session data to be printed to stdout.
Definition: qofsession.h:385
QofTime
struct QofTime64 QofTime
Use a 64-bit signed int QofTime.
Definition: qoftime.h:120
qof_collection_destroy
void qof_collection_destroy(QofCollection *col)
Definition: qofid.c:161
qof_collection_new
QofCollection * qof_collection_new(QofIdType type)
Definition: qofid.c:150
qof_session_save
void qof_session_save(QofSession *session, QofPercentageFunc percentage_func)
Definition: qofsession.c:1245
qof_session_end
void qof_session_end(QofSession *session)
Definition: qofsession.c:1399
qof_numeric_zero
static QofNumeric qof_numeric_zero(void)
Definition: qofnumeric.h:253
_QofBook
Definition: qofbook-p.h:48
safe_strcmp
gint safe_strcmp(const gchar *da, const gchar *db)
Definition: qofutil.c:72
qof_instance_version_cmp
int qof_instance_version_cmp(QofInstance *left, QofInstance *right)
Definition: qofinstance.c:116
qof_instance_init
void qof_instance_init(QofInstance *inst, QofIdType type, QofBook *book)
Definition: qofinstance.c:53
qof_init
void qof_init(void)
Initialise the Query Object Framework.
Definition: qofutil.c:833