8060094: java/util/Formatter/Basic.java failed in tr locale

Reviewed-by: naoto
This commit is contained in:
Nishit Jain 2018-02-26 11:16:24 +05:30
parent 5d3e5d9275
commit 3f5b571b5a
2 changed files with 102 additions and 57 deletions

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -284,11 +284,11 @@ import jdk.internal.math.FormattedFloatingDecimal;
* {@code 'A'}, and {@code 'T'}) are the same as those for the corresponding * {@code 'A'}, and {@code 'T'}) are the same as those for the corresponding
* lower-case conversion characters except that the result is converted to * lower-case conversion characters except that the result is converted to
* upper case according to the rules of the prevailing {@link java.util.Locale * upper case according to the rules of the prevailing {@link java.util.Locale
* Locale}. The result is equivalent to the following invocation of {@link * Locale}. If there is no explicit locale specified, either at the
* String#toUpperCase(Locale)} * construction of the instance or as a parameter to its method
* invocation, then the {@link java.util.Locale.Category#FORMAT default locale}
* is used.
* *
* <pre>
* out.toUpperCase(Locale.getDefault(Locale.Category.FORMAT)) </pre>
* *
* <table class="striped"> * <table class="striped">
* <caption style="display:none">genConv</caption> * <caption style="display:none">genConv</caption>
@ -709,11 +709,10 @@ import jdk.internal.math.FormattedFloatingDecimal;
* {@code 'G'}, {@code 'A'}, and {@code 'T'}) are the same as those for the * {@code 'G'}, {@code 'A'}, and {@code 'T'}) are the same as those for the
* corresponding lower-case conversion characters except that the result is * corresponding lower-case conversion characters except that the result is
* converted to upper case according to the rules of the prevailing {@link * converted to upper case according to the rules of the prevailing {@link
* java.util.Locale Locale}. The result is equivalent to the following * java.util.Locale Locale}. If there is no explicit locale specified,
* invocation of {@link String#toUpperCase(Locale)} * either at the construction of the instance or as a parameter to its method
* * invocation, then the {@link java.util.Locale.Category#FORMAT default locale}
* <pre> * is used.
* out.toUpperCase(Locale.getDefault(Locale.Category.FORMAT)) </pre>
* *
* <h4><a id="dgen">General</a></h4> * <h4><a id="dgen">General</a></h4>
* *
@ -2897,16 +2896,16 @@ public final class Formatter implements Closeable, Flushable {
break; break;
case Conversion.CHARACTER: case Conversion.CHARACTER:
case Conversion.CHARACTER_UPPER: case Conversion.CHARACTER_UPPER:
printCharacter(arg); printCharacter(arg, l);
break; break;
case Conversion.BOOLEAN: case Conversion.BOOLEAN:
printBoolean(arg); printBoolean(arg, l);
break; break;
case Conversion.STRING: case Conversion.STRING:
printString(arg, l); printString(arg, l);
break; break;
case Conversion.HASHCODE: case Conversion.HASHCODE:
printHashCode(arg); printHashCode(arg, l);
break; break;
case Conversion.LINE_SEPARATOR: case Conversion.LINE_SEPARATOR:
a.append(System.lineSeparator()); a.append(System.lineSeparator());
@ -2921,7 +2920,7 @@ public final class Formatter implements Closeable, Flushable {
private void printInteger(Object arg, Locale l) throws IOException { private void printInteger(Object arg, Locale l) throws IOException {
if (arg == null) if (arg == null)
print("null"); print("null", l);
else if (arg instanceof Byte) else if (arg instanceof Byte)
print(((Byte)arg).byteValue(), l); print(((Byte)arg).byteValue(), l);
else if (arg instanceof Short) else if (arg instanceof Short)
@ -2938,7 +2937,7 @@ public final class Formatter implements Closeable, Flushable {
private void printFloat(Object arg, Locale l) throws IOException { private void printFloat(Object arg, Locale l) throws IOException {
if (arg == null) if (arg == null)
print("null"); print("null", l);
else if (arg instanceof Float) else if (arg instanceof Float)
print(((Float)arg).floatValue(), l); print(((Float)arg).floatValue(), l);
else if (arg instanceof Double) else if (arg instanceof Double)
@ -2951,7 +2950,7 @@ public final class Formatter implements Closeable, Flushable {
private void printDateTime(Object arg, Locale l) throws IOException { private void printDateTime(Object arg, Locale l) throws IOException {
if (arg == null) { if (arg == null) {
print("null"); print("null", l);
return; return;
} }
Calendar cal = null; Calendar cal = null;
@ -2982,9 +2981,9 @@ public final class Formatter implements Closeable, Flushable {
print(cal, c, l); print(cal, c, l);
} }
private void printCharacter(Object arg) throws IOException { private void printCharacter(Object arg, Locale l) throws IOException {
if (arg == null) { if (arg == null) {
print("null"); print("null", l);
return; return;
} }
String s = null; String s = null;
@ -3011,7 +3010,7 @@ public final class Formatter implements Closeable, Flushable {
} else { } else {
failConversion(c, arg); failConversion(c, arg);
} }
print(s); print(s, l);
} }
private void printString(Object arg, Locale l) throws IOException { private void printString(Object arg, Locale l) throws IOException {
@ -3024,13 +3023,13 @@ public final class Formatter implements Closeable, Flushable {
if (f.contains(Flags.ALTERNATE)) if (f.contains(Flags.ALTERNATE))
failMismatch(Flags.ALTERNATE, 's'); failMismatch(Flags.ALTERNATE, 's');
if (arg == null) if (arg == null)
print("null"); print("null", l);
else else
print(arg.toString()); print(arg.toString(), l);
} }
} }
private void printBoolean(Object arg) throws IOException { private void printBoolean(Object arg, Locale l) throws IOException {
String s; String s;
if (arg != null) if (arg != null)
s = ((arg instanceof Boolean) s = ((arg instanceof Boolean)
@ -3038,24 +3037,29 @@ public final class Formatter implements Closeable, Flushable {
: Boolean.toString(true)); : Boolean.toString(true));
else else
s = Boolean.toString(false); s = Boolean.toString(false);
print(s); print(s, l);
} }
private void printHashCode(Object arg) throws IOException { private void printHashCode(Object arg, Locale l) throws IOException {
String s = (arg == null String s = (arg == null
? "null" ? "null"
: Integer.toHexString(arg.hashCode())); : Integer.toHexString(arg.hashCode()));
print(s); print(s, l);
} }
private void print(String s) throws IOException { private void print(String s, Locale l) throws IOException {
if (precision != -1 && precision < s.length()) if (precision != -1 && precision < s.length())
s = s.substring(0, precision); s = s.substring(0, precision);
if (f.contains(Flags.UPPERCASE)) if (f.contains(Flags.UPPERCASE))
s = s.toUpperCase(Locale.getDefault(Locale.Category.FORMAT)); s = toUpperCaseWithLocale(s, l);
appendJustified(a, s); appendJustified(a, s);
} }
private String toUpperCaseWithLocale(String s, Locale l) {
return s.toUpperCase(Objects.requireNonNullElse(l,
Locale.getDefault(Locale.Category.FORMAT)));
}
private Appendable appendJustified(Appendable a, CharSequence cs) throws IOException { private Appendable appendJustified(Appendable a, CharSequence cs) throws IOException {
if (width == -1) { if (width == -1) {
return a.append(cs); return a.append(cs);
@ -3276,7 +3280,7 @@ public final class Formatter implements Closeable, Flushable {
trailingZeros(sb, width - len); trailingZeros(sb, width - len);
} }
if (f.contains(Flags.UPPERCASE)) if (f.contains(Flags.UPPERCASE))
s = s.toUpperCase(Locale.getDefault(Locale.Category.FORMAT)); s = toUpperCaseWithLocale(s, l);
sb.append(s); sb.append(s);
} }
@ -3351,7 +3355,7 @@ public final class Formatter implements Closeable, Flushable {
trailingZeros(sb, width - len); trailingZeros(sb, width - len);
} }
if (f.contains(Flags.UPPERCASE)) if (f.contains(Flags.UPPERCASE))
s = s.toUpperCase(Locale.getDefault(Locale.Category.FORMAT)); s = toUpperCaseWithLocale(s, l);
sb.append(s); sb.append(s);
} }
@ -3950,7 +3954,7 @@ public final class Formatter implements Closeable, Flushable {
// justify based on width // justify based on width
if (f.contains(Flags.UPPERCASE)) { if (f.contains(Flags.UPPERCASE)) {
appendJustified(a, sb.toString().toUpperCase(Locale.getDefault(Locale.Category.FORMAT))); appendJustified(a, toUpperCaseWithLocale(sb.toString(), l));
} else { } else {
appendJustified(a, sb); appendJustified(a, sb);
} }
@ -4132,8 +4136,7 @@ public final class Formatter implements Closeable, Flushable {
StringBuilder tsb = new StringBuilder(); StringBuilder tsb = new StringBuilder();
print(tsb, t, DateTime.AM_PM, l); print(tsb, t, DateTime.AM_PM, l);
sb.append(tsb.toString().toUpperCase(Objects.requireNonNullElse(l, sb.append(toUpperCaseWithLocale(tsb.toString(), l));
Locale.getDefault(Locale.Category.FORMAT))));
break; break;
} }
case DateTime.DATE_TIME: { // 'c' (Sat Nov 04 12:02:33 EST 1999) case DateTime.DATE_TIME: { // 'c' (Sat Nov 04 12:02:33 EST 1999)
@ -4171,7 +4174,7 @@ public final class Formatter implements Closeable, Flushable {
print(sb, t, c, l); print(sb, t, c, l);
// justify based on width // justify based on width
if (f.contains(Flags.UPPERCASE)) { if (f.contains(Flags.UPPERCASE)) {
appendJustified(a, sb.toString().toUpperCase(Locale.getDefault(Locale.Category.FORMAT))); appendJustified(a, toUpperCaseWithLocale(sb.toString(), l));
} else { } else {
appendJustified(a, sb); appendJustified(a, sb);
} }
@ -4373,8 +4376,7 @@ public final class Formatter implements Closeable, Flushable {
// this may be in wrong place for some locales // this may be in wrong place for some locales
StringBuilder tsb = new StringBuilder(); StringBuilder tsb = new StringBuilder();
print(tsb, t, DateTime.AM_PM, l); print(tsb, t, DateTime.AM_PM, l);
sb.append(tsb.toString().toUpperCase(Objects.requireNonNullElse(l, sb.append(toUpperCaseWithLocale(tsb.toString(), l));
Locale.getDefault(Locale.Category.FORMAT))));
break; break;
} }
case DateTime.DATE_TIME: { // 'c' (Sat Nov 04 12:02:33 EST 1999) case DateTime.DATE_TIME: { // 'c' (Sat Nov 04 12:02:33 EST 1999)

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -23,9 +23,12 @@
/** /**
* @test * @test
* @bug 8146156 8159548 * @bug 8146156 8159548 8060094
* @modules jdk.localedata * @modules jdk.localedata
* @summary test whether uppercasing follows Locale.Category.FORMAT locale. * @summary test whether uppercasing follows Locale.Category.FORMAT locale.
* Also test whether the uppercasing uses the locale specified to the
* Formatter API.
*
* @run main/othervm FormatLocale * @run main/othervm FormatLocale
*/ */
@ -38,7 +41,6 @@ import java.util.Formatter;
import java.util.GregorianCalendar; import java.util.GregorianCalendar;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Locale.Category;
import java.util.TimeZone; import java.util.TimeZone;
import java.util.stream.IntStream; import java.util.stream.IntStream;
@ -50,40 +52,81 @@ public class FormatLocale {
"%S", "%S",
"%S", "%S",
"%TB", "%TB",
"%G"); "%G",
"%C");
static final List<Object> src = List.of( static final List<Object> src = List.of(
"Turkish", "Turkish",
"Turkish", "Turkish",
LocalDate.of(2016, Month.APRIL, 1), LocalDate.of(2016, Month.APRIL, 1),
Float.valueOf(100_000_000)); Float.valueOf(100_000_000),
'i');
static final List<Locale> defaultLocale = List.of(
Locale.ENGLISH,
TURKISH,
TURKISH,
Locale.FRANCE,
TURKISH);
static final List<Locale> formatLocale = List.of( static final List<Locale> formatLocale = List.of(
Locale.ENGLISH, TURKISH,
TURKISH, Locale.ENGLISH,
TURKISH, Locale.FRANCE,
Locale.FRANCE); Locale.ENGLISH,
static final List<String> expected = List.of( Locale.ENGLISH);
"TURKISH",
"TURK\u0130SH", static final List<String> expectedWithDefaultLocale = List.of(
"N\u0130SAN", "TURKISH",
"1,00000E+08"); "TURK\u0130SH",
"N\u0130SAN",
"1,00000E+08",
"\u0130");
static final List<String> expectedWithFormatLocale = List.of(
"TURK\u0130SH",
"TURKISH",
"AVRIL",
"1.00000E+08",
"I");
static void formatLocaleTest() { static void formatLocaleTest() {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
// checks whether upper casing follows Locale.Category.FORMAT locale
IntStream.range(0, src.size()).forEach(i -> { IntStream.range(0, src.size()).forEach(i -> {
sb.setLength(0); sb.setLength(0);
Locale.setDefault(Locale.Category.FORMAT, formatLocale.get(i)); Locale.setDefault(Locale.Category.FORMAT, defaultLocale.get(i));
new Formatter(sb).format(conversions.get(i), src.get(i)); new Formatter(sb).format(conversions.get(i), src.get(i));
if (!sb.toString().equals(expected.get(i))) { if (!sb.toString().equals(expectedWithDefaultLocale.get(i))) {
throw new RuntimeException( throw new RuntimeException(
"Wrong uppercasing with Formatter.format(" + "Wrong uppercasing while using Formatter.format(" +
"\"" + conversions.get(i) + "\"" + "\"" + conversions.get(i) + "\"" +
") in locale " ") with the default locale: '"
+ formatLocale.get(i) + + defaultLocale.get(i) +
". Expected: " + expected.get(i) + "'. Expected: " + expectedWithDefaultLocale.get(i) +
" Returned: " + sb.toString()); " Returned: " + sb.toString());
} }
}); });
// checks whether upper casing uses the locale set during creation of
// Formatter instance, instead of the default locale
IntStream.range(0, src.size()).forEach(i -> {
sb.setLength(0);
Locale.setDefault(Locale.Category.FORMAT, defaultLocale.get(i));
new Formatter(sb, formatLocale.get(i)).format(conversions.get(i),
src.get(i));
if (!sb.toString().equals(expectedWithFormatLocale.get(i))) {
throw new RuntimeException(
"Wrong uppercasing while using Formatter.format(" +
"\"" + conversions.get(i) + "\"" +
") with the locale specified during instance" +
" creation: '" + formatLocale.get(i) +
"'. Expected: " + expectedWithFormatLocale.get(i) +
" Returned: " + sb.toString());
}
});
} }
static void nullLocaleTest() { static void nullLocaleTest() {