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