• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /********************************************************************
2  * Copyright (c) 2008-2011, 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/tmunit.h"
11 #include "unicode/tmutamt.h"
12 #include "unicode/tmutfmt.h"
13 #include "tufmtts.h"
14 #include "unicode/ustring.h"
15 
16 //TODO: put as compilation flag
17 //#define TUFMTTS_DEBUG 1
18 
19 #ifdef TUFMTTS_DEBUG
20 #include <iostream>
21 #endif
22 
runIndexedTest(int32_t index,UBool exec,const char * & name,char *)23 void TimeUnitTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ ) {
24     if (exec) logln("TestSuite TimeUnitTest");
25     switch (index) {
26         TESTCASE(0, testBasic);
27         TESTCASE(1, testAPI);
28         TESTCASE(2, testGreek);
29         default: name = ""; break;
30     }
31 }
32 
33 /**
34  * Test basic
35  */
testBasic()36 void TimeUnitTest::testBasic() {
37     const char* locales[] = {"en", "sl", "fr", "zh", "ar", "ru", "zh_Hant", "pa"};
38     for ( unsigned int locIndex = 0;
39           locIndex < sizeof(locales)/sizeof(locales[0]);
40           ++locIndex ) {
41         UErrorCode status = U_ZERO_ERROR;
42         Locale loc(locales[locIndex]);
43         TimeUnitFormat** formats = new TimeUnitFormat*[2];
44         formats[UTMUTFMT_FULL_STYLE] = new TimeUnitFormat(loc, status);
45         if (!assertSuccess("TimeUnitFormat(full)", status, TRUE)) return;
46         formats[UTMUTFMT_ABBREVIATED_STYLE] = new TimeUnitFormat(loc, UTMUTFMT_ABBREVIATED_STYLE, status);
47         if (!assertSuccess("TimeUnitFormat(short)", status)) return;
48 #ifdef TUFMTTS_DEBUG
49         std::cout << "locale: " << locales[locIndex] << "\n";
50 #endif
51         for (int style = UTMUTFMT_FULL_STYLE;
52              style <= UTMUTFMT_ABBREVIATED_STYLE;
53              ++style) {
54           for (TimeUnit::UTimeUnitFields j = TimeUnit::UTIMEUNIT_YEAR;
55              j < TimeUnit::UTIMEUNIT_FIELD_COUNT;
56              j = (TimeUnit::UTimeUnitFields)(j+1)) {
57 #ifdef TUFMTTS_DEBUG
58             std::cout << "time unit: " << j << "\n";
59 #endif
60             double tests[] = {0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 5, 10, 100, 101.35};
61             for (unsigned int i = 0; i < sizeof(tests)/sizeof(tests[0]); ++i) {
62 #ifdef TUFMTTS_DEBUG
63                 std::cout << "number: " << tests[i] << "\n";
64 #endif
65                 TimeUnitAmount* source = new TimeUnitAmount(tests[i], j, status);
66                 if (!assertSuccess("TimeUnitAmount()", status)) return;
67                 UnicodeString formatted;
68                 Formattable formattable;
69                 formattable.adoptObject(source);
70                 formatted = ((Format*)formats[style])->format(formattable, formatted, status);
71                 if (!assertSuccess("format()", status)) return;
72 #ifdef TUFMTTS_DEBUG
73                 char formatResult[1000];
74                 formatted.extract(0, formatted.length(), formatResult, "UTF-8");
75                 std::cout << "format result: " << formatResult << "\n";
76 #endif
77                 Formattable result;
78                 ((Format*)formats[style])->parseObject(formatted, result, status);
79                 if (!assertSuccess("parseObject()", status)) return;
80                 if (result != formattable) {
81                     dataerrln("No round trip: ");
82                 }
83                 // other style parsing
84                 Formattable result_1;
85                 ((Format*)formats[1-style])->parseObject(formatted, result_1, status);
86                 if (!assertSuccess("parseObject()", status)) return;
87                 if (result_1 != formattable) {
88                     dataerrln("No round trip: ");
89                 }
90             }
91           }
92         }
93         delete formats[UTMUTFMT_FULL_STYLE];
94         delete formats[UTMUTFMT_ABBREVIATED_STYLE];
95         delete[] formats;
96     }
97 }
98 
99 
testAPI()100 void TimeUnitTest::testAPI() {
101     //================= TimeUnit =================
102     UErrorCode status = U_ZERO_ERROR;
103 
104     TimeUnit* tmunit = TimeUnit::createInstance(TimeUnit::UTIMEUNIT_YEAR, status);
105     if (!assertSuccess("TimeUnit::createInstance", status)) return;
106 
107     TimeUnit* another = (TimeUnit*)tmunit->clone();
108     TimeUnit third(*tmunit);
109     TimeUnit fourth = third;
110 
111     assertTrue("orig and clone are equal", (*tmunit == *another));
112     assertTrue("copied and assigned are equal", (third == fourth));
113 
114     TimeUnit* tmunit_m = TimeUnit::createInstance(TimeUnit::UTIMEUNIT_MONTH, status);
115     assertTrue("year != month", (*tmunit != *tmunit_m));
116 
117     TimeUnit::UTimeUnitFields field = tmunit_m->getTimeUnitField();
118     assertTrue("field of month time unit is month", (field == TimeUnit::UTIMEUNIT_MONTH));
119 
120     delete tmunit;
121     delete another;
122     delete tmunit_m;
123     //
124     //================= TimeUnitAmount =================
125 
126     Formattable formattable((int32_t)2);
127     TimeUnitAmount tma_long(formattable, TimeUnit::UTIMEUNIT_DAY, status);
128     if (!assertSuccess("TimeUnitAmount(formattable...)", status)) return;
129 
130     formattable.setDouble(2);
131     TimeUnitAmount tma_double(formattable, TimeUnit::UTIMEUNIT_DAY, status);
132     if (!assertSuccess("TimeUnitAmount(formattable...)", status)) return;
133 
134     formattable.setDouble(3);
135     TimeUnitAmount tma_double_3(formattable, TimeUnit::UTIMEUNIT_DAY, status);
136     if (!assertSuccess("TimeUnitAmount(formattable...)", status)) return;
137 
138     TimeUnitAmount tma(2, TimeUnit::UTIMEUNIT_DAY, status);
139     if (!assertSuccess("TimeUnitAmount(number...)", status)) return;
140 
141     TimeUnitAmount tma_h(2, TimeUnit::UTIMEUNIT_HOUR, status);
142     if (!assertSuccess("TimeUnitAmount(number...)", status)) return;
143 
144     TimeUnitAmount second(tma);
145     TimeUnitAmount third_tma = tma;
146     TimeUnitAmount* fourth_tma = (TimeUnitAmount*)tma.clone();
147 
148     assertTrue("orig and copy are equal", (second == tma));
149     assertTrue("clone and assigned are equal", (third_tma == *fourth_tma));
150     assertTrue("different if number diff", (tma_double != tma_double_3));
151     assertTrue("different if number type diff", (tma_double != tma_long));
152     assertTrue("different if time unit diff", (tma != tma_h));
153     assertTrue("same even different constructor", (tma_double == tma));
154 
155     assertTrue("getTimeUnitField", (tma.getTimeUnitField() == TimeUnit::UTIMEUNIT_DAY));
156     delete fourth_tma;
157     //
158     //================= TimeUnitFormat =================
159     //
160     TimeUnitFormat* tmf_en = new TimeUnitFormat(Locale("en"), status);
161     if (!assertSuccess("TimeUnitFormat(en...)", status, TRUE)) return;
162     TimeUnitFormat tmf_fr(Locale("fr"), status);
163     if (!assertSuccess("TimeUnitFormat(fr...)", status)) return;
164 
165     assertTrue("TimeUnitFormat: en and fr diff", (*tmf_en != tmf_fr));
166 
167     TimeUnitFormat tmf_assign = *tmf_en;
168     assertTrue("TimeUnitFormat: orig and assign are equal", (*tmf_en == tmf_assign));
169 
170     TimeUnitFormat tmf_copy(tmf_fr);
171     assertTrue("TimeUnitFormat: orig and copy are equal", (tmf_fr == tmf_copy));
172 
173     TimeUnitFormat* tmf_clone = (TimeUnitFormat*)tmf_en->clone();
174     assertTrue("TimeUnitFormat: orig and clone are equal", (*tmf_en == *tmf_clone));
175     delete tmf_clone;
176 
177     tmf_en->setLocale(Locale("fr"), status);
178     if (!assertSuccess("setLocale(fr...)", status)) return;
179 
180     NumberFormat* numberFmt = NumberFormat::createInstance(
181                                  Locale("fr"), status);
182     if (!assertSuccess("NumberFormat::createInstance()", status)) return;
183     tmf_en->setNumberFormat(*numberFmt, status);
184     if (!assertSuccess("setNumberFormat(en...)", status)) return;
185     assertTrue("TimeUnitFormat: setLocale", (*tmf_en == tmf_fr));
186 
187     delete tmf_en;
188 
189     TimeUnitFormat* en_long = new TimeUnitFormat(Locale("en"), UTMUTFMT_FULL_STYLE, status);
190     if (!assertSuccess("TimeUnitFormat(en...)", status)) return;
191     delete en_long;
192 
193     TimeUnitFormat* en_short = new TimeUnitFormat(Locale("en"), UTMUTFMT_ABBREVIATED_STYLE, status);
194     if (!assertSuccess("TimeUnitFormat(en...)", status)) return;
195     delete en_short;
196 
197     TimeUnitFormat* format = new TimeUnitFormat(status);
198     format->setLocale(Locale("zh"), status);
199     format->setNumberFormat(*numberFmt, status);
200     if (!assertSuccess("TimeUnitFormat(en...)", status)) return;
201     delete numberFmt;
202     delete format;
203 }
204 
205 /* @bug 7902
206  * Tests for Greek Language.
207  * This tests that requests for short unit names correctly fall back
208  * to long unit names for a locale where the locale data does not
209  * provide short unit names. As of CLDR 1.9, Greek is one such language.
210  */
testGreek()211 void TimeUnitTest::testGreek() {
212     UErrorCode status = U_ZERO_ERROR;
213 
214     const char* locales[] = {"el-GR", "el"};
215     TimeUnit::UTimeUnitFields tunits[] = {TimeUnit::UTIMEUNIT_SECOND, TimeUnit::UTIMEUNIT_MINUTE, TimeUnit::UTIMEUNIT_HOUR, TimeUnit::UTIMEUNIT_DAY, TimeUnit::UTIMEUNIT_MONTH, TimeUnit::UTIMEUNIT_YEAR};
216     UTimeUnitFormatStyle styles[] = {UTMUTFMT_FULL_STYLE, UTMUTFMT_ABBREVIATED_STYLE};
217     const int numbers[] = {1, 7};
218 
219     const UChar oneSecond[] = {0x0031, 0x0020, 0x03b4, 0x03b5, 0x03c5, 0x03c4, 0x03b5, 0x03c1, 0x03cc, 0x03bb, 0x03b5, 0x03c0, 0x03c4, 0x03bf, 0};
220     const UChar oneMinute[] = {0x0031, 0x0020, 0x03bb, 0x03b5, 0x03c0, 0x03c4, 0x03cc, 0};
221     const UChar oneHour[] = {0x0031, 0x0020, 0x03ce, 0x03c1, 0x03b1, 0};
222     const UChar oneDay[] = {0x0031, 0x0020, 0x03b7, 0x03bc, 0x03ad, 0x03c1, 0x03b1, 0};
223     const UChar oneMonth[] = {0x0031, 0x0020, 0x03bc, 0x03ae, 0x03bd, 0x03b1, 0x03c2, 0};
224     const UChar oneYear[] = {0x0031, 0x0020, 0x03ad, 0x03c4, 0x03bf, 0x03c2, 0};
225     const UChar sevenSeconds[] = {0x0037, 0x0020, 0x03b4, 0x03b5, 0x03c5, 0x03c4, 0x03b5, 0x03c1, 0x03cc, 0x03bb, 0x03b5, 0x03c0, 0x03c4, 0x03b1, 0};
226     const UChar sevenMinutes[] = {0x0037, 0x0020, 0x03bb, 0x03b5, 0x03c0, 0x03c4, 0x03ac, 0};
227     const UChar sevenHours[] = {0x0037, 0x0020, 0x03ce, 0x03c1, 0x03b5, 0x03c2, 0};
228     const UChar sevenDays[] = {0x0037, 0x0020, 0x03b7, 0x03bc, 0x03ad, 0x03c1, 0x03b5, 0x03c2, 0};
229     const UChar sevenMonths[] = {0x0037, 0x0020, 0x03bc, 0x03ae, 0x03bd, 0x03b5, 0x3c2, 0};
230     const UChar sevenYears[] = {0x0037, 0x0020, 0x03ad, 0x03c4, 0x03b7, 0};
231 
232     const UnicodeString oneSecondStr(oneSecond);
233     const UnicodeString oneMinuteStr(oneMinute);
234     const UnicodeString oneHourStr(oneHour);
235     const UnicodeString oneDayStr(oneDay);
236     const UnicodeString oneMonthStr(oneMonth);
237     const UnicodeString oneYearStr(oneYear);
238     const UnicodeString sevenSecondsStr(sevenSeconds);
239     const UnicodeString sevenMinutesStr(sevenMinutes);
240     const UnicodeString sevenHoursStr(sevenHours);
241     const UnicodeString sevenDaysStr(sevenDays);
242     const UnicodeString sevenMonthsStr(sevenMonths);
243     const UnicodeString sevenYearsStr(sevenYears);
244 
245     const UnicodeString expected[] = {oneSecondStr, oneMinuteStr, oneHourStr, oneDayStr, oneMonthStr, oneYearStr,
246                               oneSecondStr, oneMinuteStr, oneHourStr, oneDayStr, oneMonthStr, oneYearStr,
247                               sevenSecondsStr, sevenMinutesStr, sevenHoursStr, sevenDaysStr, sevenMonthsStr, sevenYearsStr,
248                               sevenSecondsStr, sevenMinutesStr, sevenHoursStr, sevenDaysStr, sevenMonthsStr, sevenYearsStr,
249                               oneSecondStr, oneMinuteStr, oneHourStr, oneDayStr, oneMonthStr, oneYearStr,
250                               oneSecondStr, oneMinuteStr, oneHourStr, oneDayStr, oneMonthStr, oneYearStr,
251                               sevenSecondsStr, sevenMinutesStr, sevenHoursStr, sevenDaysStr, sevenMonthsStr, sevenYearsStr,
252                               sevenSecondsStr, sevenMinutesStr, sevenHoursStr, sevenDaysStr, sevenMonthsStr, sevenYearsStr};
253 
254     int counter = 0;
255     for ( unsigned int locIndex = 0;
256         locIndex < sizeof(locales)/sizeof(locales[0]);
257         ++locIndex ) {
258 
259         Locale l = Locale::createFromName(locales[locIndex]);
260 
261         for ( unsigned int numberIndex = 0;
262             numberIndex < sizeof(numbers)/sizeof(int);
263             ++numberIndex ) {
264 
265             for ( unsigned int styleIndex = 0;
266                 styleIndex < sizeof(styles)/sizeof(styles[0]);
267                 ++styleIndex ) {
268 
269                 for ( unsigned int unitIndex = 0;
270                     unitIndex < sizeof(tunits)/sizeof(tunits[0]);
271                     ++unitIndex ) {
272 
273                     TimeUnitAmount *tamt = new TimeUnitAmount(numbers[numberIndex], tunits[unitIndex], status);
274                     if (U_FAILURE(status)) {
275                         dataerrln("generating TimeUnitAmount Object failed.");
276 #ifdef TUFMTTS_DEBUG
277                         std::cout << "Failed to get TimeUnitAmount for " << tunits[unitIndex] << "\n";
278 #endif
279                         return;
280                     }
281 
282                     TimeUnitFormat *tfmt = new TimeUnitFormat(l, styles[styleIndex], status);
283                     if (U_FAILURE(status)) {
284                         dataerrln("generating TimeUnitAmount Object failed.");
285 #ifdef TUFMTTS_DEBUG
286                        std::cout <<  "Failed to get TimeUnitFormat for " << locales[locIndex] << "\n";
287 #endif
288                        return;
289                     }
290 
291                     Formattable fmt;
292                     UnicodeString str;
293 
294                     fmt.adoptObject(tamt);
295                     str = ((Format *)tfmt)->format(fmt, str, status);
296                     if (!assertSuccess("formatting relative time failed", status)) {
297                         delete tfmt;
298 #ifdef TUFMTTS_DEBUG
299                         std::cout <<  "Failed to format" << "\n";
300 #endif
301                         return;
302                     }
303 
304 #ifdef TUFMTTS_DEBUG
305                     char tmp[128];    //output
306                     char tmp1[128];    //expected
307                     int len = 0;
308                     u_strToUTF8(tmp, 128, &len, str.getTerminatedBuffer(), str.length(), &status);
309                     u_strToUTF8(tmp1, 128, &len, expected[counter].unescape().getTerminatedBuffer(), expected[counter].unescape().length(), &status);
310                     std::cout <<  "Formatted string : " << tmp << " expected : " << tmp1 << "\n";
311 #endif
312                     if (!assertEquals("formatted time string is not expected, locale: " + UnicodeString(locales[locIndex]) + " style: " + (int)styles[styleIndex] + " units: " + (int)tunits[unitIndex], expected[counter], str)) {
313                         delete tfmt;
314                         str.remove();
315                         return;
316                     }
317                     delete tfmt;
318                     str.remove();
319                     ++counter;
320                 }
321             }
322         }
323     }
324 }
325 
326 #endif
327