]> git.saurik.com Git - apple/icu.git/blob - icuSources/test/intltest/tufmtts.cpp
ICU-57166.0.1.tar.gz
[apple/icu.git] / icuSources / test / intltest / tufmtts.cpp
1 /********************************************************************
2 * Copyright (c) 2008-2016, 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 < UPRV_LENGTHOF(locales);
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 < UPRV_LENGTHOF(tests); ++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 < UPRV_LENGTHOF(locales);
371 ++locIndex ) {
372
373 Locale l = Locale::createFromName(locales[locIndex]);
374
375 for ( unsigned int numberIndex = 0;
376 numberIndex < UPRV_LENGTHOF(numbers);
377 ++numberIndex ) {
378
379 for ( unsigned int styleIndex = 0;
380 styleIndex < UPRV_LENGTHOF(styles);
381 ++styleIndex ) {
382
383 for ( unsigned int unitIndex = 0;
384 unitIndex < UPRV_LENGTHOF(tunits);
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, TRUE);
526 }
527
528 #endif