Index: icu46/source/test/intltest/tsdate.cpp |
=================================================================== |
--- icu46/source/test/intltest/tsdate.cpp (revision 0) |
+++ icu46/source/test/intltest/tsdate.cpp (revision 0) |
@@ -0,0 +1,288 @@ |
+/*********************************************************************** |
+ * Copyright (c) 1997-2009, International Business Machines Corporation |
+ * and others. All Rights Reserved. |
+ ***********************************************************************/ |
+ |
+#include "unicode/utypes.h" |
+ |
+#if !UCONFIG_NO_FORMATTING |
+ |
+#include "unicode/datefmt.h" |
+#include "unicode/smpdtfmt.h" |
+#include "tsdate.h" |
+#include "putilimp.h" |
+ |
+#include <float.h> |
+#include <stdlib.h> |
+#include <math.h> |
+ |
+const double IntlTestDateFormat::ONEYEAR = 365.25 * ONEDAY; // Approximate |
+ |
+IntlTestDateFormat::~IntlTestDateFormat() {} |
+ |
+/** |
+ * 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, UBool exec, const char* &name, char* /*par*/ ) |
+{ |
+ if (exec) logln("TestSuite DateFormat"); |
+ switch (index) { |
+ case 0: name = "GenericTest"; |
+ if (exec) { |
+ logln(name); |
+ fFormat = DateFormat::createInstance(); |
+ fTestName = "createInstance"; |
+ fLimit = 3; |
+ testFormat(/* par */); |
+ } |
+ break; |
+ case 1: name = "DefaultLocale"; |
+ if (exec) { |
+ logln(name); |
+ testLocale(/*par, */Locale::getDefault(), "Default Locale"); |
+ } |
+ break; |
+ |
+ case 2: name = "TestAvailableLocales"; |
+ if (exec) { |
+ logln(name); |
+ testAvailableLocales(/* par */); |
+ } |
+ break; |
+ |
+ case 3: name = "MonsterTest"; |
+ 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) |
+ { |
+ dataerrln("FAIL: DateFormat creation failed"); |
+ return; |
+ } |
+ |
+ describeTest(); |
+ |
+ UDate now = Calendar::getNow(); |
+ tryDate(0); |
+ tryDate(1278161801778.0); |
+ tryDate(5264498352317.0); // Sunday, October 28, 2136 8:39:12 AM PST |
+ tryDate(9516987689250.0); // In the year 2271 |
+ 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<3; ++i) |
+ tryDate(uprv_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; |
+ UBool dump = FALSE; |
+#if defined (U_CAL_DEBUG) |
+ dump = TRUE; |
+#endif |
+ int32_t i; |
+ |
+ date[0] = theDate; |
+ fFormat->format(theDate, string[0]); |
+ |
+ for (i=1; i<DEPTH; ++i) |
+ { |
+ UErrorCode status = U_ZERO_ERROR; |
+ date[i] = fFormat->parse(string[i-1], status); |
+ if (U_FAILURE(status)) |
+ { |
+ describeTest(); |
+ errln("**** FAIL: Parse of " + prettify(string[i-1], FALSE) + " failed."); |
+ dump = TRUE; |
+ break; |
+ } |
+ fFormat->format(date[i], string[i]); |
+ 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 for " + string[i]); |
+ 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 for " + string[i]); |
+ 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 for the Date " + string[0] + "\t(" + theDate + ")."); |
+ 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=0.0; |
+ uint32_t i; |
+ char* poke = (char*)&d; |
+ do { |
+ do { |
+ for (i=0; i < sizeof(double); ++i) |
+ { |
+ poke[i] = (char)(rand() & 0xFF); |
+ } |
+ } while (uprv_isNaN(d) || uprv_isInfinite(d)); |
+ |
+ if (d < 0.0) |
+ d = -d; |
+ if (d > 0.0) |
+ { |
+ double e = uprv_floor(log10(d)); |
+ if (e < -2.0) |
+ d *= uprv_pow10((int32_t)(-e-2)); |
+ else if (e > -1.0) |
+ d /= uprv_pow10((int32_t)(e+1)); |
+ } |
+ // While this is not a real normalized number make another one. |
+ } while (uprv_isNaN(d) || uprv_isInfinite(d) |
+ || !((-DBL_MAX < d && d < DBL_MAX) || (d < -DBL_MIN && DBL_MIN < d))); |
+ 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(); |
+ } |
+ logln(all); |
+ } |
+ else dataerrln((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 > 3) { |
+ logln("quick test: testing just 3 locales!"); |
+ count = 3; |
+ } |
+ for (int32_t i=0; i<count; ++i) |
+ { |
+ UnicodeString name = UnicodeString(locales[i].getName(), ""); |
+ logln((UnicodeString)"Testing " + name + "..."); |
+ testLocale(/*par, */locales[i], name); |
+ } |
+ } |
+} |
+ |
+#endif /* #if !UCONFIG_NO_FORMATTING */ |
Property changes on: icu46/source/test/intltest/tsdate.cpp |
___________________________________________________________________ |
Added: svn:eol-style |
+ LF |