// © 2016 and later: Unicode, Inc. and others. // License & terms of use: http://www.unicode.org/copyright.html /******************************************************************** * COPYRIGHT: * Copyright (c) 2007-2016, International Business Machines Corporation and * others. All Rights Reserved. ********************************************************************/ #include "unicode/utypes.h" #if !UCONFIG_NO_FORMATTING #include "unicode/dcfmtsym.h" #include "unicode/decimfmt.h" #include "unicode/msgfmt.h" #include "unicode/plurfmt.h" #include "unicode/plurrule.h" #include "cmemory.h" #include "plurfmts.h" #include "plurults.h" #define PLURAL_PATTERN_DATA 4 #define PLURAL_TEST_ARRAY_SIZE 256 #define PLURAL_SYNTAX_DATA 8 // The value must be same as PLKeywordLookups[] order. #define PFT_ZERO 0 #define PFT_ONE 1 #define PFT_TWO 2 #define PFT_FEW 3 #define PFT_MANY 4 #define PFT_OTHER 5 void PluralFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ ) { if (exec) logln("TestSuite PluralFormat"); TESTCASE_AUTO_BEGIN; TESTCASE_AUTO(pluralFormatBasicTest); TESTCASE_AUTO(pluralFormatUnitTest); TESTCASE_AUTO(pluralFormatLocaleTest); TESTCASE_AUTO(pluralFormatExtendedTest); TESTCASE_AUTO(pluralFormatExtendedParseTest); TESTCASE_AUTO(ordinalFormatTest); TESTCASE_AUTO(TestDecimals); TESTCASE_AUTO_END; } /** * Test various generic API methods of PluralFormat for Basic usage. */ void PluralFormatTest::pluralFormatBasicTest(/*char *par*/) { UErrorCode status[8]; PluralFormat* plFmt[8]; Locale locale = Locale::getDefault(); UnicodeString otherPattern = UnicodeString("other{#}"); UnicodeString message=UnicodeString("PluralFormat basic test"); // ========= Test constructors logln(" Testing PluralFormat constructors ..."); status[0] = U_ZERO_ERROR; PluralRules* plRules = PluralRules::createDefaultRules(status[0]); status[0] = U_ZERO_ERROR; 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; } plFmt[0] = new PluralFormat(status[0]); plFmt[1] = new PluralFormat(*plRules, status[1]); plFmt[2] = new PluralFormat(locale, status[2]); plFmt[3] = new PluralFormat(locale, *plRules, status[3]); plFmt[4] = new PluralFormat(otherPattern, status[4]); plFmt[5] = new PluralFormat(*plRules, otherPattern, status[5]); plFmt[6] = new PluralFormat(locale, otherPattern, status[6]); plFmt[7] = new PluralFormat(locale, *plRules, otherPattern, status[7]); for (int32_t i=0; i< 8; ++i) { if (U_SUCCESS(status[i])) { numberFormatTest(plFmt[i], numFmt, 1, 12, NULL, NULL, FALSE, &message); numberFormatTest(plFmt[i], numFmt, 100, 112, NULL, NULL, FALSE, &message); } else { dataerrln("ERROR: PluralFormat constructor failed!"); } delete plFmt[i]; } // ======= 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]; if (plFmt[1]!=NULL) { if ( *plFmt[1] != *plFmt[0] ) { errln("ERROR: clone plural format test failed!"); } } } else { 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])); } if ( U_SUCCESS(status[1]) ) { plFmt[2] = plFmt[1]->clone(); if (plFmt[1]!=NULL) { if ( *plFmt[1] != *plFmt[2] ) { errln("ERROR: clone function test failed!"); } } delete plFmt[1]; delete plFmt[2]; } else { dataerrln("ERROR: PluralFormat clone failed! - %s", u_errorName(status[1])); } delete plFmt[0]; 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; } /** * Unit tests of PluralFormat class. */ void PluralFormatTest::pluralFormatUnitTest(/*char *par*/) { UnicodeString patternTestData[PLURAL_PATTERN_DATA] = { 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 {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 {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 {2, number, #} is even."), }; UnicodeString checkSyntaxtData[PLURAL_SYNTAX_DATA] = { // 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}"), // 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"); LocalPointerplRules(PluralRules::createRules(oddAndEvenRule, status)); if (U_FAILURE(status)) { dataerrln("ERROR: create PluralRules instance failed in unit tests.- exitting"); return; } // ======= Test PluralRules pattern syntax. logln("Testing PluralRules pattern syntax."); for (int32_t i=0; i numFmt(NumberFormat::createInstance(status)); UnicodeString message=UnicodeString("ERROR: PluralFormat tests various pattern ..."); if (U_FAILURE(status)) { dataerrln("ERROR: Could not create NumberFormat instance with default locale "); } for(int32_t i=0; iformat(i, numResult); plResult = plFmt->format(i, status); if ((numOddAppendStr!= NULL)&&(numEvenAppendStr!=NULL)) { if (overwrite) { if (i&1) { numResult = *numOddAppendStr; } else { numResult = *numEvenAppendStr; } } else { // Append the string if (i&1) { numResult += *numOddAppendStr; } else{ numResult += *numEvenAppendStr; } } } if (U_FAILURE(status)) { assertSuccess(*message + " in numberFormatTest", status); } if (numResult!=plResult) { if ( message == NULL ) { errln("ERROR: Unexpected plural format - got:"+plResult+ UnicodeString(" expecting:")+numResult); } else { assertEquals(*message + " in numberFormatTest", numResult, plResult); } } } return; } void PluralFormatTest::helperTestResults(const char** localeArray, int32_t capacityOfArray, UnicodeString& testPattern, int8_t *expResults) { UErrorCode status; UnicodeString plResult; const UnicodeString PLKeywordLookups[6] = { UNICODE_STRING_SIMPLE("zero"), UNICODE_STRING_SIMPLE("one"), UNICODE_STRING_SIMPLE("two"), UNICODE_STRING_SIMPLE("few"), UNICODE_STRING_SIMPLE("many"), UNICODE_STRING_SIMPLE("other"), }; for (int32_t i=0; i