X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/51004dcb01e06fef634b61be77ed73dd61cb6db9..9f1b115531acc2f3640893f76e8bcf6680033062:/icuSources/test/cintltst/cpluralrulestest.c diff --git a/icuSources/test/cintltst/cpluralrulestest.c b/icuSources/test/cintltst/cpluralrulestest.c index 3f33d234..e1ffcdb1 100644 --- a/icuSources/test/cintltst/cpluralrulestest.c +++ b/icuSources/test/cintltst/cpluralrulestest.c @@ -1,5 +1,7 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /******************************************************************** - * Copyright (c) 2011-2012, International Business Machines Corporation + * Copyright (c) 2011-2014, International Business Machines Corporation * and others. All Rights Reserved. ********************************************************************/ /* C API TEST FOR PLURAL RULES */ @@ -10,11 +12,14 @@ #include "unicode/upluralrules.h" #include "unicode/ustring.h" +#include "unicode/uenum.h" #include "cintltst.h" #include "cmemory.h" +#include "cstring.h" static void TestPluralRules(void); static void TestOrdinalRules(void); +static void TestGetKeywords(void); void addPluralRulesTest(TestNode** root); @@ -24,37 +29,55 @@ void addPluralRulesTest(TestNode** root) { TESTCASE(TestPluralRules); TESTCASE(TestOrdinalRules); + TESTCASE(TestGetKeywords); } typedef struct { const char * locale; double number; const char * keywordExpected; + const char * keywordExpectedForDecimals; } PluralRulesTestItem; /* Just a small set of tests for now, other functionality is tested in the C++ tests */ static const PluralRulesTestItem testItems[] = { - { "en", 0, "other" }, - { "en", 0.5, "other" }, - { "en", 1, "one" }, - { "en", 1.5, "other" }, - { "en", 2, "other" }, - { "fr", 0, "one" }, - { "fr", 0.5, "one" }, - { "fr", 1, "one" }, - { "fr", 1.5, "one" }, - { "fr", 2, "other" }, - { "ru", 0, "many" }, - { "ru", 0.5, "other" }, - { "ru", 1, "one" }, - { "ru", 1.5, "other" }, - { "ru", 2, "few" }, - { "ru", 5, "many" }, - { "ru", 10, "many" }, - { "ru", 11, "many" }, - { NULL, 0, NULL } + { "en", 0, "other", "other" }, + { "en", 0.5, "other", "other" }, + { "en", 1, "one", "other" }, + { "en", 1.5, "other", "other" }, + { "en", 2, "other", "other" }, + + { "pt_PT", 0, "other", "other" }, + { "pt_PT", 0.5, "other", "other" }, + { "pt_PT", 1, "one", "other" }, + { "pt_PT", 1.5, "other", "other" }, + { "pt_PT", 2, "other", "other" }, + + { "pt_BR", 0, "one", "one" }, + { "pt_BR", 0.5, "one", "one" }, + { "pt_BR", 1, "one", "one" }, + { "pt_BR", 1.5, "one", "one" }, + { "pt_BR", 2, "other", "other" }, + + { "fr", 0, "one", "one" }, + { "fr", 0.5, "one", "one" }, + { "fr", 1, "one", "one" }, + { "fr", 1.5, "one", "one" }, + { "fr", 2, "other", "other" }, + + { "ru", 0, "many", "other" }, + { "ru", 0.5, "other", "other" }, + { "ru", 1, "one", "other" }, + { "ru", 1.5, "other", "other" }, + { "ru", 2, "few", "other" }, + { "ru", 5, "many", "other" }, + { "ru", 10, "many", "other" }, + { "ru", 11, "many", "other" }, + { NULL, 0, NULL, NULL } }; +static const UChar twoDecimalPat[] = { 0x23,0x30,0x2E,0x30,0x30,0 }; /* "#0.00" */ + enum { kKeywordBufLen = 32 }; @@ -67,6 +90,7 @@ static void TestPluralRules() UErrorCode status = U_ZERO_ERROR; UPluralRules* uplrules = uplrules_open(testItemPtr->locale, &status); if ( U_SUCCESS(status) ) { + UNumberFormat* unumfmt; UChar keyword[kKeywordBufLen]; UChar keywordExpected[kKeywordBufLen]; int32_t keywdLen = uplrules_select(uplrules, testItemPtr->number, keyword, kKeywordBufLen, &status); @@ -84,6 +108,30 @@ static void TestPluralRules() log_err("FAIL: uplrules_select for locale %s, number %.1f: %s\n", testItemPtr->locale, testItemPtr->number, myErrorName(status) ); } + + status = U_ZERO_ERROR; + unumfmt = unum_open(UNUM_PATTERN_DECIMAL, twoDecimalPat, -1, testItemPtr->locale, NULL, &status); + if ( U_SUCCESS(status) ) { + keywdLen = uplrules_selectWithFormat(uplrules, testItemPtr->number, unumfmt, keyword, kKeywordBufLen, &status); + if (keywdLen >= kKeywordBufLen) { + keyword[kKeywordBufLen-1] = 0; + } + if ( U_SUCCESS(status) ) { + u_unescape(testItemPtr->keywordExpectedForDecimals, keywordExpected, kKeywordBufLen); + if ( u_strcmp(keyword, keywordExpected) != 0 ) { + char bcharBuf[kKeywordBufLen]; + log_data_err("ERROR: uplrules_selectWithFormat for locale %s, number %.1f: expect %s, get %s\n", + testItemPtr->locale, testItemPtr->number, testItemPtr->keywordExpectedForDecimals, u_austrcpy(bcharBuf,keyword) ); + } + } else { + log_err("FAIL: uplrules_selectWithFormat for locale %s, number %.1f: %s\n", + testItemPtr->locale, testItemPtr->number, myErrorName(status) ); + } + unum_close(unumfmt); + } else { + log_err("FAIL: unum_open for locale %s: %s\n", testItemPtr->locale, myErrorName(status) ); + } + uplrules_close(uplrules); } else { log_err("FAIL: uplrules_open for locale %s: %s\n", testItemPtr->locale, myErrorName(status) ); @@ -109,4 +157,113 @@ static void TestOrdinalRules() { uplrules_close(upr); } +/* items for TestGetKeywords */ + +/* all possible plural keywords, in alphabetical order */ +static const char* knownKeywords[] = { + "few", + "many", + "one", + "other", + "two", + "zero" +}; +enum { + kNumKeywords = UPRV_LENGTHOF(knownKeywords) +}; + +/* Return the index of keyword in knownKeywords[], or -1 if not found */ +static int32_t getKeywordIndex(const char* keyword) { + int32_t i, compare; + for (i = 0; i < kNumKeywords && (compare = uprv_strcmp(keyword,knownKeywords[i])) >= 0; i++) { + if (compare == 0) { + return i; + } + } + return -1; +} + +typedef struct { + const char* locale; + const char* keywords[kNumKeywords + 1]; +} KeywordsForLang; + +static const KeywordsForLang getKeywordsItems[] = { + { "zh", { "other" } }, + { "en", { "one", "other" } }, + { "fr", { "one", "other" } }, + { "lv", { "zero", "one", "other" } }, + { "hr", { "one", "few", "other" } }, + { "sl", { "one", "two", "few", "other" } }, + { "he", { "one", "two", "many", "other" } }, + { "cs", { "one", "few", "many", "other" } }, + { "ar", { "zero", "one", "two", "few", "many" , "other" } }, + { NULL, { NULL } } +}; + +static void TestGetKeywords() { + /* + * We don't know the order in which the enumeration will return keywords, + * so we have an array with known keywords in a fixed order and then + * parallel arrays of flags for expected and actual results that indicate + * which keywords are expected to be or actually are found. + */ + const KeywordsForLang* itemPtr = getKeywordsItems; + for (; itemPtr->locale != NULL; itemPtr++) { + UPluralRules* uplrules; + UEnumeration* uenum; + UBool expectKeywords[kNumKeywords]; + UBool getKeywords[kNumKeywords]; + int32_t i, iKnown; + UErrorCode status = U_ZERO_ERROR; + + /* initialize arrays for expected and get results */ + for (i = 0; i < kNumKeywords; i++) { + expectKeywords[i] = FALSE; + getKeywords[i] = FALSE; + } + for (i = 0; i < kNumKeywords && itemPtr->keywords[i] != NULL; i++) { + iKnown = getKeywordIndex(itemPtr->keywords[i]); + if (iKnown >= 0) { + expectKeywords[iKnown] = TRUE; + } + } + + uplrules = uplrules_openForType(itemPtr->locale, UPLURAL_TYPE_CARDINAL, &status); + if (U_FAILURE(status)) { + log_err("FAIL: uplrules_openForType for locale %s, UPLURAL_TYPE_CARDINAL: %s\n", itemPtr->locale, myErrorName(status) ); + continue; + } + uenum = uplrules_getKeywords(uplrules, &status); + if (U_FAILURE(status)) { + log_err("FAIL: uplrules_getKeywords for locale %s: %s\n", itemPtr->locale, myErrorName(status) ); + } else { + const char* keyword; + int32_t keywordLen, keywordCount = 0; + while ((keyword = uenum_next(uenum, &keywordLen, &status)) != NULL && U_SUCCESS(status)) { + iKnown = getKeywordIndex(keyword); + if (iKnown < 0) { + log_err("FAIL: uplrules_getKeywords for locale %s, unknown keyword %s\n", itemPtr->locale, keyword ); + } else { + getKeywords[iKnown] = TRUE; + } + keywordCount++; + } + if (keywordCount > kNumKeywords) { + log_err("FAIL: uplrules_getKeywords for locale %s, got too many keywords %d\n", itemPtr->locale, keywordCount ); + } + if (uprv_memcmp(expectKeywords, getKeywords, kNumKeywords) != 0) { + log_err("FAIL: uplrules_getKeywords for locale %s, got wrong keyword set; with reference to knownKeywords:\n" + " expected { %d %d %d %d %d %d },\n" + " got { %d %d %d %d %d %d }\n", itemPtr->locale, + expectKeywords[0], expectKeywords[1], expectKeywords[2], expectKeywords[3], expectKeywords[4], expectKeywords[5], + getKeywords[0], getKeywords[1], getKeywords[2], getKeywords[3], getKeywords[4], getKeywords[5] ); + } + uenum_close(uenum); + } + + uplrules_close(uplrules); + } +} + #endif /* #if !UCONFIG_NO_FORMATTING */