• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
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 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 
runIndexedTest(int32_t index,UBool exec,const char * & name,char *)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 
TestBasic()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 
TestGetAvailable()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 
TestExamplesInDocs()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 
TestFormatPeriodEn()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 
Test10219FractionalPlurals()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 
toMeasureUnit(MeasureUnit * adopted)519 static MeasureUnit toMeasureUnit(MeasureUnit *adopted) {
520     MeasureUnit result(*adopted);
521     delete adopted;
522     return result;
523 }
524 
TestGreek()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 
TestFormatSingleArg()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 
TestFormatMeasuresZeroArg()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 
TestMultiples()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 
helperTestMultiples(const Locale & locale,UMeasureFormatWidth width,const char * expected)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 
TestGram()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 
TestCurrencies()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 
TestFieldPosition()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 
TestFieldPositionMultiple()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 
TestBadArg()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 
TestEquality()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 
TestDoubleZero()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 
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)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 
verifyFormat(const char * description,const MeasureFormat & fmt,const Measure * measures,int32_t measureCount,const char * expected)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 
verifyFormatWithPrefix(const char * description,const MeasureFormat & fmt,const UnicodeString & prefix,const Measure * measures,int32_t measureCount,const char * expected)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 
verifyFormat(const char * description,const MeasureFormat & fmt,const ExpectedResult * expectedResults,int32_t count)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 
createMeasureFormatTest()974 extern IntlTest *createMeasureFormatTest() {
975     return new MeasureFormatTest();
976 }
977 
978 #endif
979 
980