ICU-11276 Adding placeholder implementation and more API functions.
This commit is contained in:
parent
553f22585d
commit
37a40b31ed
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user