QOF
0.7.5
|
00001 /*************************************************************************** 00002 * test-event.c 00003 * 00004 * Sat Feb 11 11:00:02 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 "qof.h" 00028 #include "test-engine-stuff.h" 00029 #include "test-stuff.h" 00030 00031 #define OBJ_NAME "somename" 00032 #define OBJ_AMOUNT "anamount" 00033 #define OBJ_DATE "nottoday" 00034 #define OBJ_GUID "unique" 00035 #define OBJ_DISCOUNT "hefty" 00036 #define OBJ_VERSION "early" 00037 #define OBJ_MINOR "tiny" 00038 #define OBJ_ACTIVE "ofcourse" 00039 #define OBJ_FLAG "tiny_flag" 00040 #define OBJ_EVENT_NAME "test-event-object" 00041 #define OBJ_EVENT_DESC "test object for events" 00042 00043 /* set to TRUE to get QSF XML output 00044 * requires QSF available (i.e. make install) */ 00045 static gboolean debug = FALSE; 00046 00047 /* deliberately make these global to the file to pick up 00048 errors where developers access handlers directly. This practice 00049 will be deprecated in qofevent. */ 00050 static guint test, foo; 00051 00052 /* simple object structure */ 00053 typedef struct e_obj 00054 { 00055 QofInstance inst; 00056 gchar *Name; 00057 gchar flag; 00058 QofNumeric Amount; 00059 QofTime *date; 00060 gdouble discount; /* cheap pun, I know. */ 00061 gboolean active; 00062 gint32 version; 00063 gint64 minor; 00064 } event_obj; 00065 00066 static event_obj * 00067 event_create (QofBook * book) 00068 { 00069 event_obj *e; 00070 00071 g_return_val_if_fail (book, NULL); 00072 e = g_new0 (event_obj, 1); 00073 qof_instance_init (&e->inst, OBJ_EVENT_NAME, book); 00074 e->date = qof_time_get_current (); 00075 e->discount = get_random_double (); 00076 e->active = get_random_boolean (); 00077 e->version = get_random_int_in_range (1, 10000); 00078 e->minor = get_random_int_in_range (100000, 99999999); 00079 e->flag = get_random_character (); 00080 e->Name = get_random_string (); 00081 e->Amount = get_random_qof_numeric (); 00082 qof_event_gen (&e->inst.entity, QOF_EVENT_CREATE, NULL); 00083 return e; 00084 } 00085 00086 static void 00087 event_setFlag (event_obj * e, gchar f) 00088 { 00089 g_return_if_fail (e); 00090 e->flag = f; 00091 } 00092 00093 static gchar 00094 event_getFlag (event_obj * e) 00095 { 00096 g_return_val_if_fail (e, 'n'); 00097 return e->flag; 00098 } 00099 00100 static void 00101 event_setMinor (event_obj * e, gint64 h) 00102 { 00103 g_return_if_fail (e != NULL); 00104 e->minor = h; 00105 } 00106 00107 static gint64 00108 event_getMinor (event_obj * e) 00109 { 00110 g_return_val_if_fail (e, 0); 00111 return e->minor; 00112 } 00113 00114 static void 00115 event_setVersion (event_obj * e, gint32 h) 00116 { 00117 g_return_if_fail (e); 00118 e->version = h; 00119 } 00120 00121 static gint32 00122 event_getVersion (event_obj * e) 00123 { 00124 if (!e) 00125 return 0; 00126 return e->version; 00127 } 00128 00129 static void 00130 event_setActive (event_obj * e, gboolean h) 00131 { 00132 if (!e) 00133 return; 00134 e->active = h; 00135 } 00136 00137 static gboolean 00138 event_getActive (event_obj * e) 00139 { 00140 if (!e) 00141 return FALSE; 00142 return e->active; 00143 } 00144 00145 static void 00146 event_setDiscount (event_obj * e, double h) 00147 { 00148 if (!e) 00149 return; 00150 e->discount = h; 00151 } 00152 00153 static double 00154 event_getDiscount (event_obj * e) 00155 { 00156 if (!e) 00157 return 0; 00158 return e->discount; 00159 } 00160 00161 static void 00162 event_setDate (event_obj * e, QofTime *h) 00163 { 00164 if (!e) 00165 return; 00166 e->date = h; 00167 } 00168 00169 static QofTime* 00170 event_getDate (event_obj * e) 00171 { 00172 if (!e) 00173 return NULL; 00174 return e->date; 00175 } 00176 00177 static void 00178 event_setName (event_obj * e, gchar * h) 00179 { 00180 if (!e || !h) 00181 return; 00182 e->Name = strdup (h); 00183 } 00184 00185 static gchar * 00186 event_getName (event_obj * e) 00187 { 00188 if (!e) 00189 return NULL; 00190 return e->Name; 00191 } 00192 00193 static void 00194 event_setAmount (event_obj * e, QofNumeric h) 00195 { 00196 if (!e) 00197 return; 00198 e->Amount = h; 00199 } 00200 00201 static QofNumeric 00202 event_getAmount (event_obj * e) 00203 { 00204 if (!e) 00205 return qof_numeric_zero (); 00206 return e->Amount; 00207 } 00208 00209 static QofObject event_object_def = { 00210 .interface_version = QOF_OBJECT_VERSION, 00211 .e_type = OBJ_EVENT_NAME, 00212 .type_label = OBJ_EVENT_DESC, 00213 .create = (gpointer) event_create, 00214 .book_begin = NULL, 00215 .book_end = NULL, 00216 .is_dirty = NULL, 00217 .mark_clean = NULL, 00218 .foreach = qof_collection_foreach, 00219 .printable = NULL, 00220 .version_cmp = (gint (*)(gpointer, gpointer)) 00221 qof_instance_version_cmp, 00222 }; 00223 00224 static gboolean 00225 event_objRegister (void) 00226 { 00227 static QofParam params[] = { 00228 {OBJ_NAME, QOF_TYPE_STRING, (QofAccessFunc) event_getName, 00229 (QofSetterFunc) event_setName, NULL}, 00230 {OBJ_AMOUNT, QOF_TYPE_NUMERIC, (QofAccessFunc) event_getAmount, 00231 (QofSetterFunc) event_setAmount, NULL}, 00232 {OBJ_DATE, QOF_TYPE_TIME, (QofAccessFunc) event_getDate, 00233 (QofSetterFunc) event_setDate, NULL}, 00234 {OBJ_DISCOUNT, QOF_TYPE_DOUBLE, (QofAccessFunc) event_getDiscount, 00235 (QofSetterFunc) event_setDiscount, NULL}, 00236 {OBJ_ACTIVE, QOF_TYPE_BOOLEAN, (QofAccessFunc) event_getActive, 00237 (QofSetterFunc) event_setActive, NULL}, 00238 {OBJ_VERSION, QOF_TYPE_INT32, (QofAccessFunc) event_getVersion, 00239 (QofSetterFunc) event_setVersion, NULL}, 00240 {OBJ_MINOR, QOF_TYPE_INT64, (QofAccessFunc) event_getMinor, 00241 (QofSetterFunc) event_setMinor, NULL}, 00242 {OBJ_FLAG, QOF_TYPE_CHAR, (QofAccessFunc) event_getFlag, 00243 (QofSetterFunc) event_setFlag, NULL}, 00244 {QOF_PARAM_BOOK, QOF_ID_BOOK, (QofAccessFunc) qof_instance_get_book, 00245 NULL, NULL}, 00246 {QOF_PARAM_GUID, QOF_TYPE_GUID, (QofAccessFunc) qof_instance_get_guid, 00247 NULL, NULL}, 00248 {NULL, NULL, NULL, NULL, NULL}, 00249 }; 00250 00251 qof_class_register (OBJ_EVENT_NAME, NULL, params); 00252 00253 return qof_object_register (&event_object_def); 00254 } 00255 00256 typedef struct event_context_s 00257 { 00258 QofEventId event_type; 00259 QofEntity *entity_original; 00260 QofEntity *entity_modified; 00261 const QofParam *param; 00262 gboolean destroy_used; 00263 guint counter; 00264 guint old_test_id; 00265 guint old_foo_id; 00266 } event_context; 00267 00268 static void 00269 test_event_handler (QofEntity *ent, QofEventId event_type, 00270 gpointer handler_data, 00271 gpointer user_data __attribute__ ((unused))) 00272 { 00273 event_context *context; 00274 00275 context = (event_context *) handler_data; 00276 do_test ((ent != NULL), "Null ent in test"); 00277 do_test ((context != NULL), "Null context"); 00278 switch (event_type) 00279 { 00280 case QOF_EVENT_NONE: 00281 { 00282 break; 00283 } 00284 case QOF_EVENT_CREATE: 00285 { 00286 break; 00287 } 00288 case QOF_EVENT_MODIFY: 00289 { 00290 do_test ((context->entity_original != NULL), 00291 "No original entity"); 00292 do_test ((context->event_type == QOF_EVENT_MODIFY), 00293 "wrong event sent: test (QOF_EVENT_MODIFY)"); 00294 break; 00295 } 00296 case QOF_EVENT_DESTROY: 00297 { 00298 do_test ((context->entity_original != NULL), 00299 "No original entity"); 00300 do_test ((context->event_type == QOF_EVENT_DESTROY), 00301 "wrong event sent: test (QOF_EVENT_DESTROY)"); 00302 do_test ((context->destroy_used), 00303 "destroy sent without being called"); 00304 /* make sure we can unregister an earlier handler */ 00305 qof_event_unregister_handler (foo); 00306 break; 00307 } 00308 case QOF_EVENT_ADD: 00309 { 00310 do_test ((context->entity_original != NULL), 00311 "No original entity: test"); 00312 break; 00313 } 00314 case QOF_EVENT_REMOVE: 00315 { 00316 do_test ((context->entity_original != NULL), 00317 "No original entity: test"); 00318 break; 00319 } 00320 case QOF_EVENT_ALL: 00321 { 00322 do_test ((context->entity_original != NULL), 00323 "No original entity: test"); 00324 break; 00325 } 00326 } 00327 } 00328 00329 static void 00330 foo_event_handler (QofEntity *ent, QofEventId event_type, 00331 gpointer handler_data, 00332 gpointer user_data __attribute__ ((unused))) 00333 { 00334 event_context *context; 00335 00336 context = (event_context *) handler_data; 00337 do_test ((context != NULL), "Null context"); 00338 do_test ((ent != NULL), "Null entity for foo"); 00339 switch (event_type) 00340 { 00341 case QOF_EVENT_NONE: 00342 { 00343 break; 00344 } 00345 case QOF_EVENT_CREATE: 00346 { 00347 break; 00348 } 00349 case QOF_EVENT_MODIFY: 00350 { 00351 break; 00352 } 00353 case QOF_EVENT_DESTROY: 00354 { 00355 do_test ((context->entity_original != NULL), 00356 "No original entity"); 00357 do_test ((context->event_type == QOF_EVENT_DESTROY), 00358 "wrong event sent: foo (QOF_EVENT_DESTROY)"); 00359 do_test ((context->destroy_used), 00360 "destroy sent without being called"); 00361 /* make sure we can unregister a later handler */ 00362 qof_event_unregister_handler (test); 00363 break; 00364 } 00365 case QOF_EVENT_ADD: 00366 { 00367 break; 00368 } 00369 case QOF_EVENT_REMOVE: 00370 { 00371 break; 00372 } 00373 case QOF_EVENT_ALL: 00374 { 00375 break; 00376 } 00377 } 00378 } 00379 00380 static void 00381 create_data (QofSession * original, event_context * context) 00382 { 00383 QofBook *start; 00384 event_obj *e, *e2; 00385 00386 start = qof_session_get_book (original); 00387 e = (event_obj *) qof_object_new_instance (OBJ_EVENT_NAME, start); 00388 do_test ((NULL != &e->inst), "instance init"); 00389 e2 = (event_obj *) qof_object_new_instance (OBJ_EVENT_NAME, start); 00390 switch (context->counter) 00391 { 00392 case 0: 00393 { /* empty test */ 00394 do_test ((e != NULL), "empty check"); 00395 break; 00396 } 00397 case 1: 00398 { /* create a temporary entity, modify it and destroy it */ 00399 event_obj *e1; 00400 00401 do_test ((context->old_foo_id == foo), "forward foo"); 00402 do_test ((context->old_test_id == test), "forward test"); 00403 context->entity_original = (QofEntity *) e; 00404 e1 = (event_obj *) qof_object_new_instance (OBJ_EVENT_NAME, 00405 start); 00406 do_test ((NULL != &e1->inst), "temporary instance init"); 00407 context->entity_modified = (QofEntity *) e1; 00408 context->param = 00409 qof_class_get_parameter (OBJ_EVENT_NAME, OBJ_NAME); 00410 context->event_type = QOF_EVENT_MODIFY; 00411 event_setName (e, event_getName (e1)); 00412 qof_event_gen ((QofEntity *) e, QOF_EVENT_MODIFY, NULL); 00413 context->event_type = QOF_EVENT_DESTROY; 00414 context->destroy_used = TRUE; 00415 /* this block unregisters both handlers on DESTROY in turn. 00416 Here, foo is unregistered within test */ 00417 qof_event_gen ((QofEntity *) e1, QOF_EVENT_DESTROY, NULL); 00418 qof_entity_release ((QofEntity *) e1); 00419 g_free (e1); 00420 e1 = NULL; 00421 context->destroy_used = FALSE; 00422 context->event_type = QOF_EVENT_NONE; 00423 context->entity_modified = NULL; 00424 context->param = NULL; 00425 /* repeat the test in reverse. */ 00426 qof_event_unregister_handler (test); 00427 test = 00428 qof_event_register_handler (test_event_handler, 00429 context); 00430 foo = 00431 qof_event_register_handler (foo_event_handler, 00432 context); 00433 do_test ((context->old_foo_id < foo), "reverse foo"); 00434 do_test ((context->old_test_id < test), "reverse test"); 00435 /* test is unregistered within foo */ 00436 e1 = (event_obj *) qof_object_new_instance (OBJ_EVENT_NAME, 00437 start); 00438 context->entity_modified = (QofEntity *) e1; 00439 context->event_type = QOF_EVENT_DESTROY; 00440 context->destroy_used = TRUE; 00441 qof_event_gen ((QofEntity *) e1, QOF_EVENT_DESTROY, NULL); 00442 qof_entity_release ((QofEntity *) e1); 00443 g_free (e1); 00444 e1 = NULL; 00445 context->destroy_used = FALSE; 00446 context->event_type = QOF_EVENT_NONE; 00447 context->entity_original = NULL; 00448 context->entity_modified = NULL; 00449 test = 00450 qof_event_register_handler (test_event_handler, 00451 context); 00452 context->old_foo_id = foo; 00453 context->old_test_id = test; 00454 break; 00455 } 00456 case 2: 00457 { /* create the second test entity */ 00458 context->entity_original = (QofEntity *) e; 00459 do_test ((NULL != &e2->inst), "second instance init"); 00460 context->entity_modified = (QofEntity *) e2; 00461 break; 00462 } 00463 case 3: 00464 { /* destroy the entity e2 */ 00465 context->event_type = QOF_EVENT_DESTROY; 00466 context->destroy_used = TRUE; 00467 qof_event_gen ((QofEntity *) e2, QOF_EVENT_DESTROY, NULL); 00468 qof_entity_release ((QofEntity *) e2); 00469 g_free (e2); 00470 e2 = NULL; 00471 context->destroy_used = FALSE; 00472 context->event_type = QOF_EVENT_NONE; 00473 context->entity_modified = NULL; 00474 break; 00475 } 00476 case 4: 00477 { /* destroy the original entity e */ 00478 context->event_type = QOF_EVENT_DESTROY; 00479 context->destroy_used = TRUE; 00480 qof_event_gen ((QofEntity *) e, QOF_EVENT_DESTROY, NULL); 00481 qof_entity_release ((QofEntity *) e); 00482 g_free (e); 00483 e = NULL; 00484 context->destroy_used = FALSE; 00485 context->event_type = QOF_EVENT_NONE; 00486 context->entity_original = NULL; 00487 break; 00488 } 00489 } 00490 } 00491 00492 int 00493 main (void) 00494 { 00495 QofSession *original; 00496 event_context context; 00497 guint count; 00498 00499 qof_init (); 00500 event_objRegister (); 00501 original = qof_session_new (); 00502 if (debug) 00503 { 00504 qof_session_begin (original, QOF_STDOUT, TRUE, FALSE); 00505 } 00506 context.event_type = QOF_EVENT_NONE; 00507 context.entity_original = NULL; 00508 context.entity_modified = NULL; 00509 context.destroy_used = FALSE; 00510 context.param = NULL; 00511 /* events are unregistered in reverse order, so to test for 00512 a bug when unregistering a later module from an earlier one, 00513 register the foo module first and unregister it from within 00514 a later handler. */ 00515 foo = qof_event_register_handler (foo_event_handler, &context); 00516 test = qof_event_register_handler (test_event_handler, &context); 00517 context.old_test_id = test; 00518 context.old_foo_id = foo; 00519 for (count = 0; count < 25; count++) 00520 { 00521 context.counter = (count % 5); 00522 create_data (original, &context); 00523 } 00524 print_test_results (); 00525 qof_close (); 00526 return get_rv(); 00527 }