1 /********************************************************************
3 * Copyright (c) 2007-2012, International Business Machines Corporation and
4 * others. All Rights Reserved.
5 ********************************************************************/
7 #include "unicode/utypes.h"
9 #if !UCONFIG_NO_FORMATTING
14 #include "unicode/msgfmt.h"
15 #include "unicode/plurrule.h"
16 #include "unicode/plurfmt.h"
18 #define PLURAL_PATTERN_DATA 4
19 #define PLURAL_TEST_ARRAY_SIZE 256
21 #define PLURAL_SYNTAX_DATA 8
23 // The value must be same as PLKeywordLookups[] order.
31 void PluralFormatTest::runIndexedTest( int32_t index
, UBool exec
, const char* &name
, char* /*par*/ )
33 if (exec
) logln("TestSuite PluralFormat");
35 TESTCASE_AUTO(pluralFormatBasicTest
);
36 TESTCASE_AUTO(pluralFormatUnitTest
);
37 TESTCASE_AUTO(pluralFormatLocaleTest
);
38 TESTCASE_AUTO(pluralFormatExtendedTest
);
39 TESTCASE_AUTO(pluralFormatExtendedParseTest
);
40 TESTCASE_AUTO(ordinalFormatTest
);
45 * Test various generic API methods of PluralFormat for Basic usage.
47 void PluralFormatTest::pluralFormatBasicTest(/*char *par*/)
50 PluralFormat
* plFmt
[8];
51 Locale locale
= Locale::getDefault();
52 UnicodeString otherPattern
= UnicodeString("other{#}");
53 UnicodeString message
=UnicodeString("ERROR: PluralFormat basic test");
55 // ========= Test constructors
56 logln(" Testing PluralFormat constructors ...");
57 status
[0] = U_ZERO_ERROR
;
58 PluralRules
* plRules
= PluralRules::createDefaultRules(status
[0]);
60 status
[0] = U_ZERO_ERROR
;
61 NumberFormat
*numFmt
= NumberFormat::createInstance(status
[0]);
62 if (U_FAILURE(status
[0])) {
63 dataerrln("ERROR: Could not create NumberFormat instance with default locale ");
66 for (int32_t i
=0; i
< 8; ++i
) {
67 status
[i
] = U_ZERO_ERROR
;
69 plFmt
[0] = new PluralFormat(status
[0]);
70 plFmt
[1] = new PluralFormat(*plRules
, status
[1]);
71 plFmt
[2] = new PluralFormat(locale
, status
[2]);
72 plFmt
[3] = new PluralFormat(locale
, *plRules
, status
[3]);
73 plFmt
[4] = new PluralFormat(otherPattern
, status
[4]);
74 plFmt
[5] = new PluralFormat(*plRules
, otherPattern
, status
[5]);
75 plFmt
[6] = new PluralFormat(locale
, otherPattern
, status
[6]);
76 plFmt
[7] = new PluralFormat(locale
, *plRules
, otherPattern
, status
[7]);
78 for (int32_t i
=0; i
< 8; ++i
) {
79 if (U_SUCCESS(status
[i
])) {
80 numberFormatTest(plFmt
[i
], numFmt
, 1, 12, NULL
, NULL
, FALSE
, &message
);
81 numberFormatTest(plFmt
[i
], numFmt
, 100, 112, NULL
, NULL
, FALSE
, &message
);
84 dataerrln("ERROR: PluralFormat constructor failed!");
88 // ======= Test clone, assignment operator && == operator.
89 plFmt
[0]= new PluralFormat(status
[0]);
90 plFmt
[0]->setNumberFormat(numFmt
,status
[0]);
91 UnicodeString us
= UnicodeString("");
92 plFmt
[0]->toPattern(us
);
93 plFmt
[1]= new PluralFormat(locale
, status
[1]);
94 if ( U_SUCCESS(status
[0]) && U_SUCCESS(status
[1]) ) {
95 *plFmt
[1] = *plFmt
[0];
97 if ( *plFmt
[1] != *plFmt
[0] ) {
98 errln("ERROR: clone plural format test failed!");
103 dataerrln("ERROR: PluralFormat constructor failed! - [0]%s [1]%s", u_errorName(status
[0]), u_errorName(status
[1]));
107 status
[0] = U_ZERO_ERROR
;
108 plFmt
[0]= new PluralFormat(locale
, status
[0]);
109 if ( U_SUCCESS(status
[0]) ) {
110 *plFmt
[1] = *plFmt
[0];
111 if (plFmt
[1]!=NULL
) {
112 if ( *plFmt
[1] != *plFmt
[0] ) {
113 errln("ERROR: assignment operator test failed!");
118 dataerrln("ERROR: PluralFormat constructor failed! - %s", u_errorName(status
[1]));
121 if ( U_SUCCESS(status
[1]) ) {
122 plFmt
[2] = (PluralFormat
*) plFmt
[1]->clone();
124 if (plFmt
[1]!=NULL
) {
125 if ( *plFmt
[1] != *plFmt
[2] ) {
126 errln("ERROR: clone function test failed!");
133 dataerrln("ERROR: PluralFormat clone failed! - %s", u_errorName(status
[1]));
141 UErrorCode stat
= U_ZERO_ERROR
;
142 PluralFormat
*pf
= new PluralFormat(stat
);
143 Formattable
*f
= new Formattable();
144 ParsePosition
*pp
= new ParsePosition();
145 pf
->parseObject((UnicodeString
)"",*f
,*pp
);
146 if(U_FAILURE(stat
)) {
147 dataerrln("ERROR: PluralFormat::parseObject: %s", u_errorName(stat
));
155 * Unit tests of PluralFormat class.
157 void PluralFormatTest::pluralFormatUnitTest(/*char *par*/)
159 UnicodeString patternTestData
[PLURAL_PATTERN_DATA
] = {
160 UNICODE_STRING_SIMPLE("odd {# is odd.} other{# is even.}"),
161 UNICODE_STRING_SIMPLE("other{# is odd or even.}"),
162 UNICODE_STRING_SIMPLE("odd{The number {0, number, #.#0} is odd.}other{The number {0, number, #.#0} is even.}"),
163 UNICODE_STRING_SIMPLE("odd{The number {1, number, #} is odd.}other{The number {2, number, #} is even.}"),
165 UnicodeString patternOddTestResult
[PLURAL_PATTERN_DATA
] = {
166 UNICODE_STRING_SIMPLE(" is odd."),
167 UNICODE_STRING_SIMPLE(" is odd or even."),
168 UNICODE_STRING_SIMPLE("The number {0, number, #.#0} is odd."),
169 UNICODE_STRING_SIMPLE("The number {1, number, #} is odd."),
171 UnicodeString patternEvenTestResult
[PLURAL_PATTERN_DATA
] = {
172 UNICODE_STRING_SIMPLE(" is even."),
173 UNICODE_STRING_SIMPLE(" is odd or even."),
174 UNICODE_STRING_SIMPLE("The number {0, number, #.#0} is even."),
175 UNICODE_STRING_SIMPLE("The number {2, number, #} is even."),
177 UnicodeString checkSyntaxtData
[PLURAL_SYNTAX_DATA
] = {
178 // ICU 4.8 does not check for duplicate keywords any more.
179 //UNICODE_STRING_SIMPLE("odd{foo} odd{bar} other{foobar}"),
180 //UNICODE_STRING_SIMPLE("odd{foo} other{bar} other{foobar}"),
181 UNICODE_STRING_SIMPLE("odd{foo}"),
182 // ICU 4.8 does not check for unknown keywords any more.
183 //UNICODE_STRING_SIMPLE("otto{foo} other{bar}"),
184 UNICODE_STRING_SIMPLE("*odd{foo} other{bar}"),
185 UNICODE_STRING_SIMPLE("odd{foo},other{bar}"),
186 UNICODE_STRING_SIMPLE("od d{foo} other{bar}"),
187 UNICODE_STRING_SIMPLE("odd{foo}{foobar}other{foo}"),
190 UErrorCode status
= U_ZERO_ERROR
;
191 UnicodeString oddAndEvenRule
= UNICODE_STRING_SIMPLE("odd: n mod 2 is 1");
192 PluralRules
* plRules
= PluralRules::createRules(oddAndEvenRule
, status
);
193 if (U_FAILURE(status
)) {
194 dataerrln("ERROR: create PluralRules instance failed in unit tests.- exitting");
198 // ======= Test PluralRules pattern syntax.
199 logln("Testing PluralRules pattern syntax.");
200 for (int32_t i
=0; i
<PLURAL_SYNTAX_DATA
; ++i
) {
201 status
= U_ZERO_ERROR
;
203 PluralFormat plFmt
=PluralFormat(*plRules
, status
);
204 if (U_FAILURE(status
)) {
205 dataerrln("ERROR: PluralFormat constructor failed in unit tests.- exitting");
208 plFmt
.applyPattern(checkSyntaxtData
[i
], status
);
209 if (U_SUCCESS(status
)) {
210 errln("ERROR: PluralFormat failed to detect syntax error with pattern: "+checkSyntaxtData
[i
]);
216 // ======= Test applying various pattern
217 logln("Testing various patterns");
218 status
= U_ZERO_ERROR
;
219 UBool overwrite
[PLURAL_PATTERN_DATA
] = {FALSE
, FALSE
, TRUE
, TRUE
};
221 NumberFormat
*numFmt
= NumberFormat::createInstance(status
);
222 UnicodeString message
=UnicodeString("ERROR: PluralFormat tests various pattern ...");
223 if (U_FAILURE(status
)) {
224 dataerrln("ERROR: Could not create NumberFormat instance with default locale ");
226 for(int32_t i
=0; i
<PLURAL_PATTERN_DATA
; ++i
) {
227 status
= U_ZERO_ERROR
;
228 PluralFormat plFmt
=PluralFormat(*plRules
, status
);
229 if (U_FAILURE(status
)) {
230 dataerrln("ERROR: PluralFormat constructor failed in unit tests.- exitting");
233 plFmt
.applyPattern(patternTestData
[i
], status
);
234 if (U_FAILURE(status
)) {
235 errln("ERROR: PluralFormat failed to apply pattern- "+patternTestData
[i
]);
238 numberFormatTest(&plFmt
, numFmt
, 1, 10, (UnicodeString
*)&patternOddTestResult
[i
],
239 (UnicodeString
*)&patternEvenTestResult
[i
], overwrite
[i
], &message
);
244 // ======= Test set locale
245 status
= U_ZERO_ERROR
;
246 plRules
= PluralRules::createRules(UNICODE_STRING_SIMPLE("odd: n mod 2 is 1"), status
);
247 PluralFormat pluralFmt
= PluralFormat(*plRules
, status
);
248 if (U_FAILURE(status
)) {
249 dataerrln("ERROR: Could not create PluralFormat instance in setLocale() test - exitting. ");
253 pluralFmt
.applyPattern(UNICODE_STRING_SIMPLE("odd{odd} other{even}"), status
);
254 pluralFmt
.setLocale(Locale::getEnglish(), status
);
255 if (U_FAILURE(status
)) {
256 dataerrln("ERROR: Could not setLocale() with English locale ");
260 message
= UNICODE_STRING_SIMPLE("Error set locale: pattern is not reset!");
262 // Check that pattern gets deleted.
263 logln("\n Test setLocale() ..\n");
264 numFmt
= NumberFormat::createInstance(Locale::getEnglish(), status
);
265 if (U_FAILURE(status
)) {
266 dataerrln("ERROR: Could not create NumberFormat instance with English locale ");
268 numberFormatTest(&pluralFmt
, numFmt
, 5, 5, NULL
, NULL
, FALSE
, &message
);
269 pluralFmt
.applyPattern(UNICODE_STRING_SIMPLE("odd__{odd} other{even}"), status
);
270 if (pluralFmt
.format((int32_t)1, status
) != UNICODE_STRING_SIMPLE("even")) {
271 errln("SetLocale should reset rules but did not.");
273 status
= U_ZERO_ERROR
;
274 pluralFmt
.applyPattern(UNICODE_STRING_SIMPLE("one{one} other{not one}"), status
);
275 if (U_FAILURE(status
)) {
276 errln("SetLocale should reset rules but did not.");
278 UnicodeString one
= UNICODE_STRING_SIMPLE("one");
279 UnicodeString notOne
= UNICODE_STRING_SIMPLE("not one");
280 UnicodeString plResult
, numResult
;
281 for (int32_t i
=0; i
<20; ++i
) {
282 plResult
= pluralFmt
.format(i
, status
);
289 if ( numResult
!= plResult
) {
290 errln("Wrong ruleset loaded by setLocale() - got:"+plResult
+ UnicodeString(" expecting:")+numResult
);
294 // =========== Test copy constructor
295 logln("Test copy constructor and == operator of PluralFormat");
296 PluralFormat dupPFmt
= PluralFormat(pluralFmt
);
297 if (pluralFmt
!= dupPFmt
) {
298 errln("Failed in PluralFormat copy constructor or == operator");
308 * Test locale data used in PluralFormat class.
311 PluralFormatTest::pluralFormatLocaleTest(/*char *par*/)
313 int8_t pluralResults
[PLURAL_TEST_ARRAY_SIZE
]; // 0: is for default
315 // ======= Test DefaultRule
316 logln("Testing PluralRules with no rule.");
317 const char* oneRuleLocales
[4] = {"ja", "ko", "tr", "vi"};
318 UnicodeString testPattern
= UNICODE_STRING_SIMPLE("other{other}");
319 uprv_memset(pluralResults
, -1, sizeof(pluralResults
));
320 pluralResults
[0]= PFT_OTHER
; // other
321 helperTestResults(oneRuleLocales
, 4, testPattern
, pluralResults
);
323 // ====== Test Singular1 locales.
324 logln("Testing singular1 locales.");
325 const char* singular1Locales
[52] = {"bem","da","de","el","en","eo","es","et","fi",
326 "fo","gl","he","it","nb","nl","nn","no","pt","pt_PT","sv","af","bg","bn","ca","eu","fur","fy",
327 "gu","ha","is","ku","lb","ml","mr","nah","ne","om","or","pa","pap","ps","so","sq","sw","ta",
328 "te","tk","ur","zu","mn","gsw","rm"};
329 testPattern
= UNICODE_STRING_SIMPLE("one{one} other{other}");
330 uprv_memset(pluralResults
, -1, sizeof(pluralResults
));
331 pluralResults
[0]= PFT_OTHER
;
332 pluralResults
[1]= PFT_ONE
;
333 pluralResults
[2]= PFT_OTHER
;
334 helperTestResults(singular1Locales
, 52, testPattern
, pluralResults
);
336 // ======== Test Singular01 locales.
337 logln("Testing singular1 locales.");
338 const char* singular01Locales
[3] = {"ff","fr","kab"};
339 testPattern
= UNICODE_STRING_SIMPLE("one{one} other{other}");
340 uprv_memset(pluralResults
, -1, sizeof(pluralResults
));
341 pluralResults
[0]= PFT_ONE
;
342 pluralResults
[2]= PFT_OTHER
;
343 helperTestResults(singular01Locales
, 3, testPattern
, pluralResults
);
345 // ======== Test ZeroSingular locales.
346 logln("Testing singular1 locales.");
347 const char* zeroSingularLocales
[1] = {"lv"};
348 testPattern
= UNICODE_STRING_SIMPLE("zero{zero} one{one} other{other}");
349 uprv_memset(pluralResults
, -1, sizeof(pluralResults
));
350 pluralResults
[0]= PFT_ZERO
;
351 pluralResults
[1]= PFT_ONE
;
352 pluralResults
[2]= PFT_OTHER
;
353 for (int32_t i
=2; i
<20; ++i
) {
355 pluralResults
[i
*10+1] = PFT_ONE
;
356 pluralResults
[i
*10+2] = PFT_OTHER
;
358 helperTestResults(zeroSingularLocales
, 1, testPattern
, pluralResults
);
360 // ======== Test singular dual locales.
361 logln("Testing singular1 locales.");
362 const char* singularDualLocales
[1] = {"ga"};
363 testPattern
= UNICODE_STRING_SIMPLE("one{one} two{two} other{other}");
364 uprv_memset(pluralResults
, -1, sizeof(pluralResults
));
365 pluralResults
[0]= PFT_OTHER
;
366 pluralResults
[1]= PFT_ONE
;
367 pluralResults
[2]= PFT_TWO
;
368 pluralResults
[3]= PFT_OTHER
;
369 helperTestResults(singularDualLocales
, 1, testPattern
, pluralResults
);
371 // ======== Test Singular Zero Some locales.
372 logln("Testing singular1 locales.");
373 const char* singularZeroSomeLocales
[1] = {"ro"};
374 testPattern
= UNICODE_STRING_SIMPLE("few{few} one{one} other{other}");
375 uprv_memset(pluralResults
, -1, sizeof(pluralResults
));
376 pluralResults
[0]= PFT_FEW
;
377 for (int32_t i
=1; i
<20; ++i
) {
379 pluralResults
[i
] = PFT_FEW
;
380 pluralResults
[100+i
] = PFT_FEW
;
382 pluralResults
[1]= PFT_ONE
;
383 helperTestResults(singularZeroSomeLocales
, 1, testPattern
, pluralResults
);
385 // ======== Test Special 12/19.
386 logln("Testing special 12 and 19.");
387 const char* special12_19Locales
[1] = {"lt"};
388 testPattern
= UNICODE_STRING_SIMPLE("one{one} few{few} other{other}");
389 uprv_memset(pluralResults
, -1, sizeof(pluralResults
));
390 pluralResults
[0]= PFT_OTHER
;
391 pluralResults
[1]= PFT_ONE
;
392 pluralResults
[2]= PFT_FEW
;
393 pluralResults
[10]= PFT_OTHER
;
394 for (int32_t i
=2; i
<20; ++i
) {
396 pluralResults
[i
*10+1] = PFT_ONE
;
397 pluralResults
[i
*10+2] = PFT_FEW
;
398 pluralResults
[(i
+1)*10] = PFT_OTHER
;
400 helperTestResults(special12_19Locales
, 1, testPattern
, pluralResults
);
402 // ======== Test Paucal Except 11 14.
403 logln("Testing Paucal Except 11 and 14.");
404 const char* paucal01Locales
[4] = {"hr","ru","sr","uk"};
405 testPattern
= UNICODE_STRING_SIMPLE("one{one} many{many} few{few} other{other}");
406 uprv_memset(pluralResults
, -1, sizeof(pluralResults
));
407 pluralResults
[0]= PFT_MANY
;
408 pluralResults
[1]= PFT_ONE
;
409 pluralResults
[2]= PFT_FEW
;
410 pluralResults
[5]= PFT_MANY
;
411 pluralResults
[6]= PFT_MANY
;
412 pluralResults
[7]= PFT_MANY
;
413 pluralResults
[8]= PFT_MANY
;
414 pluralResults
[9]= PFT_MANY
;
415 for (int32_t i
=2; i
<20; ++i
) {
417 pluralResults
[i
*10+1] = PFT_ONE
;
418 pluralResults
[i
*10+2] = PFT_FEW
;
419 pluralResults
[i
*10+5] = PFT_MANY
;
420 pluralResults
[i
*10+6] = PFT_MANY
;
421 pluralResults
[i
*10+7] = PFT_MANY
;
422 pluralResults
[i
*10+8] = PFT_MANY
;
423 pluralResults
[i
*10+9] = PFT_MANY
;
425 helperTestResults(paucal01Locales
, 4, testPattern
, pluralResults
);
427 // ======== Test Singular Paucal.
428 logln("Testing Singular Paucal.");
429 const char* singularPaucalLocales
[2] = {"cs","sk"};
430 testPattern
= UNICODE_STRING_SIMPLE("one{one} few{few} other{other}");
431 uprv_memset(pluralResults
, -1, sizeof(pluralResults
));
432 pluralResults
[0]= PFT_OTHER
;
433 pluralResults
[1]= PFT_ONE
;
434 pluralResults
[2]= PFT_FEW
;
435 pluralResults
[5]= PFT_OTHER
;
436 helperTestResults(singularPaucalLocales
, 2, testPattern
, pluralResults
);
438 // ======== Test Paucal (1), (2,3,4).
439 logln("Testing Paucal (1), (2,3,4).");
440 const char* paucal02Locales
[1] = {"pl"};
441 testPattern
= UNICODE_STRING_SIMPLE("one{one} few{few} other{other}");
442 uprv_memset(pluralResults
, -1, sizeof(pluralResults
));
443 pluralResults
[0]= PFT_OTHER
;
444 pluralResults
[1]= PFT_ONE
;
445 pluralResults
[5]= PFT_OTHER
;
446 for (int32_t i
=0; i
<20; ++i
) {
447 if ((i
==1)||(i
==11)) {
448 pluralResults
[i
*10+2] = PFT_OTHER
;
449 pluralResults
[i
*10+3] = PFT_OTHER
;
450 pluralResults
[i
*10+4] = PFT_OTHER
;
453 pluralResults
[i
*10+2] = PFT_FEW
;
454 pluralResults
[i
*10+3] = PFT_FEW
;
455 pluralResults
[i
*10+4] = PFT_FEW
;
456 pluralResults
[i
*10+5] = PFT_OTHER
;
459 helperTestResults(paucal02Locales
, 1, testPattern
, pluralResults
);
461 // ======== Test Paucal (1), (2), (3,4).
462 logln("Testing Paucal (1), (2), (3,4).");
463 const char* paucal03Locales
[1] = {"sl"};
464 testPattern
= UNICODE_STRING_SIMPLE("one{one} two{two} few{few} other{other}");
465 uprv_memset(pluralResults
, -1, sizeof(pluralResults
));
466 pluralResults
[0]= PFT_OTHER
;
467 pluralResults
[1]= PFT_ONE
;
468 pluralResults
[2]= PFT_TWO
;
469 pluralResults
[3]= PFT_FEW
;
470 pluralResults
[5]= PFT_OTHER
;
471 pluralResults
[101]= PFT_ONE
;
472 pluralResults
[102]= PFT_TWO
;
473 pluralResults
[103]= PFT_FEW
;
474 pluralResults
[105]= PFT_OTHER
;
475 helperTestResults(paucal03Locales
, 1, testPattern
, pluralResults
);
477 // TODO: move this test to Unit Test after CLDR 1.6 is final and we support float
478 // ======= Test French "WITHIN rule
479 logln("Testing PluralRules with fr rule.");
480 testPattern
= UNICODE_STRING_SIMPLE("one{one} other{other}");
481 Locale
ulocale((const char *)"fr");
482 UErrorCode status
= U_ZERO_ERROR
;
483 PluralFormat
plFmt(ulocale
, testPattern
, status
);
484 if (U_FAILURE(status
)) {
485 dataerrln("Failed to apply pattern to fr locale - %s", u_errorName(status
));
488 status
= U_ZERO_ERROR
;
489 UnicodeString plResult
= plFmt
.format(0.0, status
); // retrun ONE
490 plResult
= plFmt
.format(0.5, status
); // retrun ONE
491 plResult
= plFmt
.format(1.0, status
); // retrun ONE
492 plResult
= plFmt
.format(1.9, status
); // retrun ONE
493 plResult
= plFmt
.format(2.0, status
); // retrun OTHER
498 PluralFormatTest::pluralFormatExtendedTest(void) {
499 const char *targets
[] = {
500 "There are no widgets.",
501 "There is one widget.",
502 "There is a bling widget and one other widget.",
503 "There is a bling widget and 2 other widgets.",
504 "There is a bling widget and 3 other widgets.",
505 "Widgets, five (5-1=4) there be.",
506 "There is a bling widget and 5 other widgets.",
507 "There is a bling widget and 6 other widgets.",
512 "=0 {There are no widgets.} "
513 "=1.0 {There is one widget.} "
514 "=5 {Widgets, five (5-1=#) there be.} "
515 "one {There is a bling widget and one other widget.} "
516 "other {There is a bling widget and # other widgets.}";
518 UErrorCode status
= U_ZERO_ERROR
;
519 UnicodeString
fmtString(fmt
, -1, US_INV
);
520 PluralFormat
pf(Locale::getEnglish(), fmtString
, status
);
521 MessageFormat
mf(UNICODE_STRING_SIMPLE("{0,plural,").append(fmtString
).append((UChar
)0x7d /* '}' */),
522 Locale::getEnglish(), status
);
524 FieldPosition ignore
;
525 if (U_FAILURE(status
)) {
526 dataerrln("Failed to apply pattern - %s", u_errorName(status
));
529 for (int32_t i
= 0; i
< 7; ++i
) {
530 UnicodeString result
= pf
.format(i
, status
);
531 if (U_FAILURE(status
)) {
532 errln("PluralFormat.format(value %d) failed - %s", i
, u_errorName(status
));
535 UnicodeString
expected(targets
[i
], -1, US_INV
);
536 if (expected
!= result
) {
537 UnicodeString
message("PluralFormat.format(): Expected '", -1, US_INV
);
538 message
.append(expected
);
539 message
.append(UnicodeString("' but got '", -1, US_INV
));
540 message
.append(result
);
541 message
.append("'", -1, US_INV
);
545 mf
.format(&args
, 1, result
.remove(), ignore
, status
);
546 if (U_FAILURE(status
)) {
547 errln("MessageFormat.format(value %d) failed - %s", i
, u_errorName(status
));
550 if (expected
!= result
) {
551 UnicodeString
message("MessageFormat.format(): Expected '", -1, US_INV
);
552 message
.append(expected
);
553 message
.append(UnicodeString("' but got '", -1, US_INV
));
554 message
.append(result
);
555 message
.append("'", -1, US_INV
);
562 PluralFormatTest::pluralFormatExtendedParseTest(void) {
563 const char *failures
[] = {
564 "offset:1..0 =0 {Foo}",
567 "=0 {Foo} =0.0 {Bar}",
570 int len
= sizeof(failures
)/sizeof(failures
[0]);
572 for (int i
= 0; i
< len
; ++i
) {
573 UErrorCode status
= U_ZERO_ERROR
;
574 UnicodeString
fmt(failures
[i
], -1, US_INV
);
575 PluralFormat
pf(fmt
, status
);
576 if (U_SUCCESS(status
)) {
577 errln("expected failure when parsing '" + fmt
+ "'");
583 PluralFormatTest::ordinalFormatTest(void) {
584 IcuTestErrorCode
errorCode(*this, "ordinalFormatTest");
585 UnicodeString
pattern("one{#st file}two{#nd file}few{#rd file}other{#th file}");
586 PluralFormat
pf(Locale::getEnglish(), UPLURAL_TYPE_ORDINAL
, pattern
, errorCode
);
587 if (errorCode
.logDataIfFailureAndReset("PluralFormat(en, UPLURAL_TYPE_ORDINAL, pattern) failed")) {
590 UnicodeString result
= pf
.format((int32_t)321, errorCode
);
591 if (!errorCode
.logIfFailureAndReset("PluralFormat.format(321) failed") &&
592 result
!= UNICODE_STRING_SIMPLE("321st file")) {
593 errln(UnicodeString("PluralFormat.format(321) wrong result string: ") + result
);
595 result
= pf
.format((int32_t)22, errorCode
);
596 if (!errorCode
.logIfFailureAndReset("PluralFormat.format(22) failed") &&
597 result
!= UNICODE_STRING_SIMPLE("22nd file")) {
598 errln(UnicodeString("PluralFormat.format(22) wrong result string: ") + result
);
600 result
= pf
.format((int32_t)3, errorCode
);
601 if (!errorCode
.logIfFailureAndReset("PluralFormat.format(3) failed") &&
602 result
!= UNICODE_STRING_SIMPLE("3rd file")) {
603 errln(UnicodeString("PluralFormat.format(3) wrong result string: ") + result
);
606 // Code coverage: Use the other new-for-UPluralType constructor as well.
607 PluralFormat
pf2(Locale::getEnglish(), UPLURAL_TYPE_ORDINAL
, errorCode
);
608 pf2
.applyPattern(pattern
, errorCode
);
609 if (errorCode
.logIfFailureAndReset("PluralFormat(en, UPLURAL_TYPE_ORDINAL, pattern) failed")) {
612 result
= pf2
.format((int32_t)456, errorCode
);
613 if (!errorCode
.logIfFailureAndReset("PluralFormat.format(456) failed") &&
614 result
!= UNICODE_STRING_SIMPLE("456th file")) {
615 errln(UnicodeString("PluralFormat.format(456) wrong result string: ") + result
);
617 result
= pf2
.format((int32_t)111, errorCode
);
618 if (!errorCode
.logIfFailureAndReset("PluralFormat.format(111) failed") &&
619 result
!= UNICODE_STRING_SIMPLE("111th file")) {
620 errln(UnicodeString("PluralFormat.format(111) wrong result string: ") + result
);
625 PluralFormatTest::numberFormatTest(PluralFormat
* plFmt
,
626 NumberFormat
*numFmt
,
629 UnicodeString
*numOddAppendStr
,
630 UnicodeString
*numEvenAppendStr
,
631 UBool overwrite
, // overwrite the numberFormat.format result
632 UnicodeString
*message
) {
633 UErrorCode status
= U_ZERO_ERROR
;
635 if ( (plFmt
==NULL
) || (numFmt
==NULL
) ) {
636 dataerrln("ERROR: Could not create PluralFormat or NumberFormat - exitting");
639 UnicodeString plResult
, numResult
;
641 for (int32_t i
=start
; i
<= end
; ++i
) {
643 numResult
= numFmt
->format(i
, numResult
);
644 plResult
= plFmt
->format(i
, status
);
645 if ((numOddAppendStr
!= NULL
)&&(numEvenAppendStr
!=NULL
)) {
648 numResult
= *numOddAppendStr
;
651 numResult
= *numEvenAppendStr
;
654 else { // Append the string
656 numResult
+= *numOddAppendStr
;
659 numResult
+= *numEvenAppendStr
;
663 if ( (numResult
!=plResult
) || U_FAILURE(status
) ) {
664 if ( message
== NULL
) {
665 errln("ERROR: Unexpected plural format - got:"+plResult
+ UnicodeString(" expecting:")+numResult
);
668 errln( *message
+UnicodeString(" got:")+plResult
+UnicodeString(" expecting:")+numResult
);
678 PluralFormatTest::helperTestResults(const char** localeArray
,
679 int32_t capacityOfArray
,
680 UnicodeString
& testPattern
,
681 int8_t *expResults
) {
683 UnicodeString plResult
;
684 const UnicodeString PLKeywordLookups
[6] = {
685 UNICODE_STRING_SIMPLE("zero"),
686 UNICODE_STRING_SIMPLE("one"),
687 UNICODE_STRING_SIMPLE("two"),
688 UNICODE_STRING_SIMPLE("few"),
689 UNICODE_STRING_SIMPLE("many"),
690 UNICODE_STRING_SIMPLE("other"),
693 for (int32_t i
=0; i
<capacityOfArray
; ++i
) {
694 const char *locale
= localeArray
[i
];
695 Locale
ulocale((const char *)locale
);
696 status
= U_ZERO_ERROR
;
697 PluralFormat
plFmt(ulocale
, testPattern
, status
);
698 if (U_FAILURE(status
)) {
699 dataerrln("Failed to apply pattern to locale:"+UnicodeString(localeArray
[i
]) + " - " + u_errorName(status
));
702 for (int32_t n
=0; n
<PLURAL_TEST_ARRAY_SIZE
; ++n
) {
703 if (expResults
[n
]!=-1) {
704 status
= U_ZERO_ERROR
;
705 plResult
= plFmt
.format(n
, status
);
706 if (U_FAILURE(status
)) {
707 errln("ERROR: Failed to format number in locale data tests with locale: "+
708 UnicodeString(localeArray
[i
]));
710 if (plResult
!= PLKeywordLookups
[expResults
[n
]]){
711 plResult
= plFmt
.format(n
, status
);
712 errln("ERROR: Unexpected format result in locale: "+UnicodeString(localeArray
[i
])+
713 UnicodeString(" got:")+plResult
+ UnicodeString(" expecting:")+
714 PLKeywordLookups
[expResults
[n
]]);
721 #endif /* #if !UCONFIG_NO_FORMATTING */