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