1 /*
   2  * Copyright (c) 2017, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25  *
  26  * @test
  27  * @bug 8176841
  28  * @summary Tests *Format class deals with Unicode extensions
  29  *      correctly.
  30  * @modules jdk.localedata
  31  * @run testng/othervm -Djava.locale.providers=CLDR FormatTests
  32  */
  33 
  34 import static org.testng.Assert.assertEquals;
  35 
  36 import java.text.DateFormat;
  37 import java.text.NumberFormat;
  38 import java.util.Calendar;
  39 import java.util.Date;
  40 import java.util.Locale;
  41 import java.util.TimeZone;
  42 
  43 import org.testng.annotations.AfterTest;
  44 import org.testng.annotations.BeforeTest;
  45 import org.testng.annotations.DataProvider;
  46 import org.testng.annotations.Test;
  47 
  48 /**
  49  * Test *Format classes with BCP47 U extensions
  50  */
  51 @Test
  52 public class FormatTests {
  53     private static TimeZone defaultTZ;
  54 
  55     private static final TimeZone ASIATOKYO = TimeZone.getTimeZone("Asia/Tokyo");
  56     private static final TimeZone AMLA = TimeZone.getTimeZone("America/Los_Angeles");
  57 
  58     private static final Locale JPTYO = Locale.forLanguageTag("en-u-tz-jptyo");
  59     private static final Locale JCAL = Locale.forLanguageTag("en-u-ca-japanese");
  60     private static final Locale USLAX = Locale.forLanguageTag("en-u-tz-uslax");
  61 
  62     private static final Locale RG_GB = Locale.forLanguageTag("en-US-u-rg-gbzzzz");
  63     private static final Locale RG_DE = Locale.forLanguageTag("en-US-u-rg-dezzzz");
  64     
  65     private static final Locale NU_DEVA = Locale.forLanguageTag("en-US-u-nu-deva");
  66     private static final Locale NU_SINH = Locale.forLanguageTag("en-US-u-nu-sinh");
  67     private static final Locale NU_ZZZZ = Locale.forLanguageTag("en-US-u-nu-zzzz");
  68 
  69     private static final double testNum = 12345.6789;
  70     private static final String NUM_US = "12,345.6789";
  71     private static final String NUM_DE = "12.345,6789";
  72     private static final String NUM_DEVA = "\u0967\u0968,\u0969\u096a\u096b.\u096c\u096d\u096e\u096f";
  73     private static final String NUM_SINH = "\u0de7\u0de8,\u0de9\u0dea\u0deb.\u0dec\u0ded\u0dee\u0def";
  74 
  75     private static final Date testDate = new Calendar.Builder()
  76                                         .setDate(2017, 7, 10)
  77                                         .setTimeOfDay(15, 15, 0)
  78                                         .setTimeZone(AMLA)
  79                                         .build()
  80                                         .getTime();
  81 
  82     @BeforeTest
  83     public void beforeTest() {
  84         defaultTZ = TimeZone.getDefault();
  85         TimeZone.setDefault(AMLA);
  86     }
  87 
  88     @AfterTest
  89     public void afterTest() {
  90         TimeZone.setDefault(defaultTZ);
  91     }
  92 
  93     @DataProvider(name="dateFormatData")
  94     Object[][] dateFormatData() {
  95         return new Object[][] {
  96             // Locale, Expected calendar, Expected timezone, Expected formatted string
  97 
  98             // -ca
  99             {JCAL, "java.util.JapaneseImperialCalendar", null,
 100             "Thursday, August 10, 29 Heisei at 3:15:00 PM Pacific Daylight Time"
 101             },
 102 
 103             // -tz
 104             {JPTYO, null, ASIATOKYO,
 105             "Friday, August 11, 2017 at 7:15:00 AM Japan Standard Time"
 106             },
 107             {USLAX, null, AMLA,
 108             "Thursday, August 10, 2017 at 3:15:00 PM Pacific Daylight Time"
 109             },
 110 
 111             // -rg
 112             {RG_GB, null, null,
 113             "Thursday, 10 August 2017 at 15:15:00 Pacific Daylight Time"
 114             },
 115         };
 116     }
 117 
 118     @DataProvider(name="numberFormatData")
 119     Object[][] numberFormatData() {
 120         return new Object[][] {
 121             // Locale, number, expected format
 122 
 123             // -nu
 124             {NU_DEVA, testNum, NUM_DEVA},
 125             {NU_SINH, testNum, NUM_SINH},
 126             {NU_ZZZZ, testNum, NUM_US},
 127 
 128             // -rg
 129             {RG_DE, testNum, NUM_DE},
 130 
 131             // -nu & -rg, valid & invalid
 132             {Locale.forLanguageTag("en-US-u-nu-deva-rg-dezzzz"), testNum, NUM_DEVA},
 133             {Locale.forLanguageTag("en-US-u-nu-zzzz-rg-dezzzz"), testNum, NUM_US},
 134             {Locale.forLanguageTag("en-US-u-nu-zzzz-rg-zzzz"), testNum, NUM_US},
 135         };
 136     }
 137 
 138     @Test(dataProvider="dateFormatData")
 139     public void test_DateFormat(Locale locale, String calClass, TimeZone tz,
 140                                 String formatExpected) throws Exception {
 141         DateFormat df = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, locale);
 142         if (calClass != null) {
 143             try {
 144                 Class expected = Class.forName(calClass);
 145             assertEquals(df.getCalendar().getClass(), expected);
 146             } catch (Exception e) {
 147                 throw e;
 148             }
 149         }
 150         if (tz != null) {
 151             assertEquals(df.getTimeZone(), tz);
 152         }
 153         String formatted = df.format(testDate);
 154         assertEquals(formatted, formatExpected);
 155         assertEquals(df.parse(formatted), testDate);
 156     }
 157 
 158     @Test(dataProvider="numberFormatData")
 159     public void test_NumberFormat(Locale locale, double num, 
 160                                 String formatExpected) throws Exception {
 161         NumberFormat nf = NumberFormat.getNumberInstance(locale);
 162         nf.setMaximumFractionDigits(4);
 163         String formatted = nf.format(num);
 164         assertEquals(nf.format(num), formatExpected);
 165         assertEquals(nf.parse(formatted), num);
 166     }
 167 }