]> granicus.if.org Git - icu/commitdiff
ICU-11276 Adding placeholder implementation and more API functions.
authorShane Carr <shane@unicode.org>
Wed, 29 Aug 2018 03:34:41 +0000 (20:34 -0700)
committerShane Carr <shane@unicode.org>
Thu, 27 Sep 2018 21:27:39 +0000 (14:27 -0700)
icu4j/main/classes/core/src/com/ibm/icu/impl/number/range/RangeMacroProps.java
icu4j/main/classes/core/src/com/ibm/icu/number/LocalizedNumberRangeFormatter.java
icu4j/main/classes/core/src/com/ibm/icu/number/NumberRangeFormatter.java
icu4j/main/classes/core/src/com/ibm/icu/number/NumberRangeFormatterSettings.java
icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberRangeFormatterTest.java [new file with mode: 0644]

index 9595e7d55a975c284eda52e04baacc21ea6d5247..800dcf6ab9bdd9731c387cead04214587af07e0c 100644 (file)
@@ -4,9 +4,9 @@ package com.ibm.icu.impl.number.range;
 
 import java.util.Objects;
 
-import com.ibm.icu.number.NumberFormatterSettings;
 import com.ibm.icu.number.NumberRangeFormatter.RangeCollapse;
 import com.ibm.icu.number.NumberRangeFormatter.RangeIdentityFallback;
+import com.ibm.icu.number.UnlocalizedNumberFormatter;
 import com.ibm.icu.util.ULocale;
 
 /**
@@ -14,8 +14,8 @@ import com.ibm.icu.util.ULocale;
  *
  */
 public class RangeMacroProps {
-    public NumberFormatterSettings<?> formatter1;
-    public NumberFormatterSettings<?> formatter2;
+    public UnlocalizedNumberFormatter formatter1;
+    public UnlocalizedNumberFormatter formatter2;
     public RangeCollapse collapse;
     public RangeIdentityFallback identityFallback;
     public ULocale loc;
index 0721ab71bb603a3213b29aae9248f3090329d919..87d94941bb037870526964ee392ce5782101ac03 100644 (file)
@@ -5,8 +5,8 @@ package com.ibm.icu.number;
 import com.ibm.icu.impl.number.DecimalQuantity;
 import com.ibm.icu.impl.number.DecimalQuantity_DualStorageBCD;
 import com.ibm.icu.impl.number.NumberStringBuilder;
+import com.ibm.icu.impl.number.range.RangeMacroProps;
 import com.ibm.icu.number.FormattedNumberRange.RangeIdentityType;
-import com.ibm.icu.text.NumberFormat;
 
 /**
  * A NumberRangeFormatter that has a locale associated with it; this means .formatRange() methods are available.
@@ -36,16 +36,72 @@ public class LocalizedNumberRangeFormatter extends NumberRangeFormatterSettings<
      * @see NumberRangeFormatter
      */
     public FormattedNumberRange formatRange(int first, int second) {
-        // TODO: This is a placeholder implementation.
         DecimalQuantity dq1 = new DecimalQuantity_DualStorageBCD(first);
         DecimalQuantity dq2 = new DecimalQuantity_DualStorageBCD(second);
+        return formatImpl(dq1, dq2);
+    }
+
+    /**
+     * Format the given doubles to a string using the settings specified in the NumberRangeFormatter fluent setting
+     * chain.
+     *
+     * @param first
+     *            The first number in the range, usually to the left in LTR locales.
+     * @param second
+     *            The second number in the range, usually to the right in LTR locales.
+     * @return A FormattedNumber object; call .toString() to get the string.
+     * @draft ICU 63
+     * @provisional This API might change or be removed in a future release.
+     * @see NumberRangeFormatter
+     */
+    public FormattedNumberRange formatRange(double first, double second) {
+        DecimalQuantity dq1 = new DecimalQuantity_DualStorageBCD(first);
+        DecimalQuantity dq2 = new DecimalQuantity_DualStorageBCD(second);
+        return formatImpl(dq1, dq2);
+    }
+
+    /**
+     * Format the given Numbers to a string using the settings specified in the NumberRangeFormatter fluent setting
+     * chain.
+     *
+     * @param first
+     *            The first number in the range, usually to the left in LTR locales.
+     * @param second
+     *            The second number in the range, usually to the right in LTR locales.
+     * @return A FormattedNumber object; call .toString() to get the string.
+     * @draft ICU 63
+     * @provisional This API might change or be removed in a future release.
+     * @see NumberRangeFormatter
+     */
+    public FormattedNumberRange formatRange(Number first, Number second) {
+        DecimalQuantity dq1 = new DecimalQuantity_DualStorageBCD(first);
+        DecimalQuantity dq2 = new DecimalQuantity_DualStorageBCD(second);
+        return formatImpl(dq1, dq2);
+    }
+
+    FormattedNumberRange formatImpl(DecimalQuantity first, DecimalQuantity second) {
+        // TODO: This is a placeholder implementation.
+        RangeMacroProps macros = resolve();
+        LocalizedNumberFormatter f1 , f2;
+        if (macros.formatter1 != null) {
+            f1 = macros.formatter1.locale(macros.loc);
+        } else {
+            f1 = NumberFormatter.withLocale(macros.loc);
+        }
+        if (macros.formatter2 != null) {
+            f2 = macros.formatter2.locale(macros.loc);
+        } else {
+            f2 = NumberFormatter.withLocale(macros.loc);
+        }
+        FormattedNumber r1 = f1.format(first);
+        FormattedNumber r2 = f2.format(second);
         NumberStringBuilder nsb = new NumberStringBuilder();
-        nsb.append(dq1.toPlainString(), NumberFormat.Field.INTEGER);
+        nsb.append(r1.nsb);
         nsb.append(" --- ", null);
-        nsb.append(dq2.toPlainString(), NumberFormat.Field.INTEGER);
+        nsb.append(r2.nsb);
         RangeIdentityType identityType = (first == second) ? RangeIdentityType.EQUAL_BEFORE_ROUNDING
                 : RangeIdentityType.NOT_EQUAL;
-        return new FormattedNumberRange(nsb, dq1, dq2, identityType);
+        return new FormattedNumberRange(nsb, first, second, identityType);
     }
 
     @Override
index 8c351b35cf832400ab344e9e645f7750657e72ce..da6618b5626d3aa971a2aea4d4bbe24630c66721 100644 (file)
@@ -2,6 +2,10 @@
 // License & terms of use: http://www.unicode.org/copyright.html#License
 package com.ibm.icu.number;
 
+import java.util.Locale;
+
+import com.ibm.icu.util.ULocale;
+
 /**
  * The main entrypoint to the formatting of ranges of numbers, including currencies and other units of measurement.
  *
@@ -16,4 +20,18 @@ public abstract class NumberRangeFormatter {
 
     public static enum RangeIdentityFallback {}
 
+    private static final UnlocalizedNumberRangeFormatter BASE = new UnlocalizedNumberRangeFormatter();
+
+    public static UnlocalizedNumberRangeFormatter with() {
+        return BASE;
+    }
+
+    public static LocalizedNumberRangeFormatter withLocale(Locale locale) {
+        return BASE.locale(locale);
+    }
+
+    public static LocalizedNumberRangeFormatter withLocale(ULocale locale) {
+        return BASE.locale(locale);
+    }
+
 }
index d7725e8a2f922b6f2e4b4a4ea587382a86664e64..23de02a0716df6190691e771ee8e747bde78f3e4 100644 (file)
@@ -38,11 +38,11 @@ public abstract class NumberRangeFormatterSettings<T extends NumberRangeFormatte
         this.value = value;
     }
 
-    public T numberFormatter(NumberFormatterSettings<?> formatter) {
+    public T numberFormatter(UnlocalizedNumberFormatter formatter) {
         return numberFormatters(formatter, formatter);
     }
 
-    public T numberFormatters(NumberFormatterSettings<?> formatterFirst, NumberFormatterSettings<?> formatterSecond) {
+    public T numberFormatters(UnlocalizedNumberFormatter formatterFirst, UnlocalizedNumberFormatter formatterSecond) {
         T intermediate = create(KEY_FORMATTER_1, formatterFirst);
         return (T) intermediate.create(KEY_FORMATTER_2, formatterSecond);
     }
@@ -79,12 +79,12 @@ public abstract class NumberRangeFormatterSettings<T extends NumberRangeFormatte
                 break;
             case KEY_FORMATTER_1:
                 if (macros.formatter1 == null) {
-                    macros.formatter1 = (NumberFormatterSettings<?>) current.value;
+                    macros.formatter1 = (UnlocalizedNumberFormatter) current.value;
                 }
                 break;
             case KEY_FORMATTER_2:
                 if (macros.formatter2 == null) {
-                    macros.formatter2 = (NumberFormatterSettings<?>) current.value;
+                    macros.formatter2 = (UnlocalizedNumberFormatter) current.value;
                 }
                 break;
             case KEY_COLLAPSE:
@@ -131,9 +131,9 @@ public abstract class NumberRangeFormatterSettings<T extends NumberRangeFormatte
         if (other == null) {
             return false;
         }
-        if (!(other instanceof NumberFormatterSettings)) {
+        if (!(other instanceof NumberRangeFormatterSettings)) {
             return false;
         }
-        return resolve().equals(((NumberFormatterSettings<?>) other).resolve());
+        return resolve().equals(((NumberRangeFormatterSettings<?>) other).resolve());
     }
 }
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberRangeFormatterTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberRangeFormatterTest.java
new file mode 100644 (file)
index 0000000..c0cfce5
--- /dev/null
@@ -0,0 +1,162 @@
+// © 2018 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html#License
+package com.ibm.icu.dev.test.number;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Locale;
+
+import org.junit.Test;
+
+import com.ibm.icu.number.LocalizedNumberRangeFormatter;
+import com.ibm.icu.number.NumberFormatter;
+import com.ibm.icu.number.NumberFormatter.GroupingStrategy;
+import com.ibm.icu.number.NumberRangeFormatter;
+import com.ibm.icu.number.UnlocalizedNumberRangeFormatter;
+import com.ibm.icu.util.Currency;
+import com.ibm.icu.util.ULocale;
+
+/**
+ * @author sffc
+ *
+ */
+public class NumberRangeFormatterTest {
+
+    private static final Currency USD = Currency.getInstance("USD");
+    private static final Currency GBP = Currency.getInstance("GBP");
+
+    @Test
+    public void testSanity() {
+        LocalizedNumberRangeFormatter lnrf1 = NumberRangeFormatter.withLocale(ULocale.US);
+        LocalizedNumberRangeFormatter lnrf2 = NumberRangeFormatter.with().locale(ULocale.US);
+        LocalizedNumberRangeFormatter lnrf3 = NumberRangeFormatter.withLocale(Locale.US);
+        LocalizedNumberRangeFormatter lnrf4 = NumberRangeFormatter.with().locale(Locale.US);
+        assertEquals("Formatters should be equal 1", lnrf1, lnrf2);
+        assertEquals("Formatters should be equal 2", lnrf2, lnrf3);
+        assertEquals("Formatters should be equal 3", lnrf3, lnrf4);
+        assertEquals("Formatters should have same behavior 1", lnrf1.formatRange(4, 6), lnrf2.formatRange(4, 6));
+        assertEquals("Formatters should have same behavior 2", lnrf2.formatRange(4, 6), lnrf3.formatRange(4, 6));
+        assertEquals("Formatters should have same behavior 3", lnrf3.formatRange(4, 6), lnrf4.formatRange(4, 6));
+    }
+
+    @Test
+    public void testBasic() {
+        assertFormatRange(
+                "Basic",
+                NumberRangeFormatter.with(),
+                ULocale.US,
+                "1 --- 5",
+                "5 --- 5",
+                "5 --- 5",
+                "0 --- 3",
+                "0 --- 0",
+                "3 --- 3,000",
+                "3,000 --- 5,000",
+                "4,999 --- 5,001",
+                "5,000 --- 5,000",
+                "5,000 --- 5,000,000");
+    }
+
+    @Test
+    public void testNullBehavior() {
+        assertFormatRange(
+                "Basic",
+                NumberRangeFormatter.with().numberFormatter(null),
+                ULocale.US,
+                "1 --- 5",
+                "5 --- 5",
+                "5 --- 5",
+                "0 --- 3",
+                "0 --- 0",
+                "3 --- 3,000",
+                "3,000 --- 5,000",
+                "4,999 --- 5,001",
+                "5,000 --- 5,000",
+                "5,000 --- 5,000,000");
+
+        assertFormatRange(
+                "Basic",
+                NumberRangeFormatter.with().numberFormatters(null, null),
+                ULocale.US,
+                "1 --- 5",
+                "5 --- 5",
+                "5 --- 5",
+                "0 --- 3",
+                "0 --- 0",
+                "3 --- 3,000",
+                "3,000 --- 5,000",
+                "4,999 --- 5,001",
+                "5,000 --- 5,000",
+                "5,000 --- 5,000,000");
+
+        assertFormatRange(
+                "Basic",
+                NumberRangeFormatter.with().numberFormatters(
+                        NumberFormatter.with().grouping(GroupingStrategy.OFF),
+                        null
+                ),
+                ULocale.US,
+                "1 --- 5",
+                "5 --- 5",
+                "5 --- 5",
+                "0 --- 3",
+                "0 --- 0",
+                "3 --- 3,000",
+                "3000 --- 5,000",
+                "4999 --- 5,001",
+                "5000 --- 5,000",
+                "5000 --- 5,000,000");
+
+        assertFormatRange(
+                "Basic",
+                NumberRangeFormatter.with().numberFormatters(
+                        null,
+                        NumberFormatter.with().grouping(GroupingStrategy.OFF)
+                ),
+                ULocale.US,
+                "1 --- 5",
+                "5 --- 5",
+                "5 --- 5",
+                "0 --- 3",
+                "0 --- 0",
+                "3 --- 3000",
+                "3,000 --- 5000",
+                "4,999 --- 5001",
+                "5,000 --- 5000",
+                "5,000 --- 5000000");
+    }
+
+    static void assertFormatRange(
+            String message,
+            UnlocalizedNumberRangeFormatter f,
+            ULocale locale,
+            String expected_10_50,
+            String expected_49_51,
+            String expected_50_50,
+            String expected_00_30,
+            String expected_00_00,
+            String expected_30_3K,
+            String expected_30K_50K,
+            String expected_49K_51K,
+            String expected_50K_50K,
+            String expected_50K_50M) {
+        LocalizedNumberRangeFormatter l = f.locale(locale);
+        assertFormattedRangeEquals(message, l, 1, 5, expected_10_50);
+        assertFormattedRangeEquals(message, l, 4.9999999, 5.0000001, expected_49_51);
+        assertFormattedRangeEquals(message, l, 5, 5, expected_50_50);
+        assertFormattedRangeEquals(message, l, 0, 3, expected_00_30);
+        assertFormattedRangeEquals(message, l, 0, 0, expected_00_00);
+        assertFormattedRangeEquals(message, l, 3, 3000, expected_30_3K);
+        assertFormattedRangeEquals(message, l, 3000, 5000, expected_30K_50K);
+        assertFormattedRangeEquals(message, l, 4999, 5001, expected_49K_51K);
+        assertFormattedRangeEquals(message, l, 5000, 5000, expected_50K_50K);
+        assertFormattedRangeEquals(message, l, 5e3, 5e6, expected_50K_50M);
+    }
+
+    private static void assertFormattedRangeEquals(String message, LocalizedNumberRangeFormatter l, Number first,
+            Number second, String expected) {
+        String actual1 = l.formatRange(first, second).toString();
+        assertEquals(message + ": " + first + ", " + second, expected, actual1);
+    }
+
+}