/* * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions.
*/
/* * @test * @bug 4533872 4985214 4985217 4993841 5017268 5017280 8298033 * @summary Unit tests for supplementary character support (JSR-204) * @compile Supplementary.java * @run main/timeout=600 Supplementary
*/
publicstaticvoid main(String[] args) { // Do not change the order of test method calls since there // are some interdependencies.
testConstants();
test00();
// Store all Unicode code points, except for surrogate code // points, in cu[] through the loops below. Then, use the data // for code point/code unit conversion and other tests later. char[] cu = newchar[(MAX_SUPPLEMENTARY+1) * 2]; int length = test01(cu);
String str = new String(cu, 0, length);
cu = null;
test02(str);
test03(str.toCharArray());
test04(str);
test05(str);
// Test for toString(int)
test06();
// Test unpaired surrogates
testUnpaired();
// Test exceptions
testExceptions00();
testExceptions01(str);
testExceptions02(str.toCharArray());
}
staticvoid testConstants() { if (Character.MIN_HIGH_SURROGATE != MIN_HIGH) {
constantError("MIN_HIGH_SURROGATE", Character.MIN_HIGH_SURROGATE, MIN_HIGH);
} if (Character.MAX_HIGH_SURROGATE != MAX_HIGH) {
constantError("MAX_HIGH_SURROGATE", Character.MAX_HIGH_SURROGATE, MAX_HIGH);
} if (Character.MIN_LOW_SURROGATE != MIN_LOW) {
constantError("MIN_LOW_SURROGATE", Character.MIN_LOW_SURROGATE, MIN_LOW);
} if (Character.MAX_LOW_SURROGATE != MAX_LOW) {
constantError("MAX_LOW_SURROGATE", Character.MAX_LOW_SURROGATE, MAX_LOW);
} if (Character.MIN_SURROGATE != MIN_HIGH) {
constantError("MIN_SURROGATE", Character.MIN_SURROGATE, MIN_HIGH);
} if (Character.MAX_SURROGATE != MAX_LOW) {
constantError("MAX_SURROGATE", Character.MAX_SURROGATE, MAX_LOW);
} if (Character.MIN_SUPPLEMENTARY_CODE_POINT != MIN_SUPPLEMENTARY) {
constantError("MIN_SUPPLEMENTARY_CODE_POINT",
Character.MIN_SUPPLEMENTARY_CODE_POINT, MIN_SUPPLEMENTARY);
} if (Character.MIN_CODE_POINT != MIN_CODE_POINT) {
constantError("MIN_CODE_POINT", Character.MIN_CODE_POINT, MIN_CODE_POINT);
} if (Character.MAX_CODE_POINT != MAX_SUPPLEMENTARY) {
constantError("MAX_CODE_POINT", Character.MAX_CODE_POINT, MAX_SUPPLEMENTARY);
}
}
staticvoid constantError(String name, int value, int expectedValue) { thrownew RuntimeException("Character." + name + " has a wrong value: got "
+ toHexString(value)
+ ", expected " + toHexString(expectedValue));
}
/* * Test isValidCodePoint(int) * isSupplementaryCodePoint(int) * charCount(int)
*/ staticvoid test00() { for (int cp = -MAX_SUPPLEMENTARY; cp <= MAX_SUPPLEMENTARY*2; cp++) { boolean isValid = cp >= 0 && cp <= MAX_SUPPLEMENTARY; if (Character.isValidCodePoint(cp) != isValid) { thrownew RuntimeException("isValidCodePoint failed with "
+ toHexString(cp));
} boolean isSupplementary = cp >= MIN_SUPPLEMENTARY && cp <= MAX_SUPPLEMENTARY; if (Character.isSupplementaryCodePoint(cp) != isSupplementary) { thrownew RuntimeException("isSupplementaryCodePoint failed with "
+ toHexString(cp));
} int len = Character.charCount(cp); if (isValid) { if ((isSupplementary && len != 2)
|| (!isSupplementary && len != 1)) { thrownew RuntimeException("wrong character length "+len+" for "
+ toHexString(cp));
}
} elseif (len != 1 && len != 2) { thrownew RuntimeException("wrong character length "+len+" for "
+ toHexString(cp));
}
}
}
/** * Test toChar(int) * toChar(int, char[], int) * isHighSurrogate(char) * isLowSurrogate(char) * isSurrogatePair(int, int) * * While testing those methods, this method generates all Unicode * code points (except for surrogate code points) and store them * in cu. * * @return the number of code units generated in cu
*/ staticint test01(char[] cu) { int index = 0; // Test toChar(int) // toChar(int, char[], int) // isHighSurrogate(char) // isLowSurrogate(char) // with BMP code points for (int i = 0; i <= Character.MAX_VALUE; i++) { char[] u = Character.toChars(i); if (u.length != 1 || u[0] != i) { thrownew RuntimeException("wrong toChars(int) result for BMP: "
+ toHexString("u", u));
} int n = Character.toChars(i, cu, index); if (n != 1 || cu[index] != i) { thrownew RuntimeException("wrong toChars(int, char[], int) result for BMP:"
+ " len=" + n
+ ", cu["+index+"]="+toHexString(cu[index]));
} boolean isHigh = i >= MIN_HIGH && i <= MAX_HIGH; if (Character.isHighSurrogate((char) i) != isHigh) { thrownew RuntimeException("wrong high-surrogate test for "
+ toHexString(i));
} boolean isLow = i >= MIN_LOW && i <= MAX_LOW; if (Character.isLowSurrogate((char)i) != isLow) { thrownew RuntimeException("wrong low-surrogate test for "
+ toHexString(i));
} if (!isHigh && !isLow) {
index++;
}
}
// Test isSurrogatePair with all surrogate pairs // Test toChars(int) // toChars(int, char[], int) // with all supplementary characters int supplementary = MIN_SUPPLEMENTARY; for (int i = Character.MAX_VALUE/2; i <= Character.MAX_VALUE; i++) { char hi = (char) i; boolean isHigh = Character.isHighSurrogate(hi);
for (int j = Character.MAX_VALUE/2; j <= Character.MAX_VALUE; j++) { char lo = (char) j; boolean isLow = Character.isLowSurrogate(lo); boolean isSurrogatePair = isHigh && isLow; if (Character.isSurrogatePair(hi, lo) != isSurrogatePair) { thrownew RuntimeException("wrong surrogate pair test for hi="
+ toHexString(hi)
+ ", lo="+toHexString(lo));
} if (isSurrogatePair) { int cp = Character.toCodePoint(hi, lo); if (cp != supplementary) { thrownew RuntimeException("wrong code point: got "
+ toHexString(cp)
+ ", expected="
+ toHexString(supplementary));
} char[] u = Character.toChars(cp); if (u.length != 2 || u[0] != hi || u[1] != lo) { thrownew RuntimeException("wrong toChars(int) result for supplementary: "+
toHexString("u", u));
} int n = Character.toChars(cp, cu, index); if (n != 2 || cu[index] != hi || cu[index+1] != lo) { thrownew RuntimeException("wrong toChars(int, char[], int) result "
+ "for supplementary: len=" + n
+ ", cu["+index+"]=" + toHexString(cu[index])
+ ", cu["+(index+1)+"]=" + toHexString(cu[index+1]));
}
index += n;
supplementary++;
}
}
} if (supplementary != MAX_SUPPLEMENTARY + 1) { thrownew RuntimeException("wrong supplementary count (supplementary="
+ toHexString(supplementary)+")");
}
int nCodeUnits = Character.MAX_VALUE + 1 - (MAX_LOW - MIN_HIGH + 1)
+ ((MAX_SUPPLEMENTARY - MIN_SUPPLEMENTARY + 1) * 2); if (index != nCodeUnits) { thrownew RuntimeException("wrong number of code units: " + index
+ ", expected " + nCodeUnits);
} return index;
}
/** * Test codePointAt(CharSequence, int) * codePointBefore(CharSequence, int)
*/ staticvoid test02(CharSequence cs) { int cp = 0; int ch; for (int i = 0; i < cs.length(); i += Character.charCount(ch)) {
ch = Character.codePointAt(cs, i); if (ch != cp) { thrownew RuntimeException("wrong codePointAt(CharSequence, "+i+") value: got "
+ toHexString(ch)
+ ", expected "+toHexString(cp));
}
cp++; // Skip surrogates if (cp == MIN_HIGH) {
cp = MAX_LOW + 1;
}
}
cp--; for (int i = cs.length(); i > 0; i -= Character.charCount(ch)) {
ch = Character.codePointBefore(cs, i); if (ch != cp) { thrownew RuntimeException("codePointBefore(CharSequence, "+i+") returned "
+ toHexString(ch)
+ ", expected " + toHexString(cp));
}
cp--; // Skip surrogates if (cp == MAX_LOW) {
cp = MIN_HIGH - 1;
}
}
}
/** * Test codePointAt(char[], int) * codePointAt(char[], int, int) * codePointBefore(char[], int) * codePointBefore(char[], int, int)
*/ staticvoid test03(char[] a) { int cp = 0; int ch; for (int i = 0; i < a.length; i += Character.charCount(ch)) {
ch = Character.codePointAt(a, i); if (ch != cp) { thrownew RuntimeException("codePointAt(char[], "+i+") returned "
+ toHexString(ch)
+ ", expected "+toHexString(cp));
} int x = Character.codePointAt(a, i, i+1); if (x != a[i]) { thrownew RuntimeException(String.format( "codePointAt(char[], %d, %d) returned 0x%04x, expected 0x%04x\n",
i, i+1, x, (int)a[i]));
}
cp++; // Skip surrogates if (cp == MIN_HIGH) {
cp = MAX_LOW + 1;
}
}
cp--; for (int i = a.length; i > 0; i -= Character.charCount(ch)) {
ch = Character.codePointBefore(a, i); if (ch != cp) { thrownew RuntimeException("codePointBefore(char[], "+i+") returned "
+ toHexString(ch)
+ ", expected " + toHexString(cp));
} int x = Character.codePointBefore(a, i, i-1); if (x != a[i-1]) { thrownew RuntimeException(String.format( "codePointAt(char[], %d, %d) returned 0x%04x, expected 0x%04x\n",
i, i-1, x, (int)a[i-1]));
}
cp--; // Skip surrogates if (cp == MAX_LOW) {
cp = MIN_HIGH - 1;
}
}
}
/** * Test codePointCount(CharSequence, int, int) * codePointCount(char[], int, int, int, int)
*/ staticvoid test04(String str) { int length = str.length(); char[] a = str.toCharArray();
for (int i = 0; i <= length; i += 99, length -= 29999) { int n = Character.codePointCount(str, i, length); int m = codePointCount(str.substring(i, length));
checkCodePointCount(str, n, m);
n = Character.codePointCount(a, i, length - i);
checkCodePointCount(a, n, m);
}
// test special cases
length = str.length(); int n = Character.codePointCount(str, 0, 0);
checkCodePointCount(str, n, 0);
n = Character.codePointCount(str, length, length);
checkCodePointCount(str, n, 0);
n = Character.codePointCount(a, 0, 0);
checkCodePointCount(a, n, 0);
n = Character.codePointCount(a, length, 0);
checkCodePointCount(a, n, 0);
}
// This method assumes that Character.codePointAt() and // Character.charCount() work correctly. privatestaticint codePointCount(CharSequence seq) { int n = 0, len; for (int i = 0; i < seq.length(); i += len) { int codepoint = Character.codePointAt(seq, i);
n++;
len = Character.charCount(codepoint);
} return n;
}
privatestaticvoid checkCodePointCount(Object data, int n, int expected) {
String type = getType(data); if (n != expected) { thrownew RuntimeException("codePointCount(" + type + "...) returned " + n
+ ", expected " + expected);
}
}
/** * Test offsetByCodePoints(CharSequence, int, int) * offsetByCodePoints(char[], int, int, int, int) * * This test case assumes that Character.codePointCount()s work * correctly.
*/ staticvoid test05(String str) { int length = str.length(); char[] a = str.toCharArray();
for (int i = 0; i <= length; i += 99, length -= 29999) { int nCodePoints = Character.codePointCount(a, i, length - i); int index;
// offsetByCodePoints(CharSequence, int, int)
int expectedHighIndex = length; // For forward CharSequence scan, we need to adjust the // expected index in case the last char in the text range // is a high surrogate and forms a valid supplementary // code point with the next char. if (length < a.length) { int cp = Character.codePointAt(a, length - 1); if (Character.isSupplementaryCodePoint(cp)) {
expectedHighIndex++;
}
}
index = Character.offsetByCodePoints(str, i, nCodePoints);
checkNewIndex(str, nCodePoints, index, expectedHighIndex); int expectedLowIndex = i; if (i > 0) { int cp = Character.codePointBefore(a, i + 1); if (Character.isSupplementaryCodePoint(cp)) {
expectedLowIndex--;
}
}
index = Character.offsetByCodePoints(str, length, -nCodePoints);
checkNewIndex(str, -nCodePoints, index, expectedLowIndex);
// offsetByCodePoints(char[], int, int, int, int)
int start = Math.max(0, i-1); int limit = Math.min(a.length, length+1);
index = Character.offsetByCodePoints(a, start, limit - start,
i, nCodePoints);
checkNewIndex(a, nCodePoints, index, expectedHighIndex); if (length != expectedHighIndex) {
index = Character.offsetByCodePoints(a, start, length - start,
i, nCodePoints);
checkNewIndex(a, nCodePoints, index, length);
}
index = Character.offsetByCodePoints(a, start, limit - start,
length, -nCodePoints);
checkNewIndex(a, -nCodePoints, index, expectedLowIndex); if (i != expectedLowIndex) {
index = Character.offsetByCodePoints(a, i, limit - i,
length, -nCodePoints);
checkNewIndex(a, -nCodePoints, index, i);
}
}
// test special cases for 0-length text ranges.
length = str.length(); int index = Character.offsetByCodePoints(str, 0, 0);
checkNewIndex(str, 0, index, 0);
index = Character.offsetByCodePoints(str, length, 0);
checkNewIndex(str, 0, index, length);
index = Character.offsetByCodePoints(a, 0, 0, 0, 0);
checkNewIndex(a, 0, index, 0);
index = Character.offsetByCodePoints(a, 0, length, 0, 0);
checkNewIndex(a, 0, index, 0);
index = Character.offsetByCodePoints(a, 0, length, length, 0);
checkNewIndex(a, 0, index, length);
index = Character.offsetByCodePoints(a, length, 0, length, 0);
checkNewIndex(a, 0, index, length);
}
/** * Test toString(int) * * This test case assumes that Character.toChars()/String(char[]) work * correctly.
*/ staticvoid test06() { for (int cp = Character.MIN_CODE_POINT; cp <= Character.MAX_CODE_POINT; cp++) {
String result = Character.toString(cp);
String expected = new String(Character.toChars(cp)); if (!result.equals(expected)) { thrownew RuntimeException("Wrong string is created. code point: " +
cp + ", result: " + result + ", expected: " + expected);
}
}
}
privatestaticvoid checkNewIndex(Object data, int offset, int result, int expected) {
String type = getType(data);
String offsetType = (offset > 0) ? "positive" : (offset < 0) ? "negative" : "0"; if (result != expected) { thrownew RuntimeException("offsetByCodePoints(" + type + ", ...) ["
+ offsetType + " offset]"
+ " returned " + result
+ ", expected " + expected);
}
}
staticvoid testCodePoint(String str, int[] codepoints) { int c; // Test Character.codePointAt/Before(CharSequence, int) int j = 0; for (int i = 0; i < str.length(); i += Character.charCount(c)) {
c = Character.codePointAt(str, i); if (c != codepoints[j++]) { thrownew RuntimeException("codePointAt(CharSequence, " + i + ") returned "
+ toHexString(c)
+ ", expected " + toHexString(codepoints[j-1]));
}
} if (j != codepoints.length) { thrownew RuntimeException("j != codepoints.length after codePointAt(CharSequence, int)"
+ " (j=" + j + ")"
+ ", expected: " + codepoints.length);
}
j = codepoints.length; for (int i = str.length(); i > 0 ; i -= Character.charCount(c)) {
c = Character.codePointBefore(str, i); if (c != codepoints[--j]) { thrownew RuntimeException("codePointBefore(CharSequence, " + i + ") returned "
+ toHexString(c)
+ ", expected " + toHexString(codepoints[j]));
}
} if (j != 0) { thrownew RuntimeException("j != 0 after codePointBefore(CharSequence, int)"
+ " (j=" + j + ")");
}
// Test Character.codePointAt/Before(char[], int) char[] a = str.toCharArray();
j = 0; for (int i = 0; i < a.length; i += Character.charCount(c)) {
c = Character.codePointAt(a, i); if (c != codepoints[j++]) { thrownew RuntimeException("codePointAt(char[], " + i + ") returned "
+ toHexString(c)
+ ", expected " + toHexString(codepoints[j-1]));
}
} if (j != codepoints.length) { thrownew RuntimeException("j != codepoints.length after codePointAt(char[], int)"
+ " (j=" + j + ")"
+ ", expected: " + codepoints.length);
}
j = codepoints.length; for (int i = a.length; i > 0 ; i -= Character.charCount(c)) {
c = Character.codePointBefore(a, i); if (c != codepoints[--j]) { thrownew RuntimeException("codePointBefore(char[], " + i + ") returned "
+ toHexString(c)
+ ", expected " + toHexString(codepoints[j]));
}
} if (j != 0) { thrownew RuntimeException("j != 0 after codePointBefore(char[], int)"
+ " (j=" + j + ")");
}
// Test toChar(int)
j = 0; for (int i = 0; i < codepoints.length; i++) {
a = Character.toChars(codepoints[i]); for (int k = 0; k < a.length; k++) { if (str.charAt(j++) != a[k]) { thrownew RuntimeException("toChars(int) returned " + toHexString("result", a)
+ " from codepoint=" + toHexString(codepoints[i]));
}
}
}
// Test toChars(int, char[], int)
a = newchar[codepoints.length * 2];
j = 0; for (int i = 0; i < codepoints.length; i++) { int n = Character.toChars(codepoints[i], a, j);
j += n;
}
String s = new String(a, 0, j); if (!str.equals(s)) { thrownew RuntimeException("toChars(int, char[], int) returned "
+ toHexString("dst", s.toCharArray())
+ ", expected " + toHexString("data", str.toCharArray()));
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.