Path: blob/master/test/jdk/java/util/Currency/CurrencyTest.java
66644 views
/*1* Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/22/*23* @test24* @bug 4290801 4692419 4693631 5101540 5104960 6296410 6336600 637153125* 6488442 7036905 8008577 8039317 8074350 8074351 8150324 816714326* 826479227* @summary Basic tests for Currency class.28* @modules java.base/java.util:open29* jdk.localedata30*/3132import java.io.ByteArrayInputStream;33import java.io.ByteArrayOutputStream;34import java.io.ObjectInputStream;35import java.io.ObjectOutputStream;36import java.time.LocalDate;37import java.time.LocalTime;38import java.time.ZoneId;39import java.time.ZonedDateTime;40import java.util.Currency;41import java.util.Locale;424344public class CurrencyTest {4546public static void main(String[] args) throws Exception {47CheckDataVersion.check();48testCurrencyCodeValidation();49testLocaleMapping();50testSymbols();51testFractionDigits();52testSerialization();53testDisplayNames();54testFundsCodes();55}5657static void testCurrencyCodeValidation() {58// test creation of some valid currencies59testValidCurrency("USD");60testValidCurrency("EUR");61testValidCurrency("GBP");62testValidCurrency("JPY");63testValidCurrency("CNY");64testValidCurrency("CHF");6566// test creation of some fictitious currencies67testInvalidCurrency("AQD");68testInvalidCurrency("US$");69testInvalidCurrency("\u20AC");70}7172static void testValidCurrency(String currencyCode) {73Currency currency1 = Currency.getInstance(currencyCode);74Currency currency2 = Currency.getInstance(currencyCode);75if (currency1 != currency2) {76throw new RuntimeException("Didn't get same instance for same currency code");77}78if (!currency1.getCurrencyCode().equals(currencyCode)) {79throw new RuntimeException("Currency code changed");80}81}8283static void testInvalidCurrency(String currencyCode) {84boolean gotException = false;85try {86Currency currency = Currency.getInstance(currencyCode);87} catch (IllegalArgumentException e) {88gotException = true;89}90if (!gotException) {91throw new RuntimeException("didn't get specified exception");92}93}9495static void testLocaleMapping() {96// very basic test: most countries have their own currency, and then97// their currency code is an extension of their country code.98Locale[] locales = Locale.getAvailableLocales();99int goodCountries = 0;100int ownCurrencies = 0;101for (int i = 0; i < locales.length; i++) {102Locale locale = locales[i];103String ctryCode = locale.getCountry();104int ctryLength = ctryCode.length();105if (ctryLength == 0 ||106ctryLength == 3 || // UN M.49 code107ctryCode.matches("AA|Q[M-Z]|X[A-JL-Z]|ZZ" + // user defined codes, excluding "XK" (Kosovo)108"AC|CP|DG|EA|EU|FX|IC|SU|TA|UK")) { // exceptional reservation codes109boolean gotException = false;110try {111Currency.getInstance(locale);112} catch (IllegalArgumentException e) {113gotException = true;114}115if (!gotException) {116throw new RuntimeException("didn't get specified exception");117}118} else {119goodCountries++;120Currency currency = Currency.getInstance(locale);121if (currency.getCurrencyCode().indexOf(locale.getCountry()) == 0) {122ownCurrencies++;123}124}125}126System.out.println("Countries tested: " + goodCountries +127", own currencies: " + ownCurrencies);128if (ownCurrencies < (goodCountries / 2 + 1)) {129throw new RuntimeException("suspicious: not enough countries have their own currency.");130}131132// check a few countries that don't change their currencies too often133String[] country1 = {"US", "CA", "JP", "CN", "SG", "CH"};134String[] currency1 = {"USD", "CAD", "JPY", "CNY", "SGD", "CHF"};135for (int i = 0; i < country1.length; i++) {136checkCountryCurrency(country1[i], currency1[i]);137}138139/*140* check currency changes141* In current implementation, there is no data of old currency and transition date at jdk/make/data/currency/CurrencyData.properties.142* So, all the switch data arrays are empty. In the future, if data of old currency and transition date are necessary for any country, the143* arrays here can be updated so that the program can check the currency switch.144*/145String[] switchOverCtry = {};146String[] switchOverOld = {};147String[] switchOverNew = {};148String[] switchOverTZ = {};149int[] switchOverYear = {};150int[] switchOverMonth = {}; // java.time APIs accept month starting from 1 i.e. 01 for January151int[] switchOverDay = {};152153for (int i = 0; i < switchOverCtry.length; i++) {154ZoneId zoneId = ZoneId.of(switchOverTZ[i]);155ZonedDateTime zonedDateAndTime = ZonedDateTime.of(LocalDate.of(switchOverYear[i], switchOverMonth[i], switchOverDay[i]),156LocalTime.MIDNIGHT, zoneId);157ZonedDateTime currentZonedDateAndTime = ZonedDateTime.now(zoneId);158checkCountryCurrency(switchOverCtry[i], (currentZonedDateAndTime.isAfter(zonedDateAndTime) ||159currentZonedDateAndTime.isEqual(zonedDateAndTime)) ? switchOverNew[i] : switchOverOld[i]);160}161162// check a country code which doesn't have a currency163checkCountryCurrency("AQ", null);164165// check an invalid country code166boolean gotException = false;167try {168Currency.getInstance(new Locale("", "EU"));169} catch (IllegalArgumentException e) {170gotException = true;171}172if (!gotException) {173throw new RuntimeException("didn't get specified exception.");174}175}176177static void checkCountryCurrency(String countryCode, String expected) {178Locale locale = new Locale("", countryCode);179Currency currency = Currency.getInstance(locale);180String code = (currency != null) ? currency.getCurrencyCode() : null;181if (!(expected == null ? code == null : expected.equals(code))) {182throw new RuntimeException("Wrong currency for " +183locale.getDisplayCountry() +184": expected " + expected + ", got " + code);185}186}187188static void testSymbols() {189testSymbol("USD", Locale.US, "$");190testSymbol("EUR", Locale.GERMANY, "\u20AC");191testSymbol("USD", Locale.PRC, "US$");192}193194static void testSymbol(String currencyCode, Locale locale, String expectedSymbol) {195String symbol = Currency.getInstance(currencyCode).getSymbol(locale);196if (!symbol.equals(expectedSymbol)) {197throw new RuntimeException("Wrong symbol for currency " +198currencyCode +": expected " + expectedSymbol +199", got " + symbol);200}201}202203static void testFractionDigits() {204testFractionDigits("USD", 2);205testFractionDigits("EUR", 2);206testFractionDigits("JPY", 0);207testFractionDigits("XDR", -1);208209testFractionDigits("BHD", 3);210testFractionDigits("IQD", 3);211testFractionDigits("JOD", 3);212testFractionDigits("KWD", 3);213testFractionDigits("LYD", 3);214testFractionDigits("OMR", 3);215testFractionDigits("TND", 3);216217// Turkish Lira218testFractionDigits("TRL", 0);219testFractionDigits("TRY", 2);220}221222static void testFractionDigits(String currencyCode, int expectedFractionDigits) {223int digits = Currency.getInstance(currencyCode).getDefaultFractionDigits();224if (digits != expectedFractionDigits) {225throw new RuntimeException("Wrong number of fraction digits for currency " +226currencyCode +": expected " + expectedFractionDigits +227", got " + digits);228}229}230231static void testSerialization() throws Exception {232Currency currency1 = Currency.getInstance("DEM");233234ByteArrayOutputStream baos = new ByteArrayOutputStream();235ObjectOutputStream oStream = new ObjectOutputStream(baos);236oStream.writeObject(currency1);237oStream.flush();238byte[] bytes = baos.toByteArray();239240ByteArrayInputStream bais = new ByteArrayInputStream(bytes);241ObjectInputStream iStream = new ObjectInputStream(bais);242Currency currency2 = (Currency) iStream.readObject();243244if (currency1 != currency2) {245throw new RuntimeException("serialization breaks class invariant");246}247}248249static void testDisplayNames() {250// null argument test251try {252testDisplayName("USD", null, "");253throw new RuntimeException("getDisplayName(NULL) did not throw an NPE.");254} catch (NullPointerException npe) {}255256testDisplayName("USD", Locale.ENGLISH, "US Dollar");257testDisplayName("FRF", Locale.FRENCH, "franc fran\u00e7ais");258testDisplayName("DEM", Locale.GERMAN, "Deutsche Mark");259testDisplayName("ESP", new Locale("es"), "peseta espa\u00f1ola");260testDisplayName("ITL", new Locale("it"), "lira italiana");261testDisplayName("JPY", Locale.JAPANESE, "\u65e5\u672c\u5186");262testDisplayName("KRW", Locale.KOREAN, "\ub300\ud55c\ubbfc\uad6d \uc6d0");263testDisplayName("SEK", new Locale("sv"), "svensk krona");264testDisplayName("CNY", Locale.SIMPLIFIED_CHINESE, "\u4eba\u6c11\u5e01");265testDisplayName("TWD", Locale.TRADITIONAL_CHINESE, "\u65b0\u53f0\u5e63");266}267268static void testDisplayName(String currencyCode, Locale locale, String expectedName) {269String name = Currency.getInstance(currencyCode).getDisplayName(locale);270if (!name.equals(expectedName)) {271throw new RuntimeException("Wrong display name for currency " +272currencyCode +": expected '" + expectedName +273"', got '" + name + "'");274}275}276static void testFundsCodes() {277testValidCurrency("BOV");278testValidCurrency("CHE");279testValidCurrency("CHW");280testValidCurrency("CLF");281testValidCurrency("COU");282testValidCurrency("MXV");283testValidCurrency("USN");284testValidCurrency("UYI");285286testFractionDigits("BOV", 2);287testFractionDigits("CHE", 2);288testFractionDigits("CHW", 2);289testFractionDigits("CLF", 4);290testFractionDigits("COU", 2);291testFractionDigits("MXV", 2);292testFractionDigits("USN", 2);293testFractionDigits("UYI", 0);294295testNumericCode("BOV", 984);296testNumericCode("CHE", 947);297testNumericCode("CHW", 948);298testNumericCode("CLF", 990);299testNumericCode("COU", 970);300testNumericCode("MXV", 979);301testNumericCode("USN", 997);302testNumericCode("UYI", 940);303}304305static void testNumericCode(String currencyCode, int expectedNumeric) {306int numeric = Currency.getInstance(currencyCode).getNumericCode();307if (numeric != expectedNumeric) {308throw new RuntimeException("Wrong numeric code for currency " +309currencyCode +": expected " + expectedNumeric +310", got " + numeric);311}312}313}314315316