• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
runIndexedTest(int32_t index,UBool exec,const char * & name,char *)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
tmaEqual(const TimeUnitAmount & left,const TimeUnitAmount & right)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  */
testBasic()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 
testAPI()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  */
testGreekWithFallback()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
testGreekWithSanitization()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 
test10219Plurals()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