Path: blob/master/test/jdk/java/lang/String/SpecialCasingTest.java
41149 views
/*1* Copyright (c) 2018, 2019, 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. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425/*26* @test27* @bug 4397357 6565620 6959267 7070436 7198195 8041791 8032446 807260028* 822143129* @summary Confirm special case mappings are handled correctly.30* @library /lib/testlibrary/java/lang31*/3233import java.io.BufferedReader;34import java.io.IOException;35import java.nio.file.Files;36import java.nio.file.Paths;37import java.util.ArrayList;38import java.util.List;39import java.util.Locale;40import java.util.StringTokenizer;4142public class SpecialCasingTest {4344private static boolean err = false;4546// Locales which are used for testing47private static List<Locale> locales = new ArrayList<>();48static {49locales.add(new Locale("az", ""));50locales.addAll(java.util.Arrays.asList(Locale.getAvailableLocales()));51}5253// Default locale54private static String defaultLang;5556// True if the default language is az, lt, or tr which has locale-specific57// mappings.58private static boolean specificLocale;5960// Additional test cases61// Pseudo-locales which are used here:62// L1: locales other than lt63// L2: locales other than az and tr64// L3: locales other than az, lt and tr65private static final String[] additionalTestData = {66// Format:67// <code>; <lower>; <title>; <upper>; (<condition_list>)6869// Counterpart of Final_Sigma test case70// 03A3; 03C2; 03A3; 03A3; Final_Sigma71"03A3; 03C3; 03A3; 03A3; SunSpecific_Not_Final_Sigma1",72"03A3; 03C3; 03A3; 03A3; SunSpecific_Not_Final_Sigma2",7374// Counterpart of After_Soft_Dotted test case75// 0307; 0307; ; ; lt After_Soft_Dotted76"0307; 0307; 0307; 0307; L1 After_Soft_Dotted",77"0307; 0307; 0307; 0307; lt SunSpecific_Not_After_Soft_Dotted",78"0307; 0307; 0307; 0307; L1 SunSpecific_Not_After_Soft_Dotted",7980// Counterpart of More_Above test cases81// 0049; 0069 0307; 0049; 0049; lt More_Above82"0049; 0131 ; 0049; 0049; az More_Above",83"0049; 0131 ; 0049; 0049; tr More_Above",84"0049; 0069 ; 0049; 0049; L3 More_Above",85"0049; 0069 ; 0049; 0049; lt SunSpecific_Not_More_Above",86"0049; 0131 ; 0049; 0049; az SunSpecific_Not_More_Above",87"0049; 0131 ; 0049; 0049; tr SunSpecific_Not_More_Above",88"0049; 0069 ; 0049; 0049; L3 SunSpecific_Not_More_Above",89// 004A; 006A 0307; 004A; 004A; lt More_Above90"004A; 006A ; 004A; 004A; L1 More_Above",91"004A; 006A ; 004A; 004A; lt SunSpecific_Not_More_Above",92"004A; 006A ; 004A; 004A; L1 SunSpecific_Not_More_Above",93// 012E; 012F 0307; 012E; 012E; lt More_Above94"012E; 012F ; 012E; 012E; L1 More_Above",95"012E; 012F ; 012E; 012E; lt SunSpecific_Not_More_Above",96"012E; 012F ; 012E; 012E; L1 SunSpecific_Not_More_Above",9798// Counterpart of After_I test cases99// 0307; ; 0307; 0307; tr After_I100// 0307; ; 0307; 0307; az After_I101"0307; 0307 0307; 0307; 0307; lt After_I",102"0307; 0307 ; 0307; 0307; L3 After_I",103"0307; 0307 ; 0307; 0307; tr SunSpecific_Not_After_I",104"0307; 0307 ; 0307; 0307; az SunSpecific_Not_After_I",105"0307; 0307 ; 0307; 0307; L2 SunSpecific_Not_After_I",106107// Counterpart of Not_Before_Dot test cases108// 0049; 0131 ; 0049; 0049; tr Not_Before_Dot109// 0049; 0131 ; 0049; 0049; az Not_Before_Dot110"0049; 0069 ; 0049; 0049; L2 Not_Before_Dot",111"0049; 0069 ; 0049; 0049; tr SunSpecific_Before_Dot",112"0049; 0069 ; 0049; 0049; az SunSpecific_Before_Dot",113"0049; 0069 0307 0307; 0049; 0049; lt SunSpecific_Before_Dot",114"0049; 0069 0307 ; 0049; 0049; L3 SunSpecific_Before_Dot",115};116117public static void main (String[] args) {118SpecialCasingTest specialCasingTest = new SpecialCasingTest();119specialCasingTest.test();120}121122private void test () {123Locale defaultLocale = Locale.getDefault();124BufferedReader in = null;125126try {127int locale_num = locales.size();128for (int l = 0; l < locale_num; l++) {129Locale locale = locales.get(l);130Locale.setDefault(locale);131System.out.println("Testing on " + locale + " locale....");132133defaultLang = locale.getLanguage();134if (defaultLang.equals("az") ||135defaultLang.equals("lt") ||136defaultLang.equals("tr")) {137specificLocale = true;138} else {139specificLocale = false;140}141in = Files.newBufferedReader(UCDFiles.SPECIAL_CASING.toRealPath());142String line;143while ((line = in.readLine()) != null) {144if (line.length() == 0 || line.charAt(0) == '#') {145continue;146}147test(line);148}149in.close();150in = null;151System.out.println("Testing with Sun original data....");152for (String additionalTestData1 : additionalTestData) {153test(additionalTestData1);154}155}156}157catch (IOException e) {158err = true;159e.printStackTrace();160}161finally {162if (in != null) {163try {164in.close();165}166catch (IOException e) {167}168}169Locale.setDefault(defaultLocale);170if (err) {171throw new RuntimeException("SpecialCasingTest failed.");172} else {173System.out.println("*** SpecialCasingTest passed.");174}175}176}177178private void test(String line) {179int index = line.indexOf('#');180if (index != -1) {181line = line.substring(0, index);182}183184String lang = null;185String condition = null;186String[] fields = line.split("; ");187188for (int i = 0; i < 4; i++) {189if (fields[i].length() != 0) {190fields[i] = convert(fields[i]);191}192}193if (fields.length != 4) {194StringTokenizer st = new StringTokenizer(fields[4]);195196while (st.hasMoreTokens()) {197String token = st.nextToken();198199if (token.equals("Final_Sigma")) {200condition = "Final Sigma";201fields[0] = "Abc" + fields[0];202fields[1] = "abc" + fields[1];203fields[3] = "ABC" + fields[3];204} else if (token.equals("SunSpecific_Not_Final_Sigma1")) {205condition = "*Sun Specific* Not Final Sigma 1";206fields[0] = "Abc" + fields[0] + "xyz";207fields[1] = "abc" + fields[1] + "xyz";208fields[3] = "ABC" + fields[3] + "XYZ";209} else if (token.equals("SunSpecific_Not_Final_Sigma2")) {210condition = "*Sun Specific* Not Final Sigma 2";211} else if (token.equals("After_Soft_Dotted")) {212condition = "After Soft-Dotted";213fields[0] = "\u1E2D" + fields[0];214fields[1] = "\u1E2D" + fields[1];215fields[3] = "\u1E2C" + fields[3];216} else if (token.equals("SunSpecific_Not_After_Soft_Dotted")) {217condition = "*Sun Specific* Not After Soft-Dotted";218fields[0] = "Dot" + fields[0];219fields[1] = "dot" + fields[1];220fields[3] = "DOT" + fields[3];221} else if (token.equals("More_Above")) {222condition = "More Above";223fields[0] = fields[0] + "\u0306";224fields[1] = fields[1] + "\u0306";225fields[3] = fields[3] + "\u0306";226} else if (token.equals("SunSpecific_Not_More_Above")) {227condition = "*Sun Specific* Not More Above";228fields[0] = fields[0] + "breve";229fields[1] = fields[1] + "breve";230fields[3] = fields[3] + "BREVE";231} else if (token.equals("After_I")) {232condition = "After I";233fields[0] = "I" + fields[0];234fields[1] = "i" + fields[1];235fields[3] = "I" + fields[3];236} else if (token.equals("SunSpecific_Not_After_I")) {237condition = "*Sun Specific* Not After I";238fields[0] = "A" + fields[0];239fields[1] = "a" + fields[1];240fields[3] = "A" + fields[3];241} else if (token.equals("Not_Before_Dot")) {242condition = "Not Before Dot";243fields[0] = fields[0] + "Z";244fields[1] = fields[1] + "z";245fields[3] = fields[3] + "Z";246} else if (token.equals("SunSpecific_Before_Dot")) {247condition = "*Sun Specific* Before Dot";248fields[0] = fields[0] + "\u0307";249fields[3] = fields[3] + "\u0307";250} else if (token.length() == 2) {251lang = token;252253if (lang.equals("L1")) {254if (defaultLang.equals("lt")) {255lang = "en";256} else {257lang = defaultLang;258}259} else if (lang.equals("L2")) {260if (defaultLang.equals("az") ||261defaultLang.equals("tr")) {262lang = "en";263} else {264lang = defaultLang;265}266} else if (lang.equals("L3")) {267if (defaultLang.equals("az") ||268defaultLang.equals("lt") ||269defaultLang.equals("tr")) {270lang = "en";271} else {272lang = defaultLang;273}274// I want to have another test case here for double-check.275// Current implementation for Character and String considers276// only az, lt, and tr locales. I want to detect if other277// locales are specified.278} else if (!lang.equals("az") &&279!lang.equals("lt") &&280!lang.equals("tr")) {281throw new RuntimeException("Unsupported locale: " +282lang + ". It may need to be considered in ConditionalSpecialCasing.java. Please confirm.");283}284} else {285throw new RuntimeException("Unknown condition: " + token);286}287}288} else if (fields[0].equals("\u0130")) {289// special case for \u0130290if (defaultLang.equals("az") ||291defaultLang.equals("tr")) {292lang = "en";293} else {294lang = defaultLang;295}296}297testLowerCase(fields[0], fields[1], lang, condition);298testUpperCase(fields[0], fields[3], lang, condition);299}300301private void testLowerCase(String orig, String expected,302String lang, String condition) {303String got = (lang == null) ?304orig.toLowerCase() : orig.toLowerCase(new Locale(lang, ""));305306if (!expected.equals(got)) {307err = true;308System.err.println("toLowerCase(lang=" + lang +309") failed.\n\tOriginal: " + toString(orig) +310"\n\tGot: " + toString(got) +311"\n\tExpected: " + toString(expected) +312((condition == null) ? "" : ("\n under condition(" +313condition + ")")));314}315}316317private void testUpperCase(String orig, String expected,318String lang, String condition) {319String got = (lang == null) ?320orig.toUpperCase() : orig.toUpperCase(new Locale(lang, ""));321322if (!expected.equals(got)) {323err = true;324System.err.println("toUpperCase(lang=" + lang +325") failed.\n\tOriginal: " + toString(orig) +326"\n\tGot: " + toString(got) +327"\n\tExpected: " + toString(expected) +328((condition == null) ? "" : ("\n under condition(" +329condition + ")")));330}331}332StringBuilder sb = new StringBuilder();333334private String convert(String str) {335sb.setLength(0);336337String[] tokens = str.split(" ");338for (String token : tokens) {339sb.append((char) Integer.parseInt(token, 16));340}341return sb.toString();342}343344private String toString(String str) {345sb.setLength(0);346347int len = str.length();348for (int i = 0; i < len; i++) {349sb.append("0x").append(Integer.toHexString(str.charAt(i)).toUpperCase()).append(" ");350}351return sb.toString();352}353354}355356357