home *** CD-ROM | disk | FTP | other *** search
-
- /*
- ********************************************************************
- * COPYRIGHT:
- * (C) Copyright Taligent, Inc., 1997
- * (C) Copyright International Business Machines Corporation, 1997 - 1998
- * Licensed Material - Program-Property of IBM - All Rights Reserved.
- * US Government Users Restricted Rights - Use, duplication, or disclosure
- * restricted by GSA ADP Schedule Contract with IBM Corp.
- *
- ********************************************************************
- */
-
- #include "utypes.h"
- #include "tsdate.h"
-
- #include "datefmt.h"
- #include "smpdtfmt.h"
-
- #include <math.h>
-
- const double IntlTestDateFormat::ONEYEAR = 365.25 * ONEDAY; // Approximate
-
- /**
- * This test does round-trip testing (format -> parse -> format -> parse -> etc.) of
- * DateFormat.
- */
- // par is ignored throughout this file
- void IntlTestDateFormat::runIndexedTest( int32_t index, bool_t exec, char* &name, char* par )
- {
- if (exec) logln("TestSuite DateFormat");
- switch (index) {
- case 0: name = "Generic test (Default Locale)";
- if (exec) {
- logln(name);
- fFormat = DateFormat::createInstance();
- fTestName = "createInstance";
- fLimit = 3;
- testFormat( par );
- }
- break;
- case 1: name = "Default Locale";
- if (exec) {
- logln(name);
- testLocale(par, Locale::getDefault(), "Default Locale");
- }
- break;
-
- case 2: name = "Determine Available Locales";
- if (exec) {
- logln(name);
- testAvailableLocales(par);
- }
- break;
-
- case 3: name = "Test Available Locales";
- if (exec) {
- logln(name);
- monsterTest(par);
- }
- break;
-
- default: name = ""; break;
- }
- }
-
- void
- IntlTestDateFormat::testLocale(char* par, const Locale& locale, const UnicodeString& localeName)
- {
- DateFormat::EStyle timeStyle, dateStyle;
-
- // For patterns including only time information and a timezone, it may take
- // up to three iterations, since the timezone may shift as the year number
- // is determined. For other patterns, 2 iterations should suffice.
- fLimit = 3;
-
- for(timeStyle = (DateFormat::EStyle)0;
- timeStyle < (DateFormat::EStyle)4;
- timeStyle = (DateFormat::EStyle) (timeStyle+1))
- {
- fTestName = (UnicodeString) "Time test " + (int32_t) timeStyle + " (" + localeName + ")";
- fFormat = DateFormat::createTimeInstance(timeStyle, locale);
- testFormat(par);
- }
-
- fLimit = 2;
-
- for(dateStyle = (DateFormat::EStyle)0;
- dateStyle < (DateFormat::EStyle)4;
- dateStyle = (DateFormat::EStyle) (dateStyle+1))
- {
- fTestName = (UnicodeString) "Date test " + (int32_t) dateStyle + " (" + localeName + ")";
- fFormat = DateFormat::createDateInstance(dateStyle, locale);
- testFormat(par);
- }
-
- for(dateStyle = (DateFormat::EStyle)0;
- dateStyle < (DateFormat::EStyle)4;
- dateStyle = (DateFormat::EStyle) (dateStyle+1))
- {
- for(timeStyle = (DateFormat::EStyle)0;
- timeStyle < (DateFormat::EStyle)4;
- timeStyle = (DateFormat::EStyle) (timeStyle+1))
- {
- fTestName = (UnicodeString) "DateTime test " + (int32_t) dateStyle + "/" + (int32_t) timeStyle + " (" + localeName + ")";
- fFormat = DateFormat::createDateTimeInstance(dateStyle, timeStyle, locale);
- testFormat(par);
- }
- }
- }
-
- void IntlTestDateFormat::testFormat(char *par)
- {
- if (fFormat == 0)
- {
- errln("FAIL: DateFormat creation failed");
- return;
- }
-
- UDate now = Calendar::getNow();
- tryDate(0);
- tryDate(1278161801778.0);
- tryDate(now);
- // Shift 6 months into the future, AT THE SAME TIME OF DAY.
- // This will test the DST handling.
- tryDate(now + 6.0*30*ONEDAY);
-
- UDate limit = now * 10; // Arbitrary limit
- for (int32_t i=0; i<2; ++i) tryDate(icu_floor(randDouble() * limit));
-
- delete fFormat;
- }
-
- void
- IntlTestDateFormat::describeTest()
- {
- // Assume it's a SimpleDateFormat and get some info
- SimpleDateFormat *s = (SimpleDateFormat*)fFormat;
- UnicodeString str;
- logln(fTestName + " Pattern " + s->toPattern(str));
- }
-
- void IntlTestDateFormat::tryDate(UDate theDate)
- {
- const int32_t DEPTH = 10;
- UDate date[DEPTH];
- UnicodeString string[DEPTH];
-
- int32_t dateMatch = 0;
- int32_t stringMatch = 0;
- bool_t dump = FALSE;
- int32_t i;
- for (i=0; i<DEPTH; ++i)
- {
- UErrorCode status = U_ZERO_ERROR;
- if (i == 0) date[i] = theDate;
- else date[i] = fFormat->parse(string[i-1], status);
- if (U_FAILURE(status))
- {
- describeTest();
- errln("********** FAIL: Parse of " + string[i-1] + " failed.");
- dump = TRUE;
- break;
- }
- fFormat->format(date[i], string[i]);
- if (i > 0)
- {
- if (dateMatch == 0 && date[i] == date[i-1]) dateMatch = i;
- else if (dateMatch > 0 && date[i] != date[i-1])
- {
- describeTest();
- errln("********** FAIL: Date mismatch after match.");
- dump = TRUE;
- break;
- }
- if (stringMatch == 0 && string[i] == string[i-1]) stringMatch = i;
- else if (stringMatch > 0 && string[i] != string[i-1])
- {
- describeTest();
- errln("********** FAIL: String mismatch after match.");
- dump = TRUE;
- break;
- }
- }
- if (dateMatch > 0 && stringMatch > 0) break;
- }
- if (i == DEPTH) --i;
-
- if (stringMatch > fLimit || dateMatch > fLimit)
- {
- describeTest();
- errln((UnicodeString)"********** FAIL: No string and/or date match within " + fLimit + " iterations.");
- dump = TRUE;
- }
-
- if (dump)
- {
- for (int32_t k=0; k<=i; ++k)
- {
- logln((UnicodeString)"" + k + ": " + date[k] + " F> " +
- string[k] + " P> ");
- }
- }
- }
-
- // Return a random double from 0.01 to 1, inclusive
- double IntlTestDateFormat::randDouble()
- {
- // Assume 8-bit (or larger) rand values. Also assume
- // that the system rand() function is very poor, which it always is.
- double d;
- int32_t i;
- do {
- for (i=0; i < sizeof(double); ++i)
- {
- char* poke = (char*)&d;
- poke[i] = (rand() & 0xFF);
- }
- } while (icu_isNaN(d) || icu_isInfinite(d));
-
- if (d < 0.0) d = -d;
- if (d > 0.0)
- {
- double e = icu_floor(icu_log10(d));
- if (e < -2.0) d *= icu_pow10(-e-2);
- else if (e > -1.0) d /= icu_pow10(e+1);
- }
- return d;
- }
-
- void IntlTestDateFormat::testAvailableLocales(char *par)
- {
- int32_t count = 0;
- const Locale* locales = DateFormat::getAvailableLocales(count);
- logln((UnicodeString)"" + count + " available locales");
- if (locales && count)
- {
- UnicodeString name;
- UnicodeString all;
- for (int32_t i=0; i<count; ++i)
- {
- if (i!=0) all += ", ";
- all += locales[i].getName(name);
- }
- logln(all);
- }
- else errln((UnicodeString)"********** FAIL: Zero available locales or null array pointer");
- }
-
- void IntlTestDateFormat::monsterTest(char *par)
- {
- int32_t count;
- const Locale* locales = DateFormat::getAvailableLocales(count);
- if (locales && count)
- {
- if (quick && count > 2) {
- logln("quick test: testing just 2 locales!");
- count = 2;
- }
- for (int32_t i=0; i<count; ++i)
- {
- UnicodeString name;
- locales[i].getName(name);
- logln((UnicodeString)"Testing " + name + "...");
- testLocale(par, locales[i], name);
- }
- }
- }
-