blob: 8bdbed414af6a15920cfd78a8ae55e5a2e831ec3 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright (c) 2007 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 */
23/*
24 * @test
25 * @bug 4290801 4692419 4693631 5101540 5104960 6296410 6336600 6371531
26 * 6488442
27 * @summary Basic tests for Currency class.
28 */
29
30import java.io.ByteArrayInputStream;
31import java.io.ByteArrayOutputStream;
32import java.io.ObjectInputStream;
33import java.io.ObjectOutputStream;
34import java.util.Calendar;
35import java.util.Date;
36import java.util.Currency;
37import java.util.GregorianCalendar;
38import java.util.Locale;
39import java.util.TimeZone;
40
41
42public class CurrencyTest {
43
44 public static void main(String[] args) throws Exception {
45 CheckDataVersion.check();
46 testCurrencyCodeValidation();
47 testLocaleMapping();
48 testSymbols();
49 testFractionDigits();
50 testSerialization();
51 testDisplayNames();
52 }
53
54 static void testCurrencyCodeValidation() {
55 // test creation of some valid currencies
56 testValidCurrency("USD");
57 testValidCurrency("EUR");
58 testValidCurrency("GBP");
59 testValidCurrency("JPY");
60 testValidCurrency("CNY");
61 testValidCurrency("CHF");
62
63 // test creation of some fictitious currencies
64 testInvalidCurrency("AQD");
65 testInvalidCurrency("US$");
66 testInvalidCurrency("\u20AC");
67 }
68
69 static void testValidCurrency(String currencyCode) {
70 Currency currency1 = Currency.getInstance(currencyCode);
71 Currency currency2 = Currency.getInstance(currencyCode);
72 if (currency1 != currency2) {
73 throw new RuntimeException("Didn't get same instance for same currency code");
74 }
75 if (!currency1.getCurrencyCode().equals(currencyCode)) {
76 throw new RuntimeException("Currency code changed");
77 }
78 }
79
80 static void testInvalidCurrency(String currencyCode) {
81 boolean gotException = false;
82 try {
83 Currency currency = Currency.getInstance(currencyCode);
84 } catch (IllegalArgumentException e) {
85 gotException = true;
86 }
87 if (!gotException) {
88 throw new RuntimeException("didn't get specified exception");
89 }
90 }
91
92 static void testLocaleMapping() {
93 // very basic test: most countries have their own currency, and then
94 // their currency code is an extension of their country code.
95 Locale[] locales = Locale.getAvailableLocales();
96 int goodCountries = 0;
97 int ownCurrencies = 0;
98 for (int i = 0; i < locales.length; i++) {
99 Locale locale = locales[i];
100 if (locale.getCountry().length() == 0) {
101 boolean gotException = false;
102 try {
103 Currency.getInstance(locale);
104 } catch (IllegalArgumentException e) {
105 gotException = true;
106 }
107 if (!gotException) {
108 throw new RuntimeException("didn't get specified exception");
109 }
110 } else {
111 goodCountries++;
112 Currency currency = Currency.getInstance(locale);
113 if (currency.getCurrencyCode().indexOf(locale.getCountry()) == 0) {
114 ownCurrencies++;
115 }
116 }
117 }
118 System.out.println("Countries tested: " + goodCountries +
119 ", own currencies: " + ownCurrencies);
120 if (ownCurrencies < (goodCountries / 2 + 1)) {
121 throw new RuntimeException("suspicious: not enough countries have their own currency.");
122 }
123
124 // check a few countries that don't change their currencies too often
125 String[] country1 = {"US", "CA", "JP", "CN", "SG", "CH"};
126 String[] currency1 = {"USD", "CAD", "JPY", "CNY", "SGD", "CHF"};
127 for (int i = 0; i < country1.length; i++) {
128 checkCountryCurrency(country1[i], currency1[i]);
129 }
130
131 // check currency changes
132 String[] switchOverCtry = {"DE", "FR", "ES", "IT", "NL", "BE", "TR", "RO", "AZ", "MZ", "GH", "VE"};
133 String[] switchOverOld = {"DEM", "FRF", "ESP", "ITL", "NLG", "BEF", "TRL", "ROL", "AZM", "MZM", "GHC", "VEB"};
134 String[] switchOverNew = {"EUR", "EUR", "EUR", "EUR", "EUR", "EUR", "TRY", "RON", "AZN", "MZN", "GHS", "VEF"};
135 String[] switchOverTZ = {"Europe/Paris", "Europe/Paris", "Europe/Paris", "Europe/Paris",
136 "Europe/Paris", "Europe/Paris", "Asia/Istanbul", "Europe/Bucharest",
137 "Asia/Baku", "Africa/Maputo", "Africa/Accra", "America/Caracas"};
138 int[] switchOverYear = {2002, 2002, 2002, 2002, 2002, 2002, 2005, 2005, 2006, 2006, 2007, 2008};
139 int[] switchOverMonth = {Calendar.JANUARY, Calendar.JANUARY, Calendar.JANUARY, Calendar.JANUARY,
140 Calendar.JANUARY, Calendar.JANUARY, Calendar.JANUARY, Calendar.JULY,
141 Calendar.JANUARY, Calendar.JULY, Calendar.JULY, Calendar.JANUARY};
142 int[] switchOverDay = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
143 for (int i = 0; i < switchOverCtry.length; i++) {
144 TimeZone.setDefault(TimeZone.getTimeZone(switchOverTZ[i]));
145 Calendar date = new GregorianCalendar(switchOverYear[i], switchOverMonth[i], switchOverDay[i]);
146 long switchOver = date.getTime().getTime();
147 boolean switchedOver = System.currentTimeMillis() >= switchOver;
148 checkCountryCurrency(switchOverCtry[i], switchedOver ? switchOverNew[i] : switchOverOld[i]);
149 }
150
151 // check a country code which doesn't have a currency
152 checkCountryCurrency("AQ", null);
153
154 // check an invalid country code
155 boolean gotException = false;
156 try {
157 Currency.getInstance(new Locale("", "EU"));
158 } catch (IllegalArgumentException e) {
159 gotException = true;
160 }
161 if (!gotException) {
162 throw new RuntimeException("didn't get specified exception.");
163 }
164 }
165
166 static void checkCountryCurrency(String countryCode, String expected) {
167 Locale locale = new Locale("", countryCode);
168 Currency currency = Currency.getInstance(locale);
169 String code = (currency != null) ? currency.getCurrencyCode() : null;
170 if (!(expected == null ? code == null : expected.equals(code))) {
171 throw new RuntimeException("Wrong currency for " +
172 locale.getDisplayCountry() +
173 ": expected " + expected + ", got " + code);
174 }
175 }
176
177 static void testSymbols() {
178 testSymbol("USD", Locale.US, "$");
179 testSymbol("EUR", Locale.GERMANY, "\u20AC");
180 testSymbol("USD", Locale.PRC, "USD");
181 }
182
183 static void testSymbol(String currencyCode, Locale locale, String expectedSymbol) {
184 String symbol = Currency.getInstance(currencyCode).getSymbol(locale);
185 if (!symbol.equals(expectedSymbol)) {
186 throw new RuntimeException("Wrong symbol for currency " +
187 currencyCode +": expected " + expectedSymbol +
188 ", got " + symbol);
189 }
190 }
191
192 static void testFractionDigits() {
193 testFractionDigits("USD", 2);
194 testFractionDigits("EUR", 2);
195 testFractionDigits("JPY", 0);
196 testFractionDigits("XDR", -1);
197
198 testFractionDigits("BHD", 3);
199 testFractionDigits("IQD", 3);
200 testFractionDigits("JOD", 3);
201 testFractionDigits("KWD", 3);
202 testFractionDigits("LYD", 3);
203 testFractionDigits("OMR", 3);
204 testFractionDigits("TND", 3);
205
206 // Turkish Lira
207 testFractionDigits("TRL", 0);
208 testFractionDigits("TRY", 2);
209 }
210
211 static void testFractionDigits(String currencyCode, int expectedFractionDigits) {
212 int digits = Currency.getInstance(currencyCode).getDefaultFractionDigits();
213 if (digits != expectedFractionDigits) {
214 throw new RuntimeException("Wrong number of fraction digits for currency " +
215 currencyCode +": expected " + expectedFractionDigits +
216 ", got " + digits);
217 }
218 }
219
220 static void testSerialization() throws Exception {
221 Currency currency1 = Currency.getInstance("DEM");
222
223 ByteArrayOutputStream baos = new ByteArrayOutputStream();
224 ObjectOutputStream oStream = new ObjectOutputStream(baos);
225 oStream.writeObject(currency1);
226 oStream.flush();
227 byte[] bytes = baos.toByteArray();
228
229 ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
230 ObjectInputStream iStream = new ObjectInputStream(bais);
231 Currency currency2 = (Currency) iStream.readObject();
232
233 if (currency1 != currency2) {
234 throw new RuntimeException("serialization breaks class invariant");
235 }
236 }
237
238 static void testDisplayNames() {
239 // null argument test
240 try {
241 testDisplayName("USD", null, "");
242 throw new RuntimeException("getDisplayName(NULL) did not throw an NPE.");
243 } catch (NullPointerException npe) {}
244
245 testDisplayName("USD", Locale.ENGLISH, "US Dollar");
246 testDisplayName("FRF", Locale.FRENCH, "franc fran\u00e7ais");
247 testDisplayName("DEM", Locale.GERMAN, "Deutsche Mark");
248 testDisplayName("ESP", new Locale("es"), "peseta espa\u00f1ola");
249 testDisplayName("ITL", new Locale("it"), "Lira Italiana");
250 testDisplayName("JPY", Locale.JAPANESE, "\u65e5\u672c\u5186");
251 testDisplayName("KRW", Locale.KOREAN, "\ub300\ud55c\ubbfc\uad6d \uc6d0");
252 testDisplayName("SEK", new Locale("sv"), "Svensk krona");
253 testDisplayName("CNY", Locale.SIMPLIFIED_CHINESE, "\u4eba\u6c11\u5e01");
254 testDisplayName("TWD", Locale.TRADITIONAL_CHINESE, "\u65b0\u81fa\u5e63");
255 }
256
257 static void testDisplayName(String currencyCode, Locale locale, String expectedName) {
258 String name = Currency.getInstance(currencyCode).getDisplayName(locale);
259 if (!name.equals(expectedName)) {
260 throw new RuntimeException("Wrong display name for currency " +
261 currencyCode +": expected '" + expectedName +
262 "', got '" + name + "'");
263 }
264 }
265
266}