1 /*
2 *******************************************************************************
3 * Copyright (C) 2014-2015, 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 "unicode/plurrule.h"
24 #include "charstr.h"
25 #include "unicode/reldatefmt.h"
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:
MeasureFormatTest()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 TestCompatible53_1();
42     void TestCompatible54_1();
43     void TestGetAvailable();
44     void TestExamplesInDocs();
45     void TestFormatPeriodEn();
46     void Test10219FractionalPlurals();
47     void TestGreek();
48     void TestFormatSingleArg();
49     void TestFormatMeasuresZeroArg();
50     void TestSimplePer();
51     void TestNumeratorPlurals();
52     void TestMultiples();
53     void TestGram();
54     void TestCurrencies();
55     void TestFieldPosition();
56     void TestFieldPositionMultiple();
57     void TestBadArg();
58     void TestEquality();
59     void TestGroupingSeparator();
60     void TestDoubleZero();
61     void TestUnitPerUnitResolution();
62     void verifyFormat(
63         const char *description,
64         const MeasureFormat &fmt,
65         const Measure *measures,
66         int32_t measureCount,
67         const char *expected);
68     void verifyFormatWithPrefix(
69         const char *description,
70         const MeasureFormat &fmt,
71         const UnicodeString &prefix,
72         const Measure *measures,
73         int32_t measureCount,
74         const char *expected);
75     void verifyFormat(
76         const char *description,
77         const MeasureFormat &fmt,
78         const ExpectedResult *expectedResults,
79         int32_t count);
80     void helperTestSimplePer(
81         const Locale &locale,
82         UMeasureFormatWidth width,
83         double value,
84         const MeasureUnit &unit,
85         const MeasureUnit &perUnit,
86         const char *expected);
87     void helperTestSimplePer(
88         const Locale &locale,
89         UMeasureFormatWidth width,
90         double value,
91         const MeasureUnit &unit,
92         const MeasureUnit &perUnit,
93         const char *expected,
94         int32_t field,
95         int32_t expected_start,
96         int32_t expected_end);
97     void helperTestMultiples(
98         const Locale &locale,
99         UMeasureFormatWidth width,
100         const char *expected);
101     void verifyFieldPosition(
102         const char *description,
103         const MeasureFormat &fmt,
104         const UnicodeString &prefix,
105         const Measure *measures,
106         int32_t measureCount,
107         NumberFormat::EAlignmentFields field,
108         int32_t start,
109         int32_t end);
110 };
111 
runIndexedTest(int32_t index,UBool exec,const char * & name,char *)112 void MeasureFormatTest::runIndexedTest(
113         int32_t index, UBool exec, const char *&name, char *) {
114     if (exec) {
115         logln("TestSuite MeasureFormatTest: ");
116     }
117     TESTCASE_AUTO_BEGIN;
118     TESTCASE_AUTO(TestBasic);
119     TESTCASE_AUTO(TestCompatible53_1);
120     TESTCASE_AUTO(TestCompatible54_1);
121     TESTCASE_AUTO(TestGetAvailable);
122     TESTCASE_AUTO(TestExamplesInDocs);
123     TESTCASE_AUTO(TestFormatPeriodEn);
124     TESTCASE_AUTO(Test10219FractionalPlurals);
125     TESTCASE_AUTO(TestGreek);
126     TESTCASE_AUTO(TestFormatSingleArg);
127     TESTCASE_AUTO(TestFormatMeasuresZeroArg);
128     TESTCASE_AUTO(TestSimplePer);
129     TESTCASE_AUTO(TestNumeratorPlurals);
130     TESTCASE_AUTO(TestMultiples);
131     TESTCASE_AUTO(TestGram);
132     TESTCASE_AUTO(TestCurrencies);
133     TESTCASE_AUTO(TestFieldPosition);
134     TESTCASE_AUTO(TestFieldPositionMultiple);
135     TESTCASE_AUTO(TestBadArg);
136     TESTCASE_AUTO(TestEquality);
137     TESTCASE_AUTO(TestGroupingSeparator);
138     TESTCASE_AUTO(TestDoubleZero);
139     TESTCASE_AUTO(TestUnitPerUnitResolution);
140     TESTCASE_AUTO_END;
141 }
142 
TestCompatible53_1()143 void MeasureFormatTest::TestCompatible53_1() {
144     UErrorCode status = U_ZERO_ERROR;
145     LocalPointer<MeasureUnit> measureUnit;
146     measureUnit.adoptInstead(MeasureUnit::createGForce(status));
147     measureUnit.adoptInstead(MeasureUnit::createArcMinute(status));
148     measureUnit.adoptInstead(MeasureUnit::createArcSecond(status));
149     measureUnit.adoptInstead(MeasureUnit::createDegree(status));
150     measureUnit.adoptInstead(MeasureUnit::createAcre(status));
151     measureUnit.adoptInstead(MeasureUnit::createHectare(status));
152     measureUnit.adoptInstead(MeasureUnit::createSquareFoot(status));
153     measureUnit.adoptInstead(MeasureUnit::createSquareKilometer(status));
154     measureUnit.adoptInstead(MeasureUnit::createSquareMeter(status));
155     measureUnit.adoptInstead(MeasureUnit::createSquareMile(status));
156     measureUnit.adoptInstead(MeasureUnit::createDay(status));
157     measureUnit.adoptInstead(MeasureUnit::createHour(status));
158     measureUnit.adoptInstead(MeasureUnit::createMillisecond(status));
159     measureUnit.adoptInstead(MeasureUnit::createMinute(status));
160     measureUnit.adoptInstead(MeasureUnit::createMonth(status));
161     measureUnit.adoptInstead(MeasureUnit::createSecond(status));
162     measureUnit.adoptInstead(MeasureUnit::createWeek(status));
163     measureUnit.adoptInstead(MeasureUnit::createYear(status));
164     measureUnit.adoptInstead(MeasureUnit::createCentimeter(status));
165     measureUnit.adoptInstead(MeasureUnit::createFoot(status));
166     measureUnit.adoptInstead(MeasureUnit::createInch(status));
167     measureUnit.adoptInstead(MeasureUnit::createKilometer(status));
168     measureUnit.adoptInstead(MeasureUnit::createLightYear(status));
169     measureUnit.adoptInstead(MeasureUnit::createMeter(status));
170     measureUnit.adoptInstead(MeasureUnit::createMile(status));
171     measureUnit.adoptInstead(MeasureUnit::createMillimeter(status));
172     measureUnit.adoptInstead(MeasureUnit::createPicometer(status));
173     measureUnit.adoptInstead(MeasureUnit::createYard(status));
174     measureUnit.adoptInstead(MeasureUnit::createGram(status));
175     measureUnit.adoptInstead(MeasureUnit::createKilogram(status));
176     measureUnit.adoptInstead(MeasureUnit::createOunce(status));
177     measureUnit.adoptInstead(MeasureUnit::createPound(status));
178     measureUnit.adoptInstead(MeasureUnit::createHorsepower(status));
179     measureUnit.adoptInstead(MeasureUnit::createKilowatt(status));
180     measureUnit.adoptInstead(MeasureUnit::createWatt(status));
181     measureUnit.adoptInstead(MeasureUnit::createHectopascal(status));
182     measureUnit.adoptInstead(MeasureUnit::createInchHg(status));
183     measureUnit.adoptInstead(MeasureUnit::createMillibar(status));
184     measureUnit.adoptInstead(MeasureUnit::createKilometerPerHour(status));
185     measureUnit.adoptInstead(MeasureUnit::createMeterPerSecond(status));
186     measureUnit.adoptInstead(MeasureUnit::createMilePerHour(status));
187     measureUnit.adoptInstead(MeasureUnit::createCelsius(status));
188     measureUnit.adoptInstead(MeasureUnit::createFahrenheit(status));
189     measureUnit.adoptInstead(MeasureUnit::createCubicKilometer(status));
190     measureUnit.adoptInstead(MeasureUnit::createCubicMile(status));
191     measureUnit.adoptInstead(MeasureUnit::createLiter(status));
192     assertSuccess("", status);
193 }
194 
TestCompatible54_1()195 void MeasureFormatTest::TestCompatible54_1() {
196     UErrorCode status = U_ZERO_ERROR;
197     LocalPointer<MeasureUnit> measureUnit;
198     measureUnit.adoptInstead(MeasureUnit::createGForce(status));
199     measureUnit.adoptInstead(MeasureUnit::createMeterPerSecondSquared(status));
200     measureUnit.adoptInstead(MeasureUnit::createArcMinute(status));
201     measureUnit.adoptInstead(MeasureUnit::createArcSecond(status));
202     measureUnit.adoptInstead(MeasureUnit::createDegree(status));
203     measureUnit.adoptInstead(MeasureUnit::createRadian(status));
204     measureUnit.adoptInstead(MeasureUnit::createAcre(status));
205     measureUnit.adoptInstead(MeasureUnit::createHectare(status));
206     measureUnit.adoptInstead(MeasureUnit::createSquareCentimeter(status));
207     measureUnit.adoptInstead(MeasureUnit::createSquareFoot(status));
208     measureUnit.adoptInstead(MeasureUnit::createSquareInch(status));
209     measureUnit.adoptInstead(MeasureUnit::createSquareKilometer(status));
210     measureUnit.adoptInstead(MeasureUnit::createSquareMeter(status));
211     measureUnit.adoptInstead(MeasureUnit::createSquareMile(status));
212     measureUnit.adoptInstead(MeasureUnit::createSquareYard(status));
213     measureUnit.adoptInstead(MeasureUnit::createLiterPerKilometer(status));
214     measureUnit.adoptInstead(MeasureUnit::createMilePerGallon(status));
215     measureUnit.adoptInstead(MeasureUnit::createBit(status));
216     measureUnit.adoptInstead(MeasureUnit::createByte(status));
217     measureUnit.adoptInstead(MeasureUnit::createGigabit(status));
218     measureUnit.adoptInstead(MeasureUnit::createGigabyte(status));
219     measureUnit.adoptInstead(MeasureUnit::createKilobit(status));
220     measureUnit.adoptInstead(MeasureUnit::createKilobyte(status));
221     measureUnit.adoptInstead(MeasureUnit::createMegabit(status));
222     measureUnit.adoptInstead(MeasureUnit::createMegabyte(status));
223     measureUnit.adoptInstead(MeasureUnit::createTerabit(status));
224     measureUnit.adoptInstead(MeasureUnit::createTerabyte(status));
225     measureUnit.adoptInstead(MeasureUnit::createDay(status));
226     measureUnit.adoptInstead(MeasureUnit::createHour(status));
227     measureUnit.adoptInstead(MeasureUnit::createMicrosecond(status));
228     measureUnit.adoptInstead(MeasureUnit::createMillisecond(status));
229     measureUnit.adoptInstead(MeasureUnit::createMinute(status));
230     measureUnit.adoptInstead(MeasureUnit::createMonth(status));
231     measureUnit.adoptInstead(MeasureUnit::createNanosecond(status));
232     measureUnit.adoptInstead(MeasureUnit::createSecond(status));
233     measureUnit.adoptInstead(MeasureUnit::createWeek(status));
234     measureUnit.adoptInstead(MeasureUnit::createYear(status));
235     measureUnit.adoptInstead(MeasureUnit::createAmpere(status));
236     measureUnit.adoptInstead(MeasureUnit::createMilliampere(status));
237     measureUnit.adoptInstead(MeasureUnit::createOhm(status));
238     measureUnit.adoptInstead(MeasureUnit::createVolt(status));
239     measureUnit.adoptInstead(MeasureUnit::createCalorie(status));
240     measureUnit.adoptInstead(MeasureUnit::createFoodcalorie(status));
241     measureUnit.adoptInstead(MeasureUnit::createJoule(status));
242     measureUnit.adoptInstead(MeasureUnit::createKilocalorie(status));
243     measureUnit.adoptInstead(MeasureUnit::createKilojoule(status));
244     measureUnit.adoptInstead(MeasureUnit::createKilowattHour(status));
245     measureUnit.adoptInstead(MeasureUnit::createGigahertz(status));
246     measureUnit.adoptInstead(MeasureUnit::createHertz(status));
247     measureUnit.adoptInstead(MeasureUnit::createKilohertz(status));
248     measureUnit.adoptInstead(MeasureUnit::createMegahertz(status));
249     measureUnit.adoptInstead(MeasureUnit::createAstronomicalUnit(status));
250     measureUnit.adoptInstead(MeasureUnit::createCentimeter(status));
251     measureUnit.adoptInstead(MeasureUnit::createDecimeter(status));
252     measureUnit.adoptInstead(MeasureUnit::createFathom(status));
253     measureUnit.adoptInstead(MeasureUnit::createFoot(status));
254     measureUnit.adoptInstead(MeasureUnit::createFurlong(status));
255     measureUnit.adoptInstead(MeasureUnit::createInch(status));
256     measureUnit.adoptInstead(MeasureUnit::createKilometer(status));
257     measureUnit.adoptInstead(MeasureUnit::createLightYear(status));
258     measureUnit.adoptInstead(MeasureUnit::createMeter(status));
259     measureUnit.adoptInstead(MeasureUnit::createMicrometer(status));
260     measureUnit.adoptInstead(MeasureUnit::createMile(status));
261     measureUnit.adoptInstead(MeasureUnit::createMillimeter(status));
262     measureUnit.adoptInstead(MeasureUnit::createNanometer(status));
263     measureUnit.adoptInstead(MeasureUnit::createNauticalMile(status));
264     measureUnit.adoptInstead(MeasureUnit::createParsec(status));
265     measureUnit.adoptInstead(MeasureUnit::createPicometer(status));
266     measureUnit.adoptInstead(MeasureUnit::createYard(status));
267     measureUnit.adoptInstead(MeasureUnit::createLux(status));
268     measureUnit.adoptInstead(MeasureUnit::createCarat(status));
269     measureUnit.adoptInstead(MeasureUnit::createGram(status));
270     measureUnit.adoptInstead(MeasureUnit::createKilogram(status));
271     measureUnit.adoptInstead(MeasureUnit::createMetricTon(status));
272     measureUnit.adoptInstead(MeasureUnit::createMicrogram(status));
273     measureUnit.adoptInstead(MeasureUnit::createMilligram(status));
274     measureUnit.adoptInstead(MeasureUnit::createOunce(status));
275     measureUnit.adoptInstead(MeasureUnit::createOunceTroy(status));
276     measureUnit.adoptInstead(MeasureUnit::createPound(status));
277     measureUnit.adoptInstead(MeasureUnit::createStone(status));
278     measureUnit.adoptInstead(MeasureUnit::createTon(status));
279     measureUnit.adoptInstead(MeasureUnit::createGigawatt(status));
280     measureUnit.adoptInstead(MeasureUnit::createHorsepower(status));
281     measureUnit.adoptInstead(MeasureUnit::createKilowatt(status));
282     measureUnit.adoptInstead(MeasureUnit::createMegawatt(status));
283     measureUnit.adoptInstead(MeasureUnit::createMilliwatt(status));
284     measureUnit.adoptInstead(MeasureUnit::createWatt(status));
285     measureUnit.adoptInstead(MeasureUnit::createHectopascal(status));
286     measureUnit.adoptInstead(MeasureUnit::createInchHg(status));
287     measureUnit.adoptInstead(MeasureUnit::createMillibar(status));
288     measureUnit.adoptInstead(MeasureUnit::createMillimeterOfMercury(status));
289     measureUnit.adoptInstead(MeasureUnit::createPoundPerSquareInch(status));
290     measureUnit.adoptInstead(MeasureUnit::createKarat(status));
291     measureUnit.adoptInstead(MeasureUnit::createKilometerPerHour(status));
292     measureUnit.adoptInstead(MeasureUnit::createMeterPerSecond(status));
293     measureUnit.adoptInstead(MeasureUnit::createMilePerHour(status));
294     measureUnit.adoptInstead(MeasureUnit::createCelsius(status));
295     measureUnit.adoptInstead(MeasureUnit::createFahrenheit(status));
296     measureUnit.adoptInstead(MeasureUnit::createKelvin(status));
297     measureUnit.adoptInstead(MeasureUnit::createAcreFoot(status));
298     measureUnit.adoptInstead(MeasureUnit::createBushel(status));
299     measureUnit.adoptInstead(MeasureUnit::createCentiliter(status));
300     measureUnit.adoptInstead(MeasureUnit::createCubicCentimeter(status));
301     measureUnit.adoptInstead(MeasureUnit::createCubicFoot(status));
302     measureUnit.adoptInstead(MeasureUnit::createCubicInch(status));
303     measureUnit.adoptInstead(MeasureUnit::createCubicKilometer(status));
304     measureUnit.adoptInstead(MeasureUnit::createCubicMeter(status));
305     measureUnit.adoptInstead(MeasureUnit::createCubicMile(status));
306     measureUnit.adoptInstead(MeasureUnit::createCubicYard(status));
307     measureUnit.adoptInstead(MeasureUnit::createCup(status));
308     measureUnit.adoptInstead(MeasureUnit::createDeciliter(status));
309     measureUnit.adoptInstead(MeasureUnit::createFluidOunce(status));
310     measureUnit.adoptInstead(MeasureUnit::createGallon(status));
311     measureUnit.adoptInstead(MeasureUnit::createHectoliter(status));
312     measureUnit.adoptInstead(MeasureUnit::createLiter(status));
313     measureUnit.adoptInstead(MeasureUnit::createMegaliter(status));
314     measureUnit.adoptInstead(MeasureUnit::createMilliliter(status));
315     measureUnit.adoptInstead(MeasureUnit::createPint(status));
316     measureUnit.adoptInstead(MeasureUnit::createQuart(status));
317     measureUnit.adoptInstead(MeasureUnit::createTablespoon(status));
318     measureUnit.adoptInstead(MeasureUnit::createTeaspoon(status));
319     assertSuccess("", status);
320 }
321 
TestBasic()322 void MeasureFormatTest::TestBasic() {
323     UErrorCode status = U_ZERO_ERROR;
324     MeasureUnit *ptr1 = MeasureUnit::createArcMinute(status);
325     MeasureUnit *ptr2 = MeasureUnit::createArcMinute(status);
326     if (!(*ptr1 == *ptr2)) {
327         errln("Expect == to work.");
328     }
329     if (*ptr1 != *ptr2) {
330         errln("Expect != to work.");
331     }
332     MeasureUnit *ptr3 = MeasureUnit::createMeter(status);
333     if (*ptr1 == *ptr3) {
334         errln("Expect == to work.");
335     }
336     if (!(*ptr1 != *ptr3)) {
337         errln("Expect != to work.");
338     }
339     MeasureUnit *ptr4 = (MeasureUnit *) ptr1->clone();
340     if (*ptr1 != *ptr4) {
341         errln("Expect clone to work.");
342     }
343     MeasureUnit stack;
344     stack = *ptr1;
345     if (*ptr1 != stack) {
346         errln("Expect assignment to work.");
347     }
348 
349     delete ptr1;
350     delete ptr2;
351     delete ptr3;
352     delete ptr4;
353 }
354 
TestGetAvailable()355 void MeasureFormatTest::TestGetAvailable() {
356     MeasureUnit *units = NULL;
357     UErrorCode status = U_ZERO_ERROR;
358     int32_t totalCount = MeasureUnit::getAvailable(units, 0, status);
359     while (status == U_BUFFER_OVERFLOW_ERROR) {
360         status = U_ZERO_ERROR;
361         delete [] units;
362         units = new MeasureUnit[totalCount];
363         totalCount = MeasureUnit::getAvailable(units, totalCount, status);
364     }
365     if (U_FAILURE(status)) {
366         dataerrln("Failure creating format object - %s", u_errorName(status));
367         delete [] units;
368         return;
369     }
370     if (totalCount < 200) {
371         errln("Expect at least 200 measure units including currencies.");
372     }
373     delete [] units;
374     StringEnumeration *types = MeasureUnit::getAvailableTypes(status);
375     if (U_FAILURE(status)) {
376         dataerrln("Failure getting types - %s", u_errorName(status));
377         delete types;
378         return;
379     }
380     if (types->count(status) < 10) {
381         errln("Expect at least 10 distinct unit types.");
382     }
383     units = NULL;
384     int32_t unitCapacity = 0;
385     int32_t unitCountSum = 0;
386     for (
387             const char* type = types->next(NULL, status);
388             type != NULL;
389             type = types->next(NULL, status)) {
390         int32_t unitCount = MeasureUnit::getAvailable(type, units, unitCapacity, status);
391         while (status == U_BUFFER_OVERFLOW_ERROR) {
392             status = U_ZERO_ERROR;
393             delete [] units;
394             units = new MeasureUnit[unitCount];
395             unitCapacity = unitCount;
396             unitCount = MeasureUnit::getAvailable(type, units, unitCapacity, status);
397         }
398         if (U_FAILURE(status)) {
399             dataerrln("Failure getting units - %s", u_errorName(status));
400             delete [] units;
401             delete types;
402             return;
403         }
404         if (unitCount < 1) {
405             errln("Expect at least one unit count per type.");
406         }
407         unitCountSum += unitCount;
408     }
409     if (unitCountSum != totalCount) {
410         errln("Expected total unit count to equal sum of unit counts by type.");
411     }
412     delete [] units;
413     delete types;
414 }
415 
TestExamplesInDocs()416 void MeasureFormatTest::TestExamplesInDocs() {
417     UErrorCode status = U_ZERO_ERROR;
418     MeasureFormat fmtFr(Locale::getFrench(), UMEASFMT_WIDTH_SHORT, status);
419     MeasureFormat fmtFrFull(
420             Locale::getFrench(), UMEASFMT_WIDTH_WIDE, status);
421     MeasureFormat fmtFrNarrow(
422             Locale::getFrench(), UMEASFMT_WIDTH_NARROW, status);
423     MeasureFormat fmtEn(Locale::getUS(), UMEASFMT_WIDTH_WIDE, status);
424     if (!assertSuccess("Error creating formatters", status)) {
425         return;
426     }
427     Measure measureC(23, MeasureUnit::createCelsius(status), status);
428     Measure measureF(70, MeasureUnit::createFahrenheit(status), status);
429     Measure feetAndInches[] = {
430             Measure(70, MeasureUnit::createFoot(status), status),
431             Measure(5.3, MeasureUnit::createInch(status), status)};
432     Measure footAndInch[] = {
433             Measure(1, MeasureUnit::createFoot(status), status),
434             Measure(1, MeasureUnit::createInch(status), status)};
435     Measure inchAndFeet[] = {
436             Measure(1, MeasureUnit::createInch(status), status),
437             Measure(2, MeasureUnit::createFoot(status), status)};
438     if (!assertSuccess("Error creating measurements.", status)) {
439         return;
440     }
441     verifyFormat(
442             "Celsius",
443             fmtFr,
444             &measureC,
445             1,
446             "23 \\u00B0C");
447     verifyFormatWithPrefix(
448             "Celsius",
449             fmtFr,
450             "Prefix: ",
451             &measureC,
452             1,
453             "Prefix: 23 \\u00B0C");
454     verifyFormat(
455             "Fahrenheit",
456             fmtFr,
457             &measureF,
458             1,
459             "70 \\u00B0F");
460     verifyFormat(
461             "Feet and inches",
462             fmtFrFull,
463             feetAndInches,
464             UPRV_LENGTHOF(feetAndInches),
465             "70 pieds et 5,3 pouces");
466     verifyFormatWithPrefix(
467             "Feet and inches",
468             fmtFrFull,
469             "Prefix: ",
470             feetAndInches,
471             UPRV_LENGTHOF(feetAndInches),
472             "Prefix: 70 pieds et 5,3 pouces");
473     verifyFormat(
474             "Foot and inch",
475             fmtFrFull,
476             footAndInch,
477             UPRV_LENGTHOF(footAndInch),
478             "1 pied et 1 pouce");
479     verifyFormat(
480             "Foot and inch narrow",
481             fmtFrNarrow,
482             footAndInch,
483             UPRV_LENGTHOF(footAndInch),
484             "1\\u2032 1\\u2033");
485     verifyFormat(
486             "Inch and feet",
487             fmtEn,
488             inchAndFeet,
489             UPRV_LENGTHOF(inchAndFeet),
490             "1 inch, 2 feet");
491 }
492 
TestFormatPeriodEn()493 void MeasureFormatTest::TestFormatPeriodEn() {
494     UErrorCode status = U_ZERO_ERROR;
495     Measure t_19m[] = {Measure(19, MeasureUnit::createMinute(status), status)};
496     Measure t_1h_23_5s[] = {
497             Measure(1.0, MeasureUnit::createHour(status), status),
498             Measure(23.5, MeasureUnit::createSecond(status), status)
499     };
500     Measure t_1h_23_5m[] = {
501             Measure(1.0, MeasureUnit::createHour(status), status),
502             Measure(23.5, MeasureUnit::createMinute(status), status)
503     };
504     Measure t_1h_0m_23s[] = {
505             Measure(
506                     1.0,
507                     TimeUnit::createInstance(
508                             TimeUnit::UTIMEUNIT_HOUR, status),
509                     status),
510             Measure(
511                     0.0,
512                     TimeUnit::createInstance(
513                             TimeUnit::UTIMEUNIT_MINUTE, status),
514                      status),
515             Measure(
516                     23,
517                     TimeUnit::createInstance(
518                             TimeUnit::UTIMEUNIT_SECOND, status),
519                     status)
520     };
521     Measure t_2y_5M_3w_4d[] = {
522             Measure(2.0, MeasureUnit::createYear(status), status),
523             Measure(5.0, MeasureUnit::createMonth(status), status),
524             Measure(3.0, MeasureUnit::createWeek(status), status),
525             Measure(4.0, MeasureUnit::createDay(status), status)
526     };
527     Measure t_1m_59_9996s[] = {
528             Measure(1.0, MeasureUnit::createMinute(status), status),
529             Measure(59.9996, MeasureUnit::createSecond(status), status)
530     };
531     Measure t_5h_17m[] = {
532             Measure(5.0, MeasureUnit::createHour(status), status),
533             Measure(17.0, MeasureUnit::createMinute(status), status)
534     };
535     Measure t_neg5h_17m[] = {
536             Measure(-5.0, MeasureUnit::createHour(status), status),
537             Measure(17.0, MeasureUnit::createMinute(status), status)
538     };
539     Measure t_19m_28s[] = {
540             Measure(19.0, MeasureUnit::createMinute(status), status),
541             Measure(28.0, MeasureUnit::createSecond(status), status)
542     };
543     Measure t_0h_0m_9s[] = {
544             Measure(0.0, MeasureUnit::createHour(status), status),
545             Measure(0.0, MeasureUnit::createMinute(status), status),
546             Measure(9.0, MeasureUnit::createSecond(status), status)
547     };
548     Measure t_0h_0m_17s[] = {
549             Measure(0.0, MeasureUnit::createHour(status), status),
550             Measure(0.0, MeasureUnit::createMinute(status), status),
551             Measure(17.0, MeasureUnit::createSecond(status), status)
552     };
553     Measure t_6h_56_92m[] = {
554             Measure(6.0, MeasureUnit::createHour(status), status),
555             Measure(56.92, MeasureUnit::createMinute(status), status)
556     };
557     Measure t_3h_4s_5m[] = {
558             Measure(3.0, MeasureUnit::createHour(status), status),
559             Measure(4.0, MeasureUnit::createSecond(status), status),
560             Measure(5.0, MeasureUnit::createMinute(status), status)
561     };
562     Measure t_6_7h_56_92m[] = {
563             Measure(6.7, MeasureUnit::createHour(status), status),
564             Measure(56.92, MeasureUnit::createMinute(status), status)
565     };
566 
567     Measure t_3h_5h[] = {
568             Measure(3.0, MeasureUnit::createHour(status), status),
569             Measure(5.0, MeasureUnit::createHour(status), status)
570     };
571 
572     if (!assertSuccess("Error creating Measure objects", status)) {
573         return;
574     }
575 
576     ExpectedResult fullData[] = {
577             {t_1m_59_9996s, UPRV_LENGTHOF(t_1m_59_9996s), "1 minute, 59.9996 seconds"},
578             {t_19m, UPRV_LENGTHOF(t_19m), "19 minutes"},
579             {t_1h_23_5s, UPRV_LENGTHOF(t_1h_23_5s), "1 hour, 23.5 seconds"},
580             {t_1h_23_5m, UPRV_LENGTHOF(t_1h_23_5m), "1 hour, 23.5 minutes"},
581             {t_1h_0m_23s, UPRV_LENGTHOF(t_1h_0m_23s), "1 hour, 0 minutes, 23 seconds"},
582             {t_2y_5M_3w_4d, UPRV_LENGTHOF(t_2y_5M_3w_4d), "2 years, 5 months, 3 weeks, 4 days"}};
583 
584     ExpectedResult abbrevData[] = {
585             {t_1m_59_9996s, UPRV_LENGTHOF(t_1m_59_9996s), "1 min, 59.9996 sec"},
586             {t_19m, UPRV_LENGTHOF(t_19m), "19 min"},
587             {t_1h_23_5s, UPRV_LENGTHOF(t_1h_23_5s), "1 hr, 23.5 sec"},
588             {t_1h_23_5m, UPRV_LENGTHOF(t_1h_23_5m), "1 hr, 23.5 min"},
589             {t_1h_0m_23s, UPRV_LENGTHOF(t_1h_0m_23s), "1 hr, 0 min, 23 sec"},
590             {t_2y_5M_3w_4d, UPRV_LENGTHOF(t_2y_5M_3w_4d), "2 yrs, 5 mths, 3 wks, 4 days"}};
591 
592     ExpectedResult narrowData[] = {
593             {t_1m_59_9996s, UPRV_LENGTHOF(t_1m_59_9996s), "1m 59.9996s"},
594             {t_19m, UPRV_LENGTHOF(t_19m), "19m"},
595             {t_1h_23_5s, UPRV_LENGTHOF(t_1h_23_5s), "1h 23.5s"},
596             {t_1h_23_5m, UPRV_LENGTHOF(t_1h_23_5m), "1h 23.5m"},
597             {t_1h_0m_23s, UPRV_LENGTHOF(t_1h_0m_23s), "1h 0m 23s"},
598             {t_2y_5M_3w_4d, UPRV_LENGTHOF(t_2y_5M_3w_4d), "2y 5m 3w 4d"}};
599 
600     ExpectedResult numericData[] = {
601             {t_1m_59_9996s, UPRV_LENGTHOF(t_1m_59_9996s), "1:59.9996"},
602             {t_19m, UPRV_LENGTHOF(t_19m), "19m"},
603             {t_1h_23_5s, UPRV_LENGTHOF(t_1h_23_5s), "1:00:23.5"},
604             {t_1h_23_5m, UPRV_LENGTHOF(t_1h_23_5m), "1:23.5"},
605             {t_1h_0m_23s, UPRV_LENGTHOF(t_1h_0m_23s), "1:00:23"},
606             {t_5h_17m, UPRV_LENGTHOF(t_5h_17m), "5:17"},
607             {t_neg5h_17m, UPRV_LENGTHOF(t_neg5h_17m), "-5h 17m"},
608             {t_19m_28s, UPRV_LENGTHOF(t_19m_28s), "19:28"},
609             {t_2y_5M_3w_4d, UPRV_LENGTHOF(t_2y_5M_3w_4d), "2y 5m 3w 4d"},
610             {t_0h_0m_9s, UPRV_LENGTHOF(t_0h_0m_9s), "0:00:09"},
611             {t_6h_56_92m, UPRV_LENGTHOF(t_6h_56_92m), "6:56.92"},
612             {t_6_7h_56_92m, UPRV_LENGTHOF(t_6_7h_56_92m), "6:56.92"},
613             {t_3h_4s_5m, UPRV_LENGTHOF(t_3h_4s_5m), "3h 4s 5m"},
614             {t_3h_5h, UPRV_LENGTHOF(t_3h_5h), "3h 5h"}};
615 
616     ExpectedResult fullDataDe[] = {
617             {t_1m_59_9996s, UPRV_LENGTHOF(t_1m_59_9996s), "1 Minute und 59,9996 Sekunden"},
618             {t_19m, UPRV_LENGTHOF(t_19m), "19 Minuten"},
619             {t_1h_23_5s, UPRV_LENGTHOF(t_1h_23_5s), "1 Stunde und 23,5 Sekunden"},
620             {t_1h_23_5m, UPRV_LENGTHOF(t_1h_23_5m), "1 Stunde und 23,5 Minuten"},
621             {t_1h_0m_23s, UPRV_LENGTHOF(t_1h_0m_23s), "1 Stunde, 0 Minuten und 23 Sekunden"},
622             {t_2y_5M_3w_4d, UPRV_LENGTHOF(t_2y_5M_3w_4d), "2 Jahre, 5 Monate, 3 Wochen und 4 Tage"}};
623 
624     ExpectedResult numericDataDe[] = {
625             {t_1m_59_9996s, UPRV_LENGTHOF(t_1m_59_9996s), "1:59,9996"},
626             {t_19m, UPRV_LENGTHOF(t_19m), "19 Min."},
627             {t_1h_23_5s, UPRV_LENGTHOF(t_1h_23_5s), "1:00:23,5"},
628             {t_1h_23_5m, UPRV_LENGTHOF(t_1h_23_5m), "1:23,5"},
629             {t_1h_0m_23s, UPRV_LENGTHOF(t_1h_0m_23s), "1:00:23"},
630             {t_5h_17m, UPRV_LENGTHOF(t_5h_17m), "5:17"},
631             {t_19m_28s, UPRV_LENGTHOF(t_19m_28s), "19:28"},
632             {t_2y_5M_3w_4d, UPRV_LENGTHOF(t_2y_5M_3w_4d), "2 J, 5 M, 3 W und 4 T"},
633             {t_0h_0m_17s, UPRV_LENGTHOF(t_0h_0m_17s), "0:00:17"},
634             {t_6h_56_92m, UPRV_LENGTHOF(t_6h_56_92m), "6:56,92"},
635             {t_3h_5h, UPRV_LENGTHOF(t_3h_5h), "3 Std., 5 Std."}};
636 
637     Locale en(Locale::getEnglish());
638     LocalPointer<NumberFormat> nf(NumberFormat::createInstance(en, status));
639     if (U_FAILURE(status)) {
640         dataerrln("Error creating number format en object - %s", u_errorName(status));
641         return;
642     }
643     nf->setMaximumFractionDigits(4);
644     MeasureFormat mf(en, UMEASFMT_WIDTH_WIDE, (NumberFormat *) nf->clone(), status);
645     if (!assertSuccess("Error creating measure format en WIDE", status)) {
646         return;
647     }
648     verifyFormat("en WIDE", mf, fullData, UPRV_LENGTHOF(fullData));
649 
650     // exercise copy constructor
651     {
652         MeasureFormat mf2(mf);
653         verifyFormat("en WIDE copy", mf2, fullData, UPRV_LENGTHOF(fullData));
654     }
655     // exercise clone
656     {
657         MeasureFormat *mf3 = (MeasureFormat *) mf.clone();
658         verifyFormat("en WIDE copy", *mf3, fullData, UPRV_LENGTHOF(fullData));
659         delete mf3;
660     }
661     mf = MeasureFormat(en, UMEASFMT_WIDTH_SHORT, (NumberFormat *) nf->clone(), status);
662     if (!assertSuccess("Error creating measure format en SHORT", status)) {
663         return;
664     }
665     verifyFormat("en SHORT", mf, abbrevData, UPRV_LENGTHOF(abbrevData));
666     mf = MeasureFormat(en, UMEASFMT_WIDTH_NARROW, (NumberFormat *) nf->clone(), status);
667     if (!assertSuccess("Error creating measure format en NARROW", status)) {
668         return;
669     }
670     verifyFormat("en NARROW", mf, narrowData, UPRV_LENGTHOF(narrowData));
671     mf = MeasureFormat(en, UMEASFMT_WIDTH_NUMERIC, (NumberFormat *) nf->clone(), status);
672     if (!assertSuccess("Error creating measure format en NUMERIC", status)) {
673         return;
674     }
675     verifyFormat("en NUMERIC", mf, numericData, UPRV_LENGTHOF(numericData));
676 
677     Locale de(Locale::getGerman());
678     nf.adoptInstead(NumberFormat::createInstance(de, status));
679     if (!assertSuccess("Error creating number format de object", status)) {
680         return;
681     }
682     nf->setMaximumFractionDigits(4);
683     mf = MeasureFormat(de, UMEASFMT_WIDTH_WIDE, (NumberFormat *) nf->clone(), status);
684     if (!assertSuccess("Error creating measure format de WIDE", status)) {
685         return;
686     }
687     verifyFormat("de WIDE", mf, fullDataDe, UPRV_LENGTHOF(fullDataDe));
688     mf = MeasureFormat(de, UMEASFMT_WIDTH_NUMERIC, (NumberFormat *) nf->clone(), status);
689     if (!assertSuccess("Error creating measure format de NUMERIC", status)) {
690         return;
691     }
692     verifyFormat("de NUMERIC", mf, numericDataDe, UPRV_LENGTHOF(numericDataDe));
693 }
694 
Test10219FractionalPlurals()695 void MeasureFormatTest::Test10219FractionalPlurals() {
696     Locale en(Locale::getEnglish());
697     double values[] = {1.588, 1.011};
698     const char *expected[2][3] = {
699             {"1 minute", "1.5 minutes", "1.58 minutes"},
700             {"1 minute", "1.0 minutes", "1.01 minutes"}
701     };
702     UErrorCode status = U_ZERO_ERROR;
703     for (int j = 0; j < UPRV_LENGTHOF(values); j++) {
704         for (int i = 0; i < UPRV_LENGTHOF(expected[j]); i++) {
705             DecimalFormat *df =
706                 (DecimalFormat *) NumberFormat::createInstance(en, status);
707             if (U_FAILURE(status)) {
708                 dataerrln("Error creating Number format - %s", u_errorName(status));
709                 return;
710             }
711             df->setRoundingMode(DecimalFormat::kRoundDown);
712             df->setMinimumFractionDigits(i);
713             df->setMaximumFractionDigits(i);
714             MeasureFormat mf(en, UMEASFMT_WIDTH_WIDE, df, status);
715             if (!assertSuccess("Error creating Measure format", status)) {
716                 return;
717             }
718             Measure measure(values[j], MeasureUnit::createMinute(status), status);
719             if (!assertSuccess("Error creating Measure unit", status)) {
720                 return;
721             }
722             verifyFormat("Test10219", mf, &measure, 1, expected[j][i]);
723         }
724     }
725 }
726 
toMeasureUnit(MeasureUnit * adopted)727 static MeasureUnit toMeasureUnit(MeasureUnit *adopted) {
728     MeasureUnit result(*adopted);
729     delete adopted;
730     return result;
731 }
732 
TestGreek()733 void MeasureFormatTest::TestGreek() {
734     Locale locales[] = {Locale("el_GR"), Locale("el")};
735     UErrorCode status = U_ZERO_ERROR;
736     MeasureUnit units[] = {
737         toMeasureUnit(MeasureUnit::createSecond(status)),
738         toMeasureUnit(MeasureUnit::createMinute(status)),
739         toMeasureUnit(MeasureUnit::createHour(status)),
740         toMeasureUnit(MeasureUnit::createDay(status)),
741         toMeasureUnit(MeasureUnit::createWeek(status)),
742         toMeasureUnit(MeasureUnit::createMonth(status)),
743         toMeasureUnit(MeasureUnit::createYear(status))};
744     if (!assertSuccess("Error creating Measure units", status)) {
745         return;
746     }
747     UMeasureFormatWidth styles[] = {
748             UMEASFMT_WIDTH_WIDE,
749             UMEASFMT_WIDTH_SHORT};
750     int32_t numbers[] = {1, 7};
751     const char *expected[] = {
752         // "el_GR" 1 wide
753         "1 \\u03B4\\u03B5\\u03C5\\u03C4\\u03B5\\u03C1\\u03CC\\u03BB\\u03B5\\u03C0\\u03C4\\u03BF",
754         "1 \\u03BB\\u03B5\\u03C0\\u03C4\\u03CC",
755         "1 \\u03CE\\u03C1\\u03B1",
756         "1 \\u03B7\\u03BC\\u03AD\\u03C1\\u03B1",
757         "1 \\u03B5\\u03B2\\u03B4\\u03BF\\u03BC\\u03AC\\u03B4\\u03B1",
758         "1 \\u03BC\\u03AE\\u03BD\\u03B1\\u03C2",
759         "1 \\u03AD\\u03C4\\u03BF\\u03C2",
760         // "el_GR" 1 short
761         "1 \\u03B4\\u03B5\\u03C5\\u03C4.",
762         "1 \\u03BB\\u03B5\\u03C0.",
763         "1 \\u03CE\\u03C1\\u03B1",
764         "1 \\u03B7\\u03BC\\u03AD\\u03C1\\u03B1",
765         "1 \\u03B5\\u03B2\\u03B4.",
766         "1 \\u03BC\\u03AE\\u03BD.",
767         "1 \\u03AD\\u03C4.",	        // year (one)
768         // "el_GR" 7 wide
769         "7 \\u03B4\\u03B5\\u03C5\\u03C4\\u03B5\\u03C1\\u03CC\\u03BB\\u03B5\\u03C0\\u03C4\\u03B1",
770         "7 \\u03BB\\u03B5\\u03C0\\u03C4\\u03AC",
771         "7 \\u03CE\\u03C1\\u03B5\\u03C2",
772         "7 \\u03B7\\u03BC\\u03AD\\u03C1\\u03B5\\u03C2",
773         "7 \\u03B5\\u03B2\\u03B4\\u03BF\\u03BC\\u03AC\\u03B4\\u03B5\\u03C2",
774         "7 \\u03BC\\u03AE\\u03BD\\u03B5\\u03C2",
775         "7 \\u03AD\\u03C4\\u03B7",
776         // "el_GR" 7 short
777         "7 \\u03B4\\u03B5\\u03C5\\u03C4.",
778         "7 \\u03BB\\u03B5\\u03C0.",
779         "7 \\u03CE\\u03C1.",		    // hour (other)
780         "7 \\u03B7\\u03BC\\u03AD\\u03C1\\u03B5\\u03C2",
781         "7 \\u03B5\\u03B2\\u03B4.",
782         "7 \\u03BC\\u03AE\\u03BD.",
783         "7 \\u03AD\\u03C4.",            // year (other)
784 
785         // "el" 1 wide
786         "1 \\u03B4\\u03B5\\u03C5\\u03C4\\u03B5\\u03C1\\u03CC\\u03BB\\u03B5\\u03C0\\u03C4\\u03BF",
787         "1 \\u03BB\\u03B5\\u03C0\\u03C4\\u03CC",
788         "1 \\u03CE\\u03C1\\u03B1",
789         "1 \\u03B7\\u03BC\\u03AD\\u03C1\\u03B1",
790         "1 \\u03B5\\u03B2\\u03B4\\u03BF\\u03BC\\u03AC\\u03B4\\u03B1",
791         "1 \\u03BC\\u03AE\\u03BD\\u03B1\\u03C2",
792         "1 \\u03AD\\u03C4\\u03BF\\u03C2",
793         // "el" 1 short
794         "1 \\u03B4\\u03B5\\u03C5\\u03C4.",
795         "1 \\u03BB\\u03B5\\u03C0.",
796         "1 \\u03CE\\u03C1\\u03B1",
797         "1 \\u03B7\\u03BC\\u03AD\\u03C1\\u03B1",
798         "1 \\u03B5\\u03B2\\u03B4.",
799         "1 \\u03BC\\u03AE\\u03BD.",
800         "1 \\u03AD\\u03C4.",	        // year (one)
801         // "el" 7 wide
802         "7 \\u03B4\\u03B5\\u03C5\\u03C4\\u03B5\\u03C1\\u03CC\\u03BB\\u03B5\\u03C0\\u03C4\\u03B1",
803         "7 \\u03BB\\u03B5\\u03C0\\u03C4\\u03AC",
804         "7 \\u03CE\\u03C1\\u03B5\\u03C2",
805         "7 \\u03B7\\u03BC\\u03AD\\u03C1\\u03B5\\u03C2",
806         "7 \\u03B5\\u03B2\\u03B4\\u03BF\\u03BC\\u03AC\\u03B4\\u03B5\\u03C2",
807         "7 \\u03BC\\u03AE\\u03BD\\u03B5\\u03C2",
808         "7 \\u03AD\\u03C4\\u03B7",
809         // "el" 7 short
810         "7 \\u03B4\\u03B5\\u03C5\\u03C4.",
811         "7 \\u03BB\\u03B5\\u03C0.",
812         "7 \\u03CE\\u03C1.",		    // hour (other)
813         "7 \\u03B7\\u03BC\\u03AD\\u03C1\\u03B5\\u03C2",
814         "7 \\u03B5\\u03B2\\u03B4.",
815         "7 \\u03BC\\u03AE\\u03BD.",
816         "7 \\u03AD\\u03C4."};           // year (other)
817 
818     int32_t counter = 0;
819     for (int32_t locIndex = 0; locIndex < UPRV_LENGTHOF(locales); ++locIndex ) {
820         for( int32_t numIndex = 0; numIndex < UPRV_LENGTHOF(numbers); ++numIndex ) {
821             for ( int32_t styleIndex = 0; styleIndex < UPRV_LENGTHOF(styles); ++styleIndex ) {
822                 for ( int32_t unitIndex = 0; unitIndex < UPRV_LENGTHOF(units); ++unitIndex ) {
823                     Measure measure(numbers[numIndex], new MeasureUnit(units[unitIndex]), status);
824                     if (!assertSuccess("Error creating Measure", status)) {
825                         return;
826                     }
827                     MeasureFormat fmt(locales[locIndex], styles[styleIndex], status);
828                     if (!assertSuccess("Error creating Measure format", status)) {
829                         return;
830                     }
831                     verifyFormat("TestGreek", fmt, &measure, 1, expected[counter]);
832                     ++counter;
833                 }
834             }
835         }
836     }
837 }
838 
TestFormatSingleArg()839 void MeasureFormatTest::TestFormatSingleArg() {
840     UErrorCode status = U_ZERO_ERROR;
841     MeasureFormat fmt("en", UMEASFMT_WIDTH_WIDE, status);
842     if (!assertSuccess("Error creating formatter", status)) {
843         return;
844     }
845     UnicodeString buffer;
846     FieldPosition pos(0);
847     fmt.format(
848             new Measure(3.5, MeasureUnit::createFoot(status), status),
849             buffer,
850             pos,
851             status);
852     if (!assertSuccess("Error formatting", status)) {
853         return;
854     }
855     assertEquals(
856             "TestFormatSingleArg",
857             UnicodeString("3.5 feet"),
858             buffer);
859 }
860 
TestFormatMeasuresZeroArg()861 void MeasureFormatTest::TestFormatMeasuresZeroArg() {
862     UErrorCode status = U_ZERO_ERROR;
863     MeasureFormat fmt("en", UMEASFMT_WIDTH_WIDE, status);
864     verifyFormat("TestFormatMeasuresZeroArg", fmt, NULL, 0, "");
865 }
866 
TestSimplePer()867 void MeasureFormatTest::TestSimplePer() {
868     Locale en("en");
869     UErrorCode status = U_ZERO_ERROR;
870     LocalPointer<MeasureUnit> second(MeasureUnit::createSecond(status));
871     LocalPointer<MeasureUnit> minute(MeasureUnit::createMinute(status));
872     LocalPointer<MeasureUnit> pound(MeasureUnit::createPound(status));
873     if (!assertSuccess("", status)) {
874         return;
875     }
876 
877     helperTestSimplePer(
878             en, UMEASFMT_WIDTH_WIDE,
879             1.0, *pound, *second, "1 pound per second");
880     helperTestSimplePer(
881             en, UMEASFMT_WIDTH_WIDE,
882             2.0, *pound, *second, "2 pounds per second");
883     helperTestSimplePer(
884             en, UMEASFMT_WIDTH_WIDE,
885             1.0, *pound, *minute, "1 pound per minute");
886     helperTestSimplePer(
887             en, UMEASFMT_WIDTH_WIDE,
888             2.0, *pound, *minute, "2 pounds per minute");
889 
890     helperTestSimplePer(
891             en, UMEASFMT_WIDTH_SHORT, 1.0, *pound, *second, "1 lbps");
892     helperTestSimplePer(
893             en, UMEASFMT_WIDTH_SHORT, 2.0, *pound, *second, "2 lbps");
894     helperTestSimplePer(
895             en, UMEASFMT_WIDTH_SHORT, 1.0, *pound, *minute, "1 lb/min");
896     helperTestSimplePer(
897             en, UMEASFMT_WIDTH_SHORT, 2.0, *pound, *minute, "2 lb/min");
898 
899     helperTestSimplePer(
900             en, UMEASFMT_WIDTH_NARROW, 1.0, *pound, *second, "1#/s");
901     helperTestSimplePer(
902             en, UMEASFMT_WIDTH_NARROW, 2.0, *pound, *second, "2#/s");
903     helperTestSimplePer(
904             en, UMEASFMT_WIDTH_NARROW, 1.0, *pound, *minute, "1#/m");
905     helperTestSimplePer(
906             en, UMEASFMT_WIDTH_NARROW, 2.0, *pound, *minute, "2#/m");
907 
908     helperTestSimplePer(
909             en, UMEASFMT_WIDTH_SHORT,
910             23.3, *pound, *second, "23.3 lbps",
911             NumberFormat::kDecimalSeparatorField,
912             2, 3);
913 
914     helperTestSimplePer(
915             en, UMEASFMT_WIDTH_SHORT,
916             23.3, *pound, *second, "23.3 lbps",
917             NumberFormat::kIntegerField,
918             0, 2);
919 
920     helperTestSimplePer(
921             en, UMEASFMT_WIDTH_SHORT,
922             23.3, *pound, *minute, "23.3 lb/min",
923             NumberFormat::kDecimalSeparatorField,
924             2, 3);
925 
926     helperTestSimplePer(
927             en, UMEASFMT_WIDTH_SHORT,
928             23.3, *pound, *minute, "23.3 lb/min",
929             NumberFormat::kIntegerField,
930             0, 2);
931 }
932 
TestNumeratorPlurals()933 void MeasureFormatTest::TestNumeratorPlurals() {
934     Locale pl("pl");
935     UErrorCode status = U_ZERO_ERROR;
936     LocalPointer<MeasureUnit> second(MeasureUnit::createSecond(status));
937     LocalPointer<MeasureUnit> foot(MeasureUnit::createFoot(status));
938     if (!assertSuccess("", status)) {
939         return;
940     }
941 
942     helperTestSimplePer(
943             pl,
944             UMEASFMT_WIDTH_WIDE,
945             1.0, *foot, *second, "1 stopa na sekund\\u0119");
946     helperTestSimplePer(
947             pl,
948             UMEASFMT_WIDTH_WIDE,
949             2.0, *foot, *second, "2 stopy na sekund\\u0119");
950     helperTestSimplePer(
951             pl,
952             UMEASFMT_WIDTH_WIDE,
953             5.0, *foot, *second, "5 st\\u00f3p na sekund\\u0119");
954     helperTestSimplePer(
955             pl, UMEASFMT_WIDTH_WIDE,
956             1.5, *foot, *second, "1,5 stopy na sekund\\u0119");
957 }
958 
helperTestSimplePer(const Locale & locale,UMeasureFormatWidth width,double value,const MeasureUnit & unit,const MeasureUnit & perUnit,const char * expected)959 void MeasureFormatTest::helperTestSimplePer(
960         const Locale &locale,
961         UMeasureFormatWidth width,
962         double value,
963         const MeasureUnit &unit,
964         const MeasureUnit &perUnit,
965         const char *expected) {
966     helperTestSimplePer(
967             locale,
968             width,
969             value,
970             unit,
971             perUnit,
972             expected,
973             FieldPosition::DONT_CARE,
974             0,
975             0);
976 }
977 
helperTestSimplePer(const Locale & locale,UMeasureFormatWidth width,double value,const MeasureUnit & unit,const MeasureUnit & perUnit,const char * expected,int32_t field,int32_t expected_start,int32_t expected_end)978 void MeasureFormatTest::helperTestSimplePer(
979         const Locale &locale,
980         UMeasureFormatWidth width,
981         double value,
982         const MeasureUnit &unit,
983         const MeasureUnit &perUnit,
984         const char *expected,
985         int32_t field,
986         int32_t expected_start,
987         int32_t expected_end) {
988     UErrorCode status = U_ZERO_ERROR;
989     FieldPosition pos(field);
990     MeasureFormat fmt(locale, width, status);
991     if (!assertSuccess("Error creating format object", status)) {
992         return;
993     }
994     Measure measure(value, (MeasureUnit *) unit.clone(), status);
995     if (!assertSuccess("Error creating measure object", status)) {
996         return;
997     }
998     UnicodeString prefix("prefix: ");
999     UnicodeString buffer(prefix);
1000     fmt.formatMeasurePerUnit(
1001             measure,
1002             perUnit,
1003             buffer,
1004             pos,
1005             status);
1006     if (!assertSuccess("Error formatting measures with per", status)) {
1007         return;
1008     }
1009     UnicodeString uexpected(expected);
1010     uexpected = prefix + uexpected;
1011     assertEquals(
1012             "TestSimplePer",
1013             uexpected.unescape(),
1014             buffer);
1015     if (field != FieldPosition::DONT_CARE) {
1016         assertEquals(
1017                 "Start", expected_start, pos.getBeginIndex() - prefix.length());
1018         assertEquals(
1019                 "End", expected_end, pos.getEndIndex() - prefix.length());
1020     }
1021 }
1022 
TestMultiples()1023 void MeasureFormatTest::TestMultiples() {
1024     Locale ru("ru");
1025     Locale en("en");
1026     helperTestMultiples(en, UMEASFMT_WIDTH_WIDE, "2 miles, 1 foot, 2.3 inches");
1027     helperTestMultiples(en, UMEASFMT_WIDTH_SHORT, "2 mi, 1 ft, 2.3 in");
1028     helperTestMultiples(en, UMEASFMT_WIDTH_NARROW, "2mi 1\\u2032 2.3\\u2033");
1029     helperTestMultiples(ru, UMEASFMT_WIDTH_WIDE, "2 \\u043C\\u0438\\u043B\\u0438, 1 \\u0444\\u0443\\u0442 \\u0438 2,3 \\u0434\\u044E\\u0439\\u043C\\u0430");
1030     helperTestMultiples(ru, UMEASFMT_WIDTH_SHORT, "2 \\u043C\\u0438\\u043B\\u0438, 1 \\u0444\\u0443\\u0442, 2,3 \\u0434\\u044E\\u0439\\u043C.");
1031     helperTestMultiples(ru, UMEASFMT_WIDTH_NARROW, "2 \\u043C\\u0438\\u043B\\u044C 1 \\u0444\\u0443\\u0442 2,3 \\u0434\\u044E\\u0439\\u043C\\u0430");
1032 }
1033 
helperTestMultiples(const Locale & locale,UMeasureFormatWidth width,const char * expected)1034 void MeasureFormatTest::helperTestMultiples(
1035         const Locale &locale,
1036         UMeasureFormatWidth width,
1037         const char *expected) {
1038     UErrorCode status = U_ZERO_ERROR;
1039     FieldPosition pos(0);
1040     MeasureFormat fmt(locale, width, status);
1041     if (!assertSuccess("Error creating format object", status)) {
1042         return;
1043     }
1044     Measure measures[] = {
1045             Measure(2, MeasureUnit::createMile(status), status),
1046             Measure(1, MeasureUnit::createFoot(status), status),
1047             Measure(2.3, MeasureUnit::createInch(status), status)};
1048     if (!assertSuccess("Error creating measures", status)) {
1049         return;
1050     }
1051     UnicodeString buffer;
1052     fmt.formatMeasures(measures, UPRV_LENGTHOF(measures), buffer, pos, status);
1053     if (!assertSuccess("Error formatting measures", status)) {
1054         return;
1055     }
1056     assertEquals("TestMultiples", UnicodeString(expected).unescape(), buffer);
1057 }
1058 
TestGram()1059 void MeasureFormatTest::TestGram() {
1060     UErrorCode status = U_ZERO_ERROR;
1061     MeasureFormat fmt("en", UMEASFMT_WIDTH_SHORT, status);
1062     if (!assertSuccess("Error creating format object", status)) {
1063         return;
1064     }
1065     Measure gram(1, MeasureUnit::createGram(status), status);
1066     Measure gforce(1, MeasureUnit::createGForce(status), status);
1067     if (!assertSuccess("Error creating measures", status)) {
1068         return;
1069     }
1070     verifyFormat("TestGram", fmt, &gram, 1, "1 g");
1071     verifyFormat("TestGram", fmt, &gforce, 1, "1 G");
1072 }
1073 
TestCurrencies()1074 void MeasureFormatTest::TestCurrencies() {
1075     UChar USD[] = {'U', 'S', 'D', 0};
1076     UErrorCode status = U_ZERO_ERROR;
1077     CurrencyAmount USD_1(1.0, USD, status);
1078     CurrencyAmount USD_2(2.0, USD, status);
1079     CurrencyAmount USD_NEG_1(-1.0, USD, status);
1080     if (!assertSuccess("Error creating measures", status)) {
1081         return;
1082     }
1083     Locale en("en");
1084     MeasureFormat fmt(en, UMEASFMT_WIDTH_WIDE, status);
1085     if (!assertSuccess("Error creating format object", status)) {
1086         return;
1087     }
1088     verifyFormat("TestCurrenciesWide", fmt, &USD_NEG_1, 1, "-1.00 US dollars");
1089     verifyFormat("TestCurrenciesWide", fmt, &USD_1, 1, "1.00 US dollars");
1090     verifyFormat("TestCurrenciesWide", fmt, &USD_2, 1, "2.00 US dollars");
1091     fmt = MeasureFormat(en, UMEASFMT_WIDTH_SHORT, status);
1092     if (!assertSuccess("Error creating format object", status)) {
1093         return;
1094     }
1095     verifyFormat("TestCurrenciesShort", fmt, &USD_NEG_1, 1, "-USD1.00");
1096     verifyFormat("TestCurrenciesShort", fmt, &USD_1, 1, "USD1.00");
1097     verifyFormat("TestCurrenciesShort", fmt, &USD_2, 1, "USD2.00");
1098     fmt = MeasureFormat(en, UMEASFMT_WIDTH_NARROW, status);
1099     if (!assertSuccess("Error creating format object", status)) {
1100         return;
1101     }
1102     verifyFormat("TestCurrenciesNarrow", fmt, &USD_NEG_1, 1, "-$1.00");
1103     verifyFormat("TestCurrenciesNarrow", fmt, &USD_1, 1, "$1.00");
1104     verifyFormat("TestCurrenciesNarrow", fmt, &USD_2, 1, "$2.00");
1105     fmt = MeasureFormat(en, UMEASFMT_WIDTH_NUMERIC, status);
1106     if (!assertSuccess("Error creating format object", status)) {
1107         return;
1108     }
1109     verifyFormat("TestCurrenciesNumeric", fmt, &USD_NEG_1, 1, "-$1.00");
1110     verifyFormat("TestCurrenciesNumeric", fmt, &USD_1, 1, "$1.00");
1111     verifyFormat("TestCurrenciesNumeric", fmt, &USD_2, 1, "$2.00");
1112 }
1113 
TestFieldPosition()1114 void MeasureFormatTest::TestFieldPosition() {
1115     UErrorCode status = U_ZERO_ERROR;
1116     MeasureFormat fmt("en", UMEASFMT_WIDTH_SHORT, status);
1117     if (!assertSuccess("Error creating format object", status)) {
1118         return;
1119     }
1120     Measure measure(43.5, MeasureUnit::createFoot(status), status);
1121     if (!assertSuccess("Error creating measure object 1", status)) {
1122         return;
1123     }
1124     UnicodeString prefix("123456: ");
1125     verifyFieldPosition(
1126             "",
1127             fmt,
1128             prefix,
1129             &measure,
1130             1,
1131             NumberFormat::kDecimalSeparatorField,
1132             10,
1133             11);
1134     measure = Measure(43, MeasureUnit::createFoot(status), status);
1135     if (!assertSuccess("Error creating measure object 2", status)) {
1136         return;
1137     }
1138     verifyFieldPosition(
1139             "",
1140             fmt,
1141             prefix,
1142             &measure,
1143             1,
1144             NumberFormat::kDecimalSeparatorField,
1145             0,
1146             0);
1147 }
1148 
TestFieldPositionMultiple()1149 void MeasureFormatTest::TestFieldPositionMultiple() {
1150     UErrorCode status = U_ZERO_ERROR;
1151     MeasureFormat fmt("en", UMEASFMT_WIDTH_SHORT, status);
1152     if (!assertSuccess("Error creating format object", status)) {
1153         return;
1154     }
1155     Measure first[] = {
1156             Measure(354, MeasureUnit::createMeter(status), status),
1157             Measure(23, MeasureUnit::createCentimeter(status), status)};
1158     Measure second[] = {
1159             Measure(354, MeasureUnit::createMeter(status), status),
1160             Measure(23, MeasureUnit::createCentimeter(status), status),
1161             Measure(5.4, MeasureUnit::createMillimeter(status), status)};
1162     Measure third[] = {
1163             Measure(3, MeasureUnit::createMeter(status), status),
1164             Measure(23, MeasureUnit::createCentimeter(status), status),
1165             Measure(5, MeasureUnit::createMillimeter(status), status)};
1166     if (!assertSuccess("Error creating measure objects", status)) {
1167         return;
1168     }
1169     UnicodeString prefix("123456: ");
1170     verifyFieldPosition(
1171             "Integer",
1172             fmt,
1173             prefix,
1174             first,
1175             UPRV_LENGTHOF(first),
1176             NumberFormat::kIntegerField,
1177             8,
1178             11);
1179     verifyFieldPosition(
1180             "Decimal separator",
1181             fmt,
1182             prefix,
1183             second,
1184             UPRV_LENGTHOF(second),
1185             NumberFormat::kDecimalSeparatorField,
1186             23,
1187             24);
1188     verifyFieldPosition(
1189             "no decimal separator",
1190             fmt,
1191             prefix,
1192             third,
1193             UPRV_LENGTHOF(third),
1194             NumberFormat::kDecimalSeparatorField,
1195             0,
1196             0);
1197 }
1198 
TestBadArg()1199 void MeasureFormatTest::TestBadArg() {
1200     UErrorCode status = U_ZERO_ERROR;
1201     MeasureFormat fmt("en", UMEASFMT_WIDTH_SHORT, status);
1202     if (!assertSuccess("Error creating format object", status)) {
1203         return;
1204     }
1205     FieldPosition pos(0);
1206     UnicodeString buffer;
1207     fmt.format(
1208             9.3,
1209             buffer,
1210             pos,
1211             status);
1212     if (status != U_ILLEGAL_ARGUMENT_ERROR) {
1213         errln("Expected ILLEGAL_ARGUMENT_ERROR");
1214     }
1215 }
1216 
TestEquality()1217 void MeasureFormatTest::TestEquality() {
1218     UErrorCode status = U_ZERO_ERROR;
1219     NumberFormat* nfeq = NumberFormat::createInstance("en", status);
1220     NumberFormat* nfne = NumberFormat::createInstance("fr", status);
1221     MeasureFormat fmt("en", UMEASFMT_WIDTH_SHORT, status);
1222     MeasureFormat fmtEq2("en", UMEASFMT_WIDTH_SHORT, nfeq, status);
1223     MeasureFormat fmtne1("en", UMEASFMT_WIDTH_WIDE, status);
1224     MeasureFormat fmtne2("fr", UMEASFMT_WIDTH_SHORT, status);
1225     MeasureFormat fmtne3("en", UMEASFMT_WIDTH_SHORT, nfne, status);
1226     if (U_FAILURE(status)) {
1227         dataerrln("Error creating MeasureFormats - %s", u_errorName(status));
1228         return;
1229     }
1230     MeasureFormat fmtEq(fmt);
1231     assertTrue("Equal", fmt == fmtEq);
1232     assertTrue("Equal2", fmt == fmtEq2);
1233     assertFalse("Equal Neg", fmt != fmtEq);
1234     assertTrue("Not Equal 1", fmt != fmtne1);
1235     assertFalse("Not Equal Neg 1", fmt == fmtne1);
1236     assertTrue("Not Equal 2", fmt != fmtne2);
1237     assertTrue("Not Equal 3", fmt != fmtne3);
1238 }
1239 
TestGroupingSeparator()1240 void MeasureFormatTest::TestGroupingSeparator() {
1241     UErrorCode status = U_ZERO_ERROR;
1242     Locale en("en");
1243     MeasureFormat fmt(en, UMEASFMT_WIDTH_SHORT, status);
1244     if (!assertSuccess("Error creating format object", status)) {
1245         return;
1246     }
1247     Measure ms[] = {
1248             Measure((int32_t)INT32_MAX, MeasureUnit::createYear(status), status),
1249             Measure((int32_t)INT32_MIN, MeasureUnit::createMonth(status), status),
1250             Measure(-987, MeasureUnit::createDay(status), status),
1251             Measure(1362, MeasureUnit::createHour(status), status),
1252             Measure(987, MeasureUnit::createMinute(status), status)};
1253     FieldPosition pos(NumberFormat::kGroupingSeparatorField);
1254     UnicodeString appendTo;
1255     fmt.formatMeasures(ms, 5, appendTo, pos, status);
1256     if (!assertSuccess("Error formatting", status)) {
1257         return;
1258     }
1259     assertEquals(
1260             "grouping separator",
1261             "2,147,483,647 yrs, -2,147,483,648 mths, -987 days, 1,362 hr, 987 min",
1262             appendTo);
1263     assertEquals("begin index", 9, pos.getBeginIndex());
1264     assertEquals("end index", 10, pos.getEndIndex());
1265 }
1266 
TestDoubleZero()1267 void MeasureFormatTest::TestDoubleZero() {
1268     UErrorCode status = U_ZERO_ERROR;
1269     Measure measures[] = {
1270         Measure(4.7, MeasureUnit::createHour(status), status),
1271         Measure(23, MeasureUnit::createMinute(status), status),
1272         Measure(16, MeasureUnit::createSecond(status), status)};
1273     Locale en("en");
1274     NumberFormat *nf = NumberFormat::createInstance(en, status);
1275     MeasureFormat fmt("en", UMEASFMT_WIDTH_WIDE, nf, status);
1276     UnicodeString appendTo;
1277     FieldPosition pos(FieldPosition::DONT_CARE);
1278     if (U_FAILURE(status)) {
1279         dataerrln("Error creating formatter - %s", u_errorName(status));
1280         return;
1281     }
1282     nf->setMinimumFractionDigits(2);
1283     nf->setMaximumFractionDigits(2);
1284     fmt.formatMeasures(measures, UPRV_LENGTHOF(measures), appendTo, pos, status);
1285     if (!assertSuccess("Error formatting", status)) {
1286         return;
1287     }
1288     assertEquals(
1289             "TestDoubleZero",
1290             UnicodeString("4 hours, 23 minutes, 16.00 seconds"),
1291             appendTo);
1292     measures[0] = Measure(-4.7, MeasureUnit::createHour(status), status);
1293     appendTo.remove();
1294     fmt.formatMeasures(measures, UPRV_LENGTHOF(measures), appendTo, pos, status);
1295     if (!assertSuccess("Error formatting", status)) {
1296         return;
1297     }
1298     assertEquals(
1299             "TestDoubleZero",
1300             UnicodeString("-4 hours, 23 minutes, 16.00 seconds"),
1301             appendTo);
1302 }
1303 
TestUnitPerUnitResolution()1304 void MeasureFormatTest::TestUnitPerUnitResolution() {
1305     UErrorCode status = U_ZERO_ERROR;
1306     Locale en("en");
1307     MeasureFormat fmt("en", UMEASFMT_WIDTH_SHORT, status);
1308     Measure measure(50, MeasureUnit::createPound(status), status);
1309     LocalPointer<MeasureUnit> sqInch(MeasureUnit::createSquareInch(status));
1310     if (!assertSuccess("Create of format unit and per unit", status)) {
1311         return;
1312     }
1313     FieldPosition pos(0);
1314     UnicodeString actual;
1315     fmt.formatMeasurePerUnit(
1316             measure,
1317             *sqInch,
1318             actual,
1319             pos,
1320             status);
1321     assertEquals("", "50 psi", actual);
1322 }
1323 
verifyFieldPosition(const char * description,const MeasureFormat & fmt,const UnicodeString & prefix,const Measure * measures,int32_t measureCount,NumberFormat::EAlignmentFields field,int32_t start,int32_t end)1324 void MeasureFormatTest::verifyFieldPosition(
1325         const char *description,
1326         const MeasureFormat &fmt,
1327         const UnicodeString &prefix,
1328         const Measure *measures,
1329         int32_t measureCount,
1330         NumberFormat::EAlignmentFields field,
1331         int32_t start,
1332         int32_t end) {
1333     // 8 char lead
1334     UnicodeString result(prefix);
1335     FieldPosition pos(field);
1336     UErrorCode status = U_ZERO_ERROR;
1337     CharString ch;
1338     const char *descPrefix = ch.append(description, status)
1339             .append(": ", status).data();
1340     CharString beginIndex;
1341     beginIndex.append(descPrefix, status).append("beginIndex", status);
1342     CharString endIndex;
1343     endIndex.append(descPrefix, status).append("endIndex", status);
1344     fmt.formatMeasures(measures, measureCount, result, pos, status);
1345     if (!assertSuccess("Error formatting", status)) {
1346         return;
1347     }
1348     assertEquals(beginIndex.data(), start, pos.getBeginIndex());
1349     assertEquals(endIndex.data(), end, pos.getEndIndex());
1350 }
1351 
verifyFormat(const char * description,const MeasureFormat & fmt,const Measure * measures,int32_t measureCount,const char * expected)1352 void MeasureFormatTest::verifyFormat(
1353         const char *description,
1354         const MeasureFormat &fmt,
1355         const Measure *measures,
1356         int32_t measureCount,
1357         const char *expected) {
1358     verifyFormatWithPrefix(
1359             description,
1360             fmt,
1361             "",
1362             measures,
1363             measureCount,
1364             expected);
1365 }
1366 
verifyFormatWithPrefix(const char * description,const MeasureFormat & fmt,const UnicodeString & prefix,const Measure * measures,int32_t measureCount,const char * expected)1367 void MeasureFormatTest::verifyFormatWithPrefix(
1368         const char *description,
1369         const MeasureFormat &fmt,
1370         const UnicodeString &prefix,
1371         const Measure *measures,
1372         int32_t measureCount,
1373         const char *expected) {
1374     UnicodeString result(prefix);
1375     FieldPosition pos(0);
1376     UErrorCode status = U_ZERO_ERROR;
1377     fmt.formatMeasures(measures, measureCount, result, pos, status);
1378     if (!assertSuccess("Error formatting", status)) {
1379         return;
1380     }
1381     assertEquals(description, UnicodeString(expected).unescape(), result);
1382 }
1383 
verifyFormat(const char * description,const MeasureFormat & fmt,const ExpectedResult * expectedResults,int32_t count)1384 void MeasureFormatTest::verifyFormat(
1385         const char *description,
1386         const MeasureFormat &fmt,
1387         const ExpectedResult *expectedResults,
1388         int32_t count) {
1389     for (int32_t i = 0; i < count; ++i) {
1390         verifyFormat(description, fmt, expectedResults[i].measures, expectedResults[i].count, expectedResults[i].expected);
1391     }
1392 }
1393 
createMeasureFormatTest()1394 extern IntlTest *createMeasureFormatTest() {
1395     return new MeasureFormatTest();
1396 }
1397 
1398 #endif
1399 
1400