8310923: Refactor Currency tests to use JUnit
Reviewed-by: naoto, lancea
This commit is contained in:
parent
0c86c31bcc
commit
e848d9471f
@ -1,68 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
/*
|
||||
* @test
|
||||
* @bug 4512215 4818420 4819436
|
||||
* @summary Updated currency data.
|
||||
*/
|
||||
|
||||
import java.util.Currency;
|
||||
import java.util.Locale;
|
||||
|
||||
public class Bug4512215 {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
testCurrencyDefined("XBD", -1);
|
||||
testCountryCurrency("TJ", "TJS", 2);
|
||||
testCountryCurrency("FO", "DKK", 2);
|
||||
testCountryCurrency("FK", "FKP", 2);
|
||||
|
||||
testCountryCurrency("AF", "AFN", 2); // changed from "AFA"
|
||||
|
||||
// Newsletter V-5 on ISO 3166-1 (2002-05-20)
|
||||
testCountryCurrency("TL", "USD", 2); // successor to TP/TPE
|
||||
|
||||
// Newsletter V-8 on ISO 3166-1 (2003-07-23)
|
||||
testCountryCurrency("CS", "CSD", 2); // successor to YU/YUM
|
||||
}
|
||||
|
||||
private static void testCountryCurrency(String country, String currencyCode,
|
||||
int digits) {
|
||||
testCurrencyDefined(currencyCode, digits);
|
||||
Currency currency = Currency.getInstance(Locale.of("", country));
|
||||
if (!currency.getCurrencyCode().equals(currencyCode)) {
|
||||
throw new RuntimeException("[" + country
|
||||
+ "] expected: " + currencyCode
|
||||
+ "; got: " + currency.getCurrencyCode());
|
||||
}
|
||||
}
|
||||
|
||||
private static void testCurrencyDefined(String currencyCode, int digits) {
|
||||
Currency currency = Currency.getInstance(currencyCode);
|
||||
if (currency.getDefaultFractionDigits() != digits) {
|
||||
throw new RuntimeException("[" + currencyCode
|
||||
+ "] expected: " + digits
|
||||
+ "; got: " + currency.getDefaultFractionDigits());
|
||||
}
|
||||
}
|
||||
}
|
@ -1,84 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
/*
|
||||
* @test
|
||||
* @bug 6807534
|
||||
* @summary check whether the default implementation of
|
||||
* CurrencNameProvider.getDisplayName(String, Locale) throws appropriate
|
||||
* exceptions when necessary.
|
||||
*/
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.spi.CurrencyNameProvider;
|
||||
|
||||
public class Bug6807534 {
|
||||
|
||||
static final CurrencyNameProvider cnp = new CurrencyNameProviderImpl();
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
// test for NullPointerException (currencyCode)
|
||||
try {
|
||||
cnp.getDisplayName(null, Locale.US);
|
||||
throwException("NPE was not thrown with null currencyCode");
|
||||
} catch (NullPointerException npe) {}
|
||||
|
||||
// test for NullPointerException (locale)
|
||||
try {
|
||||
cnp.getDisplayName("USD", null);
|
||||
throwException("NPE was not thrown with null locale");
|
||||
} catch (NullPointerException npe) {}
|
||||
|
||||
// test for IllegalArgumentException (illegal currencyCode)
|
||||
try {
|
||||
cnp.getDisplayName("INVALID", Locale.US);
|
||||
throwException("IllegalArgumentException was not thrown with invalid currency code");
|
||||
} catch (IllegalArgumentException iae) {}
|
||||
try {
|
||||
cnp.getDisplayName("inv", Locale.US);
|
||||
throwException("IllegalArgumentException was not thrown with invalid currency code");
|
||||
} catch (IllegalArgumentException iae) {}
|
||||
|
||||
// test for IllegalArgumentException (non-supported locale)
|
||||
try {
|
||||
cnp.getDisplayName("USD", Locale.JAPAN);
|
||||
throwException("IllegalArgumentException was not thrown with non-supported locale");
|
||||
} catch (IllegalArgumentException iae) {}
|
||||
}
|
||||
|
||||
static void throwException(String msg) {
|
||||
throw new RuntimeException("test failed. "+msg);
|
||||
}
|
||||
|
||||
static class CurrencyNameProviderImpl extends CurrencyNameProvider {
|
||||
// dummy implementation
|
||||
public String getSymbol(String currencyCode, Locale locale) {
|
||||
return "";
|
||||
}
|
||||
|
||||
public Locale[] getAvailableLocales() {
|
||||
Locale[] avail = new Locale[1];
|
||||
avail[0] = Locale.US;
|
||||
return avail;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
/*
|
||||
* @test
|
||||
* @bug 8154295
|
||||
* @summary Check getNumericCodeAsString() method which returns numeric code as a 3 digit String.
|
||||
*/
|
||||
|
||||
import java.util.Currency;
|
||||
|
||||
public class Bug8154295 {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
String numericCode = Currency.getInstance("AFA").getNumericCodeAsString();
|
||||
if (!numericCode.equals("004")) { //should return "004" (a 3 digit string)
|
||||
throw new RuntimeException("[Expected 004, "
|
||||
+ "found "+numericCode+" for AFA]");
|
||||
}
|
||||
|
||||
numericCode = Currency.getInstance("AUD").getNumericCodeAsString();
|
||||
if (!numericCode.equals("036")) { //should return "036" (a 3 digit string)
|
||||
throw new RuntimeException("[Expected 036, "
|
||||
+ "found "+numericCode+" for AUD]");
|
||||
}
|
||||
|
||||
numericCode = Currency.getInstance("USD").getNumericCodeAsString();
|
||||
if (!numericCode.equals("840")) {// should return "840" (a 3 digit string)
|
||||
throw new RuntimeException("[Expected 840, "
|
||||
+ "found "+numericCode+" for USD]");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
101
test/jdk/java/util/Currency/CNPGetDisplayName.java
Normal file
101
test/jdk/java/util/Currency/CNPGetDisplayName.java
Normal file
@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6807534
|
||||
* @summary check whether the default implementation of
|
||||
* CurrencyNameProvider.getDisplayName(String, Locale) throws appropriate
|
||||
* exceptions when necessary.
|
||||
* @run junit CNPGetDisplayName
|
||||
*/
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.spi.CurrencyNameProvider;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
public class CNPGetDisplayName {
|
||||
|
||||
static final CurrencyNameProvider cnp = new CurrencyNameProviderImpl();
|
||||
|
||||
/**
|
||||
* Tests that the currency name provider throws a NullPointerException
|
||||
* under the expected circumstances.
|
||||
*/
|
||||
@ParameterizedTest
|
||||
@MethodSource("nullArgProvider")
|
||||
public void NPETest(String currencyCode, Locale locale, String err) {
|
||||
assertThrows(NullPointerException.class,
|
||||
() -> cnp.getDisplayName(currencyCode, locale), err);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the currency name provider throws a IllegalArgumentException
|
||||
* under the expected circumstances.
|
||||
*/
|
||||
@ParameterizedTest
|
||||
@MethodSource("illegalArgProvider")
|
||||
public void IAETest(String currencyCode, Locale locale, String err) {
|
||||
assertThrows(IllegalArgumentException.class,
|
||||
() -> cnp.getDisplayName(currencyCode, locale), err);
|
||||
}
|
||||
|
||||
private static Stream<Arguments> nullArgProvider() {
|
||||
return Stream.of(
|
||||
Arguments.of(null, Locale.US,
|
||||
"NPE was not thrown with null currencyCode"),
|
||||
Arguments.of("USD", null,
|
||||
"NPE was not thrown with null locale")
|
||||
);
|
||||
}
|
||||
|
||||
private static Stream<Arguments> illegalArgProvider() {
|
||||
return Stream.of(
|
||||
Arguments.of("INVALID", Locale.US,
|
||||
"IAE was not thrown with invalid currency code"),
|
||||
Arguments.of("inv", Locale.US,
|
||||
"IAE was not thrown with invalid currency code"),
|
||||
Arguments.of("USD", Locale.JAPAN,
|
||||
"IllegalArgumentException was not thrown with non-supported locale")
|
||||
);
|
||||
}
|
||||
|
||||
static class CurrencyNameProviderImpl extends CurrencyNameProvider {
|
||||
// dummy implementation
|
||||
public String getSymbol(String currencyCode, Locale locale) {
|
||||
return "";
|
||||
}
|
||||
|
||||
public Locale[] getAvailableLocales() {
|
||||
Locale[] avail = new Locale[1];
|
||||
avail[0] = Locale.US;
|
||||
return avail;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -20,15 +20,21 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
/**
|
||||
*
|
||||
*
|
||||
* Check the consistency between the regression tests and the currency data in the JRE
|
||||
|
||||
|
||||
/*
|
||||
Check the consistency between the regression tests and the currency
|
||||
data in the JRE. This class is used by other test classes.
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.reflect.*;
|
||||
import java.security.*;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.Currency;
|
||||
|
||||
class CheckDataVersion {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -20,6 +20,7 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4290801 4692419 4693631 5101540 5104960 6296410 6336600 6371531
|
||||
@ -28,6 +29,7 @@
|
||||
* @summary Basic tests for Currency class.
|
||||
* @modules java.base/java.util:open
|
||||
* jdk.localedata
|
||||
* @run junit CurrencyTest
|
||||
*/
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
@ -38,198 +40,232 @@ import java.time.LocalDate;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Currency;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
|
||||
public class CurrencyTest {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
// 'tablea1.txt' should be up-to-date before testing
|
||||
@Test
|
||||
public void dataVersionTest() {
|
||||
CheckDataVersion.check();
|
||||
testCurrencyCodeValidation();
|
||||
testLocaleMapping();
|
||||
testSymbols();
|
||||
testFractionDigits();
|
||||
testSerialization();
|
||||
testDisplayNames();
|
||||
testFundsCodes();
|
||||
}
|
||||
|
||||
static void testCurrencyCodeValidation() {
|
||||
// test creation of some valid currencies
|
||||
testValidCurrency("USD");
|
||||
testValidCurrency("EUR");
|
||||
testValidCurrency("GBP");
|
||||
testValidCurrency("JPY");
|
||||
testValidCurrency("CNY");
|
||||
testValidCurrency("CHF");
|
||||
|
||||
// test creation of some fictitious currencies
|
||||
testInvalidCurrency("AQD");
|
||||
testInvalidCurrency("US$");
|
||||
testInvalidCurrency("\u20AC");
|
||||
}
|
||||
|
||||
static void testValidCurrency(String currencyCode) {
|
||||
Currency currency1 = Currency.getInstance(currencyCode);
|
||||
Currency currency2 = Currency.getInstance(currencyCode);
|
||||
if (currency1 != currency2) {
|
||||
throw new RuntimeException("Didn't get same instance for same currency code");
|
||||
@Nested
|
||||
class CodeValidationTests {
|
||||
// Calling getInstance() on equal currency codes should return equal currencies
|
||||
@ParameterizedTest
|
||||
@MethodSource("validCurrencies")
|
||||
public void validCurrencyTest(String currencyCode) {
|
||||
compareCurrencies(currencyCode);
|
||||
}
|
||||
if (!currency1.getCurrencyCode().equals(currencyCode)) {
|
||||
throw new RuntimeException("Currency code changed");
|
||||
|
||||
private static Stream<String> validCurrencies() {
|
||||
return Stream.of("USD", "EUR", "GBP", "JPY", "CNY", "CHF");
|
||||
}
|
||||
|
||||
// Calling getInstance() with an invalid currency code should throw an IAE
|
||||
@ParameterizedTest
|
||||
@MethodSource("invalidCurrencies")
|
||||
public void invalidCurrencyTest(String currencyCode) {
|
||||
assertThrows(IllegalArgumentException.class, () ->
|
||||
Currency.getInstance(currencyCode), "getInstance() did not throw IAE");
|
||||
}
|
||||
|
||||
private static Stream<String> invalidCurrencies() {
|
||||
return Stream.of("AQD", "US$", "\u20AC");
|
||||
}
|
||||
}
|
||||
|
||||
static void testInvalidCurrency(String currencyCode) {
|
||||
boolean gotException = false;
|
||||
try {
|
||||
Currency currency = Currency.getInstance(currencyCode);
|
||||
} catch (IllegalArgumentException e) {
|
||||
gotException = true;
|
||||
@Nested
|
||||
class FundsCodesTests {
|
||||
// Calling getInstance() on equal currency codes should return equal currencies
|
||||
@ParameterizedTest
|
||||
@MethodSource("fundsCodes")
|
||||
public void validCurrencyTest(String currencyCode) {
|
||||
compareCurrencies(currencyCode);
|
||||
}
|
||||
if (!gotException) {
|
||||
throw new RuntimeException("didn't get specified exception");
|
||||
|
||||
// Verify a currency has the expected fractional digits
|
||||
@ParameterizedTest
|
||||
@MethodSource("fundsCodes")
|
||||
public void fractionDigitTest(String currencyCode, int expectedFractionDigits) {
|
||||
compareFractionDigits(currencyCode, expectedFractionDigits);
|
||||
}
|
||||
|
||||
// Verify a currency has the expected numeric code
|
||||
@ParameterizedTest
|
||||
@MethodSource("fundsCodes")
|
||||
public void numericCodeTest(String currencyCode, int ignored, int expectedNumeric) {
|
||||
int numeric = Currency.getInstance(currencyCode).getNumericCode();
|
||||
assertEquals(numeric, expectedNumeric, String.format(
|
||||
"Wrong numeric code for currency %s, expected %s, got %s",
|
||||
currencyCode, expectedNumeric, numeric));
|
||||
}
|
||||
|
||||
private static Stream<Arguments> fundsCodes() {
|
||||
return Stream.of(
|
||||
Arguments.of("BOV", 2, 984), Arguments.of("CHE", 2, 947),
|
||||
Arguments.of("CHW", 2, 948), Arguments.of("CLF", 4, 990),
|
||||
Arguments.of("COU", 2, 970), Arguments.of("MXV", 2, 979),
|
||||
Arguments.of("USN", 2, 997), Arguments.of("UYI", 0, 940)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
static void testLocaleMapping() {
|
||||
@Nested
|
||||
class LocaleMappingTests {
|
||||
|
||||
// very basic test: most countries have their own currency, and then
|
||||
// their currency code is an extension of their country code.
|
||||
Locale[] locales = Locale.getAvailableLocales();
|
||||
int goodCountries = 0;
|
||||
int ownCurrencies = 0;
|
||||
for (int i = 0; i < locales.length; i++) {
|
||||
Locale locale = locales[i];
|
||||
String ctryCode = locale.getCountry();
|
||||
int ctryLength = ctryCode.length();
|
||||
if (ctryLength == 0 ||
|
||||
ctryLength == 3 || // UN M.49 code
|
||||
ctryCode.matches("AA|Q[M-Z]|X[A-JL-Z]|ZZ" + // user defined codes, excluding "XK" (Kosovo)
|
||||
"AC|CP|DG|EA|EU|FX|IC|SU|TA|UK")) { // exceptional reservation codes
|
||||
boolean gotException = false;
|
||||
try {
|
||||
Currency.getInstance(locale);
|
||||
} catch (IllegalArgumentException e) {
|
||||
gotException = true;
|
||||
}
|
||||
if (!gotException) {
|
||||
throw new RuntimeException("didn't get specified exception");
|
||||
}
|
||||
} else {
|
||||
goodCountries++;
|
||||
Currency currency = Currency.getInstance(locale);
|
||||
if (currency.getCurrencyCode().indexOf(locale.getCountry()) == 0) {
|
||||
ownCurrencies++;
|
||||
@Test
|
||||
public void localeMappingTest() {
|
||||
Locale[] locales = Locale.getAvailableLocales();
|
||||
int goodCountries = 0;
|
||||
int ownCurrencies = 0;
|
||||
for (Locale locale : locales) {
|
||||
String ctryCode = locale.getCountry();
|
||||
int ctryLength = ctryCode.length();
|
||||
if (ctryLength == 0 ||
|
||||
ctryLength == 3 || // UN M.49 code
|
||||
ctryCode.matches("AA|Q[M-Z]|X[A-JL-Z]|ZZ" + // user defined codes, excluding "XK" (Kosovo)
|
||||
"AC|CP|DG|EA|EU|FX|IC|SU|TA|UK")) { // exceptional reservation codes
|
||||
assertThrows(IllegalArgumentException.class, () -> Currency.getInstance(locale), "Did not throw IAE");
|
||||
} else {
|
||||
goodCountries++;
|
||||
Currency currency = Currency.getInstance(locale);
|
||||
if (currency.getCurrencyCode().indexOf(locale.getCountry()) == 0) {
|
||||
ownCurrencies++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
System.out.println("Countries tested: " + goodCountries +
|
||||
", own currencies: " + ownCurrencies);
|
||||
if (ownCurrencies < (goodCountries / 2 + 1)) {
|
||||
throw new RuntimeException("suspicious: not enough countries have their own currency.");
|
||||
System.out.println("Countries tested: " + goodCountries +
|
||||
", own currencies: " + ownCurrencies);
|
||||
if (ownCurrencies < (goodCountries / 2 + 1)) {
|
||||
throw new RuntimeException("suspicious: not enough countries have their own currency.");
|
||||
}
|
||||
}
|
||||
|
||||
// check a few countries that don't change their currencies too often
|
||||
String[] country1 = {"US", "CA", "JP", "CN", "SG", "CH"};
|
||||
String[] currency1 = {"USD", "CAD", "JPY", "CNY", "SGD", "CHF"};
|
||||
for (int i = 0; i < country1.length; i++) {
|
||||
checkCountryCurrency(country1[i], currency1[i]);
|
||||
// Check an invalid country code
|
||||
@Test
|
||||
public void invalidCountryTest() {
|
||||
assertThrows(IllegalArgumentException.class, ()->
|
||||
Currency.getInstance(Locale.of("", "EU")), "Did not throw IAE");
|
||||
}
|
||||
|
||||
// Ensure a selection of countries have the expected currency
|
||||
@ParameterizedTest
|
||||
@MethodSource({"countryProvider", "switchedOverCountries"})
|
||||
public void countryCurrencyTest(String countryCode, String expected) {
|
||||
Locale locale = Locale.of("", countryCode);
|
||||
Currency currency = Currency.getInstance(locale);
|
||||
String code = (currency != null) ? currency.getCurrencyCode() : null;
|
||||
assertEquals(expected, code, generateErrMsg(
|
||||
"currency for", locale.getDisplayCountry(), expected, code));
|
||||
}
|
||||
|
||||
private static Stream<Arguments> countryProvider() {
|
||||
return Stream.of(
|
||||
// Check country that does not have a currency
|
||||
Arguments.of("AQ", null),
|
||||
// Check some countries that don't change their currencies often
|
||||
Arguments.of("US", "USD"),
|
||||
Arguments.of("CA", "CAD"),
|
||||
Arguments.of("JP", "JPY"),
|
||||
Arguments.of("CN", "CNY"),
|
||||
Arguments.of("SG", "SGD"),
|
||||
Arguments.of("CH", "CHF")
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* check currency changes
|
||||
* In current implementation, there is no data of old currency and transition date at jdk/src/java.base/share/data/currency/CurrencyData.properties.
|
||||
* So, all the switch data arrays are empty. In the future, if data of old currency and transition date are necessary for any country, the
|
||||
* arrays here can be updated so that the program can check the currency switch.
|
||||
*/
|
||||
String[] switchOverCtry = {};
|
||||
String[] switchOverOld = {};
|
||||
String[] switchOverNew = {};
|
||||
String[] switchOverTZ = {};
|
||||
int[] switchOverYear = {};
|
||||
int[] switchOverMonth = {}; // java.time APIs accept month starting from 1 i.e. 01 for January
|
||||
int[] switchOverDay = {};
|
||||
* Check Currency Changes
|
||||
* In the current implementation, there is no data of old currency and transition
|
||||
* date at jdk/src/java.base/share/data/currency/CurrencyData.properties.
|
||||
* So, all the switch data arrays are empty. In the future, if data of old
|
||||
* currency and transition date are necessary for any country, the
|
||||
* arrays here can be updated so that the program can check the currency switch.
|
||||
*/
|
||||
private static List<Arguments> switchedOverCountries() {
|
||||
List<Arguments> switched = new ArrayList<Arguments>();
|
||||
String[] switchOverCtry = {};
|
||||
String[] switchOverOld = {};
|
||||
String[] switchOverNew = {};
|
||||
String[] switchOverTZ = {};
|
||||
int[] switchOverYear = {};
|
||||
int[] switchOverMonth = {}; // java.time APIs accept month starting from 1 i.e. 01 for January
|
||||
int[] switchOverDay = {};
|
||||
|
||||
for (int i = 0; i < switchOverCtry.length; i++) {
|
||||
ZoneId zoneId = ZoneId.of(switchOverTZ[i]);
|
||||
ZonedDateTime zonedDateAndTime = ZonedDateTime.of(LocalDate.of(switchOverYear[i], switchOverMonth[i], switchOverDay[i]),
|
||||
LocalTime.MIDNIGHT, zoneId);
|
||||
ZonedDateTime currentZonedDateAndTime = ZonedDateTime.now(zoneId);
|
||||
checkCountryCurrency(switchOverCtry[i], (currentZonedDateAndTime.isAfter(zonedDateAndTime) ||
|
||||
currentZonedDateAndTime.isEqual(zonedDateAndTime)) ? switchOverNew[i] : switchOverOld[i]);
|
||||
}
|
||||
|
||||
// check a country code which doesn't have a currency
|
||||
checkCountryCurrency("AQ", null);
|
||||
|
||||
// check an invalid country code
|
||||
boolean gotException = false;
|
||||
try {
|
||||
Currency.getInstance(Locale.of("", "EU"));
|
||||
} catch (IllegalArgumentException e) {
|
||||
gotException = true;
|
||||
}
|
||||
if (!gotException) {
|
||||
throw new RuntimeException("didn't get specified exception.");
|
||||
for (int i = 0; i < switchOverCtry.length; i++) {
|
||||
ZoneId zoneId = ZoneId.of(switchOverTZ[i]);
|
||||
ZonedDateTime zonedDateAndTime = ZonedDateTime.of(LocalDate.of(
|
||||
switchOverYear[i], switchOverMonth[i], switchOverDay[i]), LocalTime.MIDNIGHT, zoneId);
|
||||
ZonedDateTime currentZonedDateAndTime = ZonedDateTime.now(zoneId);
|
||||
switched.add(Arguments.of(switchOverCtry[i], (currentZonedDateAndTime.isAfter(zonedDateAndTime)
|
||||
|| currentZonedDateAndTime.isEqual(zonedDateAndTime)) ? switchOverNew[i] : switchOverOld[i]));
|
||||
}
|
||||
return switched;
|
||||
}
|
||||
}
|
||||
|
||||
static void checkCountryCurrency(String countryCode, String expected) {
|
||||
Locale locale = Locale.of("", countryCode);
|
||||
Currency currency = Currency.getInstance(locale);
|
||||
String code = (currency != null) ? currency.getCurrencyCode() : null;
|
||||
if (!(expected == null ? code == null : expected.equals(code))) {
|
||||
throw new RuntimeException("Wrong currency for " +
|
||||
locale.getDisplayCountry() +
|
||||
": expected " + expected + ", got " + code);
|
||||
}
|
||||
// NON-NESTED TESTS
|
||||
|
||||
// Ensure selection of currencies have the correct fractional digits
|
||||
@ParameterizedTest
|
||||
@MethodSource("expectedFractionsProvider")
|
||||
public void fractionDigitsTest(String currencyCode, int expectedFractionDigits) {
|
||||
compareFractionDigits(currencyCode, expectedFractionDigits);
|
||||
}
|
||||
|
||||
static void testSymbols() {
|
||||
testSymbol("USD", Locale.US, "$");
|
||||
testSymbol("EUR", Locale.GERMANY, "\u20AC");
|
||||
testSymbol("USD", Locale.PRC, "US$");
|
||||
private static Stream<Arguments> expectedFractionsProvider() {
|
||||
return Stream.of(
|
||||
Arguments.of("USD", 2), Arguments.of("EUR", 2),
|
||||
Arguments.of("JPY", 0), Arguments.of("XDR", -1),
|
||||
Arguments.of("BHD", 3), Arguments.of("IQD", 3),
|
||||
Arguments.of("JOD", 3), Arguments.of("KWD", 3),
|
||||
Arguments.of("LYD", 3), Arguments.of("OMR", 3),
|
||||
Arguments.of("TND", 3),
|
||||
|
||||
// Old and New Turkish Lira
|
||||
Arguments.of("TRL", 0), Arguments.of("TRY", 2)
|
||||
);
|
||||
}
|
||||
|
||||
static void testSymbol(String currencyCode, Locale locale, String expectedSymbol) {
|
||||
// Ensure selection of currencies have the expected symbol
|
||||
@ParameterizedTest
|
||||
@MethodSource("symbolProvider")
|
||||
public void symbolTest(String currencyCode, Locale locale, String expectedSymbol) {
|
||||
String symbol = Currency.getInstance(currencyCode).getSymbol(locale);
|
||||
if (!symbol.equals(expectedSymbol)) {
|
||||
throw new RuntimeException("Wrong symbol for currency " +
|
||||
currencyCode +": expected " + expectedSymbol +
|
||||
", got " + symbol);
|
||||
}
|
||||
assertEquals(symbol, expectedSymbol, generateErrMsg(
|
||||
"symbol for", currencyCode, expectedSymbol, symbol));
|
||||
}
|
||||
|
||||
static void testFractionDigits() {
|
||||
testFractionDigits("USD", 2);
|
||||
testFractionDigits("EUR", 2);
|
||||
testFractionDigits("JPY", 0);
|
||||
testFractionDigits("XDR", -1);
|
||||
|
||||
testFractionDigits("BHD", 3);
|
||||
testFractionDigits("IQD", 3);
|
||||
testFractionDigits("JOD", 3);
|
||||
testFractionDigits("KWD", 3);
|
||||
testFractionDigits("LYD", 3);
|
||||
testFractionDigits("OMR", 3);
|
||||
testFractionDigits("TND", 3);
|
||||
|
||||
// Turkish Lira
|
||||
testFractionDigits("TRL", 0);
|
||||
testFractionDigits("TRY", 2);
|
||||
private static Stream<Arguments> symbolProvider() {
|
||||
return Stream.of(
|
||||
Arguments.of("USD", Locale.US, "$"),
|
||||
Arguments.of("EUR", Locale.GERMANY, "\u20AC"),
|
||||
Arguments.of("USD", Locale.PRC, "US$")
|
||||
);
|
||||
}
|
||||
|
||||
static void testFractionDigits(String currencyCode, int expectedFractionDigits) {
|
||||
int digits = Currency.getInstance(currencyCode).getDefaultFractionDigits();
|
||||
if (digits != expectedFractionDigits) {
|
||||
throw new RuntimeException("Wrong number of fraction digits for currency " +
|
||||
currencyCode +": expected " + expectedFractionDigits +
|
||||
", got " + digits);
|
||||
}
|
||||
}
|
||||
|
||||
static void testSerialization() throws Exception {
|
||||
// Ensure serialization does not break class invariant.
|
||||
// Currency should be able to round-trip and remain the same value.
|
||||
@Test
|
||||
public void serializationTest() throws Exception {
|
||||
Currency currency1 = Currency.getInstance("DEM");
|
||||
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
@ -241,74 +277,66 @@ public class CurrencyTest {
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
|
||||
ObjectInputStream iStream = new ObjectInputStream(bais);
|
||||
Currency currency2 = (Currency) iStream.readObject();
|
||||
|
||||
if (currency1 != currency2) {
|
||||
throw new RuntimeException("serialization breaks class invariant");
|
||||
}
|
||||
assertEquals(currency1, currency2, "serialization breaks class invariant");
|
||||
}
|
||||
|
||||
static void testDisplayNames() {
|
||||
// null argument test
|
||||
try {
|
||||
testDisplayName("USD", null, "");
|
||||
throw new RuntimeException("getDisplayName(NULL) did not throw an NPE.");
|
||||
} catch (NullPointerException npe) {}
|
||||
|
||||
testDisplayName("USD", Locale.ENGLISH, "US Dollar");
|
||||
testDisplayName("FRF", Locale.FRENCH, "franc fran\u00e7ais");
|
||||
testDisplayName("DEM", Locale.GERMAN, "Deutsche Mark");
|
||||
testDisplayName("ESP", Locale.of("es"), "peseta espa\u00f1ola");
|
||||
testDisplayName("ITL", Locale.ITALIAN, "lira italiana");
|
||||
testDisplayName("JPY", Locale.JAPANESE, "\u65e5\u672c\u5186");
|
||||
testDisplayName("KRW", Locale.KOREAN, "\ub300\ud55c\ubbfc\uad6d \uc6d0");
|
||||
testDisplayName("SEK", Locale.of("sv"), "svensk krona");
|
||||
testDisplayName("CNY", Locale.SIMPLIFIED_CHINESE, "\u4eba\u6c11\u5e01");
|
||||
testDisplayName("TWD", Locale.TRADITIONAL_CHINESE, "\u65b0\u53f0\u5e63");
|
||||
// Ensure getInstance() throws null when passed a null locale
|
||||
@Test
|
||||
public void nullDisplayNameTest() {
|
||||
assertThrows(NullPointerException.class, ()->
|
||||
Currency.getInstance("USD").getDisplayName(null));
|
||||
}
|
||||
|
||||
static void testDisplayName(String currencyCode, Locale locale, String expectedName) {
|
||||
// Ensure a selection of currencies/locale combos have the correct display name
|
||||
@ParameterizedTest
|
||||
@MethodSource("displayNameProvider")
|
||||
public void displayNameTest(String currencyCode, Locale locale, String expectedName) {
|
||||
String name = Currency.getInstance(currencyCode).getDisplayName(locale);
|
||||
if (!name.equals(expectedName)) {
|
||||
throw new RuntimeException("Wrong display name for currency " +
|
||||
currencyCode +": expected '" + expectedName +
|
||||
"', got '" + name + "'");
|
||||
}
|
||||
}
|
||||
static void testFundsCodes() {
|
||||
testValidCurrency("BOV");
|
||||
testValidCurrency("CHE");
|
||||
testValidCurrency("CHW");
|
||||
testValidCurrency("CLF");
|
||||
testValidCurrency("COU");
|
||||
testValidCurrency("MXV");
|
||||
testValidCurrency("USN");
|
||||
testValidCurrency("UYI");
|
||||
|
||||
testFractionDigits("BOV", 2);
|
||||
testFractionDigits("CHE", 2);
|
||||
testFractionDigits("CHW", 2);
|
||||
testFractionDigits("CLF", 4);
|
||||
testFractionDigits("COU", 2);
|
||||
testFractionDigits("MXV", 2);
|
||||
testFractionDigits("USN", 2);
|
||||
testFractionDigits("UYI", 0);
|
||||
|
||||
testNumericCode("BOV", 984);
|
||||
testNumericCode("CHE", 947);
|
||||
testNumericCode("CHW", 948);
|
||||
testNumericCode("CLF", 990);
|
||||
testNumericCode("COU", 970);
|
||||
testNumericCode("MXV", 979);
|
||||
testNumericCode("USN", 997);
|
||||
testNumericCode("UYI", 940);
|
||||
assertEquals(name, expectedName, generateErrMsg(
|
||||
"display name for", currencyCode, expectedName, name));
|
||||
}
|
||||
|
||||
static void testNumericCode(String currencyCode, int expectedNumeric) {
|
||||
int numeric = Currency.getInstance(currencyCode).getNumericCode();
|
||||
if (numeric != expectedNumeric) {
|
||||
throw new RuntimeException("Wrong numeric code for currency " +
|
||||
currencyCode +": expected " + expectedNumeric +
|
||||
", got " + numeric);
|
||||
}
|
||||
private static Stream<Arguments> displayNameProvider() {
|
||||
return Stream.of(
|
||||
Arguments.of("USD", Locale.ENGLISH, "US Dollar"),
|
||||
Arguments.of("FRF", Locale.FRENCH, "franc fran\u00e7ais"),
|
||||
Arguments.of("DEM", Locale.GERMAN, "Deutsche Mark"),
|
||||
Arguments.of("ESP", Locale.of("es"), "peseta espa\u00f1ola"),
|
||||
Arguments.of("ITL", Locale.ITALIAN, "lira italiana"),
|
||||
Arguments.of("JPY", Locale.JAPANESE, "\u65e5\u672c\u5186"),
|
||||
Arguments.of("KRW", Locale.KOREAN, "\ub300\ud55c\ubbfc\uad6d \uc6d0"),
|
||||
Arguments.of("SEK", Locale.of("sv"), "svensk krona"),
|
||||
Arguments.of("CNY", Locale.SIMPLIFIED_CHINESE, "\u4eba\u6c11\u5e01"),
|
||||
Arguments.of("TWD", Locale.TRADITIONAL_CHINESE, "\u65b0\u53f0\u5e63")
|
||||
);
|
||||
}
|
||||
|
||||
// HELPER FUNCTIONS
|
||||
|
||||
// A Currency instance returned from getInstance() should always be
|
||||
// equal if supplied the same currencyCode. getCurrencyCode() should
|
||||
// always be equal to the currencyCode used to create the Currency.
|
||||
private static void compareCurrencies(String currencyCode) {
|
||||
Currency currency1 = Currency.getInstance(currencyCode);
|
||||
Currency currency2 = Currency.getInstance(currencyCode);
|
||||
assertEquals(currency1, currency2, "Didn't get same instance for same currency code");
|
||||
assertEquals(currency1.getCurrencyCode(), currencyCode, "getCurrencyCode()" +
|
||||
" did not return the expected value");
|
||||
}
|
||||
|
||||
// Ensures the getDefaultFractionDigits() method returns the expected amount
|
||||
private static void compareFractionDigits(String currencyCode,
|
||||
int expectedFractionDigits) {
|
||||
int digits = Currency.getInstance(currencyCode).getDefaultFractionDigits();
|
||||
assertEquals(digits, expectedFractionDigits, generateErrMsg(
|
||||
"number of fraction digits for currency",
|
||||
currencyCode, Integer.toString(expectedFractionDigits), Integer.toString(digits)));
|
||||
}
|
||||
|
||||
// Used for logging on failing tests
|
||||
private static String generateErrMsg(String subject, String currency,
|
||||
String expected, String got) {
|
||||
return String.format("Wrong %s %s: expected '%s', got '%s'",
|
||||
subject, currency, expected, got);
|
||||
}
|
||||
}
|
||||
|
66
test/jdk/java/util/Currency/NoMinorUnitCurrenciesTest.java
Normal file
66
test/jdk/java/util/Currency/NoMinorUnitCurrenciesTest.java
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4512215 4818420 4819436 8310923
|
||||
* @summary Test currencies without minor units.
|
||||
* @run junit NoMinorUnitCurrenciesTest
|
||||
*/
|
||||
|
||||
import java.util.Currency;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class NoMinorUnitCurrenciesTest {
|
||||
|
||||
/**
|
||||
* Spot check some minor undefined currencies and ensure their default fraction
|
||||
* digits are not 2.
|
||||
*/
|
||||
@ParameterizedTest
|
||||
@MethodSource("minorUndefined")
|
||||
public void checkFractionDigits(String currencyCode, int digits) {
|
||||
Currency currency = Currency.getInstance(currencyCode);
|
||||
assertEquals(currency.getCurrencyCode(), currencyCode);
|
||||
assertEquals(currency.getDefaultFractionDigits(), digits, String.format(
|
||||
"[%s] expected: %s; got: %s", currencyCode, digits, currency.getDefaultFractionDigits()));
|
||||
}
|
||||
|
||||
// Currencies from the minorUndefined key of CurrencyData.properties
|
||||
// (These are currencies without minor units)
|
||||
private static Stream<Arguments> minorUndefined() {
|
||||
return Stream.of(
|
||||
Arguments.of("XBD", -1),
|
||||
Arguments.of("XAG", -1),
|
||||
Arguments.of("XAU", -1),
|
||||
Arguments.of("XBA", -1),
|
||||
Arguments.of("XBB", -1)
|
||||
);
|
||||
}
|
||||
}
|
61
test/jdk/java/util/Currency/NumCodeAsStringTest.java
Normal file
61
test/jdk/java/util/Currency/NumCodeAsStringTest.java
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8154295
|
||||
* @summary Check getNumericCodeAsString() method which returns numeric code as a 3 digit String.
|
||||
* @run junit NumCodeAsStringTest
|
||||
*/
|
||||
|
||||
import java.util.Currency;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class NumCodeAsStringTest {
|
||||
|
||||
/**
|
||||
* Ensure getNumericCodeAsString() returns the correct 3-digit numeric code
|
||||
* for the associated currency Code.
|
||||
*/
|
||||
@ParameterizedTest
|
||||
@MethodSource("codeProvider")
|
||||
public void checkNumCodeTest(String currCode, String expectedNumCode) {
|
||||
String actualNumCode = Currency.getInstance(currCode).getNumericCodeAsString();
|
||||
assertEquals(expectedNumCode, actualNumCode, String.format(
|
||||
"Expected: %s, but got: %s, for %s", expectedNumCode, actualNumCode, currCode));
|
||||
}
|
||||
|
||||
private static Stream<Arguments> codeProvider() {
|
||||
return Stream.of(
|
||||
Arguments.of("AFA", "004"),
|
||||
Arguments.of("AUD", "036"),
|
||||
Arguments.of("USD", "840")
|
||||
);
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -20,6 +20,7 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4691089 4819436 4942982 5104960 6544471 6627549 7066203 7195759
|
||||
@ -28,285 +29,293 @@
|
||||
* @summary Validate ISO 4217 data for Currency class.
|
||||
* @modules java.base/java.util:open
|
||||
* jdk.localedata
|
||||
* @run junit ValidateISO4217
|
||||
*/
|
||||
|
||||
/*
|
||||
* ############################################################################
|
||||
*
|
||||
* ValidateISO4217 is a tool to detect differences between the latest ISO 4217
|
||||
* data and Java's currency data which is based on ISO 4217.
|
||||
* If there is a difference, the following file which includes currency data
|
||||
* may need to be updated.
|
||||
* src/share/classes/java/util/CurrencyData.properties
|
||||
*
|
||||
* ############################################################################
|
||||
*
|
||||
* 1) Make a golden-data file.
|
||||
* From BSi's ISO4217 data (TABLE A1.doc), extract four (or eight, if currency is changing)
|
||||
* fields and save as ./tablea1.txt.
|
||||
* <Country code>\t<Currency code>\t<Numeric code>\t<Minor unit>[\t<Cutover Date>\t<new Currency code>\t<new Numeric code>\t<new Minor unit>]
|
||||
* The Cutover Date is given in SimpleDateFormat's 'yyyy-MM-dd-HH-mm-ss' format in the GMT time zone.
|
||||
*
|
||||
* 2) Compile ValidateISO4217.java
|
||||
*
|
||||
* 3) Execute ValidateISO4217 as follows:
|
||||
* java ValidateISO4217
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Currency;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
/**
|
||||
* This class tests the latest ISO 4217 data and Java's currency data which is
|
||||
* based on ISO 4217. The golden-data file (ISO 4217 data) 'tablea1.txt' has the following
|
||||
* format: <Country code>\t<Currency code>\t<Numeric code>\t<Minor unit>[\t<Cutover Date>\t<new Currency code>\t<new Numeric code>\t<new Minor unit>]
|
||||
* The Cutover Date is given in SimpleDateFormat's 'yyyy-MM-dd-HH-mm-ss' format in the GMT time zone.
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.text.*;
|
||||
import java.util.*;
|
||||
|
||||
public class ValidateISO4217 {
|
||||
|
||||
static final int ALPHA_NUM = 26;
|
||||
|
||||
static final byte UNDEFINED = 0;
|
||||
static final byte DEFINED = 1;
|
||||
static final byte SKIPPED = 2;
|
||||
|
||||
/* input files */
|
||||
static final String datafile = "tablea1.txt";
|
||||
|
||||
/* alpha2-code table */
|
||||
static byte[] codes = new byte[ALPHA_NUM * ALPHA_NUM];
|
||||
|
||||
static final String[][] additionalCodes = {
|
||||
/* Defined in ISO 4217 list, but don't have code and minor unit info. */
|
||||
{"AQ", "", "", "0"}, // Antarctica
|
||||
|
||||
/*
|
||||
* Defined in ISO 4217 list, but don't have code and minor unit info in
|
||||
* it. On the other hand, both code and minor unit are defined in
|
||||
* .properties file. I don't know why, though.
|
||||
*/
|
||||
{"GS", "GBP", "826", "2"}, // South Georgia And The South Sandwich Islands
|
||||
|
||||
/* Not defined in ISO 4217 list, but defined in .properties file. */
|
||||
{"AX", "EUR", "978", "2"}, // \u00c5LAND ISLANDS
|
||||
{"PS", "ILS", "376", "2"}, // Palestinian Territory, Occupied
|
||||
|
||||
/* Not defined in ISO 4217 list, but added in ISO 3166 country code list */
|
||||
{"JE", "GBP", "826", "2"}, // Jersey
|
||||
{"GG", "GBP", "826", "2"}, // Guernsey
|
||||
{"IM", "GBP", "826", "2"}, // Isle of Man
|
||||
{"BL", "EUR", "978", "2"}, // Saint Barthelemy
|
||||
{"MF", "EUR", "978", "2"}, // Saint Martin
|
||||
|
||||
/* Defined neither in ISO 4217 nor ISO 3166 list */
|
||||
{"XK", "EUR", "978", "2"}, // Kosovo
|
||||
// Input golden-data file
|
||||
private static final File dataFile = new File(System.getProperty(
|
||||
"test.src", "."), "tablea1.txt");
|
||||
// Code statuses
|
||||
private static final byte UNDEFINED = 0;
|
||||
private static final byte DEFINED = 1;
|
||||
private static final byte SKIPPED = 2;
|
||||
private static final byte TESTED = 4;
|
||||
private static final int ALPHA_NUM = 26;
|
||||
// An alpha2 code table which maps the status of a country
|
||||
private static final byte[] codes = new byte[ALPHA_NUM * ALPHA_NUM];
|
||||
// Codes derived from ISO4217 golden-data file
|
||||
private static final List<Arguments> ISO4217Codes = new ArrayList<Arguments>();
|
||||
// Additional codes not from the ISO4217 golden-data file
|
||||
private static final List<Arguments> additionalCodes = new ArrayList<Arguments>();
|
||||
// Currencies to test (derived from ISO4217Codes and additionalCodes)
|
||||
private static final Set<Currency> testCurrencies = new HashSet<>();
|
||||
// Codes that are obsolete, do not have related country, extra currency
|
||||
private static final String otherCodes =
|
||||
"ADP-AFA-ATS-AYM-AZM-BEF-BGL-BOV-BYB-BYR-CHE-CHW-CLF-COU-CUC-CYP-"
|
||||
+ "DEM-EEK-ESP-FIM-FRF-GHC-GRD-GWP-IEP-ITL-LTL-LUF-LVL-MGF-MRO-MTL-MXV-MZM-NLG-"
|
||||
+ "PTE-ROL-RUR-SDD-SIT-SLL-SKK-SRG-STD-TMM-TPE-TRL-VEF-UYI-USN-USS-VEB-VED-"
|
||||
+ "XAG-XAU-XBA-XBB-XBC-XBD-XDR-XFO-XFU-XPD-XPT-XSU-XTS-XUA-XXX-"
|
||||
+ "YUM-ZMK-ZWD-ZWN-ZWR";
|
||||
private static final String[][] extraCodes = {
|
||||
/* Defined in ISO 4217 list, but don't have code and minor unit info. */
|
||||
{"AQ", "", "", "0"}, // Antarctica
|
||||
/*
|
||||
* Defined in ISO 4217 list, but don't have code and minor unit info in
|
||||
* it. On the other hand, both code and minor unit are defined in
|
||||
* .properties file. I don't know why, though.
|
||||
*/
|
||||
{"GS", "GBP", "826", "2"}, // South Georgia And The South Sandwich Islands
|
||||
/* Not defined in ISO 4217 list, but defined in .properties file. */
|
||||
{"AX", "EUR", "978", "2"}, // \u00c5LAND ISLANDS
|
||||
{"PS", "ILS", "376", "2"}, // Palestinian Territory, Occupied
|
||||
/* Not defined in ISO 4217 list, but added in ISO 3166 country code list */
|
||||
{"JE", "GBP", "826", "2"}, // Jersey
|
||||
{"GG", "GBP", "826", "2"}, // Guernsey
|
||||
{"IM", "GBP", "826", "2"}, // Isle of Man
|
||||
{"BL", "EUR", "978", "2"}, // Saint Barthelemy
|
||||
{"MF", "EUR", "978", "2"}, // Saint Martin
|
||||
/* Defined neither in ISO 4217 nor ISO 3166 list */
|
||||
{"XK", "EUR", "978", "2"}, // Kosovo
|
||||
};
|
||||
private static SimpleDateFormat format = null;
|
||||
|
||||
/* Codes that are obsolete, do not have related country, extra currency */
|
||||
static final String otherCodes =
|
||||
"ADP-AFA-ATS-AYM-AZM-BEF-BGL-BOV-BYB-BYR-CHE-CHW-CLF-COU-CUC-CYP-"
|
||||
+ "DEM-EEK-ESP-FIM-FRF-GHC-GRD-GWP-IEP-ITL-LTL-LUF-LVL-MGF-MRO-MTL-MXV-MZM-NLG-"
|
||||
+ "PTE-ROL-RUR-SDD-SIT-SLL-SKK-SRG-STD-TMM-TPE-TRL-VEF-UYI-USN-USS-VEB-VED-"
|
||||
+ "XAG-XAU-XBA-XBB-XBC-XBD-XDR-XFO-XFU-XPD-XPT-XSU-XTS-XUA-XXX-"
|
||||
+ "YUM-ZMK-ZWD-ZWN-ZWR";
|
||||
|
||||
static boolean err = false;
|
||||
|
||||
static Set<Currency> testCurrencies = new HashSet<Currency>();
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
CheckDataVersion.check();
|
||||
test1();
|
||||
test2();
|
||||
getAvailableCurrenciesTest();
|
||||
|
||||
if (err) {
|
||||
throw new RuntimeException("Failed: Validation ISO 4217 data");
|
||||
}
|
||||
// Sets up the following test data:
|
||||
// ISO4217Codes, additionalCodes, testCurrencies, codes
|
||||
@BeforeAll
|
||||
static void setUpTestingData() throws Exception {
|
||||
// These functions laterally setup 'testCurrencies' and 'codes'
|
||||
// at the same time
|
||||
setUpISO4217Codes();
|
||||
setUpAdditionalCodes();
|
||||
setUpOtherCurrencies();
|
||||
}
|
||||
|
||||
static void test1() throws Exception {
|
||||
|
||||
try (FileReader fr = new FileReader(new File(System.getProperty("test.src", "."), datafile));
|
||||
// Parse the ISO4217 file and populate ISO4217Codes and testCurrencies.
|
||||
private static void setUpISO4217Codes() throws Exception{
|
||||
try (FileReader fr = new FileReader(dataFile);
|
||||
BufferedReader in = new BufferedReader(fr))
|
||||
{
|
||||
String line;
|
||||
SimpleDateFormat format = null;
|
||||
|
||||
while ((line = in.readLine()) != null) {
|
||||
if (line.length() == 0 || line.charAt(0) == '#') {
|
||||
// Skip comments and empty lines
|
||||
continue;
|
||||
}
|
||||
|
||||
StringTokenizer tokens = new StringTokenizer(line, "\t");
|
||||
String country = tokens.nextToken();
|
||||
if (country.length() != 2) {
|
||||
// Skip invalid countries
|
||||
continue;
|
||||
}
|
||||
// If the country is valid, process the additional columns
|
||||
processColumns(tokens, country);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String currency;
|
||||
String numeric;
|
||||
String minorUnit;
|
||||
int tokensCount = tokens.countTokens();
|
||||
if (tokensCount < 3) {
|
||||
currency = "";
|
||||
numeric = "0";
|
||||
minorUnit = "0";
|
||||
} else {
|
||||
private static void processColumns(StringTokenizer tokens, String country) throws ParseException {
|
||||
String currency;
|
||||
String numeric;
|
||||
String minorUnit;
|
||||
int tokensCount = tokens.countTokens();
|
||||
if (tokensCount < 3) {
|
||||
// Ill-defined columns
|
||||
currency = "";
|
||||
numeric = "0";
|
||||
minorUnit = "0";
|
||||
} else {
|
||||
// Fully defined columns
|
||||
currency = tokens.nextToken();
|
||||
numeric = tokens.nextToken();
|
||||
minorUnit = tokens.nextToken();
|
||||
testCurrencies.add(Currency.getInstance(currency));
|
||||
// Check for the cut-over if a currency is changing
|
||||
if (tokensCount > 3) {
|
||||
if (format == null) {
|
||||
createDateFormat();
|
||||
}
|
||||
// If the cut-over already passed, test the changed data too
|
||||
if (format.parse(tokens.nextToken()).getTime() < System.currentTimeMillis()) {
|
||||
currency = tokens.nextToken();
|
||||
numeric = tokens.nextToken();
|
||||
minorUnit = tokens.nextToken();
|
||||
testCurrencies.add(Currency.getInstance(currency));
|
||||
|
||||
// check for the cutover
|
||||
if (tokensCount > 3) {
|
||||
if (format == null) {
|
||||
format = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss", Locale.US);
|
||||
format.setTimeZone(TimeZone.getTimeZone("GMT"));
|
||||
format.setLenient(false);
|
||||
}
|
||||
if (format.parse(tokens.nextToken()).getTime() <
|
||||
System.currentTimeMillis()) {
|
||||
currency = tokens.nextToken();
|
||||
numeric = tokens.nextToken();
|
||||
minorUnit = tokens.nextToken();
|
||||
testCurrencies.add(Currency.getInstance(currency));
|
||||
}
|
||||
}
|
||||
}
|
||||
int index = toIndex(country);
|
||||
testCountryCurrency(country, currency, Integer.parseInt(numeric),
|
||||
Integer.parseInt(minorUnit), index);
|
||||
}
|
||||
}
|
||||
int index = toIndex(country);
|
||||
ISO4217Codes.add(Arguments.of(country, currency, Integer.parseInt(numeric),
|
||||
Integer.parseInt(minorUnit), index));
|
||||
codes[index] = DEFINED;
|
||||
}
|
||||
|
||||
for (int i = 0; i < additionalCodes.length; i++) {
|
||||
int index = toIndex(additionalCodes[i][0]);
|
||||
if (additionalCodes[i][1].length() != 0) {
|
||||
testCountryCurrency(additionalCodes[i][0], additionalCodes[i][1],
|
||||
Integer.parseInt(additionalCodes[i][2]),
|
||||
Integer.parseInt(additionalCodes[i][3]), index);
|
||||
testCurrencies.add(Currency.getInstance(additionalCodes[i][1]));
|
||||
// Generates a unique index for an alpha-2 country
|
||||
private static int toIndex(String country) {
|
||||
return ((country.charAt(0) - 'A') * ALPHA_NUM + country.charAt(1) - 'A');
|
||||
}
|
||||
|
||||
private static void createDateFormat() {
|
||||
format = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss", Locale.US);
|
||||
format.setTimeZone(TimeZone.getTimeZone("GMT"));
|
||||
format.setLenient(false);
|
||||
}
|
||||
|
||||
// Process 'extraCodes', turning them into JUnit arguments and populate
|
||||
// both additionalCodes and testCurrencies.
|
||||
private static void setUpAdditionalCodes() {
|
||||
for (String[] extraCode : extraCodes) {
|
||||
int index = toIndex(extraCode[0]);
|
||||
if (extraCode[1].length() != 0) {
|
||||
additionalCodes.add(Arguments.of(extraCode[0], extraCode[1],
|
||||
Integer.parseInt(extraCode[2]), Integer.parseInt(extraCode[3]), index));
|
||||
testCurrencies.add(Currency.getInstance(extraCode[1]));
|
||||
} else {
|
||||
codes[index] = SKIPPED;
|
||||
codes[index] = SKIPPED; // For example, Antarctica
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int toIndex(String s) {
|
||||
return ((s.charAt(0) - 'A') * ALPHA_NUM + s.charAt(1) - 'A');
|
||||
}
|
||||
|
||||
static void testCountryCurrency(String country, String currencyCode,
|
||||
int numericCode, int digits, int index) {
|
||||
if (currencyCode.length() == 0) {
|
||||
return;
|
||||
}
|
||||
testCurrencyDefined(currencyCode, numericCode, digits);
|
||||
|
||||
Locale loc = Locale.of("", country);
|
||||
try {
|
||||
Currency currency = Currency.getInstance(loc);
|
||||
if (!currency.getCurrencyCode().equals(currencyCode)) {
|
||||
System.err.println("Error: [" + country + ":" +
|
||||
loc.getDisplayCountry() + "] expected: " + currencyCode +
|
||||
", got: " + currency.getCurrencyCode());
|
||||
err = true;
|
||||
}
|
||||
|
||||
if (codes[index] != UNDEFINED) {
|
||||
System.out.println("Warning: [" + country + ":" +
|
||||
loc.getDisplayCountry() +
|
||||
"] multiple definitions. currency code=" + currencyCode);
|
||||
}
|
||||
codes[index] = DEFINED;
|
||||
}
|
||||
catch (Exception e) {
|
||||
System.err.println("Error: " + e + ": Country=" + country);
|
||||
err = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void testCurrencyDefined(String currencyCode, int numericCode, int digits) {
|
||||
try {
|
||||
Currency currency = currency = Currency.getInstance(currencyCode);
|
||||
|
||||
if (currency.getNumericCode() != numericCode) {
|
||||
System.err.println("Error: [" + currencyCode + "] expected: " +
|
||||
numericCode + "; got: " + currency.getNumericCode());
|
||||
err = true;
|
||||
}
|
||||
|
||||
if (currency.getDefaultFractionDigits() != digits) {
|
||||
System.err.println("Error: [" + currencyCode + "] expected: " +
|
||||
digits + "; got: " + currency.getDefaultFractionDigits());
|
||||
err = true;
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
System.err.println("Error: " + e + ": Currency code=" +
|
||||
currencyCode);
|
||||
err = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void test2() {
|
||||
for (int i = 0; i < ALPHA_NUM; i++) {
|
||||
for (int j = 0; j < ALPHA_NUM; j++) {
|
||||
char[] code = new char[2];
|
||||
code[0] = (char)('A'+ i);
|
||||
code[1] = (char)('A'+ j);
|
||||
String country = new String(code);
|
||||
boolean ex;
|
||||
|
||||
if (codes[toIndex(country)] == UNDEFINED) {
|
||||
ex = false;
|
||||
try {
|
||||
Currency.getInstance(Locale.of("", country));
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
ex = true;
|
||||
}
|
||||
if (!ex) {
|
||||
System.err.println("Error: This should be an undefined code and throw IllegalArgumentException: " +
|
||||
country);
|
||||
err = true;
|
||||
}
|
||||
} else if (codes[toIndex(country)] == SKIPPED) {
|
||||
Currency cur = null;
|
||||
try {
|
||||
cur = Currency.getInstance(Locale.of("", country));
|
||||
}
|
||||
catch (Exception e) {
|
||||
System.err.println("Error: " + e + ": Country=" +
|
||||
country);
|
||||
err = true;
|
||||
}
|
||||
if (cur != null) {
|
||||
System.err.println("Error: Currency.getInstance() for an this locale should return null: " +
|
||||
country);
|
||||
err = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This test depends on test1(), where 'testCurrencies' set is constructed
|
||||
*/
|
||||
static void getAvailableCurrenciesTest() {
|
||||
Set<Currency> jreCurrencies = Currency.getAvailableCurrencies();
|
||||
|
||||
// add otherCodes
|
||||
// The previous set-up method populated most of testCurrencies. This
|
||||
// method finishes populating the list with 'otherCodes'.
|
||||
private static void setUpOtherCurrencies() {
|
||||
// Add otherCodes
|
||||
StringTokenizer st = new StringTokenizer(otherCodes, "-");
|
||||
while (st.hasMoreTokens()) {
|
||||
testCurrencies.add(Currency.getInstance(st.nextToken()));
|
||||
}
|
||||
}
|
||||
|
||||
if (!testCurrencies.containsAll(jreCurrencies)) {
|
||||
System.err.print("Error: getAvailableCurrencies() returned extra currencies than expected: ");
|
||||
jreCurrencies.removeAll(testCurrencies);
|
||||
for (Currency c : jreCurrencies) {
|
||||
System.err.print(" "+c);
|
||||
}
|
||||
System.err.println();
|
||||
err = true;
|
||||
// Check that the data file is up-to-date
|
||||
@Test
|
||||
public void dataVersionTest() {
|
||||
CheckDataVersion.check();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the JDK's ISO4217 data and ensures the values for getNumericCode(),
|
||||
* getDefaultFractionDigits(), and getCurrencyCode() are as expected.
|
||||
*/
|
||||
@ParameterizedTest
|
||||
@MethodSource({"ISO4217CodesProvider", "additionalCodesProvider"})
|
||||
public void countryCurrencyTest(String country, String currencyCode,
|
||||
int numericCode, int digits, int index) {
|
||||
currencyTest(currencyCode, numericCode, digits);
|
||||
countryTest(country, currencyCode);
|
||||
assertNotEquals(codes[index], TESTED,
|
||||
"Error: Re-testing a previously defined code, possible duplication");
|
||||
codes[index] = TESTED;
|
||||
}
|
||||
|
||||
// Test a Currency built from currencyCode
|
||||
private static void currencyTest(String currencyCode, int numericCode, int digits) {
|
||||
Currency currency = Currency.getInstance(currencyCode);
|
||||
assertEquals(currency.getNumericCode(), numericCode);
|
||||
assertEquals(currency.getDefaultFractionDigits(), digits);
|
||||
}
|
||||
|
||||
// Test a Currency built from country
|
||||
private static void countryTest(String country, String currencyCode) {
|
||||
Locale loc = Locale.of("", country);
|
||||
Currency currency = Currency.getInstance(loc);
|
||||
assertEquals(currency.getCurrencyCode(), currencyCode);
|
||||
}
|
||||
|
||||
private static List<Arguments> ISO4217CodesProvider() {
|
||||
return ISO4217Codes;
|
||||
}
|
||||
|
||||
private static List<Arguments> additionalCodesProvider() {
|
||||
return additionalCodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests trying to create a Currency from an invalid alpha-2 country either
|
||||
* throws an IllegalArgumentException or returns null. The test data
|
||||
* supplied is every possible combination of AA -> ZZ.
|
||||
*/
|
||||
@ParameterizedTest
|
||||
@MethodSource("codeCombos")
|
||||
public void twoLetterCodesTest(String country) {
|
||||
if (codes[toIndex(country)] == UNDEFINED) {
|
||||
// if a code is undefined / 0, creating a Currency from it
|
||||
// should throw an IllegalArgumentException
|
||||
assertThrows(IllegalArgumentException.class,
|
||||
()-> Currency.getInstance(Locale.of("", country)),
|
||||
"Error: This should be an undefined code and throw IllegalArgumentException: " + country);
|
||||
} else if (codes[toIndex(country)] == SKIPPED) {
|
||||
// if a code is marked as skipped / 2, creating a Currency from it
|
||||
// should return null
|
||||
assertNull(Currency.getInstance(Locale.of("", country)),
|
||||
"Error: Currency.getInstance() for this locale should return null: " + country);
|
||||
}
|
||||
}
|
||||
|
||||
// This method generates code combos from AA to ZZ
|
||||
private static List<String> codeCombos() {
|
||||
List<String> codeCombos = new ArrayList<>();
|
||||
for (int i = 0; i < ALPHA_NUM; i++) {
|
||||
for (int j = 0; j < ALPHA_NUM; j++) {
|
||||
char[] code = new char[2];
|
||||
code[0] = (char) ('A' + i);
|
||||
code[1] = (char) ('A' + j);
|
||||
codeCombos.add(new String(code));
|
||||
}
|
||||
}
|
||||
return codeCombos;
|
||||
}
|
||||
|
||||
// This method ensures that getAvailableCurrencies() returns
|
||||
// the expected amount of currencies.
|
||||
@Test
|
||||
public void getAvailableCurrenciesTest() {
|
||||
Set<Currency> jreCurrencies = Currency.getAvailableCurrencies();
|
||||
// Ensure that testCurrencies has all the JRE currency codes
|
||||
assertTrue(testCurrencies.containsAll(jreCurrencies),
|
||||
getSetDiffs(jreCurrencies, testCurrencies));
|
||||
}
|
||||
|
||||
private static String getSetDiffs(Set<Currency> jreCurrencies, Set<Currency> testCurrencies) {
|
||||
StringBuilder bldr = new StringBuilder();
|
||||
bldr.append("Error: getAvailableCurrencies() returned unexpected currencies: ");
|
||||
jreCurrencies.removeAll(testCurrencies);
|
||||
for (Currency curr : jreCurrencies) {
|
||||
bldr.append(" " + curr);
|
||||
}
|
||||
bldr.append("\n");
|
||||
return bldr.toString();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user