Home | History | Annotate | Download | only in intltest
      1 /********************************************************************
      2  * Copyright (c) 2008-2015, 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/decimfmt.h"
     11 #include "unicode/tmunit.h"
     12 #include "unicode/tmutamt.h"
     13 #include "unicode/tmutfmt.h"
     14 #include "unicode/ustring.h"
     15 #include "cmemory.h"
     16 #include "intltest.h"
     17 
     18 //TODO: put as compilation flag
     19 //#define TUFMTTS_DEBUG 1
     20 
     21 #ifdef TUFMTTS_DEBUG
     22 #include <iostream>
     23 #endif
     24 
     25 class TimeUnitTest : public IntlTest {
     26     void runIndexedTest(int32_t index, UBool exec, const char* &name, char* /*par*/ ) {
     27         if (exec) logln("TestSuite TimeUnitTest");
     28         TESTCASE_AUTO_BEGIN;
     29         TESTCASE_AUTO(testBasic);
     30         TESTCASE_AUTO(testAPI);
     31         TESTCASE_AUTO(testGreekWithFallback);
     32         TESTCASE_AUTO(testGreekWithSanitization);
     33         TESTCASE_AUTO(test10219Plurals);
     34         TESTCASE_AUTO(TestBritishShortHourFallback);
     35         TESTCASE_AUTO_END;
     36     }
     37 
     38 public:
     39     /**
     40      * Performs basic tests
     41      **/
     42     void testBasic();
     43 
     44     /**
     45      * Performs API tests
     46      **/
     47     void testAPI();
     48 
     49     /**
     50      * Performs tests for Greek
     51      * This tests that requests for short unit names correctly fall back
     52      * to long unit names for a locale where the locale data does not
     53      * provide short unit names. As of CLDR 1.9, Greek is one such language.
     54      **/
     55     void testGreekWithFallback();
     56 
     57     /**
     58      * Performs tests for Greek
     59      * This tests that if the plural count listed in time unit format does not
     60      * match those in the plural rules for the locale, those plural count in
     61      * time unit format will be ingored and subsequently, fall back will kick in
     62      * which is tested above.
     63      * Without data sanitization, setNumberFormat() would crash.
     64      * As of CLDR shiped in ICU4.8, Greek is one such language.
     65      */
     66     void testGreekWithSanitization();
     67 
     68     /**
     69      * Performs unit test for ticket 10219 making sure that plurals work
     70      * correctly with rounding.
     71      */
     72     void test10219Plurals();
     73 
     74     void TestBritishShortHourFallback();
     75 };
     76 
     77 extern IntlTest *createTimeUnitTest() {
     78     return new TimeUnitTest();
     79 }
     80 
     81 // This function is more lenient than equals operator as it considers integer 3 hours and
     82 // double 3.0 hours to be equal
     83 static UBool tmaEqual(const TimeUnitAmount& left, const TimeUnitAmount& right) {
     84     if (left.getTimeUnitField() != right.getTimeUnitField()) {
     85         return FALSE;
     86     }
     87     UErrorCode status = U_ZERO_ERROR;
     88     if (!left.getNumber().isNumeric() || !right.getNumber().isNumeric()) {
     89         return FALSE;
     90     }
     91     UBool result = left.getNumber().getDouble(status) == right.getNumber().getDouble(status);
     92     if (U_FAILURE(status)) {
     93         return FALSE;
     94     }
     95     return result;
     96 }
     97 
     98 /**
     99  * Test basic
    100  */
    101 void TimeUnitTest::testBasic() {
    102     const char* locales[] = {"en", "sl", "fr", "zh", "ar", "ru", "zh_Hant", "pa"};
    103     for ( unsigned int locIndex = 0;
    104           locIndex < sizeof(locales)/sizeof(locales[0]);
    105           ++locIndex ) {
    106         UErrorCode status = U_ZERO_ERROR;
    107         Locale loc(locales[locIndex]);
    108         TimeUnitFormat** formats = new TimeUnitFormat*[2];
    109         formats[UTMUTFMT_FULL_STYLE] = new TimeUnitFormat(loc, status);
    110         if (!assertSuccess("TimeUnitFormat(full)", status, TRUE)) return;
    111         formats[UTMUTFMT_ABBREVIATED_STYLE] = new TimeUnitFormat(loc, UTMUTFMT_ABBREVIATED_STYLE, status);
    112         if (!assertSuccess("TimeUnitFormat(short)", status)) return;
    113 #ifdef TUFMTTS_DEBUG
    114         std::cout << "locale: " << locales[locIndex] << "\n";
    115 #endif
    116         for (int style = UTMUTFMT_FULL_STYLE;
    117              style <= UTMUTFMT_ABBREVIATED_STYLE;
    118              ++style) {
    119           for (TimeUnit::UTimeUnitFields j = TimeUnit::UTIMEUNIT_YEAR;
    120              j < TimeUnit::UTIMEUNIT_FIELD_COUNT;
    121              j = (TimeUnit::UTimeUnitFields)(j+1)) {
    122 #ifdef TUFMTTS_DEBUG
    123             std::cout << "time unit: " << j << "\n";
    124 #endif
    125             double tests[] = {0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 5, 10, 100, 101.35};
    126             for (unsigned int i = 0; i < sizeof(tests)/sizeof(tests[0]); ++i) {
    127 #ifdef TUFMTTS_DEBUG
    128                 std::cout << "number: " << tests[i] << "\n";
    129 #endif
    130                 TimeUnitAmount* source = new TimeUnitAmount(tests[i], j, status);
    131                 if (!assertSuccess("TimeUnitAmount()", status)) return;
    132                 UnicodeString formatted;
    133                 Formattable formattable;
    134                 formattable.adoptObject(source);
    135                 formatted = ((Format*)formats[style])->format(formattable, formatted, status);
    136                 if (!assertSuccess("format()", status)) return;
    137 #ifdef TUFMTTS_DEBUG
    138                 char formatResult[1000];
    139                 formatted.extract(0, formatted.length(), formatResult, "UTF-8");
    140                 std::cout << "format result: " << formatResult << "\n";
    141 #endif
    142                 Formattable result;
    143                 ((Format*)formats[style])->parseObject(formatted, result, status);
    144                 if (!assertSuccess("parseObject()", status)) return;
    145                 if (!tmaEqual(*((TimeUnitAmount *)result.getObject()), *((TimeUnitAmount *) formattable.getObject()))) {
    146                     dataerrln("No round trip: ");
    147                 }
    148                 // other style parsing
    149                 Formattable result_1;
    150                 ((Format*)formats[1-style])->parseObject(formatted, result_1, status);
    151                 if (!assertSuccess("parseObject()", status)) return;
    152                 if (!tmaEqual(*((TimeUnitAmount *)result_1.getObject()), *((TimeUnitAmount *) formattable.getObject()))) {
    153                     dataerrln("No round trip: ");
    154                 }
    155             }
    156           }
    157         }
    158         delete formats[UTMUTFMT_FULL_STYLE];
    159         delete formats[UTMUTFMT_ABBREVIATED_STYLE];
    160         delete[] formats;
    161     }
    162 }
    163 
    164 
    165 void TimeUnitTest::testAPI() {
    166     //================= TimeUnit =================
    167     UErrorCode status = U_ZERO_ERROR;
    168 
    169     TimeUnit* tmunit = TimeUnit::createInstance(TimeUnit::UTIMEUNIT_YEAR, status);
    170     if (!assertSuccess("TimeUnit::createInstance", status)) return;
    171 
    172     TimeUnit* another = (TimeUnit*)tmunit->clone();
    173     TimeUnit third(*tmunit);
    174     TimeUnit fourth = third;
    175 
    176     assertTrue("orig and clone are equal", (*tmunit == *another));
    177     assertTrue("copied and assigned are equal", (third == fourth));
    178 
    179     TimeUnit* tmunit_m = TimeUnit::createInstance(TimeUnit::UTIMEUNIT_MONTH, status);
    180     assertTrue("year != month", (*tmunit != *tmunit_m));
    181 
    182     TimeUnit::UTimeUnitFields field = tmunit_m->getTimeUnitField();
    183     assertTrue("field of month time unit is month", (field == TimeUnit::UTIMEUNIT_MONTH));
    184 
    185     //===== Interoperability with MeasureUnit ======
    186     MeasureUnit **ptrs = new MeasureUnit *[TimeUnit::UTIMEUNIT_FIELD_COUNT];
    187 
    188     ptrs[TimeUnit::UTIMEUNIT_YEAR] = MeasureUnit::createYear(status);
    189     ptrs[TimeUnit::UTIMEUNIT_MONTH] = MeasureUnit::createMonth(status);
    190     ptrs[TimeUnit::UTIMEUNIT_DAY] = MeasureUnit::createDay(status);
    191     ptrs[TimeUnit::UTIMEUNIT_WEEK] = MeasureUnit::createWeek(status);
    192     ptrs[TimeUnit::UTIMEUNIT_HOUR] = MeasureUnit::createHour(status);
    193     ptrs[TimeUnit::UTIMEUNIT_MINUTE] = MeasureUnit::createMinute(status);
    194     ptrs[TimeUnit::UTIMEUNIT_SECOND] = MeasureUnit::createSecond(status);
    195     if (!assertSuccess("TimeUnit::createInstance", status)) return;
    196 
    197     for (TimeUnit::UTimeUnitFields j = TimeUnit::UTIMEUNIT_YEAR;
    198             j < TimeUnit::UTIMEUNIT_FIELD_COUNT;
    199             j = (TimeUnit::UTimeUnitFields)(j+1)) {
    200         MeasureUnit *ptr = TimeUnit::createInstance(j, status);
    201         if (!assertSuccess("TimeUnit::createInstance", status)) return;
    202         // We have to convert *ptr to a MeasureUnit or else == will fail over
    203         // differing types (TimeUnit vs. MeasureUnit).
    204         assertTrue(
    205                 "Time unit should be equal to corresponding MeasureUnit",
    206                 MeasureUnit(*ptr) == *ptrs[j]);
    207         delete ptr;
    208     }
    209     delete tmunit;
    210     delete another;
    211     delete tmunit_m;
    212     for (int i = 0; i < TimeUnit::UTIMEUNIT_FIELD_COUNT; ++i) {
    213         delete ptrs[i];
    214     }
    215     delete [] ptrs;
    216 
    217     //
    218     //================= TimeUnitAmount =================
    219 
    220     Formattable formattable((int32_t)2);
    221     TimeUnitAmount tma_long(formattable, TimeUnit::UTIMEUNIT_DAY, status);
    222     if (!assertSuccess("TimeUnitAmount(formattable...)", status)) return;
    223 
    224     formattable.setDouble(2);
    225     TimeUnitAmount tma_double(formattable, TimeUnit::UTIMEUNIT_DAY, status);
    226     if (!assertSuccess("TimeUnitAmount(formattable...)", status)) return;
    227 
    228     formattable.setDouble(3);
    229     TimeUnitAmount tma_double_3(formattable, TimeUnit::UTIMEUNIT_DAY, status);
    230     if (!assertSuccess("TimeUnitAmount(formattable...)", status)) return;
    231 
    232     TimeUnitAmount tma(2, TimeUnit::UTIMEUNIT_DAY, status);
    233     if (!assertSuccess("TimeUnitAmount(number...)", status)) return;
    234 
    235     TimeUnitAmount tma_h(2, TimeUnit::UTIMEUNIT_HOUR, status);
    236     if (!assertSuccess("TimeUnitAmount(number...)", status)) return;
    237 
    238     TimeUnitAmount second(tma);
    239     TimeUnitAmount third_tma = tma;
    240     TimeUnitAmount* fourth_tma = (TimeUnitAmount*)tma.clone();
    241 
    242     assertTrue("orig and copy are equal", (second == tma));
    243     assertTrue("clone and assigned are equal", (third_tma == *fourth_tma));
    244     assertTrue("different if number diff", (tma_double != tma_double_3));
    245     assertTrue("different if number type diff", (tma_double != tma_long));
    246     assertTrue("different if time unit diff", (tma != tma_h));
    247     assertTrue("same even different constructor", (tma_double == tma));
    248 
    249     assertTrue("getTimeUnitField", (tma.getTimeUnitField() == TimeUnit::UTIMEUNIT_DAY));
    250     delete fourth_tma;
    251     //
    252     //================= TimeUnitFormat =================
    253     //
    254     TimeUnitFormat* tmf_en = new TimeUnitFormat(Locale("en"), status);
    255     if (!assertSuccess("TimeUnitFormat(en...)", status, TRUE)) return;
    256     TimeUnitFormat tmf_fr(Locale("fr"), status);
    257     if (!assertSuccess("TimeUnitFormat(fr...)", status)) return;
    258 
    259     assertTrue("TimeUnitFormat: en and fr diff", (*tmf_en != tmf_fr));
    260 
    261     TimeUnitFormat tmf_assign = *tmf_en;
    262     assertTrue("TimeUnitFormat: orig and assign are equal", (*tmf_en == tmf_assign));
    263 
    264     TimeUnitFormat tmf_copy(tmf_fr);
    265     assertTrue("TimeUnitFormat: orig and copy are equal", (tmf_fr == tmf_copy));
    266 
    267     TimeUnitFormat* tmf_clone = (TimeUnitFormat*)tmf_en->clone();
    268     assertTrue("TimeUnitFormat: orig and clone are equal", (*tmf_en == *tmf_clone));
    269     delete tmf_clone;
    270 
    271     tmf_en->setLocale(Locale("fr"), status);
    272     if (!assertSuccess("setLocale(fr...)", status)) return;
    273 
    274     NumberFormat* numberFmt = NumberFormat::createInstance(
    275                                  Locale("fr"), status);
    276     if (!assertSuccess("NumberFormat::createInstance()", status)) return;
    277     tmf_en->setNumberFormat(*numberFmt, status);
    278     if (!assertSuccess("setNumberFormat(en...)", status)) return;
    279     assertTrue("TimeUnitFormat: setLocale", (*tmf_en == tmf_fr));
    280 
    281     delete tmf_en;
    282 
    283     TimeUnitFormat* en_long = new TimeUnitFormat(Locale("en"), UTMUTFMT_FULL_STYLE, status);
    284     if (!assertSuccess("TimeUnitFormat(en...)", status)) return;
    285     delete en_long;
    286 
    287     TimeUnitFormat* en_short = new TimeUnitFormat(Locale("en"), UTMUTFMT_ABBREVIATED_STYLE, status);
    288     if (!assertSuccess("TimeUnitFormat(en...)", status)) return;
    289     delete en_short;
    290 
    291     TimeUnitFormat* format = new TimeUnitFormat(status);
    292     format->setLocale(Locale("zh"), status);
    293     format->setNumberFormat(*numberFmt, status);
    294     if (!assertSuccess("TimeUnitFormat(en...)", status)) return;
    295     delete numberFmt;
    296     delete format;
    297 }
    298 
    299 /* @bug 7902
    300  * Tests for Greek Language.
    301  * This tests that requests for short unit names correctly fall back
    302  * to long unit names for a locale where the locale data does not
    303  * provide short unit names. As of CLDR 1.9, Greek is one such language.
    304  */
    305 void TimeUnitTest::testGreekWithFallback() {
    306     UErrorCode status = U_ZERO_ERROR;
    307 
    308     const char* locales[] = {"el-GR", "el"};
    309     TimeUnit::UTimeUnitFields tunits[] = {TimeUnit::UTIMEUNIT_SECOND, TimeUnit::UTIMEUNIT_MINUTE, TimeUnit::UTIMEUNIT_HOUR, TimeUnit::UTIMEUNIT_DAY, TimeUnit::UTIMEUNIT_MONTH, TimeUnit::UTIMEUNIT_YEAR};
    310     UTimeUnitFormatStyle styles[] = {UTMUTFMT_FULL_STYLE, UTMUTFMT_ABBREVIATED_STYLE};
    311     const int numbers[] = {1, 7};
    312 
    313     const UChar oneSecond[] = {0x0031, 0x0020, 0x03b4, 0x03b5, 0x03c5, 0x03c4, 0x03b5, 0x03c1, 0x03cc, 0x03bb, 0x03b5, 0x03c0, 0x03c4, 0x03bf, 0};
    314     const UChar oneSecondShort[] = {0x0031, 0x0020, 0x03b4, 0x03b5, 0x03c5, 0x03c4, 0x002e, 0};
    315     const UChar oneMinute[] = {0x0031, 0x0020, 0x03bb, 0x03b5, 0x03c0, 0x03c4, 0x03cc, 0};
    316     const UChar oneMinuteShort[] = {0x0031, 0x0020, 0x03bb, 0x03b5, 0x03c0, 0x002e, 0};
    317     const UChar oneHour[] = {0x0031, 0x0020, 0x03ce, 0x03c1, 0x03b1, 0};
    318     const UChar oneDay[] = {0x0031, 0x0020, 0x03b7, 0x03bc, 0x03ad, 0x03c1, 0x03b1, 0};
    319     const UChar oneMonth[] = {0x0031, 0x0020, 0x03bc, 0x03ae, 0x03bd, 0x03b1, 0x03c2, 0};
    320     const UChar oneMonthShort[] = {0x0031, 0x0020, 0x03bc, 0x03ae, 0x03bd, 0x002e, 0};
    321     const UChar oneYear[] = {0x0031, 0x0020, 0x03ad, 0x03c4, 0x03bf, 0x03c2, 0};
    322     const UChar oneYearShort[] = {0x0031, 0x0020, 0x03ad, 0x03c4, 0x002e, 0};
    323     const UChar sevenSeconds[] = {0x0037, 0x0020, 0x03b4, 0x03b5, 0x03c5, 0x03c4, 0x03b5, 0x03c1, 0x03cc, 0x03bb, 0x03b5, 0x03c0, 0x03c4, 0x03b1, 0};
    324     const UChar sevenSecondsShort[] = {0x0037, 0x0020, 0x03b4, 0x03b5, 0x03c5, 0x03c4, 0x002e, 0};
    325     const UChar sevenMinutes[] = {0x0037, 0x0020, 0x03bb, 0x03b5, 0x03c0, 0x03c4, 0x03ac, 0};
    326     const UChar sevenMinutesShort[] = {0x0037, 0x0020, 0x03bb, 0x03b5, 0x03c0, 0x002e, 0};
    327     const UChar sevenHours[] = {0x0037, 0x0020, 0x03ce, 0x03c1, 0x03b5, 0x03c2, 0};
    328     const UChar sevenHoursShort[] = {0x0037, 0x0020, 0x03ce, 0x03c1, 0x002e, 0};
    329     const UChar sevenDays[] = {0x0037, 0x0020, 0x03b7, 0x03bc, 0x03ad, 0x03c1, 0x03b5, 0x03c2, 0};
    330     const UChar sevenMonths[] = {0x0037, 0x0020, 0x03bc, 0x03ae, 0x03bd, 0x03b5, 0x3c2, 0};
    331     const UChar sevenMonthsShort[] = {0x0037, 0x0020, 0x03bc, 0x03ae, 0x03bd, 0x002e, 0};
    332     const UChar sevenYears[] = {0x0037, 0x0020, 0x03ad, 0x03c4, 0x03b7, 0};
    333     const UChar sevenYearsShort[] = {0x0037, 0x0020, 0x03ad, 0x03c4, 0x002e, 0};
    334 
    335     const UnicodeString oneSecondStr(oneSecond);
    336     const UnicodeString oneSecondShortStr(oneSecondShort);
    337     const UnicodeString oneMinuteStr(oneMinute);
    338     const UnicodeString oneMinuteShortStr(oneMinuteShort);
    339     const UnicodeString oneHourStr(oneHour);
    340     const UnicodeString oneDayStr(oneDay);
    341     const UnicodeString oneMonthStr(oneMonth);
    342     const UnicodeString oneMonthShortStr(oneMonthShort);
    343     const UnicodeString oneYearStr(oneYear);
    344     const UnicodeString oneYearShortStr(oneYearShort);
    345     const UnicodeString sevenSecondsStr(sevenSeconds);
    346     const UnicodeString sevenSecondsShortStr(sevenSecondsShort);
    347     const UnicodeString sevenMinutesStr(sevenMinutes);
    348     const UnicodeString sevenMinutesShortStr(sevenMinutesShort);
    349     const UnicodeString sevenHoursStr(sevenHours);
    350     const UnicodeString sevenHoursShortStr(sevenHoursShort);
    351     const UnicodeString sevenDaysStr(sevenDays);
    352     const UnicodeString sevenMonthsStr(sevenMonths);
    353     const UnicodeString sevenMonthsShortStr(sevenMonthsShort);
    354     const UnicodeString sevenYearsStr(sevenYears);
    355     const UnicodeString sevenYearsShortStr(sevenYearsShort);
    356 
    357     const UnicodeString expected[] = {
    358             oneSecondStr, oneMinuteStr, oneHourStr, oneDayStr, oneMonthStr, oneYearStr,
    359             oneSecondShortStr, oneMinuteShortStr, oneHourStr, oneDayStr, oneMonthShortStr, oneYearShortStr,
    360             sevenSecondsStr, sevenMinutesStr, sevenHoursStr, sevenDaysStr, sevenMonthsStr, sevenYearsStr,
    361             sevenSecondsShortStr, sevenMinutesShortStr, sevenHoursShortStr, sevenDaysStr, sevenMonthsShortStr, sevenYearsShortStr,
    362 
    363             oneSecondStr, oneMinuteStr, oneHourStr, oneDayStr, oneMonthStr, oneYearStr,
    364             oneSecondShortStr, oneMinuteShortStr, oneHourStr, oneDayStr, oneMonthShortStr, oneYearShortStr,
    365             sevenSecondsStr, sevenMinutesStr, sevenHoursStr, sevenDaysStr, sevenMonthsStr, sevenYearsStr,
    366             sevenSecondsShortStr, sevenMinutesShortStr, sevenHoursShortStr, sevenDaysStr, sevenMonthsShortStr, sevenYearsShortStr};
    367 
    368     int counter = 0;
    369     for ( unsigned int locIndex = 0;
    370         locIndex < sizeof(locales)/sizeof(locales[0]);
    371         ++locIndex ) {
    372 
    373         Locale l = Locale::createFromName(locales[locIndex]);
    374 
    375         for ( unsigned int numberIndex = 0;
    376             numberIndex < sizeof(numbers)/sizeof(int);
    377             ++numberIndex ) {
    378 
    379             for ( unsigned int styleIndex = 0;
    380                 styleIndex < sizeof(styles)/sizeof(styles[0]);
    381                 ++styleIndex ) {
    382 
    383                 for ( unsigned int unitIndex = 0;
    384                     unitIndex < sizeof(tunits)/sizeof(tunits[0]);
    385                     ++unitIndex ) {
    386 
    387                     TimeUnitAmount *tamt = new TimeUnitAmount(numbers[numberIndex], tunits[unitIndex], status);
    388                     if (U_FAILURE(status)) {
    389                         dataerrln("generating TimeUnitAmount Object failed.");
    390 #ifdef TUFMTTS_DEBUG
    391                         std::cout << "Failed to get TimeUnitAmount for " << tunits[unitIndex] << "\n";
    392 #endif
    393                         return;
    394                     }
    395 
    396                     TimeUnitFormat *tfmt = new TimeUnitFormat(l, styles[styleIndex], status);
    397                     if (U_FAILURE(status)) {
    398                         dataerrln("generating TimeUnitAmount Object failed.");
    399 #ifdef TUFMTTS_DEBUG
    400                        std::cout <<  "Failed to get TimeUnitFormat for " << locales[locIndex] << "\n";
    401 #endif
    402                        return;
    403                     }
    404 
    405                     Formattable fmt;
    406                     UnicodeString str;
    407 
    408                     fmt.adoptObject(tamt);
    409                     str = ((Format *)tfmt)->format(fmt, str, status);
    410                     if (!assertSuccess("formatting relative time failed", status)) {
    411                         delete tfmt;
    412 #ifdef TUFMTTS_DEBUG
    413                         std::cout <<  "Failed to format" << "\n";
    414 #endif
    415                         return;
    416                     }
    417 
    418 #ifdef TUFMTTS_DEBUG
    419                     char tmp[128];    //output
    420                     char tmp1[128];    //expected
    421                     int len = 0;
    422                     u_strToUTF8(tmp, 128, &len, str.getTerminatedBuffer(), str.length(), &status);
    423                     u_strToUTF8(tmp1, 128, &len, expected[counter].unescape().getTerminatedBuffer(), expected[counter].unescape().length(), &status);
    424                     std::cout <<  "Formatted string : " << tmp << " expected : " << tmp1 << "\n";
    425 #endif
    426                     if (!assertEquals("formatted time string is not expected, locale: " + UnicodeString(locales[locIndex]) + " style: " + (int)styles[styleIndex] + " units: " + (int)tunits[unitIndex], expected[counter], str)) {
    427                         delete tfmt;
    428                         str.remove();
    429                         return;
    430                     }
    431                     delete tfmt;
    432                     str.remove();
    433                     ++counter;
    434                 }
    435             }
    436         }
    437     }
    438 }
    439 
    440 // Test bug9042
    441 void TimeUnitTest::testGreekWithSanitization() {
    442 
    443     UErrorCode status = U_ZERO_ERROR;
    444     Locale elLoc("el");
    445     NumberFormat* numberFmt = NumberFormat::createInstance(Locale("el"), status);
    446     if (!assertSuccess("NumberFormat::createInstance for el locale", status, TRUE)) return;
    447     numberFmt->setMaximumFractionDigits(1);
    448 
    449     TimeUnitFormat* timeUnitFormat = new TimeUnitFormat(elLoc, status);
    450     if (!assertSuccess("TimeUnitFormat::TimeUnitFormat for el locale", status)) return;
    451 
    452     timeUnitFormat->setNumberFormat(*numberFmt, status);
    453 
    454     delete numberFmt;
    455     delete timeUnitFormat;
    456 }
    457 
    458 void TimeUnitTest::test10219Plurals() {
    459     Locale usLocale("en_US");
    460     double values[2] = {1.588, 1.011};
    461     UnicodeString expected[2][3] = {
    462         {"1 minute", "1.5 minutes", "1.58 minutes"},
    463         {"1 minute", "1.0 minutes", "1.01 minutes"}
    464     };
    465     UErrorCode status = U_ZERO_ERROR;
    466     TimeUnitFormat tuf(usLocale, status);
    467     if (U_FAILURE(status)) {
    468         dataerrln("generating TimeUnitFormat Object failed: %s", u_errorName(status));
    469         return;
    470     }
    471     LocalPointer<DecimalFormat> nf((DecimalFormat *) NumberFormat::createInstance(usLocale, status));
    472     if (U_FAILURE(status)) {
    473         dataerrln("generating NumberFormat Object failed: %s", u_errorName(status));
    474         return;
    475     }
    476     for (int32_t j = 0; j < UPRV_LENGTHOF(values); ++j) {
    477         for (int32_t i = 0; i < UPRV_LENGTHOF(expected[j]); ++i) {
    478             nf->setMinimumFractionDigits(i);
    479             nf->setMaximumFractionDigits(i);
    480             nf->setRoundingMode(DecimalFormat::kRoundDown);
    481             tuf.setNumberFormat(*nf, status);
    482             if (U_FAILURE(status)) {
    483                 dataerrln("setting NumberFormat failed: %s", u_errorName(status));
    484                 return;
    485             }
    486             UnicodeString actual;
    487             Formattable fmt;
    488             LocalPointer<TimeUnitAmount> tamt(
    489                 new TimeUnitAmount(values[j], TimeUnit::UTIMEUNIT_MINUTE, status), status);
    490             if (U_FAILURE(status)) {
    491                 dataerrln("generating TimeUnitAmount Object failed: %s", u_errorName(status));
    492                 return;
    493             }
    494             fmt.adoptObject(tamt.orphan());
    495             tuf.format(fmt, actual, status);
    496             if (U_FAILURE(status)) {
    497                 dataerrln("Actual formatting failed: %s", u_errorName(status));
    498                 return;
    499             }
    500             if (expected[j][i] != actual) {
    501                 errln("Expected " + expected[j][i] + ", got " + actual);
    502             }
    503         }
    504     }
    505 
    506     // test parsing
    507     Formattable result;
    508     ParsePosition pos;
    509     UnicodeString formattedString = "1 minutes";
    510     tuf.parseObject(formattedString, result, pos);
    511     if (formattedString.length() != pos.getIndex()) {
    512         errln("Expect parsing to go all the way to the end of the string.");
    513     }
    514 }
    515 
    516 void TimeUnitTest::TestBritishShortHourFallback() {
    517     // See ticket #11986 "incomplete fallback in MeasureFormat".
    518     UErrorCode status = U_ZERO_ERROR;
    519     Formattable oneHour(new TimeUnitAmount(1, TimeUnit::UTIMEUNIT_HOUR, status));
    520     Locale en_GB("en_GB");
    521     TimeUnitFormat formatter(en_GB, UTMUTFMT_ABBREVIATED_STYLE, status);
    522     UnicodeString result;
    523     formatter.format(oneHour, result, status);
    524     assertSuccess("TestBritishShortHourFallback()", status);
    525     assertEquals("TestBritishShortHourFallback()", UNICODE_STRING_SIMPLE("1 hr"), result);
    526 }
    527 
    528 #endif
    529