1 /********************************************************************
3 * Copyright (c) 2007-2011, 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(0, pluralFormatBasicTest
);
36 TESTCASE(1, pluralFormatUnitTest
);
37 TESTCASE(2, pluralFormatLocaleTest
);
38 TESTCASE(3, pluralFormatExtendedTest
);
39 TESTCASE(4, pluralFormatExtendedParseTest
);
46 * Test various generic API methods of PluralFormat for Basic usage.
48 void PluralFormatTest::pluralFormatBasicTest(/*char *par*/)
51 PluralFormat
* plFmt
[8];
52 Locale locale
= Locale::getDefault();
53 UnicodeString otherPattern
= UnicodeString("other{#}");
54 UnicodeString message
=UnicodeString("ERROR: PluralFormat basic test");
56 // ========= Test constructors
57 logln(" Testing PluralFormat constructors ...");
58 status
[0] = U_ZERO_ERROR
;
59 PluralRules
* plRules
= PluralRules::createDefaultRules(status
[0]);
61 status
[0] = U_ZERO_ERROR
;
62 NumberFormat
*numFmt
= NumberFormat::createInstance(status
[0]);
63 if (U_FAILURE(status
[0])) {
64 dataerrln("ERROR: Could not create NumberFormat instance with default locale ");
67 for (int32_t i
=0; i
< 8; ++i
) {
68 status
[i
] = U_ZERO_ERROR
;
70 plFmt
[0] = new PluralFormat(status
[0]);
71 plFmt
[1] = new PluralFormat(*plRules
, status
[1]);
72 plFmt
[2] = new PluralFormat(locale
, status
[2]);
73 plFmt
[3] = new PluralFormat(locale
, *plRules
, status
[3]);
74 plFmt
[4] = new PluralFormat(otherPattern
, status
[4]);
75 plFmt
[5] = new PluralFormat(*plRules
, otherPattern
, status
[5]);
76 plFmt
[6] = new PluralFormat(locale
, otherPattern
, status
[6]);
77 plFmt
[7] = new PluralFormat(locale
, *plRules
, otherPattern
, status
[7]);
79 for (int32_t i
=0; i
< 8; ++i
) {
80 if (U_SUCCESS(status
[i
])) {
81 numberFormatTest(plFmt
[i
], numFmt
, 1, 12, NULL
, NULL
, FALSE
, &message
);
82 numberFormatTest(plFmt
[i
], numFmt
, 100, 112, NULL
, NULL
, FALSE
, &message
);
85 dataerrln("ERROR: PluralFormat constructor failed!");
89 // ======= Test clone, assignment operator && == operator.
90 plFmt
[0]= new PluralFormat(status
[0]);
91 plFmt
[0]->setNumberFormat(numFmt
,status
[0]);
92 UnicodeString us
= UnicodeString("");
93 plFmt
[0]->toPattern(us
);
94 plFmt
[1]= new PluralFormat(locale
, status
[1]);
95 if ( U_SUCCESS(status
[0]) && U_SUCCESS(status
[1]) ) {
96 *plFmt
[1] = *plFmt
[0];
98 if ( *plFmt
[1] != *plFmt
[0] ) {
99 errln("ERROR: clone plural format test failed!");
104 dataerrln("ERROR: PluralFormat constructor failed! - [0]%s [1]%s", u_errorName(status
[0]), u_errorName(status
[1]));
108 status
[0] = U_ZERO_ERROR
;
109 plFmt
[0]= new PluralFormat(locale
, status
[0]);
110 if ( U_SUCCESS(status
[0]) ) {
111 *plFmt
[1] = *plFmt
[0];
112 if (plFmt
[1]!=NULL
) {
113 if ( *plFmt
[1] != *plFmt
[0] ) {
114 errln("ERROR: assignment operator test failed!");
119 dataerrln("ERROR: PluralFormat constructor failed! - %s", u_errorName(status
[1]));
122 if ( U_SUCCESS(status
[1]) ) {
123 plFmt
[2] = (PluralFormat
*) plFmt
[1]->clone();
125 if (plFmt
[1]!=NULL
) {
126 if ( *plFmt
[1] != *plFmt
[2] ) {
127 errln("ERROR: clone function test failed!");
134 dataerrln("ERROR: PluralFormat clone failed! - %s", u_errorName(status
[1]));
142 UErrorCode stat
= U_ZERO_ERROR
;
143 PluralFormat
*pf
= new PluralFormat(stat
);
144 Formattable
*f
= new Formattable();
145 ParsePosition
*pp
= new ParsePosition();
146 pf
->parseObject((UnicodeString
)"",*f
,*pp
);
147 if(U_FAILURE(stat
)) {
148 dataerrln("ERROR: PluralFormat::parseObject: %s", u_errorName(stat
));
156 * Unit tests of PluralFormat class.
158 void PluralFormatTest::pluralFormatUnitTest(/*char *par*/)
160 UnicodeString patternTestData
[PLURAL_PATTERN_DATA
] = {
161 UNICODE_STRING_SIMPLE("odd {# is odd.} other{# is even.}"),
162 UNICODE_STRING_SIMPLE("other{# is odd or even.}"),
163 UNICODE_STRING_SIMPLE("odd{The number {0, number, #.#0} is odd.}other{The number {0, number, #.#0} is even.}"),
164 UNICODE_STRING_SIMPLE("odd{The number {1, number, #} is odd.}other{The number {2, number, #} is even.}"),
166 UnicodeString patternOddTestResult
[PLURAL_PATTERN_DATA
] = {
167 UNICODE_STRING_SIMPLE(" is odd."),
168 UNICODE_STRING_SIMPLE(" is odd or even."),
169 UNICODE_STRING_SIMPLE("The number {0, number, #.#0} is odd."),
170 UNICODE_STRING_SIMPLE("The number {1, number, #} is odd."),
172 UnicodeString patternEvenTestResult
[PLURAL_PATTERN_DATA
] = {
173 UNICODE_STRING_SIMPLE(" is even."),
174 UNICODE_STRING_SIMPLE(" is odd or even."),
175 UNICODE_STRING_SIMPLE("The number {0, number, #.#0} is even."),
176 UNICODE_STRING_SIMPLE("The number {2, number, #} is even."),
178 UnicodeString checkSyntaxtData
[PLURAL_SYNTAX_DATA
] = {
179 // ICU 4.8 does not check for duplicate keywords any more.
180 //UNICODE_STRING_SIMPLE("odd{foo} odd{bar} other{foobar}"),
181 //UNICODE_STRING_SIMPLE("odd{foo} other{bar} other{foobar}"),
182 UNICODE_STRING_SIMPLE("odd{foo}"),
183 // ICU 4.8 does not check for unknown keywords any more.
184 //UNICODE_STRING_SIMPLE("otto{foo} other{bar}"),
185 UNICODE_STRING_SIMPLE("*odd{foo} other{bar}"),
186 UNICODE_STRING_SIMPLE("odd{foo},other{bar}"),
187 UNICODE_STRING_SIMPLE("od d{foo} other{bar}"),
188 UNICODE_STRING_SIMPLE("odd{foo}{foobar}other{foo}"),
191 UErrorCode status
= U_ZERO_ERROR
;
192 UnicodeString oddAndEvenRule
= UNICODE_STRING_SIMPLE("odd: n mod 2 is 1");
193 PluralRules
* plRules
= PluralRules::createRules(oddAndEvenRule
, status
);
194 if (U_FAILURE(status
)) {
195 dataerrln("ERROR: create PluralRules instance failed in unit tests.- exitting");
199 // ======= Test PluralRules pattern syntax.
200 logln("Testing PluralRules pattern syntax.");
201 for (int32_t i
=0; i
<PLURAL_SYNTAX_DATA
; ++i
) {
202 status
= U_ZERO_ERROR
;
204 PluralFormat plFmt
=PluralFormat(*plRules
, status
);
205 if (U_FAILURE(status
)) {
206 dataerrln("ERROR: PluralFormat constructor failed in unit tests.- exitting");
209 plFmt
.applyPattern(checkSyntaxtData
[i
], status
);
210 if (U_SUCCESS(status
)) {
211 errln("ERROR: PluralFormat failed to detect syntax error with pattern: "+checkSyntaxtData
[i
]);
217 // ======= Test applying various pattern
218 logln("Testing various patterns");
219 status
= U_ZERO_ERROR
;
220 UBool overwrite
[PLURAL_PATTERN_DATA
] = {FALSE
, FALSE
, TRUE
, TRUE
};
222 NumberFormat
*numFmt
= NumberFormat::createInstance(status
);
223 UnicodeString message
=UnicodeString("ERROR: PluralFormat tests various pattern ...");
224 if (U_FAILURE(status
)) {
225 dataerrln("ERROR: Could not create NumberFormat instance with default locale ");
227 for(int32_t i
=0; i
<PLURAL_PATTERN_DATA
; ++i
) {
228 status
= U_ZERO_ERROR
;
229 PluralFormat plFmt
=PluralFormat(*plRules
, status
);
230 if (U_FAILURE(status
)) {
231 dataerrln("ERROR: PluralFormat constructor failed in unit tests.- exitting");
234 plFmt
.applyPattern(patternTestData
[i
], status
);
235 if (U_FAILURE(status
)) {
236 errln("ERROR: PluralFormat failed to apply pattern- "+patternTestData
[i
]);
239 numberFormatTest(&plFmt
, numFmt
, 1, 10, (UnicodeString
*)&patternOddTestResult
[i
],
240 (UnicodeString
*)&patternEvenTestResult
[i
], overwrite
[i
], &message
);
245 // ======= Test set locale
246 status
= U_ZERO_ERROR
;
247 plRules
= PluralRules::createRules(UNICODE_STRING_SIMPLE("odd: n mod 2 is 1"), status
);
248 PluralFormat pluralFmt
= PluralFormat(*plRules
, status
);
249 if (U_FAILURE(status
)) {
250 dataerrln("ERROR: Could not create PluralFormat instance in setLocale() test - exitting. ");
254 pluralFmt
.applyPattern(UNICODE_STRING_SIMPLE("odd{odd} other{even}"), status
);
255 pluralFmt
.setLocale(Locale::getEnglish(), status
);
256 if (U_FAILURE(status
)) {
257 dataerrln("ERROR: Could not setLocale() with English locale ");
261 message
= UNICODE_STRING_SIMPLE("Error set locale: pattern is not reset!");
263 // Check that pattern gets deleted.
264 logln("\n Test setLocale() ..\n");
265 numFmt
= NumberFormat::createInstance(Locale::getEnglish(), status
);
266 if (U_FAILURE(status
)) {
267 dataerrln("ERROR: Could not create NumberFormat instance with English locale ");
269 numberFormatTest(&pluralFmt
, numFmt
, 5, 5, NULL
, NULL
, FALSE
, &message
);
270 pluralFmt
.applyPattern(UNICODE_STRING_SIMPLE("odd__{odd} other{even}"), status
);
271 if (pluralFmt
.format((int32_t)1, status
) != UNICODE_STRING_SIMPLE("even")) {
272 errln("SetLocale should reset rules but did not.");
274 status
= U_ZERO_ERROR
;
275 pluralFmt
.applyPattern(UNICODE_STRING_SIMPLE("one{one} other{not one}"), status
);
276 if (U_FAILURE(status
)) {
277 errln("SetLocale should reset rules but did not.");
279 UnicodeString one
= UNICODE_STRING_SIMPLE("one");
280 UnicodeString notOne
= UNICODE_STRING_SIMPLE("not one");
281 UnicodeString plResult
, numResult
;
282 for (int32_t i
=0; i
<20; ++i
) {
283 plResult
= pluralFmt
.format(i
, status
);
290 if ( numResult
!= plResult
) {
291 errln("Wrong ruleset loaded by setLocale() - got:"+plResult
+ UnicodeString(" expecting:")+numResult
);
295 // =========== Test copy constructor
296 logln("Test copy constructor and == operator of PluralFormat");
297 PluralFormat dupPFmt
= PluralFormat(pluralFmt
);
298 if (pluralFmt
!= dupPFmt
) {
299 errln("Failed in PluralFormat copy constructor or == operator");
309 * Test locale data used in PluralFormat class.
312 PluralFormatTest::pluralFormatLocaleTest(/*char *par*/)
314 int8_t pluralResults
[PLURAL_TEST_ARRAY_SIZE
]; // 0: is for default
316 // ======= Test DefaultRule
317 logln("Testing PluralRules with no rule.");
318 const char* oneRuleLocales
[4] = {"ja", "ko", "tr", "vi"};
319 UnicodeString testPattern
= UNICODE_STRING_SIMPLE("other{other}");
320 uprv_memset(pluralResults
, -1, sizeof(pluralResults
));
321 pluralResults
[0]= PFT_OTHER
; // other
322 helperTestRusults(oneRuleLocales
, 4, testPattern
, pluralResults
);
324 // ====== Test Singular1 locales.
325 logln("Testing singular1 locales.");
326 const char* singular1Locales
[52] = {"bem","da","de","el","en","eo","es","et","fi",
327 "fo","gl","he","it","nb","nl","nn","no","pt","pt_PT","sv","af","bg","bn","ca","eu","fur","fy",
328 "gu","ha","is","ku","lb","ml","mr","nah","ne","om","or","pa","pap","ps","so","sq","sw","ta",
329 "te","tk","ur","zu","mn","gsw","rm"};
330 testPattern
= UNICODE_STRING_SIMPLE("one{one} other{other}");
331 uprv_memset(pluralResults
, -1, sizeof(pluralResults
));
332 pluralResults
[0]= PFT_OTHER
;
333 pluralResults
[1]= PFT_ONE
;
334 pluralResults
[2]= PFT_OTHER
;
335 helperTestRusults(singular1Locales
, 52, testPattern
, pluralResults
);
337 // ======== Test Singular01 locales.
338 logln("Testing singular1 locales.");
339 const char* singular01Locales
[3] = {"ff","fr","kab"};
340 testPattern
= UNICODE_STRING_SIMPLE("one{one} other{other}");
341 uprv_memset(pluralResults
, -1, sizeof(pluralResults
));
342 pluralResults
[0]= PFT_ONE
;
343 pluralResults
[2]= PFT_OTHER
;
344 helperTestRusults(singular01Locales
, 3, testPattern
, pluralResults
);
346 // ======== Test ZeroSingular locales.
347 logln("Testing singular1 locales.");
348 const char* zeroSingularLocales
[1] = {"lv"};
349 testPattern
= UNICODE_STRING_SIMPLE("zero{zero} one{one} other{other}");
350 uprv_memset(pluralResults
, -1, sizeof(pluralResults
));
351 pluralResults
[0]= PFT_ZERO
;
352 pluralResults
[1]= PFT_ONE
;
353 pluralResults
[2]= PFT_OTHER
;
354 for (int32_t i
=2; i
<20; ++i
) {
356 pluralResults
[i
*10+1] = PFT_ONE
;
357 pluralResults
[i
*10+2] = PFT_OTHER
;
359 helperTestRusults(zeroSingularLocales
, 1, testPattern
, pluralResults
);
361 // ======== Test singular dual locales.
362 logln("Testing singular1 locales.");
363 const char* singularDualLocales
[1] = {"ga"};
364 testPattern
= UNICODE_STRING_SIMPLE("one{one} two{two} other{other}");
365 uprv_memset(pluralResults
, -1, sizeof(pluralResults
));
366 pluralResults
[0]= PFT_OTHER
;
367 pluralResults
[1]= PFT_ONE
;
368 pluralResults
[2]= PFT_TWO
;
369 pluralResults
[3]= PFT_OTHER
;
370 helperTestRusults(singularDualLocales
, 1, testPattern
, pluralResults
);
372 // ======== Test Singular Zero Some locales.
373 logln("Testing singular1 locales.");
374 const char* singularZeroSomeLocales
[1] = {"ro"};
375 testPattern
= UNICODE_STRING_SIMPLE("few{few} one{one} other{other}");
376 uprv_memset(pluralResults
, -1, sizeof(pluralResults
));
377 pluralResults
[0]= PFT_FEW
;
378 for (int32_t i
=1; i
<20; ++i
) {
380 pluralResults
[i
] = PFT_FEW
;
381 pluralResults
[100+i
] = PFT_FEW
;
383 pluralResults
[1]= PFT_ONE
;
384 helperTestRusults(singularZeroSomeLocales
, 1, testPattern
, pluralResults
);
386 // ======== Test Special 12/19.
387 logln("Testing special 12 and 19.");
388 const char* special12_19Locales
[1] = {"lt"};
389 testPattern
= UNICODE_STRING_SIMPLE("one{one} few{few} other{other}");
390 uprv_memset(pluralResults
, -1, sizeof(pluralResults
));
391 pluralResults
[0]= PFT_OTHER
;
392 pluralResults
[1]= PFT_ONE
;
393 pluralResults
[2]= PFT_FEW
;
394 pluralResults
[10]= PFT_OTHER
;
395 for (int32_t i
=2; i
<20; ++i
) {
397 pluralResults
[i
*10+1] = PFT_ONE
;
398 pluralResults
[i
*10+2] = PFT_FEW
;
399 pluralResults
[(i
+1)*10] = PFT_OTHER
;
401 helperTestRusults(special12_19Locales
, 1, testPattern
, pluralResults
);
403 // ======== Test Paucal Except 11 14.
404 logln("Testing Paucal Except 11 and 14.");
405 const char* paucal01Locales
[4] = {"hr","ru","sr","uk"};
406 testPattern
= UNICODE_STRING_SIMPLE("one{one} many{many} few{few} other{other}");
407 uprv_memset(pluralResults
, -1, sizeof(pluralResults
));
408 pluralResults
[0]= PFT_MANY
;
409 pluralResults
[1]= PFT_ONE
;
410 pluralResults
[2]= PFT_FEW
;
411 pluralResults
[5]= PFT_MANY
;
412 pluralResults
[6]= PFT_MANY
;
413 pluralResults
[7]= PFT_MANY
;
414 pluralResults
[8]= PFT_MANY
;
415 pluralResults
[9]= PFT_MANY
;
416 for (int32_t i
=2; i
<20; ++i
) {
418 pluralResults
[i
*10+1] = PFT_ONE
;
419 pluralResults
[i
*10+2] = PFT_FEW
;
420 pluralResults
[i
*10+5] = PFT_MANY
;
421 pluralResults
[i
*10+6] = PFT_MANY
;
422 pluralResults
[i
*10+7] = PFT_MANY
;
423 pluralResults
[i
*10+8] = PFT_MANY
;
424 pluralResults
[i
*10+9] = PFT_MANY
;
426 helperTestRusults(paucal01Locales
, 4, testPattern
, pluralResults
);
428 // ======== Test Singular Paucal.
429 logln("Testing Singular Paucal.");
430 const char* singularPaucalLocales
[2] = {"cs","sk"};
431 testPattern
= UNICODE_STRING_SIMPLE("one{one} few{few} other{other}");
432 uprv_memset(pluralResults
, -1, sizeof(pluralResults
));
433 pluralResults
[0]= PFT_OTHER
;
434 pluralResults
[1]= PFT_ONE
;
435 pluralResults
[2]= PFT_FEW
;
436 pluralResults
[5]= PFT_OTHER
;
437 helperTestRusults(singularPaucalLocales
, 2, testPattern
, pluralResults
);
439 // ======== Test Paucal (1), (2,3,4).
440 logln("Testing Paucal (1), (2,3,4).");
441 const char* paucal02Locales
[1] = {"pl"};
442 testPattern
= UNICODE_STRING_SIMPLE("one{one} few{few} other{other}");
443 uprv_memset(pluralResults
, -1, sizeof(pluralResults
));
444 pluralResults
[0]= PFT_OTHER
;
445 pluralResults
[1]= PFT_ONE
;
446 pluralResults
[5]= PFT_OTHER
;
447 for (int32_t i
=0; i
<20; ++i
) {
448 if ((i
==1)||(i
==11)) {
449 pluralResults
[i
*10+2] = PFT_OTHER
;
450 pluralResults
[i
*10+3] = PFT_OTHER
;
451 pluralResults
[i
*10+4] = PFT_OTHER
;
454 pluralResults
[i
*10+2] = PFT_FEW
;
455 pluralResults
[i
*10+3] = PFT_FEW
;
456 pluralResults
[i
*10+4] = PFT_FEW
;
457 pluralResults
[i
*10+5] = PFT_OTHER
;
460 helperTestRusults(paucal02Locales
, 1, testPattern
, pluralResults
);
462 // ======== Test Paucal (1), (2), (3,4).
463 logln("Testing Paucal (1), (2), (3,4).");
464 const char* paucal03Locales
[1] = {"sl"};
465 testPattern
= UNICODE_STRING_SIMPLE("one{one} two{two} few{few} other{other}");
466 uprv_memset(pluralResults
, -1, sizeof(pluralResults
));
467 pluralResults
[0]= PFT_OTHER
;
468 pluralResults
[1]= PFT_ONE
;
469 pluralResults
[2]= PFT_TWO
;
470 pluralResults
[3]= PFT_FEW
;
471 pluralResults
[5]= PFT_OTHER
;
472 pluralResults
[101]= PFT_ONE
;
473 pluralResults
[102]= PFT_TWO
;
474 pluralResults
[103]= PFT_FEW
;
475 pluralResults
[105]= PFT_OTHER
;
476 helperTestRusults(paucal03Locales
, 1, testPattern
, pluralResults
);
478 // TODO: move this test to Unit Test after CLDR 1.6 is final and we support float
479 // ======= Test French "WITHIN rule
480 logln("Testing PluralRules with fr rule.");
481 testPattern
= UNICODE_STRING_SIMPLE("one{one} other{other}");
482 Locale
ulocale((const char *)"fr");
483 UErrorCode status
= U_ZERO_ERROR
;
484 PluralFormat
plFmt(ulocale
, testPattern
, status
);
485 if (U_FAILURE(status
)) {
486 dataerrln("Failed to apply pattern to fr locale - %s", u_errorName(status
));
489 status
= U_ZERO_ERROR
;
490 UnicodeString plResult
= plFmt
.format(0.0, status
); // retrun ONE
491 plResult
= plFmt
.format(0.5, status
); // retrun ONE
492 plResult
= plFmt
.format(1.0, status
); // retrun ONE
493 plResult
= plFmt
.format(1.9, status
); // retrun ONE
494 plResult
= plFmt
.format(2.0, status
); // retrun OTHER
499 PluralFormatTest::pluralFormatExtendedTest(void) {
500 const char *targets
[] = {
501 "There are no widgets.",
502 "There is one widget.",
503 "There is a bling widget and one other widget.",
504 "There is a bling widget and 2 other widgets.",
505 "There is a bling widget and 3 other widgets.",
506 "Widgets, five (5-1=4) there be.",
507 "There is a bling widget and 5 other widgets.",
508 "There is a bling widget and 6 other widgets.",
513 "=0 {There are no widgets.} "
514 "=1.0 {There is one widget.} "
515 "=5 {Widgets, five (5-1=#) there be.} "
516 "one {There is a bling widget and one other widget.} "
517 "other {There is a bling widget and # other widgets.}";
519 UErrorCode status
= U_ZERO_ERROR
;
520 UnicodeString
fmtString(fmt
, -1, US_INV
);
521 PluralFormat
pf(Locale::getEnglish(), fmtString
, status
);
522 MessageFormat
mf(UNICODE_STRING_SIMPLE("{0,plural,").append(fmtString
).append((UChar
)0x7d /* '}' */),
523 Locale::getEnglish(), status
);
525 FieldPosition ignore
;
526 if (U_FAILURE(status
)) {
527 dataerrln("Failed to apply pattern - %s", u_errorName(status
));
530 for (int32_t i
= 0; i
< 7; ++i
) {
531 UnicodeString result
= pf
.format(i
, status
);
532 if (U_FAILURE(status
)) {
533 errln("PluralFormat.format(value %d) failed - %s", i
, u_errorName(status
));
536 UnicodeString
expected(targets
[i
], -1, US_INV
);
537 if (expected
!= result
) {
538 UnicodeString
message("PluralFormat.format(): Expected '", -1, US_INV
);
539 message
.append(expected
);
540 message
.append(UnicodeString("' but got '", -1, US_INV
));
541 message
.append(result
);
542 message
.append("'", -1, US_INV
);
546 mf
.format(&args
, 1, result
.remove(), ignore
, status
);
547 if (U_FAILURE(status
)) {
548 errln("MessageFormat.format(value %d) failed - %s", i
, u_errorName(status
));
551 if (expected
!= result
) {
552 UnicodeString
message("MessageFormat.format(): Expected '", -1, US_INV
);
553 message
.append(expected
);
554 message
.append(UnicodeString("' but got '", -1, US_INV
));
555 message
.append(result
);
556 message
.append("'", -1, US_INV
);
563 PluralFormatTest::pluralFormatExtendedParseTest(void) {
564 const char *failures
[] = {
565 "offset:1..0 =0 {Foo}",
568 "=0 {Foo} =0.0 {Bar}",
571 int len
= sizeof(failures
)/sizeof(failures
[0]);
573 for (int i
= 0; i
< len
; ++i
) {
574 UErrorCode status
= U_ZERO_ERROR
;
575 UnicodeString
fmt(failures
[i
], -1, US_INV
);
576 PluralFormat
pf(fmt
, status
);
577 if (U_SUCCESS(status
)) {
578 errln("expected failure when parsing '" + fmt
+ "'");
584 PluralFormatTest::numberFormatTest(PluralFormat
* plFmt
,
585 NumberFormat
*numFmt
,
588 UnicodeString
*numOddAppendStr
,
589 UnicodeString
*numEvenAppendStr
,
590 UBool overwrite
, // overwrite the numberFormat.format result
591 UnicodeString
*message
) {
592 UErrorCode status
= U_ZERO_ERROR
;
594 if ( (plFmt
==NULL
) || (numFmt
==NULL
) ) {
595 dataerrln("ERROR: Could not create PluralFormat or NumberFormat - exitting");
598 UnicodeString plResult
, numResult
;
600 for (int32_t i
=start
; i
<= end
; ++i
) {
602 numResult
= numFmt
->format(i
, numResult
);
603 plResult
= plFmt
->format(i
, status
);
604 if ((numOddAppendStr
!= NULL
)&&(numEvenAppendStr
!=NULL
)) {
607 numResult
= *numOddAppendStr
;
610 numResult
= *numEvenAppendStr
;
613 else { // Append the string
615 numResult
+= *numOddAppendStr
;
618 numResult
+= *numEvenAppendStr
;
622 if ( (numResult
!=plResult
) || U_FAILURE(status
) ) {
623 if ( message
== NULL
) {
624 errln("ERROR: Unexpected plural format - got:"+plResult
+ UnicodeString(" expecting:")+numResult
);
627 errln( *message
+UnicodeString(" got:")+plResult
+UnicodeString(" expecting:")+numResult
);
637 PluralFormatTest::helperTestRusults(const char** localeArray
,
638 int32_t capacityOfArray
,
639 UnicodeString
& testPattern
,
640 int8_t *expResults
) {
642 UnicodeString plResult
;
643 const UnicodeString PLKeywordLookups
[6] = {
644 UNICODE_STRING_SIMPLE("zero"),
645 UNICODE_STRING_SIMPLE("one"),
646 UNICODE_STRING_SIMPLE("two"),
647 UNICODE_STRING_SIMPLE("few"),
648 UNICODE_STRING_SIMPLE("many"),
649 UNICODE_STRING_SIMPLE("other"),
652 for (int32_t i
=0; i
<capacityOfArray
; ++i
) {
653 const char *locale
= localeArray
[i
];
654 Locale
ulocale((const char *)locale
);
655 status
= U_ZERO_ERROR
;
656 PluralFormat
plFmt(ulocale
, testPattern
, status
);
657 if (U_FAILURE(status
)) {
658 dataerrln("Failed to apply pattern to locale:"+UnicodeString(localeArray
[i
]) + " - " + u_errorName(status
));
661 for (int32_t n
=0; n
<PLURAL_TEST_ARRAY_SIZE
; ++n
) {
662 if (expResults
[n
]!=-1) {
663 status
= U_ZERO_ERROR
;
664 plResult
= plFmt
.format(n
, status
);
665 if (U_FAILURE(status
)) {
666 errln("ERROR: Failed to format number in locale data tests with locale: "+
667 UnicodeString(localeArray
[i
]));
669 if (plResult
!= PLKeywordLookups
[expResults
[n
]]){
670 plResult
= plFmt
.format(n
, status
);
671 errln("ERROR: Unexpected format result in locale: "+UnicodeString(localeArray
[i
])+
672 UnicodeString(" got:")+plResult
+ UnicodeString(" expecting:")+
673 PLKeywordLookups
[expResults
[n
]]);
680 #endif /* #if !UCONFIG_NO_FORMATTING */