home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 6 / AACD06.ISO / AACD / Programming / ICU / src / icu / source / test / intltest / tsdate.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1999-10-19  |  7.8 KB  |  269 lines

  1.  
  2. /*
  3. ********************************************************************
  4. * COPYRIGHT: 
  5. * (C) Copyright Taligent, Inc., 1997
  6. * (C) Copyright International Business Machines Corporation, 1997 - 1998
  7. * Licensed Material - Program-Property of IBM - All Rights Reserved. 
  8. * US Government Users Restricted Rights - Use, duplication, or disclosure 
  9. * restricted by GSA ADP Schedule Contract with IBM Corp. 
  10. *
  11. ********************************************************************
  12. */
  13.  
  14. #include "utypes.h"
  15. #include "tsdate.h"
  16.  
  17. #include "datefmt.h"
  18. #include "smpdtfmt.h"
  19.  
  20. #include <math.h>
  21.  
  22. const double IntlTestDateFormat::ONEYEAR = 365.25 * ONEDAY; // Approximate
  23.  
  24. /**
  25.  * This test does round-trip testing (format -> parse -> format -> parse -> etc.) of
  26.  * DateFormat.
  27.  */
  28. // par is ignored throughout this file
  29. void IntlTestDateFormat::runIndexedTest( int32_t index, bool_t exec, char* &name, char* par )
  30. {
  31.     if (exec) logln("TestSuite DateFormat");
  32.     switch (index) {
  33.         case 0: name = "Generic test (Default Locale)"; 
  34.             if (exec) {
  35.                 logln(name);
  36.                 fFormat = DateFormat::createInstance();
  37.                 fTestName = "createInstance";
  38.                 fLimit = 3;
  39.                 testFormat( par );
  40.             }
  41.             break;
  42.         case 1: name = "Default Locale";
  43.             if (exec) {
  44.                 logln(name);
  45.                 testLocale(par, Locale::getDefault(), "Default Locale");
  46.             }
  47.             break;
  48.  
  49.         case 2: name = "Determine Available Locales"; 
  50.             if (exec) {
  51.                 logln(name);
  52.                 testAvailableLocales(par);
  53.             }
  54.             break;
  55.  
  56.         case 3: name = "Test Available Locales"; 
  57.             if (exec) {
  58.                 logln(name);
  59.                 monsterTest(par);
  60.             }
  61.             break;
  62.  
  63.         default: name = ""; break;
  64.     }
  65. }
  66.  
  67. void
  68. IntlTestDateFormat::testLocale(char* par, const Locale& locale, const UnicodeString& localeName)
  69. {
  70.     DateFormat::EStyle timeStyle, dateStyle;
  71.     
  72.     // For patterns including only time information and a timezone, it may take
  73.     // up to three iterations, since the timezone may shift as the year number
  74.     // is determined.  For other patterns, 2 iterations should suffice.
  75.     fLimit = 3;
  76.  
  77.     for(timeStyle = (DateFormat::EStyle)0; 
  78.         timeStyle < (DateFormat::EStyle)4; 
  79.         timeStyle = (DateFormat::EStyle) (timeStyle+1))
  80.     {
  81.         fTestName = (UnicodeString) "Time test " + (int32_t) timeStyle + " (" + localeName + ")";
  82.         fFormat = DateFormat::createTimeInstance(timeStyle, locale);
  83.         testFormat(par);
  84.     }
  85.  
  86.     fLimit = 2;
  87.  
  88.     for(dateStyle = (DateFormat::EStyle)0; 
  89.         dateStyle < (DateFormat::EStyle)4; 
  90.         dateStyle = (DateFormat::EStyle) (dateStyle+1))
  91.     {
  92.         fTestName = (UnicodeString) "Date test " + (int32_t) dateStyle + " (" + localeName + ")";
  93.         fFormat = DateFormat::createDateInstance(dateStyle, locale);
  94.         testFormat(par);
  95.     }
  96.  
  97.     for(dateStyle = (DateFormat::EStyle)0; 
  98.         dateStyle < (DateFormat::EStyle)4; 
  99.         dateStyle = (DateFormat::EStyle) (dateStyle+1))
  100.     {
  101.         for(timeStyle = (DateFormat::EStyle)0; 
  102.             timeStyle < (DateFormat::EStyle)4; 
  103.             timeStyle = (DateFormat::EStyle) (timeStyle+1))
  104.         {
  105.             fTestName = (UnicodeString) "DateTime test " + (int32_t) dateStyle + "/" + (int32_t) timeStyle + " (" + localeName + ")";
  106.             fFormat = DateFormat::createDateTimeInstance(dateStyle, timeStyle, locale);
  107.             testFormat(par);
  108.         }
  109.     }
  110. }
  111.  
  112. void IntlTestDateFormat::testFormat(char *par)
  113. {
  114.     if (fFormat == 0)
  115.     {
  116.         errln("FAIL: DateFormat creation failed");
  117.         return;
  118.     }
  119.  
  120.     UDate now = Calendar::getNow();
  121.     tryDate(0);
  122.     tryDate(1278161801778.0);
  123.     tryDate(now);
  124.     // Shift 6 months into the future, AT THE SAME TIME OF DAY.
  125.     // This will test the DST handling.
  126.     tryDate(now + 6.0*30*ONEDAY);
  127.  
  128.     UDate limit = now * 10; // Arbitrary limit
  129.     for (int32_t i=0; i<2; ++i) tryDate(icu_floor(randDouble() * limit));
  130.  
  131.     delete fFormat;
  132. }
  133.  
  134. void
  135. IntlTestDateFormat::describeTest()
  136. {
  137.     // Assume it's a SimpleDateFormat and get some info
  138.     SimpleDateFormat *s = (SimpleDateFormat*)fFormat;
  139.     UnicodeString str;
  140.     logln(fTestName + " Pattern " + s->toPattern(str));
  141. }
  142.  
  143. void IntlTestDateFormat::tryDate(UDate theDate)
  144. {
  145.     const int32_t DEPTH = 10;
  146.     UDate date[DEPTH];
  147.     UnicodeString string[DEPTH];
  148.  
  149.     int32_t dateMatch = 0;
  150.     int32_t stringMatch = 0;
  151.     bool_t dump = FALSE;
  152.     int32_t i;
  153.     for (i=0; i<DEPTH; ++i)
  154.     {
  155.         UErrorCode status = U_ZERO_ERROR;
  156.         if (i == 0) date[i] = theDate;
  157.         else date[i] = fFormat->parse(string[i-1], status);
  158.         if (U_FAILURE(status))
  159.         {
  160.             describeTest();
  161.             errln("********** FAIL: Parse of " + string[i-1] + " failed.");
  162.             dump = TRUE;
  163.             break;
  164.         }
  165.         fFormat->format(date[i], string[i]);
  166.         if (i > 0)
  167.         {
  168.             if (dateMatch == 0 && date[i] == date[i-1]) dateMatch = i;
  169.             else if (dateMatch > 0 && date[i] != date[i-1])
  170.             {
  171.                 describeTest();
  172.                 errln("********** FAIL: Date mismatch after match.");
  173.                 dump = TRUE;
  174.                 break;
  175.             }
  176.             if (stringMatch == 0 && string[i] == string[i-1]) stringMatch = i;
  177.             else if (stringMatch > 0 && string[i] != string[i-1])
  178.             {
  179.                 describeTest();
  180.                 errln("********** FAIL: String mismatch after match.");
  181.                 dump = TRUE;
  182.                 break;
  183.             }
  184.         }
  185.         if (dateMatch > 0 && stringMatch > 0) break;
  186.     }
  187.     if (i == DEPTH) --i;
  188.  
  189.     if (stringMatch > fLimit || dateMatch > fLimit)
  190.     {
  191.         describeTest();
  192.         errln((UnicodeString)"********** FAIL: No string and/or date match within " + fLimit + " iterations.");
  193.         dump = TRUE;
  194.     }
  195.  
  196.     if (dump)
  197.     {
  198.         for (int32_t k=0; k<=i; ++k)
  199.         {
  200.             logln((UnicodeString)"" + k + ": " + date[k] + " F> " +
  201.                   string[k] + " P> ");
  202.         }
  203.     }
  204. }
  205.     
  206. // Return a random double from 0.01 to 1, inclusive
  207. double IntlTestDateFormat::randDouble()
  208. {
  209.     // Assume 8-bit (or larger) rand values.  Also assume
  210.     // that the system rand() function is very poor, which it always is.
  211.     double d;
  212.     int32_t i;
  213.     do {
  214.         for (i=0; i < sizeof(double); ++i)
  215.         {
  216.             char* poke = (char*)&d;
  217.             poke[i] = (rand() & 0xFF);
  218.         }
  219.     } while (icu_isNaN(d) || icu_isInfinite(d));
  220.  
  221.     if (d < 0.0) d = -d;
  222.     if (d > 0.0)
  223.     {
  224.         double e = icu_floor(icu_log10(d));
  225.         if (e < -2.0) d *= icu_pow10(-e-2);
  226.         else if (e > -1.0) d /= icu_pow10(e+1);
  227.     }
  228.     return d;
  229. }
  230.  
  231. void IntlTestDateFormat::testAvailableLocales(char *par)
  232. {
  233.     int32_t count = 0;
  234.     const Locale* locales = DateFormat::getAvailableLocales(count);
  235.     logln((UnicodeString)"" + count + " available locales");
  236.     if (locales && count)
  237.     {
  238.         UnicodeString name;
  239.         UnicodeString all;
  240.         for (int32_t i=0; i<count; ++i)
  241.         {
  242.             if (i!=0) all += ", ";
  243.             all += locales[i].getName(name);
  244.         }
  245.         logln(all);
  246.     }
  247.     else errln((UnicodeString)"********** FAIL: Zero available locales or null array pointer");
  248. }
  249.  
  250. void IntlTestDateFormat::monsterTest(char *par)
  251. {
  252.     int32_t count;
  253.     const Locale* locales = DateFormat::getAvailableLocales(count);
  254.     if (locales && count)
  255.     {
  256.         if (quick && count > 2) {
  257.             logln("quick test: testing just 2 locales!");
  258.             count = 2;
  259.         }
  260.         for (int32_t i=0; i<count; ++i)
  261.         {
  262.             UnicodeString name;
  263.             locales[i].getName(name);
  264.             logln((UnicodeString)"Testing " + name + "...");
  265.             testLocale(par, locales[i], name);
  266.         }
  267.     }
  268. }
  269.