00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <glib.h>
00026 #include <glib/gprintf.h>
00027 #define _GNU_SOURCE
00028
00029 #include "qof.h"
00030 #include "test-engine-stuff.h"
00031 #include "test-stuff.h"
00032
00033 #define OBJ_NAME "somename"
00034 #define OBJ_AMOUNT "anamount"
00035 #define OBJ_DATE "nottoday"
00036 #define OBJ_GUID "unique"
00037 #define OBJ_DISCOUNT "hefty"
00038 #define OBJ_VERSION "early"
00039 #define OBJ_MINOR "tiny"
00040 #define OBJ_ACTIVE "ofcourse"
00041 #define OBJ_FLAG "tiny_flag"
00042 #define OBJ_EVENT_NAME "test-event-object"
00043 #define OBJ_EVENT_DESC "test object for events"
00044
00045
00046
00047 static gboolean debug = FALSE;
00048
00049
00050
00051
00052 static gint test, foo;
00053
00054
00055 typedef struct e_obj
00056 {
00057 QofInstance inst;
00058 gchar *Name;
00059 gchar flag;
00060 gnc_numeric Amount;
00061 Timespec date;
00062 double discount;
00063 gboolean active;
00064 gint32 version;
00065 gint64 minor;
00066 }event_obj;
00067
00068 static event_obj*
00069 event_create(QofBook *book)
00070 {
00071 event_obj *e;
00072
00073 g_return_val_if_fail(book, NULL);
00074 e = g_new0(event_obj, 1);
00075 qof_instance_init (&e->inst, OBJ_EVENT_NAME, book);
00076 e->date = *get_random_timespec();
00077 e->discount = get_random_double();
00078 e->active = get_random_boolean();
00079 e->version = get_random_int_in_range(1,10000);
00080 e->minor = get_random_int_in_range(100000,99999999);
00081 e->flag = get_random_character();
00082 e->Name = get_random_string();
00083 e->Amount = get_random_gnc_numeric();
00084 gnc_engine_gen_event(&e->inst.entity, GNC_EVENT_CREATE);
00085 return e;
00086 }
00087
00088 static void
00089 event_setFlag(event_obj *e, gchar f)
00090 {
00091 g_return_if_fail(e);
00092 e->flag = f;
00093 }
00094
00095 static gchar
00096 event_getFlag(event_obj *e)
00097 {
00098 g_return_val_if_fail(e, 'n');
00099 return e->flag;
00100 }
00101
00102 static void
00103 event_setMinor(event_obj *e, gint64 h)
00104 {
00105 g_return_if_fail(e != NULL);
00106 e->minor = h;
00107 }
00108
00109 static gint64
00110 event_getMinor(event_obj *e)
00111 {
00112 g_return_val_if_fail(e, 0);
00113 return e->minor;
00114 }
00115
00116 static void
00117 event_setVersion(event_obj *e, gint32 h)
00118 {
00119 g_return_if_fail(e);
00120 e->version = h;
00121 }
00122
00123 static gint32
00124 event_getVersion(event_obj *e)
00125 {
00126 if(!e) return 0;
00127 return e->version;
00128 }
00129
00130 static void
00131 event_setActive(event_obj *e, gboolean h)
00132 {
00133 if(!e) return;
00134 e->active = h;
00135 }
00136
00137 static gboolean
00138 event_getActive(event_obj *e)
00139 {
00140 if(!e) return FALSE;
00141 return e->active;
00142 }
00143
00144 static void
00145 event_setDiscount(event_obj *e, double h)
00146 {
00147 if(!e) return;
00148 e->discount = h;
00149 }
00150
00151 static double
00152 event_getDiscount(event_obj *e)
00153 {
00154 if(!e) return 0;
00155 return e->discount;
00156 }
00157
00158 static void
00159 event_setDate(event_obj *e, Timespec h)
00160 {
00161 if(!e) return;
00162 e->date = h;
00163 }
00164
00165 static Timespec
00166 event_getDate(event_obj *e)
00167 {
00168 Timespec ts;
00169 ts.tv_sec = 0;
00170 ts.tv_nsec = 0;
00171 if(!e) return ts;
00172 ts = e->date;
00173 return ts;
00174 }
00175
00176 static void
00177 event_setName(event_obj *e, gchar* h)
00178 {
00179 if(!e || !h) return;
00180 e->Name = strdup(h);
00181 }
00182
00183 static gchar*
00184 event_getName(event_obj *e)
00185 {
00186 if(!e) return NULL;
00187 return e->Name;
00188 }
00189
00190 static void
00191 event_setAmount(event_obj *e, gnc_numeric h)
00192 {
00193 if(!e) return;
00194 e->Amount = h;
00195 }
00196
00197 static gnc_numeric
00198 event_getAmount(event_obj *e)
00199 {
00200 if(!e) return gnc_numeric_zero();
00201 return e->Amount;
00202 }
00203
00204 static QofObject event_object_def = {
00205 interface_version: QOF_OBJECT_VERSION,
00206 e_type: OBJ_EVENT_NAME,
00207 type_label: OBJ_EVENT_DESC,
00208 create: (gpointer)event_create,
00209 book_begin: NULL,
00210 book_end: NULL,
00211 is_dirty: NULL,
00212 mark_clean: NULL,
00213 foreach: qof_collection_foreach,
00214 printable: NULL,
00215 version_cmp: (int (*)(gpointer,gpointer)) qof_instance_version_cmp,
00216 };
00217
00218 static gboolean event_objRegister (void)
00219 {
00220 static QofParam params[] = {
00221 { OBJ_NAME, QOF_TYPE_STRING, (QofAccessFunc)event_getName,
00222 (QofSetterFunc)event_setName },
00223 { OBJ_AMOUNT, QOF_TYPE_NUMERIC, (QofAccessFunc)event_getAmount,
00224 (QofSetterFunc)event_setAmount },
00225 { OBJ_DATE, QOF_TYPE_DATE, (QofAccessFunc)event_getDate,
00226 (QofSetterFunc)event_setDate },
00227 { OBJ_DISCOUNT, QOF_TYPE_DOUBLE, (QofAccessFunc)event_getDiscount,
00228 (QofSetterFunc)event_setDiscount },
00229 { OBJ_ACTIVE, QOF_TYPE_BOOLEAN, (QofAccessFunc)event_getActive,
00230 (QofSetterFunc)event_setActive },
00231 { OBJ_VERSION, QOF_TYPE_INT32, (QofAccessFunc)event_getVersion,
00232 (QofSetterFunc)event_setVersion },
00233 { OBJ_MINOR, QOF_TYPE_INT64, (QofAccessFunc)event_getMinor,
00234 (QofSetterFunc)event_setMinor },
00235 { OBJ_FLAG, QOF_TYPE_CHAR, (QofAccessFunc)event_getFlag,
00236 (QofSetterFunc)event_setFlag },
00237 { QOF_PARAM_BOOK, QOF_ID_BOOK, (QofAccessFunc)qof_instance_get_book, NULL },
00238 { QOF_PARAM_GUID, QOF_TYPE_GUID, (QofAccessFunc)qof_instance_get_guid, NULL },
00239 { NULL },
00240 };
00241
00242 qof_class_register (OBJ_EVENT_NAME, NULL, params);
00243
00244 return qof_object_register (&event_object_def);
00245 }
00246
00247 typedef struct event_context_s
00248 {
00249 GNCEngineEventType event_type;
00250 QofEntity *entity_original;
00251 QofEntity *entity_modified;
00252 const QofParam *param;
00253 gboolean destroy_used;
00254 guint counter;
00255 guint old_test_id;
00256 guint old_foo_id;
00257 }event_context;
00258
00259 static void
00260 test_event_handler(GUID* g, QofIdType id_type, GNCEngineEventType event_type,
00261 gpointer user_data)
00262 {
00263 event_context *context;
00264
00265 context = (event_context*)user_data;
00266 do_test((g != NULL), "Null GUID in test");
00267 do_test((id_type != NULL), "Null IdType in test");
00268 do_test((context != NULL), "Null context");
00269 switch (event_type)
00270 {
00271 case GNC_EVENT_NONE : { break; }
00272 case GNC_EVENT_CREATE :
00273 {
00274 break;
00275 }
00276 case GNC_EVENT_MODIFY :
00277 {
00278 do_test((context->entity_original != NULL), "No original entity");
00279 do_test((context->event_type == GNC_EVENT_MODIFY),
00280 "wrong event sent: test (GNC_EVENT_MODIFY)");
00281 break;
00282 }
00283 case GNC_EVENT_DESTROY :
00284 {
00285 do_test((context->entity_original != NULL), "No original entity");
00286 do_test((context->event_type == GNC_EVENT_DESTROY),
00287 "wrong event sent: test (GNC_EVENT_DESTROY)");
00288 do_test((context->destroy_used), "destroy sent without being called");
00289
00290 gnc_engine_unregister_event_handler(foo);
00291 break;
00292 }
00293 case GNC_EVENT_ADD :
00294 {
00295 do_test((context->entity_original != NULL),
00296 "No original entity: test");
00297 break;
00298 }
00299 case GNC_EVENT_REMOVE :
00300 {
00301 do_test((context->entity_original != NULL),
00302 "No original entity: test");
00303 break;
00304 }
00305 case GNC_EVENT_ALL :
00306 {
00307 do_test((context->entity_original != NULL),
00308 "No original entity: test");
00309 break;
00310 }
00311 }
00312 }
00313
00314 static void
00315 foo_event_handler(GUID* g, QofIdType id_type, GNCEngineEventType event_type,
00316 gpointer user_data)
00317 {
00318 event_context *context;
00319
00320 context = (event_context*)user_data;
00321 do_test((context != NULL), "Null context");
00322 do_test((g != NULL), "Null GUID for foo");
00323 do_test((id_type != NULL), "Null IdType for foo");
00324 switch (event_type)
00325 {
00326 case GNC_EVENT_NONE : { break; }
00327 case GNC_EVENT_CREATE :
00328 {
00329 break;
00330 }
00331 case GNC_EVENT_MODIFY :
00332 {
00333 break;
00334 }
00335 case GNC_EVENT_DESTROY :
00336 {
00337 do_test((context->entity_original != NULL), "No original entity");
00338 do_test((context->event_type == GNC_EVENT_DESTROY),
00339 "wrong event sent: foo (GNC_EVENT_DESTROY)");
00340 do_test((context->destroy_used), "destroy sent without being called");
00341
00342 gnc_engine_unregister_event_handler(test);
00343 break;
00344 }
00345 case GNC_EVENT_ADD :
00346 {
00347 break;
00348 }
00349 case GNC_EVENT_REMOVE :
00350 {
00351 break;
00352 }
00353 case GNC_EVENT_ALL :
00354 {
00355 break;
00356 }
00357 }
00358 }
00359
00360 static void
00361 create_data (QofSession *original, event_context *context)
00362 {
00363 QofBook *start;
00364 event_obj *e, *e2;
00365
00366 start = qof_session_get_book(original);
00367 e = (event_obj*)qof_object_new_instance(OBJ_EVENT_NAME, start);
00368 do_test ((NULL != &e->inst), "instance init");
00369 e2 = (event_obj*)qof_object_new_instance(OBJ_EVENT_NAME, start);
00370 switch (context->counter)
00371 {
00372 case 0 : {
00373 do_test((e != NULL), "empty check");
00374 break;
00375 }
00376 case 1 : {
00377 event_obj *e1;
00378
00379 do_test((context->old_foo_id == foo), "forward foo");
00380 do_test((context->old_test_id == test), "forward test");
00381 context->entity_original = (QofEntity*)e;
00382 e1 = (event_obj*)qof_object_new_instance(OBJ_EVENT_NAME, start);
00383 do_test ((NULL != &e1->inst), "temporary instance init");
00384 context->entity_modified = (QofEntity*)e1;
00385 context->param = qof_class_get_parameter(OBJ_EVENT_NAME, OBJ_NAME);
00386 context->event_type = GNC_EVENT_MODIFY;
00387 event_setName(e, event_getName(e1));
00388 gnc_engine_gen_event((QofEntity*)e, GNC_EVENT_MODIFY);
00389 context->event_type = GNC_EVENT_DESTROY;
00390 context->destroy_used = TRUE;
00391
00392
00393 gnc_engine_gen_event((QofEntity*)e1, GNC_EVENT_DESTROY);
00394 qof_entity_release((QofEntity*)e1);
00395 g_free(e1);
00396 e1 = NULL;
00397 context->destroy_used = FALSE;
00398 context->event_type = GNC_EVENT_NONE;
00399 context->entity_modified = NULL;
00400 context->param = NULL;
00401
00402 gnc_engine_unregister_event_handler(test);
00403 test = gnc_engine_register_event_handler(test_event_handler, context);
00404 foo = gnc_engine_register_event_handler(foo_event_handler, context);
00405 do_test((context->old_foo_id < foo), "reverse foo");
00406 do_test((context->old_test_id < test), "reverse test");
00407
00408 e1 = (event_obj*)qof_object_new_instance(OBJ_EVENT_NAME, start);
00409 context->entity_modified = (QofEntity*)e1;
00410 context->event_type = GNC_EVENT_DESTROY;
00411 context->destroy_used = TRUE;
00412 gnc_engine_gen_event((QofEntity*)e1, GNC_EVENT_DESTROY);
00413 qof_entity_release((QofEntity*)e1);
00414 g_free(e1);
00415 e1 = NULL;
00416 context->destroy_used = FALSE;
00417 context->event_type = GNC_EVENT_NONE;
00418 context->entity_original = NULL;
00419 context->entity_modified = NULL;
00420 test = gnc_engine_register_event_handler(test_event_handler, context);
00421 context->old_foo_id = foo;
00422 context->old_test_id = test;
00423 break;
00424 }
00425 case 2 : {
00426 context->entity_original = (QofEntity*)e;
00427 do_test ((NULL != &e2->inst), "second instance init");
00428 context->entity_modified = (QofEntity*)e2;
00429 break;
00430 }
00431 case 3 : {
00432 context->event_type = GNC_EVENT_DESTROY;
00433 context->destroy_used = TRUE;
00434 gnc_engine_gen_event((QofEntity*)e2, GNC_EVENT_DESTROY);
00435 qof_entity_release((QofEntity*)e2);
00436 g_free(e2);
00437 e2 = NULL;
00438 context->destroy_used = FALSE;
00439 context->event_type = GNC_EVENT_NONE;
00440 context->entity_modified = NULL;
00441 break;
00442 }
00443 case 4 : {
00444 context->event_type = GNC_EVENT_DESTROY;
00445 context->destroy_used = TRUE;
00446 gnc_engine_gen_event((QofEntity*)e, GNC_EVENT_DESTROY);
00447 qof_entity_release((QofEntity*)e);
00448 g_free(e);
00449 e = NULL;
00450 context->destroy_used = FALSE;
00451 context->event_type = GNC_EVENT_NONE;
00452 context->entity_original = NULL;
00453 break;
00454 }
00455 }
00456 }
00457
00458 int
00459 main (int argc, const char *argv[])
00460 {
00461 QofSession *original;
00462 event_context context;
00463 guint count;
00464
00465 qof_init ();
00466 event_objRegister();
00467 original = qof_session_new();
00468 if(debug) { qof_session_begin(original, QOF_STDOUT, TRUE, FALSE); }
00469 context.event_type = GNC_EVENT_NONE;
00470 context.entity_original = NULL;
00471 context.entity_modified = NULL;
00472 context.destroy_used = FALSE;
00473 context.param = NULL;
00474
00475
00476
00477
00478 foo = gnc_engine_register_event_handler(foo_event_handler, &context);
00479 test = gnc_engine_register_event_handler(test_event_handler, &context);
00480 context.old_test_id = test;
00481 context.old_foo_id = foo;
00482 for(count = 0; count < 25; count++)
00483 {
00484 context.counter = (count % 5);
00485 create_data(original, &context);
00486 }
00487 print_test_results();
00488 qof_close();
00489 return EXIT_SUCCESS;
00490 }