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
00026
00027
00028
00029
00030 #include <glib.h>
00031 #define _GNU_SOURCE
00032
00033 #include "qof.h"
00034 #include "qofinstance-p.h"
00035 #include "qofevent-p.h"
00036 #include "test-stuff.h"
00037
00038 #define TEST_MODULE_NAME "book-merge-test"
00039 #define TEST_MODULE_DESC "Test Book Merge"
00040 #define OBJ_NAME "somename"
00041 #define OBJ_AMOUNT "anamount"
00042 #define OBJ_DATE "nottoday"
00043 #define OBJ_GUID "unique"
00044 #define OBJ_DISCOUNT "hefty"
00045 #define OBJ_VERSION "early"
00046 #define OBJ_MINOR "tiny"
00047 #define OBJ_ACTIVE "ofcourse"
00048 #define OBJ_FLAG "tiny_flag"
00049
00050 static void test_rule_loop (QofBookMergeData*, QofBookMergeRule*, guint);
00051 static void test_merge (void);
00052 gboolean myobjRegister (void);
00053
00054
00055 typedef struct obj_s
00056 {
00057 QofInstance inst;
00058 char *Name;
00059 char flag;
00060 gnc_numeric Amount;
00061 const GUID *obj_guid;
00062 Timespec date;
00063 double discount;
00064 gboolean active;
00065 gint32 version;
00066 gint64 minor;
00067 }myobj;
00068
00069 myobj* obj_create(QofBook*);
00070
00071
00072 void obj_setName(myobj*, char*);
00073 void obj_setGUID(myobj*, const GUID*);
00074 void obj_setAmount(myobj*, gnc_numeric);
00075 void obj_setDate(myobj*, Timespec h);
00076 void obj_setDiscount(myobj*, double);
00077 void obj_setActive(myobj*, gboolean);
00078 void obj_setVersion(myobj*, gint32);
00079 void obj_setMinor(myobj*, gint64);
00080 void obj_setFlag(myobj*, char);
00081
00082
00083 char* obj_getName(myobj*);
00084 const GUID* obj_getGUID(myobj*);
00085 gnc_numeric obj_getAmount(myobj*);
00086 Timespec obj_getDate(myobj*);
00087 double obj_getDiscount(myobj*);
00088 gboolean obj_getActive(myobj*);
00089 gint32 obj_getVersion(myobj*);
00090 gint64 obj_getMinor(myobj*);
00091 char obj_getFlag(myobj*);
00092
00093 myobj*
00094 obj_create(QofBook *book)
00095 {
00096 myobj *g;
00097 g_return_val_if_fail(book, NULL);
00098 g = g_new(myobj, 1);
00099 qof_instance_init (&g->inst, TEST_MODULE_NAME, book);
00100 obj_setGUID(g,qof_instance_get_guid(&g->inst));
00101 g->date.tv_nsec = 0;
00102 g->date.tv_sec = 0;
00103 g->discount = 0;
00104 g->active = TRUE;
00105 g->version = 1;
00106 g->minor = 1;
00107 g->flag = 'n';
00108 qof_event_gen(&g->inst.entity, QOF_EVENT_CREATE, NULL);
00109 return g;
00110 }
00111
00112 void
00113 obj_setFlag(myobj *g, char f)
00114 {
00115 g_return_if_fail(g);
00116 g->flag = f;
00117 }
00118
00119 char
00120 obj_getFlag(myobj *g)
00121 {
00122 g_return_val_if_fail(g, 'n');
00123 return g->flag;
00124 }
00125
00126 void
00127 obj_setMinor(myobj *g, gint64 h)
00128 {
00129 g_return_if_fail(g != NULL);
00130 g->minor = h;
00131 }
00132
00133 gint64
00134 obj_getMinor(myobj *g)
00135 {
00136 g_return_val_if_fail((g != NULL),0);
00137 return g->minor;
00138 }
00139
00140 void
00141 obj_setVersion(myobj *g, gint32 h)
00142 {
00143 g_return_if_fail(g != NULL);
00144 g->version = h;
00145 }
00146
00147 gint32
00148 obj_getVersion(myobj *g)
00149 {
00150 if(!g) return 0;
00151 return g->version;
00152 }
00153
00154 void
00155 obj_setActive(myobj *g, gboolean h)
00156 {
00157 if(!g) return;
00158 g->active = h;
00159 }
00160
00161 gboolean
00162 obj_getActive(myobj *g)
00163 {
00164 if(!g) return FALSE;
00165 return g->active;
00166 }
00167
00168 void
00169 obj_setDiscount(myobj *g, double h)
00170 {
00171 if(!g) return;
00172 g->discount = h;
00173 }
00174
00175 double
00176 obj_getDiscount(myobj *g)
00177 {
00178 if(!g) return 0;
00179 return g->discount;
00180 }
00181
00182 void
00183 obj_setDate(myobj *g, Timespec h)
00184 {
00185 if(!g) return;
00186 g->date = h;
00187 }
00188
00189 Timespec
00190 obj_getDate(myobj *g)
00191 {
00192 Timespec ts;
00193 ts.tv_sec = 0;
00194 ts.tv_nsec = 0;
00195 if(!g) return ts;
00196 ts = g->date;
00197 return ts;
00198 }
00199
00200 void
00201 obj_setGUID(myobj* g, const GUID* h)
00202 {
00203 if(!g) return;
00204 g->obj_guid = h;
00205 }
00206
00207 const GUID*
00208 obj_getGUID(myobj *g)
00209 {
00210 if(!g) return NULL;
00211 return g->obj_guid;
00212 }
00213
00214 void
00215 obj_setName(myobj* g, char* h)
00216 {
00217 if(!g || !h) return;
00218 g->Name = strdup(h);
00219 }
00220
00221 char*
00222 obj_getName(myobj *g)
00223 {
00224 if(!g) return NULL;
00225 return g->Name;
00226 }
00227
00228 void
00229 obj_setAmount(myobj *g, gnc_numeric h)
00230 {
00231 if(!g) return;
00232 g->Amount = h;
00233 }
00234
00235 gnc_numeric
00236 obj_getAmount(myobj *g)
00237 {
00238 if(!g) return gnc_numeric_zero();
00239 return g->Amount;
00240 }
00241
00242 static QofObject obj_object_def = {
00243 interface_version: QOF_OBJECT_VERSION,
00244 e_type: TEST_MODULE_NAME,
00245 type_label: TEST_MODULE_DESC,
00246 create: (gpointer)obj_create,
00247 book_begin: NULL,
00248 book_end: NULL,
00249 is_dirty: NULL,
00250 mark_clean: NULL,
00251 foreach: qof_collection_foreach,
00252 printable: NULL,
00253 version_cmp: (gint (*)(gpointer,gpointer)) qof_instance_version_cmp,
00254 };
00255
00256 gboolean myobjRegister (void)
00257 {
00258 static QofParam params[] = {
00259 { OBJ_NAME, QOF_TYPE_STRING, (QofAccessFunc)obj_getName,
00260 (QofSetterFunc)obj_setName },
00261 { OBJ_AMOUNT, QOF_TYPE_NUMERIC, (QofAccessFunc)obj_getAmount,
00262 (QofSetterFunc)obj_setAmount },
00263 { OBJ_GUID, QOF_TYPE_GUID, (QofAccessFunc)obj_getGUID,
00264 (QofSetterFunc)obj_setGUID },
00265 { OBJ_DATE, QOF_TYPE_DATE, (QofAccessFunc)obj_getDate,
00266 (QofSetterFunc)obj_setDate },
00267 { OBJ_DISCOUNT, QOF_TYPE_DOUBLE, (QofAccessFunc)obj_getDiscount,
00268 (QofSetterFunc)obj_setDiscount },
00269 { OBJ_ACTIVE, QOF_TYPE_BOOLEAN, (QofAccessFunc)obj_getActive,
00270 (QofSetterFunc)obj_setActive },
00271 { OBJ_VERSION, QOF_TYPE_INT32, (QofAccessFunc)obj_getVersion,
00272 (QofSetterFunc)obj_setVersion },
00273 { OBJ_MINOR, QOF_TYPE_INT64, (QofAccessFunc)obj_getMinor,
00274 (QofSetterFunc)obj_setMinor },
00275 { OBJ_FLAG, QOF_TYPE_CHAR, (QofAccessFunc)obj_getFlag,
00276 (QofSetterFunc)obj_setFlag },
00277 { QOF_PARAM_BOOK, QOF_ID_BOOK, (QofAccessFunc)qof_instance_get_book, NULL },
00278 { QOF_PARAM_GUID, QOF_TYPE_GUID, (QofAccessFunc)qof_instance_get_guid, NULL },
00279 { NULL },
00280 };
00281
00282 qof_class_register (TEST_MODULE_NAME, NULL, params);
00283
00284 return qof_object_register (&obj_object_def);
00285 }
00286
00287 static void
00288 test_merge (void)
00289 {
00290 QofBook *target, *import;
00291 double init_value, discount;
00292 myobj *import_obj, *target_obj, *new_obj;
00293 int result;
00294 Timespec ts, tc;
00295 gboolean active;
00296 gint32 version;
00297 gint64 minor;
00298 gchar *import_init, *target_init;
00299 gchar flag, flag_check;
00300 gnc_numeric obj_amount;
00301 QofBookMergeData *mergeData;
00302
00303 target = qof_book_new();
00304 import = qof_book_new();
00305 init_value = 1.00;
00306 result = 0;
00307 flag = get_random_character();
00308 discount = get_random_double();
00309 active = TRUE;
00310 version = get_random_int_in_range(0,10000);
00311 minor = get_random_int_in_range(1000001,2000000);
00312 import_init = "test";
00313 target_init = "testing";
00314 qof_date_format_set(QOF_DATE_FORMAT_UK);
00315 timespecFromTime_t(&ts,time(NULL));
00316
00317 do_test ((NULL != target), "#1 target book is NULL");
00318
00319
00320 do_test ((NULL != import), "#2 import book is NULL");
00321 import_obj = g_new(myobj, 1);
00322 do_test ((NULL != import_obj), "#3 new object create");
00323 qof_instance_init (&import_obj->inst, TEST_MODULE_NAME, import);
00324 do_test ((NULL != &import_obj->inst), "#4 instance init");
00325 obj_setGUID(import_obj,qof_instance_get_guid(&import_obj->inst));
00326 do_test ((NULL != &import_obj->obj_guid), "#5 guid set");
00327 gnc_engine_gen_event(&import_obj->inst.entity, GNC_EVENT_CREATE);
00328 do_test ((NULL != &import_obj->inst.entity), "#6 gnc event create");
00329 obj_setName(import_obj, import_init);
00330 do_test ((NULL != &import_obj->Name), "#7 string set");
00331 obj_amount = double_to_gnc_numeric(init_value,1, GNC_HOW_DENOM_EXACT);
00332 obj_setAmount(import_obj, obj_amount);
00333 do_test ((gnc_numeric_check(obj_getAmount(import_obj)) == GNC_ERROR_OK),
00334 "#8 gnc_numeric set");
00335 obj_setActive(import_obj, active);
00336 do_test ((FALSE != &import_obj->active), "#9 gboolean set");
00337 obj_setDiscount(import_obj, discount);
00338 do_test ((discount == import_obj->discount), "#10 double set");
00339 obj_setVersion(import_obj, version);
00340 do_test ((version == import_obj->version), "#11 gint32 set");
00341 obj_setMinor(import_obj, minor);
00342 do_test ((minor == import_obj->minor), "#12 gint64 set");
00343 obj_setDate(import_obj, ts );
00344 tc = import_obj->date;
00345 do_test ((timespec_cmp(&ts, &tc) == 0), "#13 date set");
00346 obj_setFlag(import_obj, flag);
00347 do_test ((flag == obj_getFlag(import_obj)), "#14 flag set");
00348
00349 obj_amount = gnc_numeric_add(obj_amount, obj_amount, 1, GNC_HOW_DENOM_EXACT);
00350 discount = get_random_double();
00351 version = 2;
00352 minor = 3;
00353
00354
00355 new_obj = g_new(myobj, 1);
00356 qof_instance_init (&new_obj->inst, TEST_MODULE_NAME, import);
00357 obj_setGUID(new_obj,qof_instance_get_guid(&new_obj->inst));
00358 qof_event_gen (&new_obj->inst.entity, GNC_EVENT_CREATE, NULL);
00359 obj_setName(new_obj, import_init);
00360 obj_setAmount(new_obj, obj_amount);
00361 obj_setActive(new_obj, active);
00362 obj_setDiscount(new_obj, discount);
00363 obj_setVersion(new_obj, version);
00364 obj_setMinor(new_obj, minor);
00365 obj_setDate(new_obj, ts);
00366 obj_setFlag(new_obj, flag);
00367
00368 obj_amount = gnc_numeric_add(obj_amount, obj_amount, 1, GNC_HOW_DENOM_EXACT);
00369 discount = get_random_double();
00370 version = 2;
00371 minor = 3;
00372 flag = 'z';
00373 tc.tv_sec = ts.tv_sec -1;
00374 tc.tv_nsec = 0;
00375
00376
00377 target_obj = g_new(myobj, 1);
00378 qof_instance_init (&target_obj->inst, TEST_MODULE_NAME, target);
00379 obj_setGUID(target_obj,qof_instance_get_guid(&target_obj->inst));
00380 qof_event_gen (&target_obj->inst.entity, GNC_EVENT_CREATE, NULL);
00381 obj_setName(target_obj, target_init);
00382 obj_setAmount(target_obj, obj_amount);
00383 obj_setActive(target_obj, active);
00384 obj_setDiscount(target_obj, discount);
00385 obj_setVersion(target_obj, version);
00386 obj_setMinor(target_obj, minor);
00387 obj_setDate(target_obj, tc );
00388 obj_setFlag(target_obj, flag);
00389 do_test ((flag == obj_getFlag(target_obj)), "#15 flag set");
00390
00391 mergeData = qof_book_merge_init(import, target);
00392 do_test ( mergeData != NULL, "FATAL: Merge could not be initialised!\t aborting . . ");
00393 g_return_if_fail(mergeData != NULL);
00394 qof_book_merge_rule_foreach(mergeData, test_rule_loop, MERGE_REPORT);
00395 qof_book_merge_rule_foreach(mergeData, test_rule_loop, MERGE_UPDATE);
00396 qof_book_merge_rule_foreach(mergeData, test_rule_loop, MERGE_NEW);
00397
00398 qof_book_merge_rule_foreach(mergeData, test_rule_loop, MERGE_ABSOLUTE);
00399 qof_book_merge_rule_foreach(mergeData, test_rule_loop, MERGE_DUPLICATE);
00400
00401
00402 do_test (((safe_strcmp(obj_getName(import_obj),obj_getName(target_obj))) != 0),
00403 "Init value test #1");
00404
00405
00406 do_test (qof_book_merge_commit(mergeData) == 0, "Commit failed");
00407
00408
00409 do_test (((safe_strcmp(import_init,obj_getName(target_obj))) == 0),
00410 "Merged value test #1");
00411
00412
00413 do_test (((safe_strcmp(obj_getName(target_obj),obj_getName(import_obj))) == 0),
00414 "Merged value test #2");
00415
00416
00417 do_test ((gnc_numeric_check(obj_getAmount(import_obj)) == GNC_ERROR_OK),
00418 "import gnc_numeric check");
00419 do_test ((gnc_numeric_check(obj_getAmount(target_obj)) == GNC_ERROR_OK),
00420 "target gnc_numeric check");
00421
00422
00423 do_test ((gnc_numeric_compare(obj_getAmount(import_obj), obj_amount) != GNC_ERROR_OK),
00424 "gnc_numeric value check #1");
00425
00426
00427 do_test ((gnc_numeric_compare(obj_getAmount(target_obj), obj_amount) != GNC_ERROR_OK),
00428 "gnc_numeric value check #2");
00429
00430
00431 tc = target_obj->date;
00432 do_test ((timespec_cmp(&ts, &tc) == 0), "date value check: 1");
00433 tc = import_obj->date;
00434 do_test ((timespec_cmp(&tc, &ts) == 0), "date value check: 2");
00435 do_test ((timespec_cmp(&import_obj->date, &target_obj->date) == 0),
00436 "date value check: 3");
00437
00438
00439 flag_check = obj_getFlag(target_obj);
00440 do_test ((flag_check == obj_getFlag(import_obj)), "flag value check: 1");
00441 do_test ((obj_getFlag(import_obj) == obj_getFlag(target_obj)),
00442 "flag value check: 2");
00443 }
00444
00445 static void
00446 test_rule_loop (QofBookMergeData *mergeData, QofBookMergeRule *rule, guint remainder)
00447 {
00448 GSList *testing;
00449 QofParam *eachParam;
00450 char *importstring;
00451 char *targetstring;
00452 gboolean skip_target;
00453
00454 importstring = NULL;
00455 targetstring = NULL;
00456 skip_target = FALSE;
00457 mergeData->currentRule = rule;
00458 do_test ((rule != NULL), "loop:#1 Rule is NULL");
00459 do_test (remainder > 0, "loop:#2 remainder error.");
00460 do_test ((safe_strcmp(NULL, rule->mergeLabel) != 0), "loop:#3 object label\n");
00461 do_test ((rule->importEnt != NULL), "loop:#4 empty import entity");
00462
00463 if(rule->targetEnt == NULL) { skip_target = TRUE; }
00464 if(!skip_target) {
00465 do_test ((safe_strcmp(rule->importEnt->e_type, rule->targetEnt->e_type) == 0),
00466 "loop: entity type mismatch");
00467 }
00468 do_test ((rule->mergeParam != NULL), "loop: empty parameter list");
00469 testing = rule->mergeParam;
00470
00471 while(testing != NULL) {
00472 eachParam = testing->data;
00473 do_test ((eachParam != NULL), "loop:#8 no QofParam data");
00474 do_test ((eachParam->param_name != NULL), "loop:#9 no parameter name");
00475 do_test ((eachParam->param_getfcn != NULL), "loop:#10 no get function");
00476 do_test ((eachParam->param_setfcn != NULL), "loop:#11 no set function");
00477
00478 if(safe_strcmp(eachParam->param_type, QOF_TYPE_STRING) == 0) {
00479 importstring = g_strdup(eachParam->param_getfcn(rule->importEnt, eachParam));
00480 do_test ((importstring != NULL), "loop:#12 direct get_fcn import");
00481 do_test ((safe_strcmp(importstring, "test") == 0), "loop:#13 direct import comparison");
00482 if(!skip_target) {
00483 targetstring = eachParam->param_getfcn(rule->targetEnt, eachParam);
00484 do_test ((targetstring != NULL), "loop:#14 direct get_fcn target");
00485 do_test ((safe_strcmp(targetstring, "testing") == 0), "loop:#15 direct target comparison");
00486 }
00487 }
00488
00489
00490 importstring = qof_book_merge_param_as_string(eachParam, rule->importEnt);
00491 do_test ((importstring != NULL), "loop:#16 import param_as_string is null");
00492 if(!skip_target) {
00493 targetstring = qof_book_merge_param_as_string(eachParam, rule->targetEnt);
00494 do_test ((targetstring != NULL), "loop:#17 target param_as_string is null");
00495 }
00496 testing = g_slist_next(testing);
00497 }
00498
00499
00500 mergeData = qof_book_merge_update_result(mergeData, MERGE_UPDATE);
00501 do_test ((rule->mergeResult != MERGE_REPORT), "update result fail");
00502 }
00503
00504 int
00505 main (int argc, const char *argv[])
00506 {
00507 qof_init();
00508 myobjRegister();
00509 test_merge();
00510 print_test_results();
00511 qof_close();
00512 return 0;
00513 }