blob: 4ae63877a2a6ec5b44d803e66633764e3cab32a0 [file] [log] [blame]
/*
*******************************************************************************
* Copyright (C) 2008-2012, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
package com.ibm.icu.dev.test.localespi;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Locale;
import com.ibm.icu.dev.test.TestFmwk;
import com.ibm.icu.util.ULocale;
public class NumberFormatTest extends TestFmwk {
public static void main(String[] args) throws Exception {
new NumberFormatTest().run(args);
}
private static final int DEFAULT_TYPE = 0;
private static final int NUMBER_TYPE = 1;
private static final int INTEGER_TYPE = 2;
private static final int PERCENT_TYPE = 3;
private static final int CURRENCY_TYPE = 4;
/*
* Check if getInstance returns the ICU implementation.
*/
public void TestGetInstance() {
for (Locale loc : NumberFormat.getAvailableLocales()) {
if (TestUtil.isProblematicIBMLocale(loc)) {
logln("Skipped " + loc);
continue;
}
checkGetInstance(DEFAULT_TYPE, loc);
checkGetInstance(NUMBER_TYPE, loc);
checkGetInstance(INTEGER_TYPE, loc);
checkGetInstance(PERCENT_TYPE, loc);
checkGetInstance(CURRENCY_TYPE, loc);
}
}
private void checkGetInstance(int type, Locale loc) {
NumberFormat nf;
String[] method = new String[1];
nf = getJDKInstance(type, loc, method);
boolean isIcuImpl = (nf instanceof com.ibm.icu.impl.jdkadapter.DecimalFormatICU)
|| (nf instanceof com.ibm.icu.impl.jdkadapter.NumberFormatICU);
if (TestUtil.isICUExtendedLocale(loc)) {
if (!isIcuImpl) {
errln("FAIL: " + method[0] + " returned JDK NumberFormat for locale " + loc);
}
} else {
if (isIcuImpl) {
logln("INFO: " + method[0] + " returned ICU NumberFormat for locale " + loc);
}
Locale iculoc = TestUtil.toICUExtendedLocale(loc);
NumberFormat nfIcu = null;
nfIcu = getJDKInstance(type, iculoc, null);
if (isIcuImpl) {
if (!nf.equals(nfIcu)) {
errln("FAIL: " + method[0] + " returned ICU NumberFormat for locale " + loc
+ ", but different from the one for locale " + iculoc);
}
} else {
if (!(nfIcu instanceof com.ibm.icu.impl.jdkadapter.DecimalFormatICU)
&& !(nfIcu instanceof com.ibm.icu.impl.jdkadapter.NumberFormatICU)) {
errln("FAIL: " + method[0] + " returned JDK NumberFormat for locale " + iculoc);
}
}
}
}
private NumberFormat getJDKInstance(int type, Locale loc, String[] methodName) {
NumberFormat nf = null;
String method = null;
switch (type) {
case DEFAULT_TYPE:
nf = NumberFormat.getInstance(loc);
method = "getInstance";
break;
case NUMBER_TYPE:
nf = NumberFormat.getNumberInstance(loc);
method = "getNumberInstance";
break;
case INTEGER_TYPE:
nf = NumberFormat.getIntegerInstance(loc);
method = "getIntegerInstance";
break;
case PERCENT_TYPE:
nf = NumberFormat.getPercentInstance(loc);
method = "getPercentInstance";
break;
case CURRENCY_TYPE:
nf = NumberFormat.getCurrencyInstance(loc);
method = "getCurrencyInstance";
break;
}
if (methodName != null) {
methodName[0] = method;
}
return nf;
}
private com.ibm.icu.text.NumberFormat getICUInstance(int type, Locale loc, String[] methodName) {
com.ibm.icu.text.NumberFormat icunf = null;
String method = null;
switch (type) {
case DEFAULT_TYPE:
icunf = com.ibm.icu.text.NumberFormat.getInstance(loc);
method = "getInstance";
break;
case NUMBER_TYPE:
icunf = com.ibm.icu.text.NumberFormat.getNumberInstance(loc);
method = "getNumberInstance";
break;
case INTEGER_TYPE:
icunf = com.ibm.icu.text.NumberFormat.getIntegerInstance(loc);
method = "getIntegerInstance";
break;
case PERCENT_TYPE:
icunf = com.ibm.icu.text.NumberFormat.getPercentInstance(loc);
method = "getPercentInstance";
break;
case CURRENCY_TYPE:
icunf = com.ibm.icu.text.NumberFormat.getCurrencyInstance(loc);
method = "getCurrencyInstance";
break;
}
if (methodName != null) {
methodName[0] = method;
}
return icunf;
}
/*
* Testing the behavior of number format between ICU instance and its
* equivalent created via the Locale SPI framework.
*/
public void TestICUEquivalent() {
Locale[] TEST_LOCALES = {
new Locale("en", "US"),
new Locale("de", "DE"),
new Locale("zh"),
};
long[] TEST_LONGS = {
40L,
-1578L,
112233445566778899L,
};
double[] TEST_DOUBLES = {
0.0451D,
-1.679D,
124578.369D,
};
Object[] TEST_NUMBERS = {
Byte.valueOf((byte)13),
Integer.valueOf(3961),
Long.valueOf(-3451237890000L),
Float.valueOf(1.754F),
Double.valueOf(-129.942362353D),
new BigInteger("-15253545556575859505"),
new BigDecimal("3.14159265358979323846264338"),
};
String[] methodName = new String[1];
for (Locale loc : TEST_LOCALES) {
for (int type = 0; type <= 4; type++) {
Locale iculoc = TestUtil.toICUExtendedLocale(loc);
NumberFormat nf = getJDKInstance(type, iculoc, methodName);
com.ibm.icu.text.NumberFormat icunf = getICUInstance(type, loc, null);
String s1, s2;
Number n1, n2;
boolean pe1, pe2;
for (long l : TEST_LONGS) {
s1 = nf.format(l);
s2 = icunf.format(l);
if (!s1.equals(s2)) {
errln("FAIL: Different results for formatting long " + l + " by NumberFormat("
+ methodName[0] + ") in locale " + loc + " - JDK:" + s1 + " ICU:" + s2);
}
pe1 = false;
n1 = n2 = null;
try {
n1 = nf.parse(s1);
} catch (ParseException e) {
pe1 = true;
}
pe2 = false;
try {
n2 = icunf.parse(s2);
} catch (ParseException e) {
pe2 = true;
}
if ((pe1 && !pe2) || (!pe1 && pe2)) {
errln("FAIL: ParseException thrown by " + (pe1 ? "JDK" : "ICU")
+ " NumberFormat(" + methodName[0] + ") for parsing long" + l
+ " in locale " + loc);
} else if (!pe1 && !pe2 && !n1.equals(n2)) {
errln("FAIL: Different results for parsing long " + l + " by NumberFormat("
+ methodName[0] + ") in locale " + loc + " - JDK:" + n1 + " ICU:" + n2);
} else if (pe1 && pe2) {
logln("INFO: ParseException thrown by both JDK and ICU NumberFormat("
+ methodName[0] + ") for parsing long " + l + " in locale " + loc);
}
}
for (double d : TEST_DOUBLES) {
s1 = nf.format(d);
s2 = icunf.format(d);
if (!s1.equals(s2)) {
errln("FAIL: Different results for formatting double " + d + " by NumberFormat("
+ methodName[0] + ") in locale " + loc + " - JDK:" + s1 + " ICU:" + s2);
}
pe1 = false;
n1 = n2 = null;
try {
n1 = nf.parse(s1);
} catch (ParseException e) {
pe1 = true;
}
pe2 = false;
try {
n2 = icunf.parse(s2);
} catch (ParseException e) {
pe2 = true;
}
if ((pe1 && !pe2) || (!pe1 && pe2)) {
errln("FAIL: ParseException thrown by " + (pe1 ? "JDK" : "ICU")
+ " NumberFormat(" + methodName[0] + ") for parsing double" + d
+ " in locale " + loc);
} else if (!pe1 && !pe2 && !n1.equals(n2)) {
errln("FAIL: Different results for parsing double " + d + " by NumberFormat("
+ methodName[0] + ") in locale " + loc + " - JDK:" + n1 + " ICU:" + n2);
} else if (pe1 && pe2) {
logln("INFO: ParseException thrown by both JDK and ICU NumberFormat("
+ methodName[0] + ") for parsing double " + d + " in locale " + loc);
}
}
for (Object o : TEST_NUMBERS) {
s1 = nf.format(o);
s2 = icunf.format(o);
if (!s1.equals(s2)) {
errln("FAIL: Different results for formatting " + o.getClass().getName() + " by NumberFormat("
+ methodName[0] + ") in locale " + loc + " - JDK:" + s1 + " ICU:" + s2);
}
pe1 = false;
n1 = n2 = null;
try {
n1 = nf.parse(s1);
} catch (ParseException e) {
pe1 = true;
}
pe2 = false;
try {
n2 = icunf.parse(s2);
} catch (ParseException e) {
pe2 = true;
}
if ((pe1 && !pe2) || (!pe1 && pe2)) {
errln("FAIL: ParseException thrown by " + (pe1 ? "JDK" : "ICU")
+ " NumberFormat(" + methodName[0] + ") for parsing " + o.getClass().getName()
+ " in locale " + loc);
} else if (!pe1 && !pe2 && !n1.equals(n2)) {
errln("FAIL: Different results for parsing " + o.getClass().getName() + " by NumberFormat("
+ methodName[0] + ") in locale " + loc + " - JDK:" + n1 + " ICU:" + n2);
} else if (pe1 && pe2) {
logln("INFO: ParseException thrown by both JDK and ICU NumberFormat("
+ methodName[0] + ") for parsing " + o.getClass().getName() + " in locale " + loc);
}
}
}
}
}
public void TestKeywords() {
// ICU provider variant is appended
ULocale uloc0 = new ULocale("en_US_" + TestUtil.ICU_VARIANT + "@numbers=Arab;currency=EUR");
Locale loc = uloc0.toLocale();
// On Java 7+, locale extension is preserved
ULocale uloc = ULocale.forLocale(loc);
String nsType = uloc.getKeywordValue("numbers");
if (nsType == null) {
// Java 6 - skip this test
return;
}
NumberFormat jdkNfmt = NumberFormat.getCurrencyInstance(loc);
com.ibm.icu.text.NumberFormat icuNfmt = com.ibm.icu.text.NumberFormat.getCurrencyInstance(uloc);
final double num = 12345.67d;
String jdkOut = jdkNfmt.format(num);
String icuOut = icuNfmt.format(num);
if (!jdkOut.equals(icuOut)) {
errln("FAIL: JDK number format with Locale " + loc + " is " + jdkOut + ", expected: " + icuOut);
}
}
}