]> granicus.if.org Git - icu/commitdiff
ICU-11276 Fixing pluralRanges data loading and adding more tests.
authorShane Carr <shane@unicode.org>
Fri, 14 Sep 2018 23:33:22 +0000 (16:33 -0700)
committerShane Carr <shane@unicode.org>
Thu, 27 Sep 2018 21:27:40 +0000 (14:27 -0700)
icu4c/source/i18n/numrange_impl.cpp
icu4c/source/test/intltest/numbertest.h
icu4c/source/test/intltest/numbertest_range.cpp

index a2493bcf29fd9e6453f9b3e81fd45ba72e39f9db..140effaaa64dd525b3927499d8f03daf5f623f37 100644 (file)
@@ -82,7 +82,6 @@ void getNumberRangeData(const char* localeName, const char* nsName, NumberRangeD
     }
 }
 
-
 class PluralRangesDataSink : public ResourceSink {
   public:
     PluralRangesDataSink(StandardPluralRanges& output) : fOutput(output) {}
@@ -123,7 +122,7 @@ void getPluralRangesData(const Locale& locale, StandardPluralRanges& output, UEr
     int32_t setLen;
     // Not all languages are covered: fail gracefully
     UErrorCode internalStatus = U_ZERO_ERROR;
-    const UChar* set = ures_getStringByKey(rb.getAlias(), dataPath.data(), &setLen, &internalStatus);
+    const UChar* set = ures_getStringByKeyWithFallback(rb.getAlias(), dataPath.data(), &setLen, &internalStatus);
     if (U_FAILURE(internalStatus)) { return; }
 
     dataPath.clear();
index 03ef809d6e5f4942dfc56fc2f461ab4d6f610543..0d0f7dec81575c52dfcb79e93406e48ac98e7127 100644 (file)
@@ -256,6 +256,7 @@ class NumberRangeFormatterTest : public IntlTest {
     void testCollapse();
     void testIdentity();
     void testDifferentFormatters();
+    void testPlurals();
 
     void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0);
 
index 63bf5986079982011d26e1b62406db92824bda22..dad8a51cee5f7f5d163df2d24caab2c7b4bfa657 100644 (file)
@@ -47,6 +47,7 @@ void NumberRangeFormatterTest::runIndexedTest(int32_t index, UBool exec, const c
         TESTCASE_AUTO(testCollapse);
         TESTCASE_AUTO(testIdentity);
         TESTCASE_AUTO(testDifferentFormatters);
+        TESTCASE_AUTO(testPlurals);
     TESTCASE_AUTO_END;
 }
 
@@ -373,6 +374,39 @@ void NumberRangeFormatterTest::testCollapse() {
         u"~5,000 m",
         u"5,000–5,000,000 m");
 
+    assertFormatRange(
+        u"Default collapse, long-form compact notation",
+        NumberRangeFormatter::with()
+            .numberFormatterBoth(NumberFormatter::with().notation(Notation::compactLong())),
+        Locale("de-CH"),
+        u"1–5",
+        u"~5",
+        u"~5",
+        u"0–3",
+        u"~0",
+        u"3–3 Tausend",
+        u"3–5 Tausend",
+        u"~5 Tausend",
+        u"~5 Tausend",
+        u"5 Tausend – 5 Millionen");
+
+    assertFormatRange(
+        u"Unit collapse, long-form compact notation",
+        NumberRangeFormatter::with()
+            .collapse(UNUM_RANGE_COLLAPSE_UNIT)
+            .numberFormatterBoth(NumberFormatter::with().notation(Notation::compactLong())),
+        Locale("de-CH"),
+        u"1–5",
+        u"~5",
+        u"~5",
+        u"0–3",
+        u"~0",
+        u"3–3 Tausend",
+        u"3 Tausend – 5 Tausend",
+        u"~5 Tausend",
+        u"~5 Tausend",
+        u"5 Tausend – 5 Millionen");
+
     assertFormatRange(
         u"Default collapse on measurement unit with compact-short notation",
         NumberRangeFormatter::with()
@@ -561,6 +595,69 @@ void NumberRangeFormatterTest::testDifferentFormatters() {
         u"5,000–5,000,000");
 }
 
+void NumberRangeFormatterTest::testPlurals() {
+    IcuTestErrorCode status(*this, "testPlurals");
+
+    // Locale sl has interesting plural forms:
+    // GBP{
+    //     one{"britanski funt"}
+    //     two{"britanska funta"}
+    //     few{"britanski funti"}
+    //     other{"britanskih funtov"}
+    // }
+    Locale locale("sl");
+
+    UnlocalizedNumberFormatter unf = NumberFormatter::with()
+        .unit(GBP)
+        .unitWidth(UNUM_UNIT_WIDTH_FULL_NAME)
+        .precision(Precision::integer());
+    LocalizedNumberFormatter lnf = unf.locale(locale);
+
+    // For comparison, run the non-range version of the formatter
+    assertEquals(Int64ToUnicodeString(1), u"1 britanski funt", lnf.formatDouble(1, status).toString(status));
+    assertEquals(Int64ToUnicodeString(2), u"2 britanska funta", lnf.formatDouble(2, status).toString(status));
+    assertEquals(Int64ToUnicodeString(3), u"3 britanski funti", lnf.formatDouble(3, status).toString(status));
+    assertEquals(Int64ToUnicodeString(5), u"5 britanskih funtov", lnf.formatDouble(5, status).toString(status));
+    if (status.errIfFailureAndReset()) { return; }
+
+    LocalizedNumberRangeFormatter lnrf = NumberRangeFormatter::with()
+        .numberFormatterBoth(unf)
+        .identityFallback(UNUM_IDENTITY_FALLBACK_RANGE)
+        .locale(locale);
+
+    struct TestCase {
+        double first;
+        double second;
+        const char16_t* expected;
+    } cases[] = {
+        {1, 1, u"1–1 britanski funti"}, // one + one -> few
+        {1, 2, u"1–2 britanska funta"}, // one + two -> two
+        {1, 3, u"1–3 britanski funti"}, // one + few -> few
+        {1, 5, u"1–5 britanskih funtov"}, // one + other -> other
+        {2, 1, u"2–1 britanski funti"}, // two + one -> few
+        {2, 2, u"2–2 britanska funta"}, // two + two -> two
+        {2, 3, u"2–3 britanski funti"}, // two + few -> few
+        {2, 5, u"2–5 britanskih funtov"}, // two + other -> other
+        {3, 1, u"3–1 britanski funti"}, // few + one -> few
+        {3, 2, u"3–2 britanska funta"}, // few + two -> two
+        {3, 3, u"3–3 britanski funti"}, // few + few -> few
+        {3, 5, u"3–5 britanskih funtov"}, // few + other -> other
+        {5, 1, u"5–1 britanski funti"}, // other + one -> few
+        {5, 2, u"5–2 britanska funta"}, // other + two -> two
+        {5, 3, u"5–3 britanski funti"}, // other + few -> few
+        {5, 5, u"5–5 britanskih funtov"}, // other + other -> other
+    };
+    for (auto& cas : cases) {
+        UnicodeString message = Int64ToUnicodeString(cas.first);
+        message += u" ";
+        message += Int64ToUnicodeString(cas.second);
+        status.setScope(message);
+        UnicodeString actual = lnrf.formatFormattableRange(cas.first, cas.second, status).toString(status);
+        assertEquals(message, cas.expected, actual);
+        status.errIfFailureAndReset();
+    }
+}
+
 void  NumberRangeFormatterTest::assertFormatRange(
       const char16_t* message,
       const UnlocalizedNumberRangeFormatter& f,