Home | History | Annotate | Download | only in intltest
      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