Home | History | Annotate | Download | only in intltest
      1 /********************************************************************
      2  * Copyright (c) 2008-2012, International Business Machines Corporation and
      3  * others. All Rights Reserved.
      4  ********************************************************************/
      5 
      6 #include "unicode/utypes.h"
      7 
      8 #if !UCONFIG_NO_FORMATTING
      9 
     10 #include "unicode/tmunit.h"
     11 #include "unicode/tmutamt.h"
     12 #include "unicode/tmutfmt.h"
     13 #include "tufmtts.h"
     14 #include "unicode/ustring.h"
     15 
     16 //TODO: put as compilation flag
     17 //#define TUFMTTS_DEBUG 1
     18 
     19 #ifdef TUFMTTS_DEBUG
     20 #include <iostream>
     21 #endif
     22 
     23 void TimeUnitTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ ) {
     24     if (exec) logln("TestSuite TimeUnitTest");
     25     switch (index) {
     26         TESTCASE(0, testBasic);
     27         TESTCASE(1, testAPI);
     28         TESTCASE(2, testGreekWithFallback);
     29         TESTCASE(3, testGreekWithSanitization);
     30         default: name = ""; break;
     31     }
     32 }
     33 
     34 /**
     35  * Test basic
     36  */
     37 void TimeUnitTest::testBasic() {
     38     const char* locales[] = {"en", "sl", "fr", "zh", "ar", "ru", "zh_Hant", "pa"};
     39     for ( unsigned int locIndex = 0;
     40           locIndex < sizeof(locales)/sizeof(locales[0]);
     41           ++locIndex ) {
     42         UErrorCode status = U_ZERO_ERROR;
     43         Locale loc(locales[locIndex]);
     44         TimeUnitFormat** formats = new TimeUnitFormat*[2];
     45         formats[UTMUTFMT_FULL_STYLE] = new TimeUnitFormat(loc, status);
     46         if (!assertSuccess("TimeUnitFormat(full)", status, TRUE)) return;
     47         formats[UTMUTFMT_ABBREVIATED_STYLE] = new TimeUnitFormat(loc, UTMUTFMT_ABBREVIATED_STYLE, status);
     48         if (!assertSuccess("TimeUnitFormat(short)", status)) return;
     49 #ifdef TUFMTTS_DEBUG
     50         std::cout << "locale: " << locales[locIndex] << "\n";
     51 #endif
     52         for (int style = UTMUTFMT_FULL_STYLE;
     53              style <= UTMUTFMT_ABBREVIATED_STYLE;
     54              ++style) {
     55           for (TimeUnit::UTimeUnitFields j = TimeUnit::UTIMEUNIT_YEAR;
     56              j < TimeUnit::UTIMEUNIT_FIELD_COUNT;
     57              j = (TimeUnit::UTimeUnitFields)(j+1)) {
     58 #ifdef TUFMTTS_DEBUG
     59             std::cout << "time unit: " << j << "\n";
     60 #endif
     61             double tests[] = {0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 5, 10, 100, 101.35};
     62             for (unsigned int i = 0; i < sizeof(tests)/sizeof(tests[0]); ++i) {
     63 #ifdef TUFMTTS_DEBUG
     64                 std::cout << "number: " << tests[i] << "\n";
     65 #endif
     66                 TimeUnitAmount* source = new TimeUnitAmount(tests[i], j, status);
     67                 if (!assertSuccess("TimeUnitAmount()", status)) return;
     68                 UnicodeString formatted;
     69                 Formattable formattable;
     70                 formattable.adoptObject(source);
     71                 formatted = ((Format*)formats[style])->format(formattable, formatted, status);
     72                 if (!assertSuccess("format()", status)) return;
     73 #ifdef TUFMTTS_DEBUG
     74                 char formatResult[1000];
     75                 formatted.extract(0, formatted.length(), formatResult, "UTF-8");
     76                 std::cout << "format result: " << formatResult << "\n";
     77 #endif
     78                 Formattable result;
     79                 ((Format*)formats[style])->parseObject(formatted, result, status);
     80                 if (!assertSuccess("parseObject()", status)) return;
     81                 if (result != formattable) {
     82                     dataerrln("No round trip: ");
     83                 }
     84                 // other style parsing
     85                 Formattable result_1;
     86                 ((Format*)formats[1-style])->parseObject(formatted, result_1, status);
     87                 if (!assertSuccess("parseObject()", status)) return;
     88                 if (result_1 != formattable) {
     89                     dataerrln("No round trip: ");
     90                 }
     91             }
     92           }
     93         }
     94         delete formats[UTMUTFMT_FULL_STYLE];
     95         delete formats[UTMUTFMT_ABBREVIATED_STYLE];
     96         delete[] formats;
     97     }
     98 }
     99 
    100 
    101 void TimeUnitTest::testAPI() {
    102     //================= TimeUnit =================
    103     UErrorCode status = U_ZERO_ERROR;
    104 
    105     TimeUnit* tmunit = TimeUnit::createInstance(TimeUnit::UTIMEUNIT_YEAR, status);
    106     if (!assertSuccess("TimeUnit::createInstance", status)) return;
    107 
    108     TimeUnit* another = (TimeUnit*)tmunit->clone();
    109     TimeUnit third(*tmunit);
    110     TimeUnit fourth = third;
    111 
    112     assertTrue("orig and clone are equal", (*tmunit == *another));
    113     assertTrue("copied and assigned are equal", (third == fourth));
    114 
    115     TimeUnit* tmunit_m = TimeUnit::createInstance(TimeUnit::UTIMEUNIT_MONTH, status);
    116     assertTrue("year != month", (*tmunit != *tmunit_m));
    117 
    118     TimeUnit::UTimeUnitFields field = tmunit_m->getTimeUnitField();
    119     assertTrue("field of month time unit is month", (field == TimeUnit::UTIMEUNIT_MONTH));
    120 
    121     delete tmunit;
    122     delete another;
    123     delete tmunit_m;
    124     //
    125     //================= TimeUnitAmount =================
    126 
    127     Formattable formattable((int32_t)2);
    128     TimeUnitAmount tma_long(formattable, TimeUnit::UTIMEUNIT_DAY, status);
    129     if (!assertSuccess("TimeUnitAmount(formattable...)", status)) return;
    130 
    131     formattable.setDouble(2);
    132     TimeUnitAmount tma_double(formattable, TimeUnit::UTIMEUNIT_DAY, status);
    133     if (!assertSuccess("TimeUnitAmount(formattable...)", status)) return;
    134 
    135     formattable.setDouble(3);
    136     TimeUnitAmount tma_double_3(formattable, TimeUnit::UTIMEUNIT_DAY, status);
    137     if (!assertSuccess("TimeUnitAmount(formattable...)", status)) return;
    138 
    139     TimeUnitAmount tma(2, TimeUnit::UTIMEUNIT_DAY, status);
    140     if (!assertSuccess("TimeUnitAmount(number...)", status)) return;
    141 
    142     TimeUnitAmount tma_h(2, TimeUnit::UTIMEUNIT_HOUR, status);
    143     if (!assertSuccess("TimeUnitAmount(number...)", status)) return;
    144 
    145     TimeUnitAmount second(tma);
    146     TimeUnitAmount third_tma = tma;
    147     TimeUnitAmount* fourth_tma = (TimeUnitAmount*)tma.clone();
    148 
    149     assertTrue("orig and copy are equal", (second == tma));
    150     assertTrue("clone and assigned are equal", (third_tma == *fourth_tma));
    151     assertTrue("different if number diff", (tma_double != tma_double_3));
    152     assertTrue("different if number type diff", (tma_double != tma_long));
    153     assertTrue("different if time unit diff", (tma != tma_h));
    154     assertTrue("same even different constructor", (tma_double == tma));
    155 
    156     assertTrue("getTimeUnitField", (tma.getTimeUnitField() == TimeUnit::UTIMEUNIT_DAY));
    157     delete fourth_tma;
    158     //
    159     //================= TimeUnitFormat =================
    160     //
    161     TimeUnitFormat* tmf_en = new TimeUnitFormat(Locale("en"), status);
    162     if (!assertSuccess("TimeUnitFormat(en...)", status, TRUE)) return;
    163     TimeUnitFormat tmf_fr(Locale("fr"), status);
    164     if (!assertSuccess("TimeUnitFormat(fr...)", status)) return;
    165 
    166     assertTrue("TimeUnitFormat: en and fr diff", (*tmf_en != tmf_fr));
    167 
    168     TimeUnitFormat tmf_assign = *tmf_en;
    169     assertTrue("TimeUnitFormat: orig and assign are equal", (*tmf_en == tmf_assign));
    170 
    171     TimeUnitFormat tmf_copy(tmf_fr);
    172     assertTrue("TimeUnitFormat: orig and copy are equal", (tmf_fr == tmf_copy));
    173 
    174     TimeUnitFormat* tmf_clone = (TimeUnitFormat*)tmf_en->clone();
    175     assertTrue("TimeUnitFormat: orig and clone are equal", (*tmf_en == *tmf_clone));
    176     delete tmf_clone;
    177 
    178     tmf_en->setLocale(Locale("fr"), status);
    179     if (!assertSuccess("setLocale(fr...)", status)) return;
    180 
    181     NumberFormat* numberFmt = NumberFormat::createInstance(
    182                                  Locale("fr"), status);
    183     if (!assertSuccess("NumberFormat::createInstance()", status)) return;
    184     tmf_en->setNumberFormat(*numberFmt, status);
    185     if (!assertSuccess("setNumberFormat(en...)", status)) return;
    186     assertTrue("TimeUnitFormat: setLocale", (*tmf_en == tmf_fr));
    187 
    188     delete tmf_en;
    189 
    190     TimeUnitFormat* en_long = new TimeUnitFormat(Locale("en"), UTMUTFMT_FULL_STYLE, status);
    191     if (!assertSuccess("TimeUnitFormat(en...)", status)) return;
    192     delete en_long;
    193 
    194     TimeUnitFormat* en_short = new TimeUnitFormat(Locale("en"), UTMUTFMT_ABBREVIATED_STYLE, status);
    195     if (!assertSuccess("TimeUnitFormat(en...)", status)) return;
    196     delete en_short;
    197 
    198     TimeUnitFormat* format = new TimeUnitFormat(status);
    199     format->setLocale(Locale("zh"), status);
    200     format->setNumberFormat(*numberFmt, status);
    201     if (!assertSuccess("TimeUnitFormat(en...)", status)) return;
    202     delete numberFmt;
    203     delete format;
    204 }
    205 
    206 /* @bug 7902
    207  * Tests for Greek Language.
    208  * This tests that requests for short unit names correctly fall back
    209  * to long unit names for a locale where the locale data does not
    210  * provide short unit names. As of CLDR 1.9, Greek is one such language.
    211  */
    212 void TimeUnitTest::testGreekWithFallback() {
    213     UErrorCode status = U_ZERO_ERROR;
    214 
    215     const char* locales[] = {"el-GR", "el"};
    216     TimeUnit::UTimeUnitFields tunits[] = {TimeUnit::UTIMEUNIT_SECOND, TimeUnit::UTIMEUNIT_MINUTE, TimeUnit::UTIMEUNIT_HOUR, TimeUnit::UTIMEUNIT_DAY, TimeUnit::UTIMEUNIT_MONTH, TimeUnit::UTIMEUNIT_YEAR};
    217     UTimeUnitFormatStyle styles[] = {UTMUTFMT_FULL_STYLE, UTMUTFMT_ABBREVIATED_STYLE};
    218     const int numbers[] = {1, 7};
    219 
    220     const UChar oneSecond[] = {0x0031, 0x0020, 0x03b4, 0x03b5, 0x03c5, 0x03c4, 0x03b5, 0x03c1, 0x03cc, 0x03bb, 0x03b5, 0x03c0, 0x03c4, 0x03bf, 0};
    221     const UChar oneMinute[] = {0x0031, 0x0020, 0x03bb, 0x03b5, 0x03c0, 0x03c4, 0x03cc, 0};
    222     const UChar oneHour[] = {0x0031, 0x0020, 0x03ce, 0x03c1, 0x03b1, 0};
    223     const UChar oneDay[] = {0x0031, 0x0020, 0x03b7, 0x03bc, 0x03ad, 0x03c1, 0x03b1, 0};
    224     const UChar oneMonth[] = {0x0031, 0x0020, 0x03bc, 0x03ae, 0x03bd, 0x03b1, 0x03c2, 0};
    225     const UChar oneYear[] = {0x0031, 0x0020, 0x03ad, 0x03c4, 0x03bf, 0x03c2, 0};
    226     const UChar sevenSeconds[] = {0x0037, 0x0020, 0x03b4, 0x03b5, 0x03c5, 0x03c4, 0x03b5, 0x03c1, 0x03cc, 0x03bb, 0x03b5, 0x03c0, 0x03c4, 0x03b1, 0};
    227     const UChar sevenMinutes[] = {0x0037, 0x0020, 0x03bb, 0x03b5, 0x03c0, 0x03c4, 0x03ac, 0};
    228     const UChar sevenHours[] = {0x0037, 0x0020, 0x03ce, 0x03c1, 0x03b5, 0x03c2, 0};
    229     const UChar sevenDays[] = {0x0037, 0x0020, 0x03b7, 0x03bc, 0x03ad, 0x03c1, 0x03b5, 0x03c2, 0};
    230     const UChar sevenMonths[] = {0x0037, 0x0020, 0x03bc, 0x03ae, 0x03bd, 0x03b5, 0x3c2, 0};
    231     const UChar sevenYears[] = {0x0037, 0x0020, 0x03ad, 0x03c4, 0x03b7, 0};
    232 
    233     const UnicodeString oneSecondStr(oneSecond);
    234     const UnicodeString oneMinuteStr(oneMinute);
    235     const UnicodeString oneHourStr(oneHour);
    236     const UnicodeString oneDayStr(oneDay);
    237     const UnicodeString oneMonthStr(oneMonth);
    238     const UnicodeString oneYearStr(oneYear);
    239     const UnicodeString sevenSecondsStr(sevenSeconds);
    240     const UnicodeString sevenMinutesStr(sevenMinutes);
    241     const UnicodeString sevenHoursStr(sevenHours);
    242     const UnicodeString sevenDaysStr(sevenDays);
    243     const UnicodeString sevenMonthsStr(sevenMonths);
    244     const UnicodeString sevenYearsStr(sevenYears);
    245 
    246     const UnicodeString expected[] = {oneSecondStr, oneMinuteStr, oneHourStr, oneDayStr, oneMonthStr, oneYearStr,
    247                               oneSecondStr, oneMinuteStr, oneHourStr, oneDayStr, oneMonthStr, oneYearStr,
    248                               sevenSecondsStr, sevenMinutesStr, sevenHoursStr, sevenDaysStr, sevenMonthsStr, sevenYearsStr,
    249                               sevenSecondsStr, sevenMinutesStr, sevenHoursStr, sevenDaysStr, sevenMonthsStr, sevenYearsStr,
    250                               oneSecondStr, oneMinuteStr, oneHourStr, oneDayStr, oneMonthStr, oneYearStr,
    251                               oneSecondStr, oneMinuteStr, oneHourStr, oneDayStr, oneMonthStr, oneYearStr,
    252                               sevenSecondsStr, sevenMinutesStr, sevenHoursStr, sevenDaysStr, sevenMonthsStr, sevenYearsStr,
    253                               sevenSecondsStr, sevenMinutesStr, sevenHoursStr, sevenDaysStr, sevenMonthsStr, sevenYearsStr};
    254 
    255     int counter = 0;
    256     for ( unsigned int locIndex = 0;
    257         locIndex < sizeof(locales)/sizeof(locales[0]);
    258         ++locIndex ) {
    259 
    260         Locale l = Locale::createFromName(locales[locIndex]);
    261 
    262         for ( unsigned int numberIndex = 0;
    263             numberIndex < sizeof(numbers)/sizeof(int);
    264             ++numberIndex ) {
    265 
    266             for ( unsigned int styleIndex = 0;
    267                 styleIndex < sizeof(styles)/sizeof(styles[0]);
    268                 ++styleIndex ) {
    269 
    270                 for ( unsigned int unitIndex = 0;
    271                     unitIndex < sizeof(tunits)/sizeof(tunits[0]);
    272                     ++unitIndex ) {
    273 
    274                     TimeUnitAmount *tamt = new TimeUnitAmount(numbers[numberIndex], tunits[unitIndex], status);
    275                     if (U_FAILURE(status)) {
    276                         dataerrln("generating TimeUnitAmount Object failed.");
    277 #ifdef TUFMTTS_DEBUG
    278                         std::cout << "Failed to get TimeUnitAmount for " << tunits[unitIndex] << "\n";
    279 #endif
    280                         return;
    281                     }
    282 
    283                     TimeUnitFormat *tfmt = new TimeUnitFormat(l, styles[styleIndex], status);
    284                     if (U_FAILURE(status)) {
    285                         dataerrln("generating TimeUnitAmount Object failed.");
    286 #ifdef TUFMTTS_DEBUG
    287                        std::cout <<  "Failed to get TimeUnitFormat for " << locales[locIndex] << "\n";
    288 #endif
    289                        return;
    290                     }
    291 
    292                     Formattable fmt;
    293                     UnicodeString str;
    294 
    295                     fmt.adoptObject(tamt);
    296                     str = ((Format *)tfmt)->format(fmt, str, status);
    297                     if (!assertSuccess("formatting relative time failed", status)) {
    298                         delete tfmt;
    299 #ifdef TUFMTTS_DEBUG
    300                         std::cout <<  "Failed to format" << "\n";
    301 #endif
    302                         return;
    303                     }
    304 
    305 #ifdef TUFMTTS_DEBUG
    306                     char tmp[128];    //output
    307                     char tmp1[128];    //expected
    308                     int len = 0;
    309                     u_strToUTF8(tmp, 128, &len, str.getTerminatedBuffer(), str.length(), &status);
    310                     u_strToUTF8(tmp1, 128, &len, expected[counter].unescape().getTerminatedBuffer(), expected[counter].unescape().length(), &status);
    311                     std::cout <<  "Formatted string : " << tmp << " expected : " << tmp1 << "\n";
    312 #endif
    313                     if (!assertEquals("formatted time string is not expected, locale: " + UnicodeString(locales[locIndex]) + " style: " + (int)styles[styleIndex] + " units: " + (int)tunits[unitIndex], expected[counter], str)) {
    314                         delete tfmt;
    315                         str.remove();
    316                         return;
    317                     }
    318                     delete tfmt;
    319                     str.remove();
    320                     ++counter;
    321                 }
    322             }
    323         }
    324     }
    325 }
    326 
    327 // Test bug9042
    328 void TimeUnitTest::testGreekWithSanitization() {
    329 
    330     UErrorCode status = U_ZERO_ERROR;
    331     Locale elLoc("el");
    332     NumberFormat* numberFmt = NumberFormat::createInstance(Locale("el"), status);
    333     if (!assertSuccess("NumberFormat::createInstance for el locale", status, TRUE)) return;
    334     numberFmt->setMaximumFractionDigits(1);
    335 
    336     TimeUnitFormat* timeUnitFormat = new TimeUnitFormat(elLoc, status);
    337     if (!assertSuccess("TimeUnitFormat::TimeUnitFormat for el locale", status)) return;
    338 
    339     timeUnitFormat->setNumberFormat(*numberFmt, status);
    340 
    341     delete numberFmt;
    342     delete timeUnitFormat;
    343 }
    344 
    345 
    346 #endif
    347