From e1d338542880815f871f7741682e673781412716 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Fri, 15 Dec 2017 10:13:41 -0800 Subject: [PATCH] Handle mid-pacific timezones in date-sensitive tests. --- gnucash/import-export/aqb/test/test-kvp.c | 33 ++++---- .../test/test-report-utilities.scm | 4 +- .../test/test-cashflow-barchart.scm | 23 +++--- libgnucash/app-utils/date-utilities.scm | 4 +- libgnucash/engine/test/gtest-gnc-datetime.cpp | 13 +++- libgnucash/engine/test/test-gnc-date.c | 75 ++++++++++++------- 6 files changed, 90 insertions(+), 62 deletions(-) diff --git a/gnucash/import-export/aqb/test/test-kvp.c b/gnucash/import-export/aqb/test/test-kvp.c index 415eed688f..fc7fd60d73 100644 --- a/gnucash/import-export/aqb/test/test-kvp.c +++ b/gnucash/import-export/aqb/test/test-kvp.c @@ -149,7 +149,7 @@ test_qofsession_aqb_kvp( void ) // Check the kvp slots of a aqbanking-enabled account QofBook *book = qof_session_get_book(new_session); Account* account = gnc_book_get_root_account(book); - GDate retrieved_date, original_date; + struct tm *retrieved_date, *original_date; gchar buff[MAX_DATE_LENGTH]; g_assert(account); @@ -160,18 +160,17 @@ test_qofsession_aqb_kvp( void ) { Timespec retrieved_ts = gnc_ab_get_account_trans_retrieval(account); g_test_message("retrieved_ts=%s\n", gnc_print_date(retrieved_ts)); - //printf("Time=%s\n", gnc_print_date(retrieved_ts)); - retrieved_date = timespec_to_gdate(retrieved_ts); - g_date_set_dmy(&original_date, 29, 8, 2014); - - g_assert_cmpint(g_date_compare(&retrieved_date, &original_date), ==, 0); + retrieved_date = gnc_gmtime (&retrieved_ts.tv_sec); + g_assert_cmpint (retrieved_date->tm_year, ==, 114); + g_assert_cmpint (retrieved_date->tm_mon, ==, 7); + g_assert_cmpint (retrieved_date->tm_mday, ==, 29); } // A lower-level test here: Can we write and read again the // trans_retrieval date? This wouldn't need this particular // Account, just a general Account object. - if (0) + if (1) { Timespec original_ts = timespec_now(), retrieved_ts; @@ -179,21 +178,15 @@ test_qofsession_aqb_kvp( void ) // is written and read again correctly. gnc_ab_set_account_trans_retrieval(account, original_ts); retrieved_ts = gnc_ab_get_account_trans_retrieval(account); + g_test_message("original_ts=%s\n", gnc_print_date(original_ts)); + g_test_message("retrieved_ts=%s\n", gnc_print_date(retrieved_ts)); -// printf("original_ts=%s = %d retrieved_ts=%s = %d\n", -// gnc_print_date(original_ts), original_ts.tv_sec, -// gnc_print_date(retrieved_ts), retrieved_ts.tv_sec); + original_date = gnc_gmtime (&original_ts.tv_sec); + retrieved_date = gnc_gmtime (&retrieved_ts.tv_sec); - original_date = timespec_to_gdate(original_ts); - retrieved_date = timespec_to_gdate(retrieved_ts); - - qof_print_gdate (buff, sizeof (buff), &original_date); - //printf("original_date=%s\n", buff); - qof_print_gdate (buff, sizeof (buff), &retrieved_date); - //printf("retrieved_date=%s\n", buff); - - // Is the retrieved date identical to the one written - g_assert_cmpint(g_date_compare(&retrieved_date, &original_date), ==, 0); + g_assert_cmpint (retrieved_date->tm_year, ==, original_date->tm_year); + g_assert_cmpint (retrieved_date->tm_mon, ==, original_date->tm_mon); + g_assert_cmpint (retrieved_date->tm_mday, ==, original_date->tm_mday); } } diff --git a/gnucash/report/report-system/test/test-report-utilities.scm b/gnucash/report/report-system/test/test-report-utilities.scm index d6d26ac657..21a2532ee9 100644 --- a/gnucash/report/report-system/test/test-report-utilities.scm +++ b/gnucash/report/report-system/test/test-report-utilities.scm @@ -37,9 +37,9 @@ (wallet (cdr (assoc "Wallet" accounts)))) (env-create-daily-transactions env start-date-tp end-date-tp bank-account wallet) - + (format #t "Created transactions for each day from ~a to ~a~%" (gnc-ctime (gnc:timepair->secs start-date-tp)) (gnc-ctime (gnc:timepair->secs end-date-tp))) (let ((splits (gnc:account-get-trans-type-splits-interval (list bank-account wallet) ACCT-TYPE-ASSET q-start-date-tp q-end-date-tp))) ;; 10 is the right number (5 days, two splits per tx) - (and (equal? 10 (length splits))))))) + (or (equal? 10 (length splits)) (begin (format #t "Fail, ~d splits, expected 10~%" (length splits)) #f)))))) diff --git a/gnucash/report/standard-reports/test/test-cashflow-barchart.scm b/gnucash/report/standard-reports/test/test-cashflow-barchart.scm index 481df91462..5dc958f874 100644 --- a/gnucash/report/standard-reports/test/test-cashflow-barchart.scm +++ b/gnucash/report/standard-reports/test/test-cashflow-barchart.scm @@ -93,7 +93,8 @@ (set-option report gnc:pagename-general "Price Source" 'pricedb-nearest) (set-option report gnc:pagename-general "Report's currency" (gnc-default-report-currency)) (set-option report gnc:pagename-accounts "Accounts" (list wallet-account bank-account)) - + (format #t "Create first transaction on ~a~%" (gnc-ctime (gnc:timepair->secs date-1))) + (format #t "Create second transaction on ~a~%" (gnc-ctime (gnc:timepair->secs date-2))) (let ((doc (renderer report))) (gnc:html-document-set-style-sheet! doc (gnc:report-stylesheet report)) (let* ((result (gnc:html-document-render doc #f)) @@ -112,16 +113,18 @@ (list "[^0-9]*([^<]*)" 1)) result)))) (and (every (lambda (row) ; test in=net & out=0 in all rows (all days) - (and (equal? (second row) (fourth row)) - (= 0 (string->number (car (third row)))))) + (and (or (equal? (second row) (fourth row)) + (begin (format #t "Failed, ~a and ~a differ~%" (second row) (fourth row)) #f)) + (or (= 0 (string->number (car (third row)))) + (begin (format #t "Failed ~d isn't 0~%" (car (third row))) #f)))) tbl) - (= 0 (tbl-ref->number tbl 0 1)) ; 1st day in =0 - (= 1 (tbl-ref->number tbl 1 1)) ; 2nd day in =1 - (= 5 (tbl-ref->number tbl 2 1)) ; 3rd day in =5 - (= (tbl-ref->number total 0 0) (tbl-ref->number total 0 2)) ; total in=total net - (= 0 (tbl-ref->number total 0 1)) ; total out=0 - (= 3 (tbl-row-count tbl)) - (= 4 (tbl-column-count tbl))))) + (or (= 0 (tbl-ref->number tbl 0 1)) (begin (format #t "Failed refnum ~d isn't 0~%" (tbl-ref->number tbl 0 1) )) #f)) ; 1st day in =0 + (or (= 1 (tbl-ref->number tbl 1 1)) (begin (format #t "Failed refnum ~d isn't 1~%" (tbl-ref->number tbl 1 1)) #f)) ; 2nd day in =1 + (or (= 5 (tbl-ref->number tbl 2 1)) (begin (format #t "Failed refnum ~d isn't 5~%" (tbl-ref->number tbl 2 1)) #f)) ; 3rd day in =5 + (or (= (tbl-ref->number total 0 0) (tbl-ref->number total 0 2)) (begin (format #t "Failed refnums ~d and ~d differ ~%" (tbl-ref->number total 0 0) (tbl-ref->number total 0 2)) #f)); total in=total net + (or (= 0 (tbl-ref->number total 0 1)) (begin (format #t "Failed refnum ~d isn't 0~%" (tbl-ref->number total 0 1)) #f)) ; total out=0 + (or (= 3 (tbl-row-count tbl)) (begin (format #t "Failed row count ~d isn't 3~%" (tbl-row-count tbl)) #f)) + (or (= 4 (tbl-column-count tbl)) (begin (format #t "Failed column count ~d isn't 4~%" (tbl-column-count tbl)) #f)))) ) ) ) diff --git a/libgnucash/app-utils/date-utilities.scm b/libgnucash/app-utils/date-utilities.scm index 03faa8fa81..1bba52fa0d 100644 --- a/libgnucash/app-utils/date-utilities.scm +++ b/libgnucash/app-utils/date-utilities.scm @@ -229,7 +229,7 @@ (set-tm:mday newtm (op (tm:mday newtm) (tm:mday delta))) (set-tm:mon newtm (op (tm:mon newtm) (tm:mon delta))) (set-tm:year newtm (op (tm:year newtm) (tm:year delta))) - (set-tm:isdst newtm -1) + (set-tm:isdst newtm 0) (gnc:date->timepair newtm)))) ;; Add or subtract time from a date @@ -324,7 +324,7 @@ (set-tm:year zd 0) (set-tm:yday zd 0) (set-tm:wday zd 0) - (set-tm:isdst zd -1) + (set-tm:isdst zd 0) zd)) diff --git a/libgnucash/engine/test/gtest-gnc-datetime.cpp b/libgnucash/engine/test/gtest-gnc-datetime.cpp index b77b303333..3f1712dd32 100644 --- a/libgnucash/engine/test/gtest-gnc-datetime.cpp +++ b/libgnucash/engine/test/gtest-gnc-datetime.cpp @@ -320,13 +320,22 @@ TEST(gnc_datetime_constructors, test_gncdate_neutral_constructor) { const ymd aymd = { 2017, 04, 20 }; GncDateTime atime(GncDate(aymd.year, aymd.month, aymd.day), DayPart::neutral); - EXPECT_EQ(atime.format("%d-%m-%Y %H:%M:%S %z"), "20-04-2017 10:59:00 UTC"); + GncDateTime gncdt(1492685940); /* 20 Apr 2017 10:59:00 Z */ + /* The ymd constructor sets the time of day at 10:59:00 for + * timezones between UTC-10 and UTC+13. For other timezones the + * time of day is adjusted to ensure a consistent date and the + * adjustment invalidates the test, so skip it. + */ + constexpr time64 max_western_offset = -10 * 3600; + constexpr time64 max_eastern_offset = 13 * 3600; + if (gncdt.offset() >= max_western_offset && gncdt.offset() <= max_eastern_offset) + EXPECT_EQ(atime.format("%d-%m-%Y %H:%M:%S %z"), "20-04-2017 10:59:00 UTC"); } TEST(gnc_datetime_functions, test_format) { GncDateTime atime(2394187200); //2045-11-13 12:00:00 Z - if ((atime.offset() / 3600) > 12) + if ((atime.offset() / 3600) > 11 || (atime.offset() / 3600) < -11) EXPECT_EQ(atime.format("%d-%m-%Y"), "14-11-2045"); else EXPECT_EQ(atime.format("%d-%m-%Y"), "13-11-2045"); diff --git a/libgnucash/engine/test/test-gnc-date.c b/libgnucash/engine/test/test-gnc-date.c index 4b765c8581..5e23396842 100644 --- a/libgnucash/engine/test/test-gnc-date.c +++ b/libgnucash/engine/test/test-gnc-date.c @@ -319,7 +319,8 @@ test_gnc_mktime_normalization (void) #endif }; guint ind; - time_t calc_timegm = timegm(&normal_time); + struct tm other_time = normal_time; + time_t calc_timegm = timegm(&other_time); time_t calc_time = mktime(&normal_time); for (ind = 0; ind < G_N_ELEMENTS (time); ind++) { @@ -1001,12 +1002,12 @@ test_qof_print_date_buff (void) gchar buff[MAX_DATE_LENGTH], ans[MAX_DATE_LENGTH]; gchar *locale = g_strdup (setlocale (LC_TIME, NULL)); - time64 time1 = 154436399; //1974-11-23 10:59:59 - time64 time2 = -281192401; //1961-02-02 10:59:59 - time64 time3 = 2381223599LL; //2045-06-16 10:59:59 struct tm tm1 = {0, 0, 12, 23, 10, 74}; struct tm tm2 = {0, 0, 12, 2, 1, 61}; struct tm tm3 = {0, 0, 12, 16, 5, 145}; + time64 time1 = gnc_mktime(&tm1); + time64 time2 = gnc_mktime(&tm2); + time64 time3 = gnc_mktime(&tm3); qof_date_format_set (QOF_DATE_FORMAT_UK); memset ((gpointer)buff, 0, sizeof (buff)); @@ -1283,12 +1284,12 @@ test_qof_print_date (void) { gchar *locale = g_strdup (setlocale (LC_TIME, NULL)); char ans[MAX_DATE_LENGTH]; - time64 time1 = 154436399; //1974-11-23 10:59:59 - time64 time2 = -281192401; //1961-02-02 10:59:59 - time64 time3 = 2381223599LL; //2045-06-16 10:59:59 struct tm tm1 = {0, 0, 12, 23, 10, 74}; struct tm tm2 = {0, 0, 12, 2, 1, 61}; struct tm tm3 = {0, 0, 12, 16, 5, 145}; + time64 time1 = gnc_mktime(&tm1); + time64 time2 = gnc_mktime(&tm2); + time64 time3 = gnc_mktime(&tm3); qof_date_format_set (QOF_DATE_FORMAT_UK); test_assert_qof_print_date (time1, "23/11/1974"); @@ -1902,13 +1903,24 @@ test_gnc_dmy2timespec_neutral (FixtureB *f, gconstpointer pData) gchar *logdomain = "qof.engine"; TestErrorStruct check = {loglevel, logdomain, msg1, 0}; GLogFunc hdlr = g_log_set_default_handler ((GLogFunc)test_null_handler, &check); - g_test_log_set_fatal_handler ((GTestLogFatalFunc)test_checked_handler, &check); - for (int i = 0; i < sizeof(f->test)/sizeof(TimeMap); ++i) + struct tm check_tz; + gnc_localtime_r(&(f->test[0].secs), &check_tz); + /* gnc_dmy2timespec_neutral returns the timespec for 10:59:00 Z + * for timezones in the range -11 to +13. If the timezone being + * tested is outside that range then the day of the month will be + * different from the one in the test fixture and we skip the + * test. + */ + if (check_tz.tm_mday == f->test[0].day) { - Timespec r_t = gnc_dmy2timespec_neutral (f->test[i].day, f->test[i].mon, - f->test[i].yr); + g_test_log_set_fatal_handler ((GTestLogFatalFunc)test_checked_handler, &check); + for (int i = 0; i < sizeof(f->test)/sizeof(TimeMap); ++i) + { + Timespec r_t = gnc_dmy2timespec_neutral (f->test[i].day, f->test[i].mon, + f->test[i].yr); - g_assert_cmpint (r_t.tv_sec, ==, f->test[i].secs); + g_assert_cmpint (r_t.tv_sec, ==, f->test[i].secs); + } } g_log_set_default_handler (hdlr, 0); } @@ -2005,21 +2017,32 @@ test_gdate_to_timespec (FixtureB *f, gconstpointer pData) gchar *logdomain = G_LOG_DOMAIN; TestErrorStruct check = {loglevel, logdomain, msg, 0}; GLogFunc hdlr = g_log_set_default_handler ((GLogFunc)test_null_handler, &check); - g_test_log_set_fatal_handler ((GTestLogFatalFunc)test_checked_handler, &check); - for (int i = 0; i < sizeof(f->test)/sizeof(TimeMap); ++i) + struct tm check_tz; + gnc_localtime_r(&(f->test[0].secs), &check_tz); + /* gdate_to_timespec returns the timespec for 10:59:00 Z + * for timezones in the range -11 to +13. If the timezone being + * tested is outside that range then the day of the month will be + * different from the one in the test fixture and we skip the + * test. + */ + if (check_tz.tm_mday == f->test[0].day) { - GDate gd, gd2; - Timespec r_t; - g_date_clear(&gd, 1); - g_date_clear(&gd2, 1); - g_date_set_dmy(&gd, f->test[i].day, f->test[i].mon, f->test[i].yr); - r_t = gdate_to_timespec(gd); - g_assert_cmpint (r_t.tv_sec, ==, f->test[i].secs); - if (f->test[i].secs < INT64_MAX) - { - gd2 = timespec_to_gdate(r_t); - g_assert (g_date_compare (&gd2, &gd) == 0); - } + g_test_log_set_fatal_handler ((GTestLogFatalFunc)test_checked_handler, &check); + for (int i = 0; i < sizeof(f->test)/sizeof(TimeMap); ++i) + { + GDate gd, gd2; + Timespec r_t; + g_date_clear(&gd, 1); + g_date_clear(&gd2, 1); + g_date_set_dmy(&gd, f->test[i].day, f->test[i].mon, f->test[i].yr); + r_t = gdate_to_timespec(gd); + g_assert_cmpint (r_t.tv_sec, ==, f->test[i].secs); + if (f->test[i].secs < INT64_MAX) + { + gd2 = timespec_to_gdate(r_t); + g_assert (g_date_compare (&gd2, &gd) == 0); + } + } } g_log_set_default_handler (hdlr, 0); }