1 /********************************************************************
2 * Copyright (c) 2008-2016, International Business Machines Corporation and
3 * others. All Rights Reserved.
4 ********************************************************************/
6 #include "unicode/utypes.h"
8 #if !UCONFIG_NO_FORMATTING
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"
18 //TODO: put as compilation flag
19 //#define TUFMTTS_DEBUG 1
25 class TimeUnitTest
: public IntlTest
{
26 void runIndexedTest(int32_t index
, UBool exec
, const char* &name
, char* /*par*/ ) {
27 if (exec
) logln("TestSuite TimeUnitTest");
29 TESTCASE_AUTO(testBasic
);
30 TESTCASE_AUTO(testAPI
);
31 TESTCASE_AUTO(testGreekWithFallback
);
32 TESTCASE_AUTO(testGreekWithSanitization
);
33 TESTCASE_AUTO(test10219Plurals
);
34 TESTCASE_AUTO(TestBritishShortHourFallback
);
40 * Performs basic tests
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.
55 void testGreekWithFallback();
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.
66 void testGreekWithSanitization();
69 * Performs unit test for ticket 10219 making sure that plurals work
70 * correctly with rounding.
72 void test10219Plurals();
74 void TestBritishShortHourFallback();
77 extern IntlTest
*createTimeUnitTest() {
78 return new TimeUnitTest();
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()) {
87 UErrorCode status
= U_ZERO_ERROR
;
88 if (!left
.getNumber().isNumeric() || !right
.getNumber().isNumeric()) {
91 UBool result
= left
.getNumber().getDouble(status
) == right
.getNumber().getDouble(status
);
92 if (U_FAILURE(status
)) {
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
);
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;
114 std::cout
<< "locale: " << locales
[locIndex
] << "\n";
116 for (int style
= UTMUTFMT_FULL_STYLE
;
117 style
<= UTMUTFMT_ABBREVIATED_STYLE
;
119 for (TimeUnit::UTimeUnitFields j
= TimeUnit::UTIMEUNIT_YEAR
;
120 j
< TimeUnit::UTIMEUNIT_FIELD_COUNT
;
121 j
= (TimeUnit::UTimeUnitFields
)(j
+1)) {
123 std::cout
<< "time unit: " << j
<< "\n";
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
) {
128 std::cout
<< "number: " << tests
[i
] << "\n";
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;
138 char formatResult
[1000];
139 formatted
.extract(0, formatted
.length(), formatResult
, "UTF-8");
140 std::cout
<< "format result: " << formatResult
<< "\n";
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: ");
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: ");
158 delete formats
[UTMUTFMT_FULL_STYLE
];
159 delete formats
[UTMUTFMT_ABBREVIATED_STYLE
];
165 void TimeUnitTest::testAPI() {
166 //================= TimeUnit =================
167 UErrorCode status
= U_ZERO_ERROR
;
169 TimeUnit
* tmunit
= TimeUnit::createInstance(TimeUnit::UTIMEUNIT_YEAR
, status
);
170 if (!assertSuccess("TimeUnit::createInstance", status
)) return;
172 TimeUnit
* another
= (TimeUnit
*)tmunit
->clone();
173 TimeUnit
third(*tmunit
);
174 TimeUnit fourth
= third
;
176 assertTrue("orig and clone are equal", (*tmunit
== *another
));
177 assertTrue("copied and assigned are equal", (third
== fourth
));
179 TimeUnit
* tmunit_m
= TimeUnit::createInstance(TimeUnit::UTIMEUNIT_MONTH
, status
);
180 assertTrue("year != month", (*tmunit
!= *tmunit_m
));
182 TimeUnit::UTimeUnitFields field
= tmunit_m
->getTimeUnitField();
183 assertTrue("field of month time unit is month", (field
== TimeUnit::UTIMEUNIT_MONTH
));
185 //===== Interoperability with MeasureUnit ======
186 MeasureUnit
**ptrs
= new MeasureUnit
*[TimeUnit::UTIMEUNIT_FIELD_COUNT
];
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;
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).
205 "Time unit should be equal to corresponding MeasureUnit",
206 MeasureUnit(*ptr
) == *ptrs
[j
]);
212 for (int i
= 0; i
< TimeUnit::UTIMEUNIT_FIELD_COUNT
; ++i
) {
218 //================= TimeUnitAmount =================
220 Formattable
formattable((int32_t)2);
221 TimeUnitAmount
tma_long(formattable
, TimeUnit::UTIMEUNIT_DAY
, status
);
222 if (!assertSuccess("TimeUnitAmount(formattable...)", status
)) return;
224 formattable
.setDouble(2);
225 TimeUnitAmount
tma_double(formattable
, TimeUnit::UTIMEUNIT_DAY
, status
);
226 if (!assertSuccess("TimeUnitAmount(formattable...)", status
)) return;
228 formattable
.setDouble(3);
229 TimeUnitAmount
tma_double_3(formattable
, TimeUnit::UTIMEUNIT_DAY
, status
);
230 if (!assertSuccess("TimeUnitAmount(formattable...)", status
)) return;
232 TimeUnitAmount
tma(2, TimeUnit::UTIMEUNIT_DAY
, status
);
233 if (!assertSuccess("TimeUnitAmount(number...)", status
)) return;
235 TimeUnitAmount
tma_h(2, TimeUnit::UTIMEUNIT_HOUR
, status
);
236 if (!assertSuccess("TimeUnitAmount(number...)", status
)) return;
238 TimeUnitAmount
second(tma
);
239 TimeUnitAmount third_tma
= tma
;
240 TimeUnitAmount
* fourth_tma
= (TimeUnitAmount
*)tma
.clone();
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
));
249 assertTrue("getTimeUnitField", (tma
.getTimeUnitField() == TimeUnit::UTIMEUNIT_DAY
));
252 //================= TimeUnitFormat =================
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;
259 assertTrue("TimeUnitFormat: en and fr diff", (*tmf_en
!= tmf_fr
));
261 TimeUnitFormat tmf_assign
= *tmf_en
;
262 assertTrue("TimeUnitFormat: orig and assign are equal", (*tmf_en
== tmf_assign
));
264 TimeUnitFormat
tmf_copy(tmf_fr
);
265 assertTrue("TimeUnitFormat: orig and copy are equal", (tmf_fr
== tmf_copy
));
267 TimeUnitFormat
* tmf_clone
= (TimeUnitFormat
*)tmf_en
->clone();
268 assertTrue("TimeUnitFormat: orig and clone are equal", (*tmf_en
== *tmf_clone
));
271 tmf_en
->setLocale(Locale("fr"), status
);
272 if (!assertSuccess("setLocale(fr...)", status
)) return;
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
));
283 TimeUnitFormat
* en_long
= new TimeUnitFormat(Locale("en"), UTMUTFMT_FULL_STYLE
, status
);
284 if (!assertSuccess("TimeUnitFormat(en...)", status
)) return;
287 TimeUnitFormat
* en_short
= new TimeUnitFormat(Locale("en"), UTMUTFMT_ABBREVIATED_STYLE
, status
);
288 if (!assertSuccess("TimeUnitFormat(en...)", status
)) return;
291 TimeUnitFormat
* format
= new TimeUnitFormat(status
);
292 format
->setLocale(Locale("zh"), status
);
293 format
->setNumberFormat(*numberFmt
, status
);
294 if (!assertSuccess("TimeUnitFormat(en...)", status
)) return;
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.
305 void TimeUnitTest::testGreekWithFallback() {
306 UErrorCode status
= U_ZERO_ERROR
;
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};
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};
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
);
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
,
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
};
369 for ( unsigned int locIndex
= 0;
370 locIndex
< UPRV_LENGTHOF(locales
);
373 Locale l
= Locale::createFromName(locales
[locIndex
]);
375 for ( unsigned int numberIndex
= 0;
376 numberIndex
< UPRV_LENGTHOF(numbers
);
379 for ( unsigned int styleIndex
= 0;
380 styleIndex
< UPRV_LENGTHOF(styles
);
383 for ( unsigned int unitIndex
= 0;
384 unitIndex
< UPRV_LENGTHOF(tunits
);
387 TimeUnitAmount
*tamt
= new TimeUnitAmount(numbers
[numberIndex
], tunits
[unitIndex
], status
);
388 if (U_FAILURE(status
)) {
389 dataerrln("generating TimeUnitAmount Object failed.");
391 std::cout
<< "Failed to get TimeUnitAmount for " << tunits
[unitIndex
] << "\n";
396 TimeUnitFormat
*tfmt
= new TimeUnitFormat(l
, styles
[styleIndex
], status
);
397 if (U_FAILURE(status
)) {
398 dataerrln("generating TimeUnitAmount Object failed.");
400 std::cout
<< "Failed to get TimeUnitFormat for " << locales
[locIndex
] << "\n";
408 fmt
.adoptObject(tamt
);
409 str
= ((Format
*)tfmt
)->format(fmt
, str
, status
);
410 if (!assertSuccess("formatting relative time failed", status
)) {
413 std::cout
<< "Failed to format" << "\n";
419 char tmp
[128]; //output
420 char tmp1
[128]; //expected
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";
426 if (!assertEquals("formatted time string is not expected, locale: " + UnicodeString(locales
[locIndex
]) + " style: " + (int)styles
[styleIndex
] + " units: " + (int)tunits
[unitIndex
], expected
[counter
], str
)) {
441 void TimeUnitTest::testGreekWithSanitization() {
443 UErrorCode status
= U_ZERO_ERROR
;
445 NumberFormat
* numberFmt
= NumberFormat::createInstance(Locale("el"), status
);
446 if (!assertSuccess("NumberFormat::createInstance for el locale", status
, TRUE
)) return;
447 numberFmt
->setMaximumFractionDigits(1);
449 TimeUnitFormat
* timeUnitFormat
= new TimeUnitFormat(elLoc
, status
);
450 if (!assertSuccess("TimeUnitFormat::TimeUnitFormat for el locale", status
)) return;
452 timeUnitFormat
->setNumberFormat(*numberFmt
, status
);
455 delete timeUnitFormat
;
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"}
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
));
471 LocalPointer
<DecimalFormat
> nf((DecimalFormat
*) NumberFormat::createInstance(usLocale
, status
));
472 if (U_FAILURE(status
)) {
473 dataerrln("generating NumberFormat Object failed: %s", u_errorName(status
));
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
));
486 UnicodeString actual
;
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
));
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
));
500 if (expected
[j
][i
] != actual
) {
501 errln("Expected " + expected
[j
][i
] + ", got " + actual
);
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.");
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
);