]> granicus.if.org Git - icu/commitdiff
ICU-11276 Adding more test cases. Fixing minor issues with extended locales.
authorShane Carr <shane@unicode.org>
Sat, 15 Sep 2018 04:20:13 +0000 (21:20 -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_range.cpp
icu4j/main/classes/core/src/com/ibm/icu/number/NumberRangeFormatterImpl.java
icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberRangeFormatterTest.java

index 096609bfd41e36a3a36d88dcbc07d1e8d433e377..19b8b10321f8be93c5bc5ecee5a19a2ecc46648c 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "unicode/numberrangeformatter.h"
 #include "numrange_impl.h"
+#include "patternprops.h"
 #include "uresimp.h"
 #include "util.h"
 
@@ -207,6 +208,9 @@ void NumberRangeFormatterImpl::format(UFormattedNumberRangeData& data, bool equa
     } else {
         formatterImpl2.preProcess(data.quantity2, micros2, status);
     }
+    if (U_FAILURE(status)) {
+        return;
+    }
 
     // If any of the affixes are different, an identity is not possible
     // and we must use formatRange().
@@ -392,18 +396,25 @@ void NumberRangeFormatterImpl::formatRange(UFormattedNumberRangeData& data,
         status);
     if (U_FAILURE(status)) { return; }
     lengthInfix = lengthRange - lengthPrefix - lengthSuffix;
+    U_ASSERT(lengthInfix > 0);
 
     // SPACING HEURISTIC
     // Add spacing unless all modifiers are collapsed.
     // TODO: add API to control this?
+    // TODO: Use a data-driven heuristic like currency spacing?
+    // TODO: Use Unicode [:whitespace:] instead of PatternProps whitespace? (consider speed implications)
     {
         bool repeatInner = !collapseInner && micros1.modInner->getCodePointCount() > 0;
         bool repeatMiddle = !collapseMiddle && micros1.modMiddle->getCodePointCount() > 0;
         bool repeatOuter = !collapseOuter && micros1.modOuter->getCodePointCount() > 0;
         if (repeatInner || repeatMiddle || repeatOuter) {
-            // Add spacing
-            lengthInfix += string.insertCodePoint(UPRV_INDEX_1, u'\u0020', UNUM_FIELD_COUNT, status);
-            lengthInfix += string.insertCodePoint(UPRV_INDEX_2, u'\u0020', UNUM_FIELD_COUNT, status);
+            // Add spacing if there is not already spacing
+            if (!PatternProps::isWhiteSpace(string.charAt(UPRV_INDEX_1))) {
+                lengthInfix += string.insertCodePoint(UPRV_INDEX_1, u'\u0020', UNUM_FIELD_COUNT, status);
+            }
+            if (!PatternProps::isWhiteSpace(string.charAt(UPRV_INDEX_2 - 1))) {
+                lengthInfix += string.insertCodePoint(UPRV_INDEX_2, u'\u0020', UNUM_FIELD_COUNT, status);
+            }
         }
     }
 
index dad8a51cee5f7f5d163df2d24caab2c7b4bfa657..1199f886545804f396310f63f19c66cb3fe3c90e 100644 (file)
@@ -141,6 +141,54 @@ void NumberRangeFormatterTest::testBasic() {
         u"~5 000 degrés Fahrenheit",
         u"5 000–5 000 000 degrés Fahrenheit");
 
+    assertFormatRange(
+        u"Locale with custom range separator",
+        NumberRangeFormatter::with(),
+        Locale("ja"),
+        u"1~5",
+        u"~5",
+        u"~5",
+        u"0~3",
+        u"~0",
+        u"3~3,000",
+        u"3,000~5,000",
+        u"4,999~5,001",
+        u"~5,000",
+        u"5,000~5,000,000");
+
+    assertFormatRange(
+        u"Locale that already has spaces around range separator",
+        NumberRangeFormatter::with()
+            .collapse(UNUM_RANGE_COLLAPSE_NONE)
+            .numberFormatterBoth(NumberFormatter::with().unit(KELVIN)),
+        Locale("hr"),
+        u"1 K – 5 K",
+        u"~5 K",
+        u"~5 K",
+        u"0 K – 3 K",
+        u"~0 K",
+        u"3 K – 3.000 K",
+        u"3.000 K – 5.000 K",
+        u"4.999 K – 5.001 K",
+        u"~5.000 K",
+        u"5.000 K – 5.000.000 K");
+
+    assertFormatRange(
+        u"Locale with custom numbering system and no plural ranges data",
+        NumberRangeFormatter::with(),
+        Locale("shn@numbers=beng"),
+        // 012459 = ০১৩৪৫৯
+        u"১–৫",
+        u"~৫",
+        u"~৫",
+        u"০–৩",
+        u"~০",
+        u"৩–৩,০০০",
+        u"৩,০০০–৫,০০০",
+        u"৪,৯৯৯–৫,০০১",
+        u"~৫,০০০",
+        u"৫,০০০–৫,০০০,০০০");
+
     assertFormatRange(
         u"Portuguese currency",
         NumberRangeFormatter::with()
index c05a9155711079a872e754ff22a65487c5b4aa08..71aafe51cd1e8174e4ca5a1c85db6051e7e75694 100644 (file)
@@ -4,6 +4,7 @@ package com.ibm.icu.number;
 
 import com.ibm.icu.impl.ICUData;
 import com.ibm.icu.impl.ICUResourceBundle;
+import com.ibm.icu.impl.PatternProps;
 import com.ibm.icu.impl.SimpleFormatterImpl;
 import com.ibm.icu.impl.StandardPlural;
 import com.ibm.icu.impl.UResource;
@@ -287,18 +288,25 @@ class NumberRangeFormatterImpl {
         PrefixInfixSuffixLengthHelper h = new PrefixInfixSuffixLengthHelper();
 
         SimpleModifier.formatTwoArgPattern(fRangePattern, string, 0, h, null);
+        assert h.lengthInfix > 0;
 
         // SPACING HEURISTIC
         // Add spacing unless all modifiers are collapsed.
         // TODO: add API to control this?
+        // TODO: Use a data-driven heuristic like currency spacing?
+        // TODO: Use Unicode [:whitespace:] instead of PatternProps whitespace? (consider speed implications)
         {
             boolean repeatInner = !collapseInner && micros1.modInner.getCodePointCount() > 0;
             boolean repeatMiddle = !collapseMiddle && micros1.modMiddle.getCodePointCount() > 0;
             boolean repeatOuter = !collapseOuter && micros1.modOuter.getCodePointCount() > 0;
             if (repeatInner || repeatMiddle || repeatOuter) {
-                // Add spacing
-                h.lengthInfix += string.insertCodePoint(h.index1(), '\u0020', null);
-                h.lengthInfix += string.insertCodePoint(h.index2(), '\u0020', null);
+                // Add spacing if there is not already spacing
+                if (!PatternProps.isWhiteSpace(string.charAt(h.index1()))) {
+                    h.lengthInfix += string.insertCodePoint(h.index1(), '\u0020', null);
+                }
+                if (!PatternProps.isWhiteSpace(string.charAt(h.index2() - 1))) {
+                    h.lengthInfix += string.insertCodePoint(h.index2(), '\u0020', null);
+                }
             }
         }
 
index 21e599d71b04f58a3505b5b6f428222a3f2fe10b..52933d0b271524cb9bb62c812ece646e53e03422 100644 (file)
@@ -129,6 +129,54 @@ public class NumberRangeFormatterTest {
             "~5 000 degrés Fahrenheit",
             "5 000–5 000 000 degrés Fahrenheit");
 
+        assertFormatRange(
+            "Locale with custom range separator",
+            NumberRangeFormatter.with(),
+            new ULocale("ja"),
+            "1~5",
+            "~5",
+            "~5",
+            "0~3",
+            "~0",
+            "3~3,000",
+            "3,000~5,000",
+            "4,999~5,001",
+            "~5,000",
+            "5,000~5,000,000");
+
+        assertFormatRange(
+            "Locale that already has spaces around range separator",
+            NumberRangeFormatter.with()
+                .collapse(RangeCollapse.NONE)
+                .numberFormatterBoth(NumberFormatter.with().unit(MeasureUnit.KELVIN)),
+            new ULocale("hr"),
+            "1 K – 5 K",
+            "~5 K",
+            "~5 K",
+            "0 K – 3 K",
+            "~0 K",
+            "3 K – 3.000 K",
+            "3.000 K – 5.000 K",
+            "4.999 K – 5.001 K",
+            "~5.000 K",
+            "5.000 K – 5.000.000 K");
+
+        assertFormatRange(
+            "Locale with custom numbering system and no plural ranges data",
+            NumberRangeFormatter.with(),
+            new ULocale("shn@numbers=beng"),
+            // 012459 = ০১৩৪৫৯
+            "১–৫",
+            "~৫",
+            "~৫",
+            "০–৩",
+            "~০",
+            "৩–৩,০০০",
+            "৩,০০০–৫,০০০",
+            "৪,৯৯৯–৫,০০১",
+            "~৫,০০০",
+            "৫,০০০–৫,০০০,০০০");
+
         assertFormatRange(
             "Portuguese currency",
             NumberRangeFormatter.with()