1 /******************************************************************** 2 * Copyright (c) 2008-2010, 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 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 */ 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[TimeUnitFormat::kFull] = new TimeUnitFormat(loc, status); 45 if (!assertSuccess("TimeUnitFormat(full)", status, TRUE)) return; 46 formats[TimeUnitFormat::kAbbreviate] = new TimeUnitFormat(loc, TimeUnitFormat::kAbbreviate, 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 = TimeUnitFormat::kFull; 52 style <= TimeUnitFormat::kAbbreviate; 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[TimeUnitFormat::kFull]; 94 delete formats[TimeUnitFormat::kAbbreviate]; 95 delete[] formats; 96 } 97 } 98 99 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"), TimeUnitFormat::kFull, status); 190 if (!assertSuccess("TimeUnitFormat(en...)", status)) return; 191 delete en_long; 192 193 TimeUnitFormat* en_short = new TimeUnitFormat(Locale("en"), TimeUnitFormat::kAbbreviate, 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 */ 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 TimeUnitFormat::EStyle styles[] = {TimeUnitFormat::kFull, TimeUnitFormat::kAbbreviate}; 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