Home | History | Annotate | Download | only in util
      1 /*
      2  **********************************************************************
      3  * Copyright (c) 2002-2015, International Business Machines
      4  * Corporation and others.  All Rights Reserved.
      5  **********************************************************************
      6  * Author: Alan Liu
      7  * Created: December 18 2002
      8  * Since: ICU 2.4
      9  **********************************************************************
     10  */
     11 
     12 package com.ibm.icu.dev.test.util;
     13 
     14 import java.util.Arrays;
     15 import java.util.Date;
     16 import java.util.HashSet;
     17 import java.util.List;
     18 import java.util.Locale;
     19 import java.util.Set;
     20 
     21 import com.ibm.icu.dev.test.TestFmwk;
     22 import com.ibm.icu.dev.test.TestUtil;
     23 import com.ibm.icu.dev.test.TestUtil.JavaVendor;
     24 import com.ibm.icu.impl.CurrencyData;
     25 import com.ibm.icu.text.CurrencyDisplayNames;
     26 import com.ibm.icu.text.CurrencyMetaInfo;
     27 import com.ibm.icu.text.CurrencyMetaInfo.CurrencyFilter;
     28 import com.ibm.icu.text.CurrencyMetaInfo.CurrencyInfo;
     29 import com.ibm.icu.text.DateFormat;
     30 import com.ibm.icu.text.DecimalFormatSymbols;
     31 import com.ibm.icu.text.SimpleDateFormat;
     32 import com.ibm.icu.util.Currency;
     33 import com.ibm.icu.util.GregorianCalendar;
     34 import com.ibm.icu.util.TimeZone;
     35 import com.ibm.icu.util.ULocale;
     36 
     37 /**
     38  * @test
     39  * @summary General test of Currency
     40  */
     41 public class CurrencyTest extends TestFmwk {
     42 
     43     public static void main(String[] args) throws Exception {
     44         new CurrencyTest().run(args);
     45     }
     46 
     47     /**
     48      * Test of basic API.
     49      */
     50     public void TestAPI() {
     51         Currency usd = Currency.getInstance("USD");
     52         /*int hash = */usd.hashCode();
     53         Currency jpy = Currency.getInstance("JPY");
     54         if (usd.equals(jpy)) {
     55             errln("FAIL: USD == JPY");
     56         }
     57         if (usd.equals("abc")) {
     58             errln("FAIL: USD == (String)");
     59         }
     60         if (usd.equals(null)) {
     61             errln("FAIL: USD == (null)");
     62         }
     63         if (!usd.equals(usd)) {
     64             errln("FAIL: USD != USD");
     65         }
     66 
     67         try {
     68             Currency nullCurrency = Currency.getInstance((String)null);
     69             errln("FAIL: Expected getInstance(null) to throw "
     70                     + "a NullPointerException, but returned " + nullCurrency);
     71         } catch (NullPointerException npe) {
     72             logln("PASS: getInstance(null) threw a NullPointerException");
     73         }
     74 
     75         try {
     76             Currency bogusCurrency = Currency.getInstance("BOGUS");
     77             errln("FAIL: Expected getInstance(\"BOGUS\") to throw "
     78                     + "an IllegalArgumentException, but returned " + bogusCurrency);
     79         } catch (IllegalArgumentException iae) {
     80             logln("PASS: getInstance(\"BOGUS\") threw an IllegalArgumentException");
     81         }
     82 
     83         Locale[] avail = Currency.getAvailableLocales();
     84         if(avail==null){
     85             errln("FAIL: getAvailableLocales returned null");
     86         }
     87 
     88         try {
     89             usd.getName(ULocale.US, 5, new boolean[1]);
     90             errln("expected getName with invalid type parameter to throw exception");
     91         }
     92         catch (Exception e) {
     93             logln("PASS: getName failed as expected");
     94         }
     95     }
     96 
     97     /**
     98      * Test registration.
     99      */
    100     public void TestRegistration() {
    101         final Currency jpy = Currency.getInstance("JPY");
    102         final Currency usd = Currency.getInstance(Locale.US);
    103 
    104     try {
    105       Currency.unregister(null); // should fail, coverage
    106       errln("expected unregister of null to throw exception");
    107     }
    108     catch (Exception e) {
    109         logln("PASS: unregister of null failed as expected");
    110     }
    111 
    112     if (Currency.unregister("")) { // coverage
    113       errln("unregister before register erroneously succeeded");
    114     }
    115 
    116         ULocale fu_FU = new ULocale("fu_FU");
    117 
    118         Object key1 = Currency.registerInstance(jpy, ULocale.US);
    119         Object key2 = Currency.registerInstance(jpy, fu_FU);
    120 
    121         Currency nus = Currency.getInstance(Locale.US);
    122         if (!nus.equals(jpy)) {
    123             errln("expected " + jpy + " but got: " + nus);
    124         }
    125 
    126         // converage, make sure default factory works
    127         Currency nus1 = Currency.getInstance(Locale.JAPAN);
    128         if (!nus1.equals(jpy)) {
    129             errln("expected " + jpy + " but got: " + nus1);
    130         }
    131 
    132         ULocale[] locales = Currency.getAvailableULocales();
    133         boolean found = false;
    134         for (int i = 0; i < locales.length; ++i) {
    135             if (locales[i].equals(fu_FU)) {
    136                 found = true;
    137                 break;
    138             }
    139         }
    140         if (!found) {
    141             errln("did not find locale" + fu_FU + " in currency locales");
    142         }
    143 
    144         if (!Currency.unregister(key1)) {
    145             errln("unable to unregister currency using key1");
    146         }
    147         if (!Currency.unregister(key2)) {
    148             errln("unable to unregister currency using key2");
    149         }
    150 
    151         Currency nus2 = Currency.getInstance(Locale.US);
    152         if (!nus2.equals(usd)) {
    153             errln("expected " + usd + " but got: " + nus2);
    154         }
    155 
    156         locales = Currency.getAvailableULocales();
    157         found = false;
    158         for (int i = 0; i < locales.length; ++i) {
    159             if (locales[i].equals(fu_FU)) {
    160                 found = true;
    161                 break;
    162             }
    163         }
    164         if (found) {
    165             errln("found locale" + fu_FU + " in currency locales after unregister");
    166         }
    167 
    168         Locale[] locs = Currency.getAvailableLocales();
    169         found = false;
    170         for (int i = 0; i < locs.length; ++i) {
    171             if (locs[i].equals(fu_FU)) {
    172                 found = true;
    173                 break;
    174             }
    175         }
    176         if (found) {
    177             errln("found locale" + fu_FU + " in currency locales after unregister");
    178         }
    179     }
    180 
    181     /**
    182      * Test names.
    183      */
    184     public void TestNames() {
    185         // Do a basic check of getName()
    186         // USD { "US$", "US Dollar"            } // 04/04/1792-
    187         ULocale en = ULocale.ENGLISH;
    188         boolean[] isChoiceFormat = new boolean[1];
    189         Currency usd = Currency.getInstance("USD");
    190         // Warning: HARD-CODED LOCALE DATA in this test.  If it fails, CHECK
    191         // THE LOCALE DATA before diving into the code.
    192         if (!noData()) {
    193             assertEquals("USD.getName(SYMBOL_NAME)",
    194                          "$",
    195                          usd.getName(en, Currency.SYMBOL_NAME, isChoiceFormat));
    196             assertEquals("USD.getName(LONG_NAME)",
    197                          "US Dollar",
    198                          usd.getName(en, Currency.LONG_NAME, isChoiceFormat));
    199         }
    200         // TODO add more tests later
    201     }
    202 
    203     public void TestCoverage() {
    204         Currency usd = Currency.getInstance("USD");
    205         if (!noData()) {
    206         assertEquals("USD.getSymbol()",
    207                 "$",
    208                 usd.getSymbol());
    209         }
    210     }
    211 
    212     // A real test of the CurrencyDisplayNames class.
    213     public void TestCurrencyDisplayNames() {
    214         if (!CurrencyDisplayNames.hasData()) {
    215             errln("hasData() should return true.");
    216         }
    217 
    218         // with substitute
    219         CurrencyDisplayNames cdn = CurrencyDisplayNames.getInstance(ULocale.GERMANY);
    220         assertEquals("de_USD_name", "US-Dollar", cdn.getName("USD"));
    221         assertEquals("de_USD_symbol", "$", cdn.getSymbol("USD"));
    222         assertEquals("de_USD_plural_other", "US-Dollar", cdn.getPluralName("USD", "other"));
    223         // unknown plural category, substitute "other"
    224         assertEquals("de_USD_plural_foo", "US-Dollar", cdn.getPluralName("USD", "foo"));
    225 
    226         cdn = CurrencyDisplayNames.getInstance(ULocale.forLanguageTag("en-US"));
    227         assertEquals("en-US_USD_name", "US Dollar", cdn.getName("USD"));
    228         assertEquals("en-US_USD_symbol", "$", cdn.getSymbol("USD"));
    229         assertEquals("en-US_USD_plural_one", "US dollar", cdn.getPluralName("USD", "one"));
    230         assertEquals("en-US_USD_plural_other", "US dollars", cdn.getPluralName("USD", "other"));
    231 
    232         assertEquals("en-US_FOO_name", "FOO", cdn.getName("FOO"));
    233         assertEquals("en-US_FOO_symbol", "FOO", cdn.getSymbol("FOO"));
    234         assertEquals("en-US_FOO_plural_other", "FOO", cdn.getPluralName("FOO", "other"));
    235 
    236         assertEquals("en-US bundle", "en", cdn.getULocale().toString());
    237 
    238         cdn = CurrencyDisplayNames.getInstance(ULocale.forLanguageTag("zz-Gggg-YY"));
    239         assertEquals("bundle from current locale", "en", cdn.getULocale().toString());
    240 
    241         // with no substitute
    242         cdn = CurrencyDisplayNames.getInstance(ULocale.GERMANY, true);
    243         assertNotNull("have currency data for Germany", cdn);
    244 
    245         // known currency, behavior unchanged
    246         assertEquals("de_USD_name", "US-Dollar", cdn.getName("USD"));
    247         assertEquals("de_USD_symbol", "$", cdn.getSymbol("USD"));
    248         assertEquals("de_USD_plural_other", "US-Dollar", cdn.getPluralName("USD", "other"));
    249 
    250         // known currency but unknown plural category
    251         assertNull("de_USD_plural_foo", cdn.getPluralName("USD", "foo"));
    252 
    253         // unknown currency, get null
    254         assertNull("de_FOO_name", cdn.getName("FOO"));
    255         assertNull("de_FOO_symbol", cdn.getSymbol("FOO"));
    256         assertNull("de_FOO_plural_other", cdn.getPluralName("FOO", "other"));
    257         assertNull("de_FOO_plural_foo", cdn.getPluralName("FOO", "foo"));
    258 
    259         // unknown locale with no substitute
    260         cdn = CurrencyDisplayNames.getInstance(ULocale.forLanguageTag("zz-Gggg-YY"), true);
    261         String ln = "";
    262         if (cdn != null) {
    263             ln = " (" + cdn.getULocale().toString() + ")";
    264         }
    265         assertNull("no fallback from unknown locale" + ln , cdn);
    266 
    267         // Locale version
    268         cdn = CurrencyDisplayNames.getInstance(Locale.GERMANY, true);
    269         assertNotNull("have currency data for Germany (Java Locale)", cdn);
    270         assertEquals("de_USD_name (Locale)", "US-Dollar", cdn.getName("USD"));
    271         assertNull("de_FOO_name (Locale)", cdn.getName("FOO"));
    272     }
    273 
    274     // Coverage-only test of CurrencyData
    275     public void TestCurrencyData() {
    276         CurrencyData.DefaultInfo info_fallback = (CurrencyData.DefaultInfo)CurrencyData.DefaultInfo.getWithFallback(true);
    277         if (info_fallback == null) {
    278             errln("getWithFallback() returned null.");
    279             return;
    280         }
    281 
    282         CurrencyData.DefaultInfo info_nofallback = (CurrencyData.DefaultInfo)CurrencyData.DefaultInfo.getWithFallback(false);
    283         if (info_nofallback == null) {
    284             errln("getWithFallback() returned null.");
    285             return;
    286         }
    287 
    288         if (!info_fallback.getName("isoCode").equals("isoCode") || info_nofallback.getName("isoCode") != null) {
    289             errln("Error calling getName().");
    290             return;
    291         }
    292 
    293         if (!info_fallback.getPluralName("isoCode", "type").equals("isoCode") || info_nofallback.getPluralName("isoCode", "type") != null) {
    294             errln("Error calling getPluralName().");
    295             return;
    296         }
    297 
    298         if (!info_fallback.getSymbol("isoCode").equals("isoCode") || info_nofallback.getSymbol("isoCode") != null) {
    299             errln("Error calling getSymbol().");
    300             return;
    301         }
    302 
    303         if (!info_fallback.symbolMap().isEmpty()) {
    304             errln("symbolMap() should return empty map.");
    305             return;
    306         }
    307 
    308         if (!info_fallback.nameMap().isEmpty()) {
    309             errln("nameMap() should return empty map.");
    310             return;
    311         }
    312 
    313         if (!info_fallback.getUnitPatterns().isEmpty() || info_nofallback.getUnitPatterns() != null) {
    314             errln("Error calling getUnitPatterns().");
    315             return;
    316         }
    317 
    318         if (!info_fallback.getSpacingInfo().equals((CurrencyData.CurrencySpacingInfo.DEFAULT)) ||
    319                 info_nofallback.getSpacingInfo() != null) {
    320             errln("Error calling getSpacingInfo().");
    321             return;
    322         }
    323 
    324         if (info_fallback.getULocale() != ULocale.ROOT) {
    325             errln("Error calling getLocale().");
    326             return;
    327         }
    328 
    329         if (info_fallback.getFormatInfo("isoCode") != null) {
    330             errln("Error calling getFormatInfo().");
    331             return;
    332         }
    333     }
    334 
    335     // A real test of CurrencyMetaInfo.
    336     public void testCurrencyMetaInfoRanges() {
    337         CurrencyMetaInfo metainfo = CurrencyMetaInfo.getInstance(true);
    338         assertNotNull("have metainfo", metainfo);
    339 
    340         CurrencyFilter filter = CurrencyFilter.onRegion("DE"); // must be capitalized
    341         List<CurrencyInfo> currenciesInGermany = metainfo.currencyInfo(filter);
    342         logln("currencies: " + currenciesInGermany.size());
    343         DateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS z");
    344         fmt.setTimeZone(TimeZone.getTimeZone("GMT"));
    345         Date demLastDate = new Date(Long.MAX_VALUE);
    346         Date eurFirstDate = new Date(Long.MIN_VALUE);
    347         for (CurrencyInfo info : currenciesInGermany) {
    348             logln(info.toString());
    349             logln("from: " + fmt.format(info.from)+ Long.toHexString(info.from));
    350             logln("  to: " + fmt.format(info.to) + Long.toHexString(info.to));
    351             if (info.code.equals("DEM")) {
    352                 demLastDate = new Date(info.to);
    353             } else if (info.code.equals("EUR")) {
    354                 eurFirstDate = new Date(info.from);
    355             }
    356         }
    357 
    358         // the Euro and Deutschmark overlapped for several years
    359         assertEquals("DEM available at last date", 2, metainfo.currencyInfo(filter.withDate(demLastDate)).size());
    360 
    361         // demLastDate + 1 millisecond is not the start of the last day, we consider it the next day, so...
    362         Date demLastDatePlus1ms = new Date(demLastDate.getTime() + 1);
    363         assertEquals("DEM not available after very start of last date", 1, metainfo.currencyInfo(filter.withDate(demLastDatePlus1ms)).size());
    364 
    365         // both available for start of euro
    366         assertEquals("EUR available on start of first date", 2, metainfo.currencyInfo(filter.withDate(eurFirstDate)).size());
    367 
    368         // but not one millisecond before the start of the first day
    369         Date eurFirstDateMinus1ms = new Date(eurFirstDate.getTime() - 1);
    370         assertEquals("EUR not avilable before very start of first date", 1, metainfo.currencyInfo(filter.withDate(eurFirstDateMinus1ms)).size());
    371 
    372         // end time is last millisecond of day
    373         GregorianCalendar cal = new GregorianCalendar();
    374         cal.setTimeZone(TimeZone.getTimeZone("GMT"));
    375         cal.setTime(demLastDate);
    376         assertEquals("hour is 23", 23, cal.get(GregorianCalendar.HOUR_OF_DAY));
    377         assertEquals("minute is 59", 59, cal.get(GregorianCalendar.MINUTE));
    378         assertEquals("second is 59", 59, cal.get(GregorianCalendar.SECOND));
    379         assertEquals("millisecond is 999", 999, cal.get(GregorianCalendar.MILLISECOND));
    380 
    381         // start time is first millisecond of day
    382         cal.setTime(eurFirstDate);
    383         assertEquals("hour is 0", 0, cal.get(GregorianCalendar.HOUR_OF_DAY));
    384         assertEquals("minute is 0", 0, cal.get(GregorianCalendar.MINUTE));
    385         assertEquals("second is 0", 0, cal.get(GregorianCalendar.SECOND));
    386         assertEquals("millisecond is 0", 0, cal.get(GregorianCalendar.MILLISECOND));
    387     }
    388 
    389     public void testCurrencyMetaInfoRangesWithLongs() {
    390         CurrencyMetaInfo metainfo = CurrencyMetaInfo.getInstance(true);
    391         assertNotNull("have metainfo", metainfo);
    392 
    393         CurrencyFilter filter = CurrencyFilter.onRegion("DE"); // must be capitalized
    394         List<CurrencyInfo> currenciesInGermany = metainfo.currencyInfo(filter);
    395         logln("currencies: " + currenciesInGermany.size());
    396         long demLastDate = Long.MAX_VALUE;
    397         long eurFirstDate = Long.MIN_VALUE;
    398         for (CurrencyInfo info : currenciesInGermany) {
    399             logln(info.toString());
    400             if (info.code.equals("DEM")) {
    401                 demLastDate = info.to;
    402             } else if (info.code.equals("EUR")) {
    403                 eurFirstDate = info.from;
    404             }
    405         }
    406         // the Euro and Deutschmark overlapped for several years
    407         assertEquals("DEM available at last date", 2, metainfo.currencyInfo(filter.withDate(demLastDate)).size());
    408 
    409         // demLastDate + 1 millisecond is not the start of the last day, we consider it the next day, so...
    410         long demLastDatePlus1ms = demLastDate + 1;
    411         assertEquals("DEM not available after very start of last date", 1, metainfo.currencyInfo(filter.withDate(demLastDatePlus1ms)).size());
    412 
    413         // both available for start of euro
    414         assertEquals("EUR available on start of first date", 2, metainfo.currencyInfo(filter.withDate(eurFirstDate)).size());
    415 
    416         // but not one millisecond before the start of the first day
    417         long eurFirstDateMinus1ms = eurFirstDate - 1;
    418         assertEquals("EUR not avilable before very start of first date", 1, metainfo.currencyInfo(filter.withDate(eurFirstDateMinus1ms)).size());
    419     }
    420 
    421     public void TestWithTender() {
    422         CurrencyMetaInfo metainfo = CurrencyMetaInfo.getInstance();
    423         if (metainfo == null) {
    424             errln("Unable to get CurrencyMetaInfo instance.");
    425             return;
    426         }
    427         CurrencyMetaInfo.CurrencyFilter filter =
    428                 CurrencyMetaInfo.CurrencyFilter.onRegion("CH");
    429         List<String> currencies = metainfo.currencies(filter);
    430         assertTrue("More than one currency for switzerland", currencies.size() > 1);
    431         assertEquals(
    432                 "With tender",
    433                 Arrays.asList(new String[] {"CHF", "CHE", "CHW"}),
    434                 metainfo.currencies(filter.withTender()));
    435     }
    436 
    437     // Coverage-only test of the CurrencyMetaInfo class
    438     public void TestCurrencyMetaInfo() {
    439         CurrencyMetaInfo metainfo = CurrencyMetaInfo.getInstance();
    440         if (metainfo == null) {
    441             errln("Unable to get CurrencyMetaInfo instance.");
    442             return;
    443         }
    444 
    445         if (!CurrencyMetaInfo.hasData()) {
    446             errln("hasData() should note return false.");
    447             return;
    448         }
    449 
    450         CurrencyMetaInfo.CurrencyFilter filter;
    451         CurrencyMetaInfo.CurrencyInfo info;
    452         CurrencyMetaInfo.CurrencyDigits digits;
    453 
    454         { // CurrencyFilter
    455             filter = CurrencyMetaInfo.CurrencyFilter.onCurrency("currency");
    456             CurrencyMetaInfo.CurrencyFilter filter2 = CurrencyMetaInfo.CurrencyFilter.onCurrency("test");
    457             if (filter == null) {
    458                 errln("Unable to create CurrencyFilter.");
    459                 return;
    460             }
    461 
    462             if (filter.equals(new Object())) {
    463                 errln("filter should not equal to Object");
    464                 return;
    465             }
    466 
    467             if (filter.equals(filter2)) {
    468                 errln("filter should not equal filter2");
    469                 return;
    470             }
    471 
    472             if (filter.hashCode() == 0) {
    473                 errln("Error getting filter hashcode");
    474                 return;
    475             }
    476 
    477             if (filter.toString() == null) {
    478                 errln("Error calling toString()");
    479                 return;
    480             }
    481         }
    482 
    483         { // CurrencyInfo
    484             info = new CurrencyMetaInfo.CurrencyInfo("region", "code", 0, 1, 1, false);
    485             if (info == null) {
    486                 errln("Error creating CurrencyInfo.");
    487                 return;
    488             }
    489 
    490             if (info.toString() == null) {
    491                 errln("Error calling toString()");
    492                 return;
    493             }
    494         }
    495 
    496         { // CurrencyDigits
    497             digits = metainfo.currencyDigits("isoCode");
    498             if (digits == null) {
    499                 errln("Unable to get CurrencyDigits.");
    500                 return;
    501             }
    502 
    503             if (digits.toString() == null) {
    504                 errln("Error calling toString()");
    505                 return;
    506             }
    507         }
    508     }
    509 
    510     public void TestCurrencyKeyword() {
    511         ULocale locale = new ULocale("th_TH@collation=traditional;currency=QQQ");
    512         Currency currency = Currency.getInstance(locale);
    513         String result = currency.getCurrencyCode();
    514         if (!"QQQ".equals(result)) {
    515             errln("got unexpected currency: " + result);
    516         }
    517     }
    518 
    519     public void TestAvailableCurrencyCodes() {
    520         String[][] tests = {
    521             { "eo_AM", "1950-01-05" },
    522             { "eo_AM", "1969-12-31", "SUR" },
    523             { "eo_AM", "1991-12-26", "RUR" },
    524             { "eo_AM", "2000-12-23", "AMD" },
    525             { "eo_AD", "2000-12-23", "EUR", "ESP", "FRF", "ADP" },
    526             { "eo_AD", "1969-12-31", "ESP", "FRF", "ADP" },
    527             { "eo_AD", "1950-01-05", "ESP", "ADP" },
    528             { "eo_AD", "1900-01-17", "ESP" },
    529             { "eo_UA", "1994-12-25" },
    530             { "eo_QQ", "1969-12-31" },
    531             { "eo_AO", "2000-12-23", "AOA" },
    532             { "eo_AO", "1995-12-25", "AOR", "AON" },
    533             { "eo_AO", "1990-12-26", "AON", "AOK" },
    534             { "eo_AO", "1979-12-29", "AOK" },
    535             { "eo_AO", "1969-12-31" },
    536             { "eo_DE@currency=DEM", "2000-12-23", "EUR", "DEM" },
    537             { "eo-DE-u-cu-dem", "2000-12-23", "EUR", "DEM" },
    538             { "en_US", null, "USD", "USN" },
    539             { "en_US_PREEURO", null, "USD", "USN" },
    540             { "en_US_Q", null, "USD", "USN" },
    541         };
    542 
    543         DateFormat fmt = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
    544         for (String[] test : tests) {
    545             ULocale locale = new ULocale(test[0]);
    546             String timeString = test[1];
    547             Date date;
    548             if (timeString == null) {
    549                 date = new Date();
    550                 timeString = "today";
    551             } else {
    552                 try {
    553                     date = fmt.parse(timeString);
    554                 } catch (Exception e) {
    555                     fail("could not parse date: " + timeString);
    556                     continue;
    557                 }
    558             }
    559             String[] expected = null;
    560             if (test.length > 2) {
    561                 expected = new String[test.length - 2];
    562                 System.arraycopy(test, 2, expected, 0, expected.length);
    563             }
    564             String[] actual = Currency.getAvailableCurrencyCodes(locale, date);
    565 
    566             // Order is not important as of 4.4.  We never documented that it was.
    567             Set<String> expectedSet = new HashSet<String>();
    568             if (expected != null) {
    569                 expectedSet.addAll(Arrays.asList(expected));
    570             }
    571             Set<String> actualSet = new HashSet<String>();
    572             if (actual != null) {
    573                 actualSet.addAll(Arrays.asList(actual));
    574             }
    575             assertEquals(locale + " on " + timeString, expectedSet, actualSet);
    576 
    577             // With Java Locale
    578             // Note: skip this test on Java 6 or older when keywords are available
    579             if (locale.getKeywords() == null || TestUtil.getJavaVendor() == JavaVendor.Android || TestUtil.getJavaVersion() >= 7) {
    580                 Locale javaloc = locale.toLocale();
    581                 String[] actualWithJavaLocale = Currency.getAvailableCurrencyCodes(javaloc, date);
    582                 // should be exactly same with the ULocale version
    583                 boolean same = true;
    584                 if (actual == null) {
    585                     if (actualWithJavaLocale != null) {
    586                         same = false;
    587                     }
    588                 } else {
    589                     if (actualWithJavaLocale == null || actual.length != actualWithJavaLocale.length) {
    590                         same = false;
    591                     } else {
    592                         same = true;
    593                         for (int i = 0; i < actual.length; i++) {
    594                             if (!actual[i].equals(actualWithJavaLocale[i])) {
    595                                 same = false;
    596                                 break;
    597                             }
    598                         }
    599                     }
    600                 }
    601                 assertTrue("getAvailableCurrencyCodes with ULocale vs Locale", same);
    602             }
    603         }
    604     }
    605 
    606     public void TestDeprecatedCurrencyFormat() {
    607         // bug 5952
    608         Locale locale = new Locale("sr", "QQ");
    609         DecimalFormatSymbols icuSymbols = new
    610         com.ibm.icu.text.DecimalFormatSymbols(locale);
    611         String symbol = icuSymbols.getCurrencySymbol();
    612         Currency currency = icuSymbols.getCurrency();
    613         String expectCur = null;
    614         String expectSym = "\u00A4";
    615         if(!symbol.toString().equals(expectSym) || currency != null) {
    616             errln("for " + locale + " expected " + expectSym+"/"+expectCur + " but got " + symbol+"/"+currency);
    617         } else {
    618             logln("for " + locale + " expected " + expectSym+"/"+expectCur + " and got " + symbol+"/"+currency);
    619         }
    620     }
    621 
    622     public void TestGetKeywordValues(){
    623 
    624         final String[][] PREFERRED = {
    625             {"root",                 },
    626             {"und",                  },
    627             {"und_ZZ",          "XAG", "XAU", "XBA", "XBB", "XBC", "XBD", "XDR", "XPD", "XPT", "XSU", "XTS", "XUA", "XXX"},
    628             {"en_US",           "USD", "USN"},
    629             {"en_029",               },
    630             {"en_TH",           "THB"},
    631             {"de",              "EUR"},
    632             {"de_DE",           "EUR"},
    633             {"de_ZZ",           "XAG", "XAU", "XBA", "XBB", "XBC", "XBD", "XDR", "XPD", "XPT", "XSU", "XTS", "XUA", "XXX"},
    634             {"ar",              "EGP"},
    635             {"ar_PS",           "ILS", "JOD"},
    636             {"en@currency=CAD",     "USD", "USN"},
    637             {"fr@currency=ZZZ",     "EUR"},
    638             {"de_DE@currency=DEM",  "EUR"},
    639         };
    640 
    641         String[] ALL = Currency.getKeywordValuesForLocale("currency", ULocale.getDefault(), false);
    642         HashSet ALLSET = new HashSet();
    643         for (int i = 0; i < ALL.length; i++) {
    644             ALLSET.add(ALL[i]);
    645         }
    646 
    647         for (int i = 0; i < PREFERRED.length; i++) {
    648             ULocale loc = new ULocale(PREFERRED[i][0]);
    649             String[] expected = new String[PREFERRED[i].length - 1];
    650             System.arraycopy(PREFERRED[i], 1, expected, 0, expected.length);
    651             String[] pref = Currency.getKeywordValuesForLocale("currency", loc, true);
    652             assertEquals(loc.toString(), expected, pref);
    653 
    654             String[] all = Currency.getKeywordValuesForLocale("currency", loc, false);
    655             // The items in the two collections should match (ignore order,
    656             // behavior change from 4.3.3)
    657             Set<String> returnedSet = new HashSet<String>();
    658             returnedSet.addAll(Arrays.asList(all));
    659             assertEquals(loc.toString(), ALLSET, returnedSet);
    660         }
    661     }
    662 
    663     public void TestIsAvailable() {
    664         Date d1995 = new Date(788918400000L);   // 1995-01-01 00:00 GMT
    665         Date d2000 = new Date(946684800000L);   // 2000-01-01 00:00 GMT
    666         Date d2005 = new Date(1104537600000L);  // 2005-01-01 00:00 GMT
    667 
    668         assertTrue("USD all time", Currency.isAvailable("USD", null, null));
    669         assertTrue("USD before 1995", Currency.isAvailable("USD", null, d1995));
    670         assertTrue("USD 1995-2005", Currency.isAvailable("USD", d1995, d2005));
    671         assertTrue("USD after 2005", Currency.isAvailable("USD", d2005, null));
    672         assertTrue("USD on 2005-01-01", Currency.isAvailable("USD", d2005, d2005));
    673 
    674         assertTrue("usd all time", Currency.isAvailable("usd", null, null));
    675 
    676         assertTrue("DEM all time", Currency.isAvailable("DEM", null, null));
    677         assertTrue("DEM before 1995", Currency.isAvailable("DEM", null, d1995));
    678         assertTrue("DEM 1995-2000", Currency.isAvailable("DEM", d1995, d2000));
    679         assertTrue("DEM 1995-2005", Currency.isAvailable("DEM", d1995, d2005));
    680         assertFalse("DEM after 2005", Currency.isAvailable("DEM", d2005, null));
    681         assertTrue("DEM on 2000-01-01", Currency.isAvailable("DEM", d2000, d2000));
    682         assertFalse("DEM on 2005-01-01", Currency.isAvailable("DEM", d2005, d2005));
    683         assertTrue("CHE all the time", Currency.isAvailable("CHE", null, null));
    684 
    685         assertFalse("XXY unknown code", Currency.isAvailable("XXY", null, null));
    686 
    687         assertFalse("USDOLLAR invalid code", Currency.isAvailable("USDOLLAR", null, null));
    688 
    689         // illegal argument combination
    690         try {
    691             Currency.isAvailable("USD", d2005, d1995);
    692             errln("Expected IllegalArgumentException, because lower range is after upper range");
    693         } catch (IllegalArgumentException e) {
    694             logln("IllegalArgumentException, because lower range is after upper range");
    695         }
    696     }
    697 
    698     /**
    699      * Test case for getAvailableCurrencies()
    700      */
    701     public void TestGetAvailableCurrencies() {
    702         Set<Currency> avail1 = Currency.getAvailableCurrencies();
    703 
    704         // returned set must be modifiable - add one more currency
    705         avail1.add(Currency.getInstance("ZZZ"));    // ZZZ is not defined by ISO 4217
    706 
    707         Set<Currency> avail2 = Currency.getAvailableCurrencies();
    708         assertTrue("avail1 does not contain all currencies in avail2", avail1.containsAll(avail2));
    709         assertTrue("avail1 must have one more currency", (avail1.size() - avail2.size() == 1));
    710     }
    711 
    712     /**
    713      * Test case for getNumericCode()
    714      */
    715     public void TestGetNumericCode() {
    716         final Object[][] NUMCODE_TESTDATA = {
    717             {"USD", 840},
    718             {"Usd", 840},   /* mixed casing */
    719             {"EUR", 978},
    720             {"JPY", 392},
    721             {"XFU", 0},     /* XFU: no numeric code */
    722             {"ZZZ", 0},     /* ZZZ: undefined ISO currency code */
    723         };
    724 
    725         for (Object[] data : NUMCODE_TESTDATA) {
    726             Currency cur = Currency.getInstance((String)data[0]);
    727             int numCode = cur.getNumericCode();
    728             int expected = ((Integer)data[1]).intValue();
    729             if (numCode != expected) {
    730                 errln("FAIL: getNumericCode returned " + numCode + " for "
    731                         + cur.getCurrencyCode() + " - expected: " + expected);
    732             }
    733         }
    734     }
    735 
    736     /**
    737      * Test case for getDisplayName()
    738      */
    739     public void TestGetDisplayName() {
    740         final String[][] DISPNAME_TESTDATA = {
    741             {"USD", "US Dollar"},
    742             {"EUR", "Euro"},
    743             {"JPY", "Japanese Yen"},
    744         };
    745 
    746         Locale defLocale = Locale.getDefault();
    747         Locale jaJP = new Locale("ja", "JP");
    748         Locale root = new Locale("");
    749 
    750         for (String[] data : DISPNAME_TESTDATA) {
    751             Currency cur = Currency.getInstance(data[0]);
    752             assertEquals("getDisplayName() for " + data[0], data[1], cur.getDisplayName());
    753             assertEquals("getDisplayName() for " + data[0] + " in locale " + defLocale, data[1], cur.getDisplayName(defLocale));
    754 
    755             // ICU has localized display name for ja
    756             assertNotEquals("getDisplayName() for " + data[0] + " in locale " + jaJP, data[1], cur.getDisplayName(jaJP));
    757 
    758             // root locale does not have any localized display names,
    759             // so the currency code itself should be returned
    760             assertEquals("getDisplayName() for " + data[0] + " in locale " + root, data[0], cur.getDisplayName(root));
    761         }
    762     }
    763 
    764     public void TestCurrencyInfoCtor() {
    765         new CurrencyMetaInfo.CurrencyInfo("region", "code", 0, 0, 1);
    766     }
    767 }
    768