1 /********************************************************************
2 * Copyright (c) 2008-2012, International Business Machines Corporation and
3 * others. All Rights Reserved.
4 ********************************************************************/
6 #include "unicode/utypes.h"
8 #if !UCONFIG_NO_FORMATTING
10 #include "unicode/tmunit.h"
11 #include "unicode/tmutamt.h"
12 #include "unicode/tmutfmt.h"
14 #include "unicode/ustring.h"
16 //TODO: put as compilation flag
17 //#define TUFMTTS_DEBUG 1
23 void TimeUnitTest::runIndexedTest( int32_t index
, UBool exec
, const char* &name
, char* /*par*/ ) {
24 if (exec
) logln("TestSuite TimeUnitTest");
26 TESTCASE(0, testBasic
);
28 TESTCASE(2, testGreekWithFallback
);
29 TESTCASE(3, testGreekWithSanitization
);
30 default: name
= ""; break;
37 void TimeUnitTest::testBasic() {
38 const char* locales
[] = {"en", "sl", "fr", "zh", "ar", "ru", "zh_Hant", "pa"};
39 for ( unsigned int locIndex
= 0;
40 locIndex
< sizeof(locales
)/sizeof(locales
[0]);
42 UErrorCode status
= U_ZERO_ERROR
;
43 Locale
loc(locales
[locIndex
]);
44 TimeUnitFormat
** formats
= new TimeUnitFormat
*[2];
45 formats
[UTMUTFMT_FULL_STYLE
] = new TimeUnitFormat(loc
, status
);
46 if (!assertSuccess("TimeUnitFormat(full)", status
, TRUE
)) return;
47 formats
[UTMUTFMT_ABBREVIATED_STYLE
] = new TimeUnitFormat(loc
, UTMUTFMT_ABBREVIATED_STYLE
, status
);
48 if (!assertSuccess("TimeUnitFormat(short)", status
)) return;
50 std::cout
<< "locale: " << locales
[locIndex
] << "\n";
52 for (int style
= UTMUTFMT_FULL_STYLE
;
53 style
<= UTMUTFMT_ABBREVIATED_STYLE
;
55 for (TimeUnit::UTimeUnitFields j
= TimeUnit::UTIMEUNIT_YEAR
;
56 j
< TimeUnit::UTIMEUNIT_FIELD_COUNT
;
57 j
= (TimeUnit::UTimeUnitFields
)(j
+1)) {
59 std::cout
<< "time unit: " << j
<< "\n";
61 double tests
[] = {0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 5, 10, 100, 101.35};
62 for (unsigned int i
= 0; i
< sizeof(tests
)/sizeof(tests
[0]); ++i
) {
64 std::cout
<< "number: " << tests
[i
] << "\n";
66 TimeUnitAmount
* source
= new TimeUnitAmount(tests
[i
], j
, status
);
67 if (!assertSuccess("TimeUnitAmount()", status
)) return;
68 UnicodeString formatted
;
69 Formattable formattable
;
70 formattable
.adoptObject(source
);
71 formatted
= ((Format
*)formats
[style
])->format(formattable
, formatted
, status
);
72 if (!assertSuccess("format()", status
)) return;
74 char formatResult
[1000];
75 formatted
.extract(0, formatted
.length(), formatResult
, "UTF-8");
76 std::cout
<< "format result: " << formatResult
<< "\n";
79 ((Format
*)formats
[style
])->parseObject(formatted
, result
, status
);
80 if (!assertSuccess("parseObject()", status
)) return;
81 if (result
!= formattable
) {
82 dataerrln("No round trip: ");
84 // other style parsing
86 ((Format
*)formats
[1-style
])->parseObject(formatted
, result_1
, status
);
87 if (!assertSuccess("parseObject()", status
)) return;
88 if (result_1
!= formattable
) {
89 dataerrln("No round trip: ");
94 delete formats
[UTMUTFMT_FULL_STYLE
];
95 delete formats
[UTMUTFMT_ABBREVIATED_STYLE
];
101 void TimeUnitTest::testAPI() {
102 //================= TimeUnit =================
103 UErrorCode status
= U_ZERO_ERROR
;
105 TimeUnit
* tmunit
= TimeUnit::createInstance(TimeUnit::UTIMEUNIT_YEAR
, status
);
106 if (!assertSuccess("TimeUnit::createInstance", status
)) return;
108 TimeUnit
* another
= (TimeUnit
*)tmunit
->clone();
109 TimeUnit
third(*tmunit
);
110 TimeUnit fourth
= third
;
112 assertTrue("orig and clone are equal", (*tmunit
== *another
));
113 assertTrue("copied and assigned are equal", (third
== fourth
));
115 TimeUnit
* tmunit_m
= TimeUnit::createInstance(TimeUnit::UTIMEUNIT_MONTH
, status
);
116 assertTrue("year != month", (*tmunit
!= *tmunit_m
));
118 TimeUnit::UTimeUnitFields field
= tmunit_m
->getTimeUnitField();
119 assertTrue("field of month time unit is month", (field
== TimeUnit::UTIMEUNIT_MONTH
));
125 //================= TimeUnitAmount =================
127 Formattable
formattable((int32_t)2);
128 TimeUnitAmount
tma_long(formattable
, TimeUnit::UTIMEUNIT_DAY
, status
);
129 if (!assertSuccess("TimeUnitAmount(formattable...)", status
)) return;
131 formattable
.setDouble(2);
132 TimeUnitAmount
tma_double(formattable
, TimeUnit::UTIMEUNIT_DAY
, status
);
133 if (!assertSuccess("TimeUnitAmount(formattable...)", status
)) return;
135 formattable
.setDouble(3);
136 TimeUnitAmount
tma_double_3(formattable
, TimeUnit::UTIMEUNIT_DAY
, status
);
137 if (!assertSuccess("TimeUnitAmount(formattable...)", status
)) return;
139 TimeUnitAmount
tma(2, TimeUnit::UTIMEUNIT_DAY
, status
);
140 if (!assertSuccess("TimeUnitAmount(number...)", status
)) return;
142 TimeUnitAmount
tma_h(2, TimeUnit::UTIMEUNIT_HOUR
, status
);
143 if (!assertSuccess("TimeUnitAmount(number...)", status
)) return;
145 TimeUnitAmount
second(tma
);
146 TimeUnitAmount third_tma
= tma
;
147 TimeUnitAmount
* fourth_tma
= (TimeUnitAmount
*)tma
.clone();
149 assertTrue("orig and copy are equal", (second
== tma
));
150 assertTrue("clone and assigned are equal", (third_tma
== *fourth_tma
));
151 assertTrue("different if number diff", (tma_double
!= tma_double_3
));
152 assertTrue("different if number type diff", (tma_double
!= tma_long
));
153 assertTrue("different if time unit diff", (tma
!= tma_h
));
154 assertTrue("same even different constructor", (tma_double
== tma
));
156 assertTrue("getTimeUnitField", (tma
.getTimeUnitField() == TimeUnit::UTIMEUNIT_DAY
));
159 //================= TimeUnitFormat =================
161 TimeUnitFormat
* tmf_en
= new TimeUnitFormat(Locale("en"), status
);
162 if (!assertSuccess("TimeUnitFormat(en...)", status
, TRUE
)) return;
163 TimeUnitFormat
tmf_fr(Locale("fr"), status
);
164 if (!assertSuccess("TimeUnitFormat(fr...)", status
)) return;
166 assertTrue("TimeUnitFormat: en and fr diff", (*tmf_en
!= tmf_fr
));
168 TimeUnitFormat tmf_assign
= *tmf_en
;
169 assertTrue("TimeUnitFormat: orig and assign are equal", (*tmf_en
== tmf_assign
));
171 TimeUnitFormat
tmf_copy(tmf_fr
);
172 assertTrue("TimeUnitFormat: orig and copy are equal", (tmf_fr
== tmf_copy
));
174 TimeUnitFormat
* tmf_clone
= (TimeUnitFormat
*)tmf_en
->clone();
175 assertTrue("TimeUnitFormat: orig and clone are equal", (*tmf_en
== *tmf_clone
));
178 tmf_en
->setLocale(Locale("fr"), status
);
179 if (!assertSuccess("setLocale(fr...)", status
)) return;
181 NumberFormat
* numberFmt
= NumberFormat::createInstance(
182 Locale("fr"), status
);
183 if (!assertSuccess("NumberFormat::createInstance()", status
)) return;
184 tmf_en
->setNumberFormat(*numberFmt
, status
);
185 if (!assertSuccess("setNumberFormat(en...)", status
)) return;
186 assertTrue("TimeUnitFormat: setLocale", (*tmf_en
== tmf_fr
));
190 TimeUnitFormat
* en_long
= new TimeUnitFormat(Locale("en"), UTMUTFMT_FULL_STYLE
, status
);
191 if (!assertSuccess("TimeUnitFormat(en...)", status
)) return;
194 TimeUnitFormat
* en_short
= new TimeUnitFormat(Locale("en"), UTMUTFMT_ABBREVIATED_STYLE
, status
);
195 if (!assertSuccess("TimeUnitFormat(en...)", status
)) return;
198 TimeUnitFormat
* format
= new TimeUnitFormat(status
);
199 format
->setLocale(Locale("zh"), status
);
200 format
->setNumberFormat(*numberFmt
, status
);
201 if (!assertSuccess("TimeUnitFormat(en...)", status
)) return;
207 * Tests for Greek Language.
208 * This tests that requests for short unit names correctly fall back
209 * to long unit names for a locale where the locale data does not
210 * provide short unit names. As of CLDR 1.9, Greek is one such language.
212 void TimeUnitTest::testGreekWithFallback() {
213 UErrorCode status
= U_ZERO_ERROR
;
215 const char* locales
[] = {"el-GR", "el"};
216 TimeUnit::UTimeUnitFields tunits
[] = {TimeUnit::UTIMEUNIT_SECOND
, TimeUnit::UTIMEUNIT_MINUTE
, TimeUnit::UTIMEUNIT_HOUR
, TimeUnit::UTIMEUNIT_DAY
, TimeUnit::UTIMEUNIT_MONTH
, TimeUnit::UTIMEUNIT_YEAR
};
217 UTimeUnitFormatStyle styles
[] = {UTMUTFMT_FULL_STYLE
, UTMUTFMT_ABBREVIATED_STYLE
};
218 const int numbers
[] = {1, 7};
220 const UChar oneSecond
[] = {0x0031, 0x0020, 0x03b4, 0x03b5, 0x03c5, 0x03c4, 0x03b5, 0x03c1, 0x03cc, 0x03bb, 0x03b5, 0x03c0, 0x03c4, 0x03bf, 0};
221 const UChar oneMinute
[] = {0x0031, 0x0020, 0x03bb, 0x03b5, 0x03c0, 0x03c4, 0x03cc, 0};
222 const UChar oneHour
[] = {0x0031, 0x0020, 0x03ce, 0x03c1, 0x03b1, 0};
223 const UChar oneDay
[] = {0x0031, 0x0020, 0x03b7, 0x03bc, 0x03ad, 0x03c1, 0x03b1, 0};
224 const UChar oneMonth
[] = {0x0031, 0x0020, 0x03bc, 0x03ae, 0x03bd, 0x03b1, 0x03c2, 0};
225 const UChar oneYear
[] = {0x0031, 0x0020, 0x03ad, 0x03c4, 0x03bf, 0x03c2, 0};
226 const UChar sevenSeconds
[] = {0x0037, 0x0020, 0x03b4, 0x03b5, 0x03c5, 0x03c4, 0x03b5, 0x03c1, 0x03cc, 0x03bb, 0x03b5, 0x03c0, 0x03c4, 0x03b1, 0};
227 const UChar sevenMinutes
[] = {0x0037, 0x0020, 0x03bb, 0x03b5, 0x03c0, 0x03c4, 0x03ac, 0};
228 const UChar sevenHours
[] = {0x0037, 0x0020, 0x03ce, 0x03c1, 0x03b5, 0x03c2, 0};
229 const UChar sevenDays
[] = {0x0037, 0x0020, 0x03b7, 0x03bc, 0x03ad, 0x03c1, 0x03b5, 0x03c2, 0};
230 const UChar sevenMonths
[] = {0x0037, 0x0020, 0x03bc, 0x03ae, 0x03bd, 0x03b5, 0x3c2, 0};
231 const UChar sevenYears
[] = {0x0037, 0x0020, 0x03ad, 0x03c4, 0x03b7, 0};
233 const UnicodeString
oneSecondStr(oneSecond
);
234 const UnicodeString
oneMinuteStr(oneMinute
);
235 const UnicodeString
oneHourStr(oneHour
);
236 const UnicodeString
oneDayStr(oneDay
);
237 const UnicodeString
oneMonthStr(oneMonth
);
238 const UnicodeString
oneYearStr(oneYear
);
239 const UnicodeString
sevenSecondsStr(sevenSeconds
);
240 const UnicodeString
sevenMinutesStr(sevenMinutes
);
241 const UnicodeString
sevenHoursStr(sevenHours
);
242 const UnicodeString
sevenDaysStr(sevenDays
);
243 const UnicodeString
sevenMonthsStr(sevenMonths
);
244 const UnicodeString
sevenYearsStr(sevenYears
);
246 const UnicodeString expected
[] = {oneSecondStr
, oneMinuteStr
, oneHourStr
, oneDayStr
, oneMonthStr
, oneYearStr
,
247 oneSecondStr
, oneMinuteStr
, oneHourStr
, oneDayStr
, oneMonthStr
, oneYearStr
,
248 sevenSecondsStr
, sevenMinutesStr
, sevenHoursStr
, sevenDaysStr
, sevenMonthsStr
, sevenYearsStr
,
249 sevenSecondsStr
, sevenMinutesStr
, sevenHoursStr
, sevenDaysStr
, sevenMonthsStr
, sevenYearsStr
,
250 oneSecondStr
, oneMinuteStr
, oneHourStr
, oneDayStr
, oneMonthStr
, oneYearStr
,
251 oneSecondStr
, oneMinuteStr
, oneHourStr
, oneDayStr
, oneMonthStr
, oneYearStr
,
252 sevenSecondsStr
, sevenMinutesStr
, sevenHoursStr
, sevenDaysStr
, sevenMonthsStr
, sevenYearsStr
,
253 sevenSecondsStr
, sevenMinutesStr
, sevenHoursStr
, sevenDaysStr
, sevenMonthsStr
, sevenYearsStr
};
256 for ( unsigned int locIndex
= 0;
257 locIndex
< sizeof(locales
)/sizeof(locales
[0]);
260 Locale l
= Locale::createFromName(locales
[locIndex
]);
262 for ( unsigned int numberIndex
= 0;
263 numberIndex
< sizeof(numbers
)/sizeof(int);
266 for ( unsigned int styleIndex
= 0;
267 styleIndex
< sizeof(styles
)/sizeof(styles
[0]);
270 for ( unsigned int unitIndex
= 0;
271 unitIndex
< sizeof(tunits
)/sizeof(tunits
[0]);
274 TimeUnitAmount
*tamt
= new TimeUnitAmount(numbers
[numberIndex
], tunits
[unitIndex
], status
);
275 if (U_FAILURE(status
)) {
276 dataerrln("generating TimeUnitAmount Object failed.");
278 std::cout
<< "Failed to get TimeUnitAmount for " << tunits
[unitIndex
] << "\n";
283 TimeUnitFormat
*tfmt
= new TimeUnitFormat(l
, styles
[styleIndex
], status
);
284 if (U_FAILURE(status
)) {
285 dataerrln("generating TimeUnitAmount Object failed.");
287 std::cout
<< "Failed to get TimeUnitFormat for " << locales
[locIndex
] << "\n";
295 fmt
.adoptObject(tamt
);
296 str
= ((Format
*)tfmt
)->format(fmt
, str
, status
);
297 if (!assertSuccess("formatting relative time failed", status
)) {
300 std::cout
<< "Failed to format" << "\n";
306 char tmp
[128]; //output
307 char tmp1
[128]; //expected
309 u_strToUTF8(tmp
, 128, &len
, str
.getTerminatedBuffer(), str
.length(), &status
);
310 u_strToUTF8(tmp1
, 128, &len
, expected
[counter
].unescape().getTerminatedBuffer(), expected
[counter
].unescape().length(), &status
);
311 std::cout
<< "Formatted string : " << tmp
<< " expected : " << tmp1
<< "\n";
313 if (!assertEquals("formatted time string is not expected, locale: " + UnicodeString(locales
[locIndex
]) + " style: " + (int)styles
[styleIndex
] + " units: " + (int)tunits
[unitIndex
], expected
[counter
], str
)) {
328 void TimeUnitTest::testGreekWithSanitization() {
330 UErrorCode status
= U_ZERO_ERROR
;
332 NumberFormat
* numberFmt
= NumberFormat::createInstance(Locale("el"), status
);
333 if (!assertSuccess("NumberFormat::createInstance for el locale", status
, TRUE
)) return;
334 numberFmt
->setMaximumFractionDigits(1);
336 TimeUnitFormat
* timeUnitFormat
= new TimeUnitFormat(elLoc
, status
);
337 if (!assertSuccess("TimeUnitFormat::TimeUnitFormat for el locale", status
)) return;
339 timeUnitFormat
->setNumberFormat(*numberFmt
, status
);
342 delete timeUnitFormat
;