Home | History | Annotate | Download | only in intltest
      1 /********************************************************************
      2  * Copyright (c) 2008-2013, 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 oneSecondShort[] = {0x0031, 0x0020, 0x03b4, 0x03b5, 0x03c5, 0x03c4, 0x002e, 0};
    222     const UChar oneMinute[] = {0x0031, 0x0020, 0x03bb, 0x03b5, 0x03c0, 0x03c4, 0x03cc, 0};
    223     const UChar oneMinuteShort[] = {0x0031, 0x0020, 0x03bb, 0x03b5, 0x03c0, 0x002e, 0};
    224     const UChar oneHour[] = {0x0031, 0x0020, 0x03ce, 0x03c1, 0x03b1, 0};
    225     const UChar oneDay[] = {0x0031, 0x0020, 0x03b7, 0x03bc, 0x03ad, 0x03c1, 0x03b1, 0};
    226     const UChar oneMonth[] = {0x0031, 0x0020, 0x03bc, 0x03ae, 0x03bd, 0x03b1, 0x03c2, 0};
    227     const UChar oneMonthShort[] = {0x0031, 0x0020, 0x03bc, 0x03ae, 0x03bd, 0x002e, 0};
    228     const UChar oneYear[] = {0x0031, 0x0020, 0x03ad, 0x03c4, 0x03bf, 0x03c2, 0};
    229     const UChar sevenSeconds[] = {0x0037, 0x0020, 0x03b4, 0x03b5, 0x03c5, 0x03c4, 0x03b5, 0x03c1, 0x03cc, 0x03bb, 0x03b5, 0x03c0, 0x03c4, 0x03b1, 0};
    230     const UChar sevenSecondsShort[] = {0x0037, 0x0020, 0x03b4, 0x03b5, 0x03c5, 0x03c4, 0x002e, 0};
    231     const UChar sevenMinutes[] = {0x0037, 0x0020, 0x03bb, 0x03b5, 0x03c0, 0x03c4, 0x03ac, 0};
    232     const UChar sevenMinutesShort[] = {0x0037, 0x0020, 0x03bb, 0x03b5, 0x03c0, 0x002e, 0};
    233     const UChar sevenHours[] = {0x0037, 0x0020, 0x03ce, 0x03c1, 0x03b5, 0x03c2, 0};
    234     const UChar sevenDays[] = {0x0037, 0x0020, 0x03b7, 0x03bc, 0x03ad, 0x03c1, 0x03b5, 0x03c2, 0};
    235     const UChar sevenMonths[] = {0x0037, 0x0020, 0x03bc, 0x03ae, 0x03bd, 0x03b5, 0x3c2, 0};
    236     const UChar sevenMonthsShort[] = {0x0037, 0x0020, 0x03bc, 0x03ae, 0x03bd, 0x002e, 0};
    237     const UChar sevenYears[] = {0x0037, 0x0020, 0x03ad, 0x03c4, 0x03b7, 0};
    238 
    239     const UnicodeString oneSecondStr(oneSecond);
    240     const UnicodeString oneSecondShortStr(oneSecondShort);
    241     const UnicodeString oneMinuteStr(oneMinute);
    242     const UnicodeString oneMinuteShortStr(oneMinuteShort);
    243     const UnicodeString oneHourStr(oneHour);
    244     const UnicodeString oneDayStr(oneDay);
    245     const UnicodeString oneMonthStr(oneMonth);
    246     const UnicodeString oneMonthShortStr(oneMonthShort);
    247     const UnicodeString oneYearStr(oneYear);
    248     const UnicodeString sevenSecondsStr(sevenSeconds);
    249     const UnicodeString sevenSecondsShortStr(sevenSecondsShort);
    250     const UnicodeString sevenMinutesStr(sevenMinutes);
    251     const UnicodeString sevenMinutesShortStr(sevenMinutesShort);
    252     const UnicodeString sevenHoursStr(sevenHours);
    253     const UnicodeString sevenDaysStr(sevenDays);
    254     const UnicodeString sevenMonthsStr(sevenMonths);
    255     const UnicodeString sevenMonthsShortStr(sevenMonthsShort);
    256     const UnicodeString sevenYearsStr(sevenYears);
    257 
    258     const UnicodeString expected[] = {oneSecondStr, oneMinuteStr, oneHourStr, oneDayStr, oneMonthStr, oneYearStr,
    259                               oneSecondShortStr, oneMinuteShortStr, oneHourStr, oneDayStr, oneMonthShortStr, oneYearStr,
    260                               sevenSecondsStr, sevenMinutesStr, sevenHoursStr, sevenDaysStr, sevenMonthsStr, sevenYearsStr,
    261                               sevenSecondsShortStr, sevenMinutesShortStr, sevenHoursStr, sevenDaysStr, sevenMonthsShortStr, sevenYearsStr,
    262                               oneSecondStr, oneMinuteStr, oneHourStr, oneDayStr, oneMonthStr, oneYearStr,
    263                               oneSecondShortStr, oneMinuteShortStr, oneHourStr, oneDayStr, oneMonthShortStr, oneYearStr,
    264                               sevenSecondsStr, sevenMinutesStr, sevenHoursStr, sevenDaysStr, sevenMonthsStr, sevenYearsStr,
    265                               sevenSecondsShortStr, sevenMinutesShortStr, sevenHoursStr, sevenDaysStr, sevenMonthsShortStr, sevenYearsStr};
    266 
    267     int counter = 0;
    268     for ( unsigned int locIndex = 0;
    269         locIndex < sizeof(locales)/sizeof(locales[0]);
    270         ++locIndex ) {
    271 
    272         Locale l = Locale::createFromName(locales[locIndex]);
    273 
    274         for ( unsigned int numberIndex = 0;
    275             numberIndex < sizeof(numbers)/sizeof(int);
    276             ++numberIndex ) {
    277 
    278             for ( unsigned int styleIndex = 0;
    279                 styleIndex < sizeof(styles)/sizeof(styles[0]);
    280                 ++styleIndex ) {
    281 
    282                 for ( unsigned int unitIndex = 0;
    283                     unitIndex < sizeof(tunits)/sizeof(tunits[0]);
    284                     ++unitIndex ) {
    285 
    286                     TimeUnitAmount *tamt = new TimeUnitAmount(numbers[numberIndex], tunits[unitIndex], status);
    287                     if (U_FAILURE(status)) {
    288                         dataerrln("generating TimeUnitAmount Object failed.");
    289 #ifdef TUFMTTS_DEBUG
    290                         std::cout << "Failed to get TimeUnitAmount for " << tunits[unitIndex] << "\n";
    291 #endif
    292                         return;
    293                     }
    294 
    295                     TimeUnitFormat *tfmt = new TimeUnitFormat(l, styles[styleIndex], status);
    296                     if (U_FAILURE(status)) {
    297                         dataerrln("generating TimeUnitAmount Object failed.");
    298 #ifdef TUFMTTS_DEBUG
    299                        std::cout <<  "Failed to get TimeUnitFormat for " << locales[locIndex] << "\n";
    300 #endif
    301                        return;
    302                     }
    303 
    304                     Formattable fmt;
    305                     UnicodeString str;
    306 
    307                     fmt.adoptObject(tamt);
    308                     str = ((Format *)tfmt)->format(fmt, str, status);
    309                     if (!assertSuccess("formatting relative time failed", status)) {
    310                         delete tfmt;
    311 #ifdef TUFMTTS_DEBUG
    312                         std::cout <<  "Failed to format" << "\n";
    313 #endif
    314                         return;
    315                     }
    316 
    317 #ifdef TUFMTTS_DEBUG
    318                     char tmp[128];    //output
    319                     char tmp1[128];    //expected
    320                     int len = 0;
    321                     u_strToUTF8(tmp, 128, &len, str.getTerminatedBuffer(), str.length(), &status);
    322                     u_strToUTF8(tmp1, 128, &len, expected[counter].unescape().getTerminatedBuffer(), expected[counter].unescape().length(), &status);
    323                     std::cout <<  "Formatted string : " << tmp << " expected : " << tmp1 << "\n";
    324 #endif
    325                     if (!assertEquals("formatted time string is not expected, locale: " + UnicodeString(locales[locIndex]) + " style: " + (int)styles[styleIndex] + " units: " + (int)tunits[unitIndex], expected[counter], str)) {
    326                         delete tfmt;
    327                         str.remove();
    328                         return;
    329                     }
    330                     delete tfmt;
    331                     str.remove();
    332                     ++counter;
    333                 }
    334             }
    335         }
    336     }
    337 }
    338 
    339 // Test bug9042
    340 void TimeUnitTest::testGreekWithSanitization() {
    341 
    342     UErrorCode status = U_ZERO_ERROR;
    343     Locale elLoc("el");
    344     NumberFormat* numberFmt = NumberFormat::createInstance(Locale("el"), status);
    345     if (!assertSuccess("NumberFormat::createInstance for el locale", status, TRUE)) return;
    346     numberFmt->setMaximumFractionDigits(1);
    347 
    348     TimeUnitFormat* timeUnitFormat = new TimeUnitFormat(elLoc, status);
    349     if (!assertSuccess("TimeUnitFormat::TimeUnitFormat for el locale", status)) return;
    350 
    351     timeUnitFormat->setNumberFormat(*numberFmt, status);
    352 
    353     delete numberFmt;
    354     delete timeUnitFormat;
    355 }
    356 
    357 #endif
    358