1 /* 2 ******************************************************************************* 3 * Copyright (C) 2014, International Business Machines Corporation and * 4 * others. All Rights Reserved. * 5 ******************************************************************************* 6 * 7 * File MEASFMTTEST.CPP 8 * 9 ******************************************************************************* 10 */ 11 #include <stdio.h> 12 #include <stdlib.h> 13 14 #include "intltest.h" 15 16 #if !UCONFIG_NO_FORMATTING 17 18 #include "unicode/decimfmt.h" 19 #include "unicode/measfmt.h" 20 #include "unicode/measure.h" 21 #include "unicode/measunit.h" 22 #include "unicode/tmunit.h" 23 #include "charstr.h" 24 25 #define LENGTHOF(array) (int32_t)(sizeof(array) / sizeof((array)[0])) 26 27 struct ExpectedResult { 28 const Measure *measures; 29 int32_t count; 30 const char *expected; 31 }; 32 33 class MeasureFormatTest : public IntlTest { 34 public: 35 MeasureFormatTest() { 36 } 37 38 void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par=0); 39 private: 40 void TestBasic(); 41 void TestGetAvailable(); 42 void TestExamplesInDocs(); 43 void TestFormatPeriodEn(); 44 void Test10219FractionalPlurals(); 45 void TestGreek(); 46 void TestFormatSingleArg(); 47 void TestFormatMeasuresZeroArg(); 48 void TestMultiples(); 49 void TestGram(); 50 void TestCurrencies(); 51 void TestFieldPosition(); 52 void TestFieldPositionMultiple(); 53 void TestBadArg(); 54 void TestEquality(); 55 void TestDoubleZero(); 56 void verifyFormat( 57 const char *description, 58 const MeasureFormat &fmt, 59 const Measure *measures, 60 int32_t measureCount, 61 const char *expected); 62 void verifyFormatWithPrefix( 63 const char *description, 64 const MeasureFormat &fmt, 65 const UnicodeString &prefix, 66 const Measure *measures, 67 int32_t measureCount, 68 const char *expected); 69 void verifyFormat( 70 const char *description, 71 const MeasureFormat &fmt, 72 const ExpectedResult *expectedResults, 73 int32_t count); 74 void helperTestMultiples( 75 const Locale &locale, 76 UMeasureFormatWidth width, 77 const char *expected); 78 void verifyFieldPosition( 79 const char *description, 80 const MeasureFormat &fmt, 81 const UnicodeString &prefix, 82 const Measure *measures, 83 int32_t measureCount, 84 NumberFormat::EAlignmentFields field, 85 int32_t start, 86 int32_t end); 87 }; 88 89 void MeasureFormatTest::runIndexedTest( 90 int32_t index, UBool exec, const char *&name, char *) { 91 if (exec) { 92 logln("TestSuite MeasureFormatTest: "); 93 } 94 TESTCASE_AUTO_BEGIN; 95 TESTCASE_AUTO(TestBasic); 96 TESTCASE_AUTO(TestGetAvailable); 97 TESTCASE_AUTO(TestExamplesInDocs); 98 TESTCASE_AUTO(TestFormatPeriodEn); 99 TESTCASE_AUTO(Test10219FractionalPlurals); 100 TESTCASE_AUTO(TestGreek); 101 TESTCASE_AUTO(TestFormatSingleArg); 102 TESTCASE_AUTO(TestFormatMeasuresZeroArg); 103 TESTCASE_AUTO(TestMultiples); 104 TESTCASE_AUTO(TestGram); 105 TESTCASE_AUTO(TestCurrencies); 106 TESTCASE_AUTO(TestFieldPosition); 107 TESTCASE_AUTO(TestFieldPositionMultiple); 108 TESTCASE_AUTO(TestBadArg); 109 TESTCASE_AUTO(TestEquality); 110 TESTCASE_AUTO(TestDoubleZero); 111 TESTCASE_AUTO_END; 112 } 113 114 void MeasureFormatTest::TestBasic() { 115 UErrorCode status = U_ZERO_ERROR; 116 MeasureUnit *ptr1 = MeasureUnit::createArcMinute(status); 117 MeasureUnit *ptr2 = MeasureUnit::createArcMinute(status); 118 if (!(*ptr1 == *ptr2)) { 119 errln("Expect == to work."); 120 } 121 if (*ptr1 != *ptr2) { 122 errln("Expect != to work."); 123 } 124 MeasureUnit *ptr3 = MeasureUnit::createMeter(status); 125 if (*ptr1 == *ptr3) { 126 errln("Expect == to work."); 127 } 128 if (!(*ptr1 != *ptr3)) { 129 errln("Expect != to work."); 130 } 131 MeasureUnit *ptr4 = (MeasureUnit *) ptr1->clone(); 132 if (*ptr1 != *ptr4) { 133 errln("Expect clone to work."); 134 } 135 MeasureUnit stack; 136 stack = *ptr1; 137 if (*ptr1 != stack) { 138 errln("Expect assignment to work."); 139 } 140 141 delete ptr1; 142 delete ptr2; 143 delete ptr3; 144 delete ptr4; 145 } 146 147 void MeasureFormatTest::TestGetAvailable() { 148 MeasureUnit *units = NULL; 149 UErrorCode status = U_ZERO_ERROR; 150 int32_t totalCount = MeasureUnit::getAvailable(units, 0, status); 151 while (status == U_BUFFER_OVERFLOW_ERROR) { 152 status = U_ZERO_ERROR; 153 delete [] units; 154 units = new MeasureUnit[totalCount]; 155 totalCount = MeasureUnit::getAvailable(units, totalCount, status); 156 } 157 if (U_FAILURE(status)) { 158 dataerrln("Failure creating format object - %s", u_errorName(status)); 159 delete [] units; 160 return; 161 } 162 if (totalCount < 200) { 163 errln("Expect at least 200 measure units including currencies."); 164 } 165 delete [] units; 166 StringEnumeration *types = MeasureUnit::getAvailableTypes(status); 167 if (U_FAILURE(status)) { 168 dataerrln("Failure getting types - %s", u_errorName(status)); 169 delete types; 170 return; 171 } 172 if (types->count(status) < 10) { 173 errln("Expect at least 10 distinct unit types."); 174 } 175 units = NULL; 176 int32_t unitCapacity = 0; 177 int32_t unitCountSum = 0; 178 for ( 179 const char* type = types->next(NULL, status); 180 type != NULL; 181 type = types->next(NULL, status)) { 182 int32_t unitCount = MeasureUnit::getAvailable(type, units, unitCapacity, status); 183 while (status == U_BUFFER_OVERFLOW_ERROR) { 184 status = U_ZERO_ERROR; 185 delete [] units; 186 units = new MeasureUnit[unitCount]; 187 unitCapacity = unitCount; 188 unitCount = MeasureUnit::getAvailable(type, units, unitCapacity, status); 189 } 190 if (U_FAILURE(status)) { 191 dataerrln("Failure getting units - %s", u_errorName(status)); 192 delete [] units; 193 delete types; 194 return; 195 } 196 if (unitCount < 1) { 197 errln("Expect at least one unit count per type."); 198 } 199 unitCountSum += unitCount; 200 } 201 if (unitCountSum != totalCount) { 202 errln("Expected total unit count to equal sum of unit counts by type."); 203 } 204 delete [] units; 205 delete types; 206 } 207 208 void MeasureFormatTest::TestExamplesInDocs() { 209 UErrorCode status = U_ZERO_ERROR; 210 MeasureFormat fmtFr(Locale::getFrench(), UMEASFMT_WIDTH_SHORT, status); 211 MeasureFormat fmtFrFull( 212 Locale::getFrench(), UMEASFMT_WIDTH_WIDE, status); 213 MeasureFormat fmtFrNarrow( 214 Locale::getFrench(), UMEASFMT_WIDTH_NARROW, status); 215 MeasureFormat fmtEn(Locale::getUS(), UMEASFMT_WIDTH_WIDE, status); 216 if (!assertSuccess("Error creating formatters", status)) { 217 return; 218 } 219 Measure measureC(23, MeasureUnit::createCelsius(status), status); 220 Measure measureF(70, MeasureUnit::createFahrenheit(status), status); 221 Measure feetAndInches[] = { 222 Measure(70, MeasureUnit::createFoot(status), status), 223 Measure(5.3, MeasureUnit::createInch(status), status)}; 224 Measure footAndInch[] = { 225 Measure(1, MeasureUnit::createFoot(status), status), 226 Measure(1, MeasureUnit::createInch(status), status)}; 227 Measure inchAndFeet[] = { 228 Measure(1, MeasureUnit::createInch(status), status), 229 Measure(2, MeasureUnit::createFoot(status), status)}; 230 if (!assertSuccess("Error creating measurements.", status)) { 231 return; 232 } 233 verifyFormat( 234 "Celsius", 235 fmtFr, 236 &measureC, 237 1, 238 "23 \\u00B0C"); 239 verifyFormatWithPrefix( 240 "Celsius", 241 fmtFr, 242 "Prefix: ", 243 &measureC, 244 1, 245 "Prefix: 23 \\u00B0C"); 246 verifyFormat( 247 "Fahrenheit", 248 fmtFr, 249 &measureF, 250 1, 251 "70 \\u00B0F"); 252 verifyFormat( 253 "Feet and inches", 254 fmtFrFull, 255 feetAndInches, 256 LENGTHOF(feetAndInches), 257 "70 pieds et 5,3 pouces"); 258 verifyFormatWithPrefix( 259 "Feet and inches", 260 fmtFrFull, 261 "Prefix: ", 262 feetAndInches, 263 LENGTHOF(feetAndInches), 264 "Prefix: 70 pieds et 5,3 pouces"); 265 verifyFormat( 266 "Foot and inch", 267 fmtFrFull, 268 footAndInch, 269 LENGTHOF(footAndInch), 270 "1 pied et 1 pouce"); 271 verifyFormat( 272 "Foot and inch narrow", 273 fmtFrNarrow, 274 footAndInch, 275 LENGTHOF(footAndInch), 276 "1\\u2032 1\\u2033"); 277 verifyFormat( 278 "Inch and feet", 279 fmtEn, 280 inchAndFeet, 281 LENGTHOF(inchAndFeet), 282 "1 inch, 2 feet"); 283 } 284 285 void MeasureFormatTest::TestFormatPeriodEn() { 286 UErrorCode status = U_ZERO_ERROR; 287 Measure t_19m[] = {Measure(19, MeasureUnit::createMinute(status), status)}; 288 Measure t_1h_23_5s[] = { 289 Measure(1.0, MeasureUnit::createHour(status), status), 290 Measure(23.5, MeasureUnit::createSecond(status), status) 291 }; 292 Measure t_1h_23_5m[] = { 293 Measure(1.0, MeasureUnit::createHour(status), status), 294 Measure(23.5, MeasureUnit::createMinute(status), status) 295 }; 296 Measure t_1h_0m_23s[] = { 297 Measure( 298 1.0, 299 TimeUnit::createInstance( 300 TimeUnit::UTIMEUNIT_HOUR, status), 301 status), 302 Measure( 303 0.0, 304 TimeUnit::createInstance( 305 TimeUnit::UTIMEUNIT_MINUTE, status), 306 status), 307 Measure( 308 23, 309 TimeUnit::createInstance( 310 TimeUnit::UTIMEUNIT_SECOND, status), 311 status) 312 }; 313 Measure t_2y_5M_3w_4d[] = { 314 Measure(2.0, MeasureUnit::createYear(status), status), 315 Measure(5.0, MeasureUnit::createMonth(status), status), 316 Measure(3.0, MeasureUnit::createWeek(status), status), 317 Measure(4.0, MeasureUnit::createDay(status), status) 318 }; 319 Measure t_1m_59_9996s[] = { 320 Measure(1.0, MeasureUnit::createMinute(status), status), 321 Measure(59.9996, MeasureUnit::createSecond(status), status) 322 }; 323 Measure t_5h_17m[] = { 324 Measure(5.0, MeasureUnit::createHour(status), status), 325 Measure(17.0, MeasureUnit::createMinute(status), status) 326 }; 327 Measure t_neg5h_17m[] = { 328 Measure(-5.0, MeasureUnit::createHour(status), status), 329 Measure(17.0, MeasureUnit::createMinute(status), status) 330 }; 331 Measure t_19m_28s[] = { 332 Measure(19.0, MeasureUnit::createMinute(status), status), 333 Measure(28.0, MeasureUnit::createSecond(status), status) 334 }; 335 Measure t_0h_0m_9s[] = { 336 Measure(0.0, MeasureUnit::createHour(status), status), 337 Measure(0.0, MeasureUnit::createMinute(status), status), 338 Measure(9.0, MeasureUnit::createSecond(status), status) 339 }; 340 Measure t_0h_0m_17s[] = { 341 Measure(0.0, MeasureUnit::createHour(status), status), 342 Measure(0.0, MeasureUnit::createMinute(status), status), 343 Measure(17.0, MeasureUnit::createSecond(status), status) 344 }; 345 Measure t_6h_56_92m[] = { 346 Measure(6.0, MeasureUnit::createHour(status), status), 347 Measure(56.92, MeasureUnit::createMinute(status), status) 348 }; 349 Measure t_3h_4s_5m[] = { 350 Measure(3.0, MeasureUnit::createHour(status), status), 351 Measure(4.0, MeasureUnit::createSecond(status), status), 352 Measure(5.0, MeasureUnit::createMinute(status), status) 353 }; 354 Measure t_6_7h_56_92m[] = { 355 Measure(6.7, MeasureUnit::createHour(status), status), 356 Measure(56.92, MeasureUnit::createMinute(status), status) 357 }; 358 359 Measure t_3h_5h[] = { 360 Measure(3.0, MeasureUnit::createHour(status), status), 361 Measure(5.0, MeasureUnit::createHour(status), status) 362 }; 363 364 if (!assertSuccess("Error creating Measure objects", status)) { 365 return; 366 } 367 368 ExpectedResult fullData[] = { 369 {t_1m_59_9996s, LENGTHOF(t_1m_59_9996s), "1 minute, 59.9996 seconds"}, 370 {t_19m, LENGTHOF(t_19m), "19 minutes"}, 371 {t_1h_23_5s, LENGTHOF(t_1h_23_5s), "1 hour, 23.5 seconds"}, 372 {t_1h_23_5m, LENGTHOF(t_1h_23_5m), "1 hour, 23.5 minutes"}, 373 {t_1h_0m_23s, LENGTHOF(t_1h_0m_23s), "1 hour, 0 minutes, 23 seconds"}, 374 {t_2y_5M_3w_4d, LENGTHOF(t_2y_5M_3w_4d), "2 years, 5 months, 3 weeks, 4 days"}}; 375 376 ExpectedResult abbrevData[] = { 377 {t_1m_59_9996s, LENGTHOF(t_1m_59_9996s), "1 min, 59.9996 secs"}, 378 {t_19m, LENGTHOF(t_19m), "19 mins"}, 379 {t_1h_23_5s, LENGTHOF(t_1h_23_5s), "1 hr, 23.5 secs"}, 380 {t_1h_23_5m, LENGTHOF(t_1h_23_5m), "1 hr, 23.5 mins"}, 381 {t_1h_0m_23s, LENGTHOF(t_1h_0m_23s), "1 hr, 0 mins, 23 secs"}, 382 {t_2y_5M_3w_4d, LENGTHOF(t_2y_5M_3w_4d), "2 yrs, 5 mths, 3 wks, 4 days"}}; 383 384 ExpectedResult narrowData[] = { 385 {t_1m_59_9996s, LENGTHOF(t_1m_59_9996s), "1m 59.9996s"}, 386 {t_19m, LENGTHOF(t_19m), "19m"}, 387 {t_1h_23_5s, LENGTHOF(t_1h_23_5s), "1h 23.5s"}, 388 {t_1h_23_5m, LENGTHOF(t_1h_23_5m), "1h 23.5m"}, 389 {t_1h_0m_23s, LENGTHOF(t_1h_0m_23s), "1h 0m 23s"}, 390 {t_2y_5M_3w_4d, LENGTHOF(t_2y_5M_3w_4d), "2y 5m 3w 4d"}}; 391 392 ExpectedResult numericData[] = { 393 {t_1m_59_9996s, LENGTHOF(t_1m_59_9996s), "1:59.9996"}, 394 {t_19m, LENGTHOF(t_19m), "19m"}, 395 {t_1h_23_5s, LENGTHOF(t_1h_23_5s), "1:00:23.5"}, 396 {t_1h_23_5m, LENGTHOF(t_1h_23_5m), "1:23.5"}, 397 {t_1h_0m_23s, LENGTHOF(t_1h_0m_23s), "1:00:23"}, 398 {t_5h_17m, LENGTHOF(t_5h_17m), "5:17"}, 399 {t_neg5h_17m, LENGTHOF(t_neg5h_17m), "-5h 17m"}, 400 {t_19m_28s, LENGTHOF(t_19m_28s), "19:28"}, 401 {t_2y_5M_3w_4d, LENGTHOF(t_2y_5M_3w_4d), "2y 5m 3w 4d"}, 402 {t_0h_0m_9s, LENGTHOF(t_0h_0m_9s), "0:00:09"}, 403 {t_6h_56_92m, LENGTHOF(t_6h_56_92m), "6:56.92"}, 404 {t_6_7h_56_92m, LENGTHOF(t_6_7h_56_92m), "6:56.92"}, 405 {t_3h_4s_5m, LENGTHOF(t_3h_4s_5m), "3h 4s 5m"}, 406 {t_3h_5h, LENGTHOF(t_3h_5h), "3h 5h"}}; 407 408 ExpectedResult fullDataDe[] = { 409 {t_1m_59_9996s, LENGTHOF(t_1m_59_9996s), "1 Minute und 59,9996 Sekunden"}, 410 {t_19m, LENGTHOF(t_19m), "19 Minuten"}, 411 {t_1h_23_5s, LENGTHOF(t_1h_23_5s), "1 Stunde und 23,5 Sekunden"}, 412 {t_1h_23_5m, LENGTHOF(t_1h_23_5m), "1 Stunde und 23,5 Minuten"}, 413 {t_1h_0m_23s, LENGTHOF(t_1h_0m_23s), "1 Stunde, 0 Minuten und 23 Sekunden"}, 414 {t_2y_5M_3w_4d, LENGTHOF(t_2y_5M_3w_4d), "2 Jahre, 5 Monate, 3 Wochen und 4 Tage"}}; 415 416 ExpectedResult numericDataDe[] = { 417 {t_1m_59_9996s, LENGTHOF(t_1m_59_9996s), "1:59,9996"}, 418 {t_19m, LENGTHOF(t_19m), "19 Min."}, 419 {t_1h_23_5s, LENGTHOF(t_1h_23_5s), "1:00:23,5"}, 420 {t_1h_23_5m, LENGTHOF(t_1h_23_5m), "1:23,5"}, 421 {t_1h_0m_23s, LENGTHOF(t_1h_0m_23s), "1:00:23"}, 422 {t_5h_17m, LENGTHOF(t_5h_17m), "5:17"}, 423 {t_19m_28s, LENGTHOF(t_19m_28s), "19:28"}, 424 {t_2y_5M_3w_4d, LENGTHOF(t_2y_5M_3w_4d), "2 J, 5 M, 3 W und 4 T"}, 425 {t_0h_0m_17s, LENGTHOF(t_0h_0m_17s), "0:00:17"}, 426 {t_6h_56_92m, LENGTHOF(t_6h_56_92m), "6:56,92"}, 427 {t_3h_5h, LENGTHOF(t_3h_5h), "3 Std., 5 Std."}}; 428 429 Locale en(Locale::getEnglish()); 430 LocalPointer<NumberFormat> nf(NumberFormat::createInstance(en, status)); 431 if (U_FAILURE(status)) { 432 dataerrln("Error creating number format en object - %s", u_errorName(status)); 433 return; 434 } 435 nf->setMaximumFractionDigits(4); 436 MeasureFormat mf(en, UMEASFMT_WIDTH_WIDE, (NumberFormat *) nf->clone(), status); 437 if (!assertSuccess("Error creating measure format en WIDE", status)) { 438 return; 439 } 440 verifyFormat("en WIDE", mf, fullData, LENGTHOF(fullData)); 441 442 // exercise copy constructor 443 { 444 MeasureFormat mf2(mf); 445 verifyFormat("en WIDE copy", mf2, fullData, LENGTHOF(fullData)); 446 } 447 // exercise clone 448 { 449 MeasureFormat *mf3 = (MeasureFormat *) mf.clone(); 450 verifyFormat("en WIDE copy", *mf3, fullData, LENGTHOF(fullData)); 451 delete mf3; 452 } 453 mf = MeasureFormat(en, UMEASFMT_WIDTH_SHORT, (NumberFormat *) nf->clone(), status); 454 if (!assertSuccess("Error creating measure format en SHORT", status)) { 455 return; 456 } 457 verifyFormat("en SHORT", mf, abbrevData, LENGTHOF(abbrevData)); 458 mf = MeasureFormat(en, UMEASFMT_WIDTH_NARROW, (NumberFormat *) nf->clone(), status); 459 if (!assertSuccess("Error creating measure format en NARROW", status)) { 460 return; 461 } 462 verifyFormat("en NARROW", mf, narrowData, LENGTHOF(narrowData)); 463 mf = MeasureFormat(en, UMEASFMT_WIDTH_NUMERIC, (NumberFormat *) nf->clone(), status); 464 if (!assertSuccess("Error creating measure format en NUMERIC", status)) { 465 return; 466 } 467 verifyFormat("en NUMERIC", mf, numericData, LENGTHOF(numericData)); 468 469 Locale de(Locale::getGerman()); 470 nf.adoptInstead(NumberFormat::createInstance(de, status)); 471 if (!assertSuccess("Error creating number format de object", status)) { 472 return; 473 } 474 nf->setMaximumFractionDigits(4); 475 mf = MeasureFormat(de, UMEASFMT_WIDTH_WIDE, (NumberFormat *) nf->clone(), status); 476 if (!assertSuccess("Error creating measure format de WIDE", status)) { 477 return; 478 } 479 verifyFormat("de WIDE", mf, fullDataDe, LENGTHOF(fullDataDe)); 480 mf = MeasureFormat(de, UMEASFMT_WIDTH_NUMERIC, (NumberFormat *) nf->clone(), status); 481 if (!assertSuccess("Error creating measure format de NUMERIC", status)) { 482 return; 483 } 484 verifyFormat("de NUMERIC", mf, numericDataDe, LENGTHOF(numericDataDe)); 485 } 486 487 void MeasureFormatTest::Test10219FractionalPlurals() { 488 Locale en(Locale::getEnglish()); 489 double values[] = {1.588, 1.011}; 490 const char *expected[2][3] = { 491 {"1 minute", "1.5 minutes", "1.58 minutes"}, 492 {"1 minute", "1.0 minutes", "1.01 minutes"} 493 }; 494 UErrorCode status = U_ZERO_ERROR; 495 for (int j = 0; j < LENGTHOF(values); j++) { 496 for (int i = 0; i < LENGTHOF(expected[j]); i++) { 497 DecimalFormat *df = 498 (DecimalFormat *) NumberFormat::createInstance(en, status); 499 if (U_FAILURE(status)) { 500 dataerrln("Error creating Number format - %s", u_errorName(status)); 501 return; 502 } 503 df->setRoundingMode(DecimalFormat::kRoundDown); 504 df->setMinimumFractionDigits(i); 505 df->setMaximumFractionDigits(i); 506 MeasureFormat mf(en, UMEASFMT_WIDTH_WIDE, df, status); 507 if (!assertSuccess("Error creating Measure format", status)) { 508 return; 509 } 510 Measure measure(values[j], MeasureUnit::createMinute(status), status); 511 if (!assertSuccess("Error creating Measure unit", status)) { 512 return; 513 } 514 verifyFormat("Test10219", mf, &measure, 1, expected[j][i]); 515 } 516 } 517 } 518 519 static MeasureUnit toMeasureUnit(MeasureUnit *adopted) { 520 MeasureUnit result(*adopted); 521 delete adopted; 522 return result; 523 } 524 525 void MeasureFormatTest::TestGreek() { 526 Locale locales[] = {Locale("el_GR"), Locale("el")}; 527 UErrorCode status = U_ZERO_ERROR; 528 MeasureUnit units[] = { 529 toMeasureUnit(MeasureUnit::createSecond(status)), 530 toMeasureUnit(MeasureUnit::createMinute(status)), 531 toMeasureUnit(MeasureUnit::createHour(status)), 532 toMeasureUnit(MeasureUnit::createDay(status)), 533 toMeasureUnit(MeasureUnit::createWeek(status)), 534 toMeasureUnit(MeasureUnit::createMonth(status)), 535 toMeasureUnit(MeasureUnit::createYear(status))}; 536 if (!assertSuccess("Error creating Measure units", status)) { 537 return; 538 } 539 UMeasureFormatWidth styles[] = { 540 UMEASFMT_WIDTH_WIDE, 541 UMEASFMT_WIDTH_SHORT}; 542 int32_t numbers[] = {1, 7}; 543 const char *expected[] = { 544 "1 \\u03B4\\u03B5\\u03C5\\u03C4\\u03B5\\u03C1\\u03CC\\u03BB\\u03B5\\u03C0\\u03C4\\u03BF", 545 "1 \\u03BB\\u03B5\\u03C0\\u03C4\\u03CC", 546 "1 \\u03CE\\u03C1\\u03B1", 547 "1 \\u03B7\\u03BC\\u03AD\\u03C1\\u03B1", 548 "1 \\u03B5\\u03B2\\u03B4\\u03BF\\u03BC\\u03AC\\u03B4\\u03B1", 549 "1 \\u03BC\\u03AE\\u03BD\\u03B1\\u03C2", 550 "1 \\u03AD\\u03C4\\u03BF\\u03C2", 551 "1 \\u03B4\\u03B5\\u03C5\\u03C4.", 552 "1 \\u03BB\\u03B5\\u03C0.", 553 "1 \\u03CE\\u03C1\\u03B1", 554 "1 \\u03B7\\u03BC\\u03AD\\u03C1\\u03B1", 555 "1 \\u03B5\\u03B2\\u03B4.", 556 "1 \\u03BC\\u03AE\\u03BD.", 557 "1 \\u03AD\\u03C4\\u03BF\\u03C2", 558 "7 \\u03B4\\u03B5\\u03C5\\u03C4\\u03B5\\u03C1\\u03CC\\u03BB\\u03B5\\u03C0\\u03C4\\u03B1", 559 "7 \\u03BB\\u03B5\\u03C0\\u03C4\\u03AC", 560 "7 \\u03CE\\u03C1\\u03B5\\u03C2", 561 "7 \\u03B7\\u03BC\\u03AD\\u03C1\\u03B5\\u03C2", 562 "7 \\u03B5\\u03B2\\u03B4\\u03BF\\u03BC\\u03AC\\u03B4\\u03B5\\u03C2", 563 "7 \\u03BC\\u03AE\\u03BD\\u03B5\\u03C2", 564 "7 \\u03AD\\u03C4\\u03B7", 565 "7 \\u03B4\\u03B5\\u03C5\\u03C4.", 566 "7 \\u03BB\\u03B5\\u03C0.", 567 "7 \\u03CE\\u03C1\\u03B5\\u03C2", 568 "7 \\u03B7\\u03BC\\u03AD\\u03C1\\u03B5\\u03C2", 569 "7 \\u03B5\\u03B2\\u03B4.", 570 "7 \\u03BC\\u03AE\\u03BD.", 571 "7 \\u03AD\\u03C4\\u03B7", 572 "1 \\u03B4\\u03B5\\u03C5\\u03C4\\u03B5\\u03C1\\u03CC\\u03BB\\u03B5\\u03C0\\u03C4\\u03BF", 573 "1 \\u03BB\\u03B5\\u03C0\\u03C4\\u03CC", 574 "1 \\u03CE\\u03C1\\u03B1", 575 "1 \\u03B7\\u03BC\\u03AD\\u03C1\\u03B1", 576 "1 \\u03B5\\u03B2\\u03B4\\u03BF\\u03BC\\u03AC\\u03B4\\u03B1", 577 "1 \\u03BC\\u03AE\\u03BD\\u03B1\\u03C2", 578 "1 \\u03AD\\u03C4\\u03BF\\u03C2", 579 "1 \\u03B4\\u03B5\\u03C5\\u03C4.", 580 "1 \\u03BB\\u03B5\\u03C0.", 581 "1 \\u03CE\\u03C1\\u03B1", 582 "1 \\u03B7\\u03BC\\u03AD\\u03C1\\u03B1", 583 "1 \\u03B5\\u03B2\\u03B4.", 584 "1 \\u03BC\\u03AE\\u03BD.", 585 "1 \\u03AD\\u03C4\\u03BF\\u03C2", 586 "7 \\u03B4\\u03B5\\u03C5\\u03C4\\u03B5\\u03C1\\u03CC\\u03BB\\u03B5\\u03C0\\u03C4\\u03B1", 587 "7 \\u03BB\\u03B5\\u03C0\\u03C4\\u03AC", 588 "7 \\u03CE\\u03C1\\u03B5\\u03C2", 589 "7 \\u03B7\\u03BC\\u03AD\\u03C1\\u03B5\\u03C2", 590 "7 \\u03B5\\u03B2\\u03B4\\u03BF\\u03BC\\u03AC\\u03B4\\u03B5\\u03C2", 591 "7 \\u03BC\\u03AE\\u03BD\\u03B5\\u03C2", 592 "7 \\u03AD\\u03C4\\u03B7", 593 "7 \\u03B4\\u03B5\\u03C5\\u03C4.", 594 "7 \\u03BB\\u03B5\\u03C0.", 595 "7 \\u03CE\\u03C1\\u03B5\\u03C2", 596 "7 \\u03B7\\u03BC\\u03AD\\u03C1\\u03B5\\u03C2", 597 "7 \\u03B5\\u03B2\\u03B4.", 598 "7 \\u03BC\\u03AE\\u03BD.", 599 "7 \\u03AD\\u03C4\\u03B7"}; 600 601 int32_t counter = 0; 602 for (int32_t locIndex = 0; locIndex < LENGTHOF(locales); ++locIndex ) { 603 for( int32_t numIndex = 0; numIndex < LENGTHOF(numbers); ++numIndex ) { 604 for ( int32_t styleIndex = 0; styleIndex < LENGTHOF(styles); ++styleIndex ) { 605 for ( int32_t unitIndex = 0; unitIndex < LENGTHOF(units); ++unitIndex ) { 606 Measure measure(numbers[numIndex], new MeasureUnit(units[unitIndex]), status); 607 if (!assertSuccess("Error creating Measure", status)) { 608 return; 609 } 610 MeasureFormat fmt(locales[locIndex], styles[styleIndex], status); 611 if (!assertSuccess("Error creating Measure format", status)) { 612 return; 613 } 614 verifyFormat("TestGreek", fmt, &measure, 1, expected[counter]); 615 ++counter; 616 } 617 } 618 } 619 } 620 } 621 622 void MeasureFormatTest::TestFormatSingleArg() { 623 UErrorCode status = U_ZERO_ERROR; 624 MeasureFormat fmt("en", UMEASFMT_WIDTH_WIDE, status); 625 if (!assertSuccess("Error creating formatter", status)) { 626 return; 627 } 628 UnicodeString buffer; 629 FieldPosition pos(0); 630 fmt.format( 631 new Measure(3.5, MeasureUnit::createFoot(status), status), 632 buffer, 633 pos, 634 status); 635 if (!assertSuccess("Error formatting", status)) { 636 return; 637 } 638 assertEquals( 639 "TestFormatSingleArg", 640 UnicodeString("3.5 feet"), 641 buffer); 642 } 643 644 void MeasureFormatTest::TestFormatMeasuresZeroArg() { 645 UErrorCode status = U_ZERO_ERROR; 646 MeasureFormat fmt("en", UMEASFMT_WIDTH_WIDE, status); 647 verifyFormat("TestFormatMeasuresZeroArg", fmt, NULL, 0, ""); 648 } 649 650 void MeasureFormatTest::TestMultiples() { 651 Locale ru("ru"); 652 Locale en("en"); 653 helperTestMultiples(en, UMEASFMT_WIDTH_WIDE, "2 miles, 1 foot, 2.3 inches"); 654 helperTestMultiples(en, UMEASFMT_WIDTH_SHORT, "2 mi, 1 ft, 2.3 in"); 655 helperTestMultiples(en, UMEASFMT_WIDTH_NARROW, "2mi 1\\u2032 2.3\\u2033"); 656 helperTestMultiples(ru, UMEASFMT_WIDTH_WIDE, "2 \\u043C\\u0438\\u043B\\u0438, 1 \\u0444\\u0443\\u0442 \\u0438 2,3 \\u0434\\u044E\\u0439\\u043C\\u0430"); 657 helperTestMultiples(ru, UMEASFMT_WIDTH_SHORT, "2 \\u043C\\u0438\\u043B\\u0438, 1 \\u0444\\u0443\\u0442, 2,3 \\u0434\\u044E\\u0439\\u043C\\u0430"); 658 helperTestMultiples(ru, UMEASFMT_WIDTH_NARROW, "2 \\u043C\\u0438\\u043B\\u044C 1 \\u0444\\u0443\\u0442 2,3 \\u0434\\u044E\\u0439\\u043C\\u0430"); 659 } 660 661 void MeasureFormatTest::helperTestMultiples( 662 const Locale &locale, 663 UMeasureFormatWidth width, 664 const char *expected) { 665 UErrorCode status = U_ZERO_ERROR; 666 FieldPosition pos(0); 667 MeasureFormat fmt(locale, width, status); 668 if (!assertSuccess("Error creating format object", status)) { 669 return; 670 } 671 Measure measures[] = { 672 Measure(2, MeasureUnit::createMile(status), status), 673 Measure(1, MeasureUnit::createFoot(status), status), 674 Measure(2.3, MeasureUnit::createInch(status), status)}; 675 if (!assertSuccess("Error creating measures", status)) { 676 return; 677 } 678 UnicodeString buffer; 679 fmt.formatMeasures(measures, LENGTHOF(measures), buffer, pos, status); 680 if (!assertSuccess("Error formatting measures", status)) { 681 return; 682 } 683 assertEquals("TestMultiples", UnicodeString(expected).unescape(), buffer); 684 } 685 686 void MeasureFormatTest::TestGram() { 687 UErrorCode status = U_ZERO_ERROR; 688 MeasureFormat fmt("en", UMEASFMT_WIDTH_SHORT, status); 689 if (!assertSuccess("Error creating format object", status)) { 690 return; 691 } 692 Measure gram(1, MeasureUnit::createGram(status), status); 693 Measure gforce(1, MeasureUnit::createGForce(status), status); 694 if (!assertSuccess("Error creating measures", status)) { 695 return; 696 } 697 verifyFormat("TestGram", fmt, &gram, 1, "1 g"); 698 verifyFormat("TestGram", fmt, &gforce, 1, "1 G"); 699 } 700 701 void MeasureFormatTest::TestCurrencies() { 702 UChar USD[] = {'U', 'S', 'D', 0}; 703 UErrorCode status = U_ZERO_ERROR; 704 CurrencyAmount USD_1(1.0, USD, status); 705 CurrencyAmount USD_2(2.0, USD, status); 706 CurrencyAmount USD_NEG_1(-1.0, USD, status); 707 if (!assertSuccess("Error creating measures", status)) { 708 return; 709 } 710 Locale en("en"); 711 MeasureFormat fmt(en, UMEASFMT_WIDTH_WIDE, status); 712 if (!assertSuccess("Error creating format object", status)) { 713 return; 714 } 715 verifyFormat("TestCurrenciesWide", fmt, &USD_NEG_1, 1, "-1.00 US dollars"); 716 verifyFormat("TestCurrenciesWide", fmt, &USD_1, 1, "1.00 US dollars"); 717 verifyFormat("TestCurrenciesWide", fmt, &USD_2, 1, "2.00 US dollars"); 718 fmt = MeasureFormat(en, UMEASFMT_WIDTH_SHORT, status); 719 if (!assertSuccess("Error creating format object", status)) { 720 return; 721 } 722 verifyFormat("TestCurrenciesShort", fmt, &USD_NEG_1, 1, "-USD1.00"); 723 verifyFormat("TestCurrenciesShort", fmt, &USD_1, 1, "USD1.00"); 724 verifyFormat("TestCurrenciesShort", fmt, &USD_2, 1, "USD2.00"); 725 fmt = MeasureFormat(en, UMEASFMT_WIDTH_NARROW, status); 726 if (!assertSuccess("Error creating format object", status)) { 727 return; 728 } 729 verifyFormat("TestCurrenciesNarrow", fmt, &USD_NEG_1, 1, "-$1.00"); 730 verifyFormat("TestCurrenciesNarrow", fmt, &USD_1, 1, "$1.00"); 731 verifyFormat("TestCurrenciesNarrow", fmt, &USD_2, 1, "$2.00"); 732 fmt = MeasureFormat(en, UMEASFMT_WIDTH_NUMERIC, status); 733 if (!assertSuccess("Error creating format object", status)) { 734 return; 735 } 736 verifyFormat("TestCurrenciesNumeric", fmt, &USD_NEG_1, 1, "-$1.00"); 737 verifyFormat("TestCurrenciesNumeric", fmt, &USD_1, 1, "$1.00"); 738 verifyFormat("TestCurrenciesNumeric", fmt, &USD_2, 1, "$2.00"); 739 } 740 741 void MeasureFormatTest::TestFieldPosition() { 742 UErrorCode status = U_ZERO_ERROR; 743 MeasureFormat fmt("en", UMEASFMT_WIDTH_SHORT, status); 744 if (!assertSuccess("Error creating format object", status)) { 745 return; 746 } 747 Measure measure(43.5, MeasureUnit::createFoot(status), status); 748 if (!assertSuccess("Error creating measure object 1", status)) { 749 return; 750 } 751 UnicodeString prefix("123456: "); 752 verifyFieldPosition( 753 "", 754 fmt, 755 prefix, 756 &measure, 757 1, 758 NumberFormat::kDecimalSeparatorField, 759 10, 760 11); 761 measure = Measure(43, MeasureUnit::createFoot(status), status); 762 if (!assertSuccess("Error creating measure object 2", status)) { 763 return; 764 } 765 verifyFieldPosition( 766 "", 767 fmt, 768 prefix, 769 &measure, 770 1, 771 NumberFormat::kDecimalSeparatorField, 772 0, 773 0); 774 } 775 776 void MeasureFormatTest::TestFieldPositionMultiple() { 777 UErrorCode status = U_ZERO_ERROR; 778 MeasureFormat fmt("en", UMEASFMT_WIDTH_SHORT, status); 779 if (!assertSuccess("Error creating format object", status)) { 780 return; 781 } 782 Measure first[] = { 783 Measure(354, MeasureUnit::createMeter(status), status), 784 Measure(23, MeasureUnit::createCentimeter(status), status)}; 785 Measure second[] = { 786 Measure(354, MeasureUnit::createMeter(status), status), 787 Measure(23, MeasureUnit::createCentimeter(status), status), 788 Measure(5.4, MeasureUnit::createMillimeter(status), status)}; 789 Measure third[] = { 790 Measure(3, MeasureUnit::createMeter(status), status), 791 Measure(23, MeasureUnit::createCentimeter(status), status), 792 Measure(5, MeasureUnit::createMillimeter(status), status)}; 793 if (!assertSuccess("Error creating measure objects", status)) { 794 return; 795 } 796 UnicodeString prefix("123456: "); 797 verifyFieldPosition( 798 "Integer", 799 fmt, 800 prefix, 801 first, 802 LENGTHOF(first), 803 NumberFormat::kIntegerField, 804 8, 805 11); 806 verifyFieldPosition( 807 "Decimal separator", 808 fmt, 809 prefix, 810 second, 811 LENGTHOF(second), 812 NumberFormat::kDecimalSeparatorField, 813 23, 814 24); 815 verifyFieldPosition( 816 "no decimal separator", 817 fmt, 818 prefix, 819 third, 820 LENGTHOF(third), 821 NumberFormat::kDecimalSeparatorField, 822 0, 823 0); 824 } 825 826 void MeasureFormatTest::TestBadArg() { 827 UErrorCode status = U_ZERO_ERROR; 828 MeasureFormat fmt("en", UMEASFMT_WIDTH_SHORT, status); 829 if (!assertSuccess("Error creating format object", status)) { 830 return; 831 } 832 FieldPosition pos(0); 833 UnicodeString buffer; 834 fmt.format( 835 9.3, 836 buffer, 837 pos, 838 status); 839 if (status != U_ILLEGAL_ARGUMENT_ERROR) { 840 errln("Expected ILLEGAL_ARGUMENT_ERROR"); 841 } 842 } 843 844 void MeasureFormatTest::TestEquality() { 845 UErrorCode status = U_ZERO_ERROR; 846 NumberFormat* nfeq = NumberFormat::createInstance("en", status); 847 NumberFormat* nfne = NumberFormat::createInstance("fr", status); 848 MeasureFormat fmt("en", UMEASFMT_WIDTH_SHORT, status); 849 MeasureFormat fmtEq2("en", UMEASFMT_WIDTH_SHORT, nfeq, status); 850 MeasureFormat fmtne1("en", UMEASFMT_WIDTH_WIDE, status); 851 MeasureFormat fmtne2("fr", UMEASFMT_WIDTH_SHORT, status); 852 MeasureFormat fmtne3("en", UMEASFMT_WIDTH_SHORT, nfne, status); 853 if (U_FAILURE(status)) { 854 dataerrln("Error creating MeasureFormats - %s", u_errorName(status)); 855 return; 856 } 857 MeasureFormat fmtEq(fmt); 858 assertTrue("Equal", fmt == fmtEq); 859 assertTrue("Equal2", fmt == fmtEq2); 860 assertFalse("Equal Neg", fmt != fmtEq); 861 assertTrue("Not Equal 1", fmt != fmtne1); 862 assertFalse("Not Equal Neg 1", fmt == fmtne1); 863 assertTrue("Not Equal 2", fmt != fmtne2); 864 assertTrue("Not Equal 3", fmt != fmtne3); 865 } 866 867 void MeasureFormatTest::TestDoubleZero() { 868 UErrorCode status = U_ZERO_ERROR; 869 Measure measures[] = { 870 Measure(4.7, MeasureUnit::createHour(status), status), 871 Measure(23, MeasureUnit::createMinute(status), status), 872 Measure(16, MeasureUnit::createSecond(status), status)}; 873 Locale en("en"); 874 NumberFormat *nf = NumberFormat::createInstance(en, status); 875 MeasureFormat fmt("en", UMEASFMT_WIDTH_WIDE, nf, status); 876 UnicodeString appendTo; 877 FieldPosition pos(FieldPosition::DONT_CARE); 878 if (U_FAILURE(status)) { 879 dataerrln("Error creating formatter - %s", u_errorName(status)); 880 return; 881 } 882 nf->setMinimumFractionDigits(2); 883 nf->setMaximumFractionDigits(2); 884 fmt.formatMeasures(measures, LENGTHOF(measures), appendTo, pos, status); 885 if (!assertSuccess("Error formatting", status)) { 886 return; 887 } 888 assertEquals( 889 "TestDoubleZero", 890 UnicodeString("4 hours, 23 minutes, 16.00 seconds"), 891 appendTo); 892 measures[0] = Measure(-4.7, MeasureUnit::createHour(status), status); 893 appendTo.remove(); 894 fmt.formatMeasures(measures, LENGTHOF(measures), appendTo, pos, status); 895 if (!assertSuccess("Error formatting", status)) { 896 return; 897 } 898 assertEquals( 899 "TestDoubleZero", 900 UnicodeString("-4 hours, 23 minutes, 16.00 seconds"), 901 appendTo); 902 } 903 904 void MeasureFormatTest::verifyFieldPosition( 905 const char *description, 906 const MeasureFormat &fmt, 907 const UnicodeString &prefix, 908 const Measure *measures, 909 int32_t measureCount, 910 NumberFormat::EAlignmentFields field, 911 int32_t start, 912 int32_t end) { 913 // 8 char lead 914 UnicodeString result(prefix); 915 FieldPosition pos(field); 916 UErrorCode status = U_ZERO_ERROR; 917 CharString ch; 918 const char *descPrefix = ch.append(description, status) 919 .append(": ", status).data(); 920 CharString beginIndex; 921 beginIndex.append(descPrefix, status).append("beginIndex", status); 922 CharString endIndex; 923 endIndex.append(descPrefix, status).append("endIndex", status); 924 fmt.formatMeasures(measures, measureCount, result, pos, status); 925 if (!assertSuccess("Error formatting", status)) { 926 return; 927 } 928 assertEquals(beginIndex.data(), start, pos.getBeginIndex()); 929 assertEquals(endIndex.data(), end, pos.getEndIndex()); 930 } 931 932 void MeasureFormatTest::verifyFormat( 933 const char *description, 934 const MeasureFormat &fmt, 935 const Measure *measures, 936 int32_t measureCount, 937 const char *expected) { 938 verifyFormatWithPrefix( 939 description, 940 fmt, 941 "", 942 measures, 943 measureCount, 944 expected); 945 } 946 947 void MeasureFormatTest::verifyFormatWithPrefix( 948 const char *description, 949 const MeasureFormat &fmt, 950 const UnicodeString &prefix, 951 const Measure *measures, 952 int32_t measureCount, 953 const char *expected) { 954 UnicodeString result(prefix); 955 FieldPosition pos(0); 956 UErrorCode status = U_ZERO_ERROR; 957 fmt.formatMeasures(measures, measureCount, result, pos, status); 958 if (!assertSuccess("Error formatting", status)) { 959 return; 960 } 961 assertEquals(description, UnicodeString(expected).unescape(), result); 962 } 963 964 void MeasureFormatTest::verifyFormat( 965 const char *description, 966 const MeasureFormat &fmt, 967 const ExpectedResult *expectedResults, 968 int32_t count) { 969 for (int32_t i = 0; i < count; ++i) { 970 verifyFormat(description, fmt, expectedResults[i].measures, expectedResults[i].count, expectedResults[i].expected); 971 } 972 } 973 974 extern IntlTest *createMeasureFormatTest() { 975 return new MeasureFormatTest(); 976 } 977 978 #endif 979 980