X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/46f4442e9a5a4f3b98b7c1083586332f6a8a99a4..e4f10fab0c078f399c9deef476d9c9b73b47dff8:/icuSources/test/intltest/plurfmts.cpp diff --git a/icuSources/test/intltest/plurfmts.cpp b/icuSources/test/intltest/plurfmts.cpp index 1998403d..69e8f882 100644 --- a/icuSources/test/intltest/plurfmts.cpp +++ b/icuSources/test/intltest/plurfmts.cpp @@ -1,6 +1,6 @@ /******************************************************************** * COPYRIGHT: - * Copyright (c) 2007-2008, International Business Machines Corporation and + * Copyright (c) 2007-2012, International Business Machines Corporation and * others. All Rights Reserved. ********************************************************************/ @@ -11,11 +11,10 @@ #include "plurults.h" #include "plurfmts.h" #include "cmemory.h" +#include "unicode/msgfmt.h" #include "unicode/plurrule.h" #include "unicode/plurfmt.h" - -const UnicodeString oddAndEvenRule = UNICODE_STRING_SIMPLE("odd: n mod 2 is 1"); #define PLURAL_PATTERN_DATA 4 #define PLURAL_TEST_ARRAY_SIZE 256 @@ -32,13 +31,14 @@ const UnicodeString oddAndEvenRule = UNICODE_STRING_SIMPLE("odd: n mod 2 is 1"); void PluralFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ ) { if (exec) logln("TestSuite PluralFormat"); - switch (index) { - TESTCASE(0, pluralFormatBasicTest); - TESTCASE(1, pluralFormatUnitTest); - TESTCASE(2, pluralFormatLocaleTest); - default: name = ""; - break; - } + TESTCASE_AUTO_BEGIN; + TESTCASE_AUTO(pluralFormatBasicTest); + TESTCASE_AUTO(pluralFormatUnitTest); + TESTCASE_AUTO(pluralFormatLocaleTest); + TESTCASE_AUTO(pluralFormatExtendedTest); + TESTCASE_AUTO(pluralFormatExtendedParseTest); + TESTCASE_AUTO(ordinalFormatTest); + TESTCASE_AUTO_END; } /** @@ -61,7 +61,7 @@ void PluralFormatTest::pluralFormatBasicTest(/*char *par*/) NumberFormat *numFmt = NumberFormat::createInstance(status[0]); if (U_FAILURE(status[0])) { dataerrln("ERROR: Could not create NumberFormat instance with default locale "); - } + } for (int32_t i=0; i< 8; ++i) { status[i] = U_ZERO_ERROR; @@ -87,6 +87,9 @@ void PluralFormatTest::pluralFormatBasicTest(/*char *par*/) } // ======= Test clone, assignment operator && == operator. plFmt[0]= new PluralFormat(status[0]); + plFmt[0]->setNumberFormat(numFmt,status[0]); + UnicodeString us = UnicodeString(""); + plFmt[0]->toPattern(us); plFmt[1]= new PluralFormat(locale, status[1]); if ( U_SUCCESS(status[0]) && U_SUCCESS(status[1]) ) { *plFmt[1] = *plFmt[0]; @@ -97,25 +100,55 @@ void PluralFormatTest::pluralFormatBasicTest(/*char *par*/) } } else { - errln("ERROR: PluralFormat constructor failed!"); + dataerrln("ERROR: PluralFormat constructor failed! - [0]%s [1]%s", u_errorName(status[0]), u_errorName(status[1])); + } + delete plFmt[0]; + + status[0] = U_ZERO_ERROR; + plFmt[0]= new PluralFormat(locale, status[0]); + if ( U_SUCCESS(status[0]) ) { + *plFmt[1] = *plFmt[0]; + if (plFmt[1]!=NULL) { + if ( *plFmt[1] != *plFmt[0] ) { + errln("ERROR: assignment operator test failed!"); + } + } + } + else { + dataerrln("ERROR: PluralFormat constructor failed! - %s", u_errorName(status[1])); } - plFmt[2]= new PluralFormat(locale, status[1]); + if ( U_SUCCESS(status[1]) ) { - *plFmt[1] = *plFmt[2]; + plFmt[2] = (PluralFormat*) plFmt[1]->clone(); + if (plFmt[1]!=NULL) { if ( *plFmt[1] != *plFmt[2] ) { - errln("ERROR: assignment operator test failed!"); + errln("ERROR: clone function test failed!"); } } delete plFmt[1]; + delete plFmt[2]; } else { - errln("ERROR: PluralFormat constructor failed!"); + dataerrln("ERROR: PluralFormat clone failed! - %s", u_errorName(status[1])); } + delete plFmt[0]; - delete plFmt[2]; delete numFmt; delete plRules; + + // Tests parseObject + UErrorCode stat = U_ZERO_ERROR; + PluralFormat *pf = new PluralFormat(stat); + Formattable *f = new Formattable(); + ParsePosition *pp = new ParsePosition(); + pf->parseObject((UnicodeString)"",*f,*pp); + if(U_FAILURE(stat)) { + dataerrln("ERROR: PluralFormat::parseObject: %s", u_errorName(stat)); + } + delete pf; + delete f; + delete pp; } /** @@ -127,32 +160,35 @@ void PluralFormatTest::pluralFormatUnitTest(/*char *par*/) UNICODE_STRING_SIMPLE("odd {# is odd.} other{# is even.}"), UNICODE_STRING_SIMPLE("other{# is odd or even.}"), UNICODE_STRING_SIMPLE("odd{The number {0, number, #.#0} is odd.}other{The number {0, number, #.#0} is even.}"), - UNICODE_STRING_SIMPLE("odd{The number {#} is odd.}other{The number {#} is even.}"), + UNICODE_STRING_SIMPLE("odd{The number {1, number, #} is odd.}other{The number {2, number, #} is even.}"), }; UnicodeString patternOddTestResult[PLURAL_PATTERN_DATA] = { UNICODE_STRING_SIMPLE(" is odd."), UNICODE_STRING_SIMPLE(" is odd or even."), UNICODE_STRING_SIMPLE("The number {0, number, #.#0} is odd."), - UNICODE_STRING_SIMPLE("The number {#} is odd."), + UNICODE_STRING_SIMPLE("The number {1, number, #} is odd."), }; UnicodeString patternEvenTestResult[PLURAL_PATTERN_DATA] = { UNICODE_STRING_SIMPLE(" is even."), UNICODE_STRING_SIMPLE(" is odd or even."), UNICODE_STRING_SIMPLE("The number {0, number, #.#0} is even."), - UNICODE_STRING_SIMPLE("The number {#} is even."), + UNICODE_STRING_SIMPLE("The number {2, number, #} is even."), }; UnicodeString checkSyntaxtData[PLURAL_SYNTAX_DATA] = { - UNICODE_STRING_SIMPLE("odd{foo} odd{bar} other{foobar}"), - UNICODE_STRING_SIMPLE("odd{foo} other{bar} other{foobar}"), + // ICU 4.8 does not check for duplicate keywords any more. + //UNICODE_STRING_SIMPLE("odd{foo} odd{bar} other{foobar}"), + //UNICODE_STRING_SIMPLE("odd{foo} other{bar} other{foobar}"), UNICODE_STRING_SIMPLE("odd{foo}"), - UNICODE_STRING_SIMPLE("otto{foo} other{bar}"), - UNICODE_STRING_SIMPLE("1odd{foo} other{bar}"), + // ICU 4.8 does not check for unknown keywords any more. + //UNICODE_STRING_SIMPLE("otto{foo} other{bar}"), + UNICODE_STRING_SIMPLE("*odd{foo} other{bar}"), UNICODE_STRING_SIMPLE("odd{foo},other{bar}"), UNICODE_STRING_SIMPLE("od d{foo} other{bar}"), UNICODE_STRING_SIMPLE("odd{foo}{foobar}other{foo}"), }; UErrorCode status = U_ZERO_ERROR; + UnicodeString oddAndEvenRule = UNICODE_STRING_SIMPLE("odd: n mod 2 is 1"); PluralRules* plRules = PluralRules::createRules(oddAndEvenRule, status); if (U_FAILURE(status)) { dataerrln("ERROR: create PluralRules instance failed in unit tests.- exitting"); @@ -231,7 +267,7 @@ void PluralFormatTest::pluralFormatUnitTest(/*char *par*/) } numberFormatTest(&pluralFmt, numFmt, 5, 5, NULL, NULL, FALSE, &message); pluralFmt.applyPattern(UNICODE_STRING_SIMPLE("odd__{odd} other{even}"), status); - if (U_SUCCESS(status)) { + if (pluralFmt.format((int32_t)1, status) != UNICODE_STRING_SIMPLE("even")) { errln("SetLocale should reset rules but did not."); } status = U_ZERO_ERROR; @@ -282,27 +318,29 @@ PluralFormatTest::pluralFormatLocaleTest(/*char *par*/) UnicodeString testPattern = UNICODE_STRING_SIMPLE("other{other}"); uprv_memset(pluralResults, -1, sizeof(pluralResults)); pluralResults[0]= PFT_OTHER; // other - helperTestRusults(oneRuleLocales, 4, testPattern, pluralResults); + helperTestResults(oneRuleLocales, 4, testPattern, pluralResults); // ====== Test Singular1 locales. logln("Testing singular1 locales."); - const char* singular1Locales[19] = {"da","de","el","en","eo","es","et","fi", - "fo","he","it","nb","nl","nn","no","pt_PT","sv"}; + const char* singular1Locales[52] = {"bem","da","de","el","en","eo","es","et","fi", + "fo","gl","he","it","nb","nl","nn","no","pt","pt_PT","sv","af","bg","bn","ca","eu","fur","fy", + "gu","ha","is","ku","lb","ml","mr","nah","ne","om","or","pa","pap","ps","so","sq","sw","ta", + "te","tk","ur","zu","mn","gsw","rm"}; testPattern = UNICODE_STRING_SIMPLE("one{one} other{other}"); uprv_memset(pluralResults, -1, sizeof(pluralResults)); pluralResults[0]= PFT_OTHER; pluralResults[1]= PFT_ONE; pluralResults[2]= PFT_OTHER; - helperTestRusults(singular1Locales, 19, testPattern, pluralResults); + helperTestResults(singular1Locales, 52, testPattern, pluralResults); // ======== Test Singular01 locales. logln("Testing singular1 locales."); - const char* singular01Locales[2] = {"fr","pt"}; + const char* singular01Locales[3] = {"ff","fr","kab"}; testPattern = UNICODE_STRING_SIMPLE("one{one} other{other}"); uprv_memset(pluralResults, -1, sizeof(pluralResults)); pluralResults[0]= PFT_ONE; pluralResults[2]= PFT_OTHER; - helperTestRusults(singular01Locales, 2, testPattern, pluralResults); + helperTestResults(singular01Locales, 3, testPattern, pluralResults); // ======== Test ZeroSingular locales. logln("Testing singular1 locales."); @@ -317,7 +355,7 @@ PluralFormatTest::pluralFormatLocaleTest(/*char *par*/) pluralResults[i*10+1] = PFT_ONE; pluralResults[i*10+2] = PFT_OTHER; } - helperTestRusults(zeroSingularLocales, 1, testPattern, pluralResults); + helperTestResults(zeroSingularLocales, 1, testPattern, pluralResults); // ======== Test singular dual locales. logln("Testing singular1 locales."); @@ -328,7 +366,7 @@ PluralFormatTest::pluralFormatLocaleTest(/*char *par*/) pluralResults[1]= PFT_ONE; pluralResults[2]= PFT_TWO; pluralResults[3]= PFT_OTHER; - helperTestRusults(singularDualLocales, 1, testPattern, pluralResults); + helperTestResults(singularDualLocales, 1, testPattern, pluralResults); // ======== Test Singular Zero Some locales. logln("Testing singular1 locales."); @@ -342,7 +380,7 @@ PluralFormatTest::pluralFormatLocaleTest(/*char *par*/) pluralResults[100+i] = PFT_FEW; } pluralResults[1]= PFT_ONE; - helperTestRusults(singularZeroSomeLocales, 1, testPattern, pluralResults); + helperTestResults(singularZeroSomeLocales, 1, testPattern, pluralResults); // ======== Test Special 12/19. logln("Testing special 12 and 19."); @@ -359,7 +397,7 @@ PluralFormatTest::pluralFormatLocaleTest(/*char *par*/) pluralResults[i*10+2] = PFT_FEW; pluralResults[(i+1)*10] = PFT_OTHER; } - helperTestRusults(special12_19Locales, 1, testPattern, pluralResults); + helperTestResults(special12_19Locales, 1, testPattern, pluralResults); // ======== Test Paucal Except 11 14. logln("Testing Paucal Except 11 and 14."); @@ -384,7 +422,7 @@ PluralFormatTest::pluralFormatLocaleTest(/*char *par*/) pluralResults[i*10+8] = PFT_MANY; pluralResults[i*10+9] = PFT_MANY; } - helperTestRusults(paucal01Locales, 4, testPattern, pluralResults); + helperTestResults(paucal01Locales, 4, testPattern, pluralResults); // ======== Test Singular Paucal. logln("Testing Singular Paucal."); @@ -395,7 +433,7 @@ PluralFormatTest::pluralFormatLocaleTest(/*char *par*/) pluralResults[1]= PFT_ONE; pluralResults[2]= PFT_FEW; pluralResults[5]= PFT_OTHER; - helperTestRusults(singularPaucalLocales, 2, testPattern, pluralResults); + helperTestResults(singularPaucalLocales, 2, testPattern, pluralResults); // ======== Test Paucal (1), (2,3,4). logln("Testing Paucal (1), (2,3,4)."); @@ -406,7 +444,7 @@ PluralFormatTest::pluralFormatLocaleTest(/*char *par*/) pluralResults[1]= PFT_ONE; pluralResults[5]= PFT_OTHER; for (int32_t i=0; i<20; ++i) { - if ((i==1)||(i==2)||(i==11)||(i==12)) { + if ((i==1)||(i==11)) { pluralResults[i*10+2] = PFT_OTHER; pluralResults[i*10+3] = PFT_OTHER; pluralResults[i*10+4] = PFT_OTHER; @@ -418,7 +456,7 @@ PluralFormatTest::pluralFormatLocaleTest(/*char *par*/) pluralResults[i*10+5] = PFT_OTHER; } } - helperTestRusults(paucal02Locales, 1, testPattern, pluralResults); + helperTestResults(paucal02Locales, 1, testPattern, pluralResults); // ======== Test Paucal (1), (2), (3,4). logln("Testing Paucal (1), (2), (3,4)."); @@ -434,7 +472,7 @@ PluralFormatTest::pluralFormatLocaleTest(/*char *par*/) pluralResults[102]= PFT_TWO; pluralResults[103]= PFT_FEW; pluralResults[105]= PFT_OTHER; - helperTestRusults(paucal03Locales, 1, testPattern, pluralResults); + helperTestResults(paucal03Locales, 1, testPattern, pluralResults); // TODO: move this test to Unit Test after CLDR 1.6 is final and we support float // ======= Test French "WITHIN rule @@ -444,7 +482,7 @@ PluralFormatTest::pluralFormatLocaleTest(/*char *par*/) UErrorCode status = U_ZERO_ERROR; PluralFormat plFmt(ulocale, testPattern, status); if (U_FAILURE(status)) { - errln("Failed to apply pattern to fr locale"); + dataerrln("Failed to apply pattern to fr locale - %s", u_errorName(status)); } else { status = U_ZERO_ERROR; @@ -456,6 +494,133 @@ PluralFormatTest::pluralFormatLocaleTest(/*char *par*/) } } +void +PluralFormatTest::pluralFormatExtendedTest(void) { + const char *targets[] = { + "There are no widgets.", + "There is one widget.", + "There is a bling widget and one other widget.", + "There is a bling widget and 2 other widgets.", + "There is a bling widget and 3 other widgets.", + "Widgets, five (5-1=4) there be.", + "There is a bling widget and 5 other widgets.", + "There is a bling widget and 6 other widgets.", + }; + + const char* fmt = + "offset:1.0 " + "=0 {There are no widgets.} " + "=1.0 {There is one widget.} " + "=5 {Widgets, five (5-1=#) there be.} " + "one {There is a bling widget and one other widget.} " + "other {There is a bling widget and # other widgets.}"; + + UErrorCode status = U_ZERO_ERROR; + UnicodeString fmtString(fmt, -1, US_INV); + PluralFormat pf(Locale::getEnglish(), fmtString, status); + MessageFormat mf(UNICODE_STRING_SIMPLE("{0,plural,").append(fmtString).append((UChar)0x7d /* '}' */), + Locale::getEnglish(), status); + Formattable args; + FieldPosition ignore; + if (U_FAILURE(status)) { + dataerrln("Failed to apply pattern - %s", u_errorName(status)); + return; + } + for (int32_t i = 0; i < 7; ++i) { + UnicodeString result = pf.format(i, status); + if (U_FAILURE(status)) { + errln("PluralFormat.format(value %d) failed - %s", i, u_errorName(status)); + return; + } + UnicodeString expected(targets[i], -1, US_INV); + if (expected != result) { + UnicodeString message("PluralFormat.format(): Expected '", -1, US_INV); + message.append(expected); + message.append(UnicodeString("' but got '", -1, US_INV)); + message.append(result); + message.append("'", -1, US_INV); + errln(message); + } + args.setLong(i); + mf.format(&args, 1, result.remove(), ignore, status); + if (U_FAILURE(status)) { + errln("MessageFormat.format(value %d) failed - %s", i, u_errorName(status)); + return; + } + if (expected != result) { + UnicodeString message("MessageFormat.format(): Expected '", -1, US_INV); + message.append(expected); + message.append(UnicodeString("' but got '", -1, US_INV)); + message.append(result); + message.append("'", -1, US_INV); + errln(message); + } + } +} + +void +PluralFormatTest::pluralFormatExtendedParseTest(void) { + const char *failures[] = { + "offset:1..0 =0 {Foo}", + "offset:1.0 {Foo}", + "=0= {Foo}", + "=0 {Foo} =0.0 {Bar}", + " = {Foo}", + }; + int len = sizeof(failures)/sizeof(failures[0]); + + for (int i = 0; i < len; ++i) { + UErrorCode status = U_ZERO_ERROR; + UnicodeString fmt(failures[i], -1, US_INV); + PluralFormat pf(fmt, status); + if (U_SUCCESS(status)) { + errln("expected failure when parsing '" + fmt + "'"); + } + } +} + +void +PluralFormatTest::ordinalFormatTest(void) { + IcuTestErrorCode errorCode(*this, "ordinalFormatTest"); + UnicodeString pattern("one{#st file}two{#nd file}few{#rd file}other{#th file}"); + PluralFormat pf(Locale::getEnglish(), UPLURAL_TYPE_ORDINAL, pattern, errorCode); + if (errorCode.logDataIfFailureAndReset("PluralFormat(en, UPLURAL_TYPE_ORDINAL, pattern) failed")) { + return; + } + UnicodeString result = pf.format((int32_t)321, errorCode); + if (!errorCode.logIfFailureAndReset("PluralFormat.format(321) failed") && + result != UNICODE_STRING_SIMPLE("321st file")) { + errln(UnicodeString("PluralFormat.format(321) wrong result string: ") + result); + } + result = pf.format((int32_t)22, errorCode); + if (!errorCode.logIfFailureAndReset("PluralFormat.format(22) failed") && + result != UNICODE_STRING_SIMPLE("22nd file")) { + errln(UnicodeString("PluralFormat.format(22) wrong result string: ") + result); + } + result = pf.format((int32_t)3, errorCode); + if (!errorCode.logIfFailureAndReset("PluralFormat.format(3) failed") && + result != UNICODE_STRING_SIMPLE("3rd file")) { + errln(UnicodeString("PluralFormat.format(3) wrong result string: ") + result); + } + + // Code coverage: Use the other new-for-UPluralType constructor as well. + PluralFormat pf2(Locale::getEnglish(), UPLURAL_TYPE_ORDINAL, errorCode); + pf2.applyPattern(pattern, errorCode); + if (errorCode.logIfFailureAndReset("PluralFormat(en, UPLURAL_TYPE_ORDINAL, pattern) failed")) { + return; + } + result = pf2.format((int32_t)456, errorCode); + if (!errorCode.logIfFailureAndReset("PluralFormat.format(456) failed") && + result != UNICODE_STRING_SIMPLE("456th file")) { + errln(UnicodeString("PluralFormat.format(456) wrong result string: ") + result); + } + result = pf2.format((int32_t)111, errorCode); + if (!errorCode.logIfFailureAndReset("PluralFormat.format(111) failed") && + result != UNICODE_STRING_SIMPLE("111th file")) { + errln(UnicodeString("PluralFormat.format(111) wrong result string: ") + result); + } +} + void PluralFormatTest::numberFormatTest(PluralFormat* plFmt, NumberFormat *numFmt, @@ -510,7 +675,7 @@ PluralFormatTest::numberFormatTest(PluralFormat* plFmt, void -PluralFormatTest::helperTestRusults(const char** localeArray, +PluralFormatTest::helperTestResults(const char** localeArray, int32_t capacityOfArray, UnicodeString& testPattern, int8_t *expResults) { @@ -531,7 +696,7 @@ PluralFormatTest::helperTestRusults(const char** localeArray, status = U_ZERO_ERROR; PluralFormat plFmt(ulocale, testPattern, status); if (U_FAILURE(status)) { - errln("Failed to apply pattern to locale:"+UnicodeString(localeArray[i])); + dataerrln("Failed to apply pattern to locale:"+UnicodeString(localeArray[i]) + " - " + u_errorName(status)); continue; } for (int32_t n=0; n