1 /* 2 * Copyright (c) 2018, 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 * @test 26 * @bug 4533872 4985214 4985217 4993841 5017268 5017280 27 * @summary Unit tests for supplementary character support (JSR-204) 28 * @compile Supplementary.java 29 * @run main/timeout=600 Supplementary 30 */ 31 32 public class Supplementary { 33 private static final char MIN_HIGH = '\uD800'; 34 private static final char MAX_HIGH = '\uDBFF'; 35 private static final char MIN_LOW = MAX_HIGH + 1; 36 private static final char MAX_LOW = '\uDFFF'; 37 private static final int MIN_CODE_POINT = 0x000000; 38 private static final int MIN_SUPPLEMENTARY = 0x010000; 39 private static final int MAX_SUPPLEMENTARY = 0x10ffff; 40 main(String[] args)41 public static void main(String[] args) { 42 // Do not change the order of test method calls since there 43 // are some interdependencies. 44 45 testConstants(); 46 47 test00(); 48 49 // Store all Unicode code points, except for surrogate code 50 // points, in cu[] through the loops below. Then, use the data 51 // for code point/code unit conversion and other tests later. 52 char[] cu = new char[(MAX_SUPPLEMENTARY+1) * 2]; 53 int length = test01(cu); 54 55 String str = new String(cu, 0, length); 56 cu = null; 57 test02(str); 58 test03(str.toCharArray()); 59 test04(str); 60 test05(str); 61 62 // Test for toString(int) 63 test06(); 64 65 // Test unpaired surrogates 66 testUnpaired(); 67 68 // Test exceptions 69 testExceptions00(); 70 testExceptions01(str); 71 testExceptions02(str.toCharArray()); 72 } 73 testConstants()74 static void testConstants() { 75 if (Character.MIN_HIGH_SURROGATE != MIN_HIGH) { 76 constantError("MIN_HIGH_SURROGATE", Character.MIN_HIGH_SURROGATE, MIN_HIGH); 77 } 78 if (Character.MAX_HIGH_SURROGATE != MAX_HIGH) { 79 constantError("MAX_HIGH_SURROGATE", Character.MAX_HIGH_SURROGATE, MAX_HIGH); 80 } 81 if (Character.MIN_LOW_SURROGATE != MIN_LOW) { 82 constantError("MIN_LOW_SURROGATE", Character.MIN_LOW_SURROGATE, MIN_LOW); 83 } 84 if (Character.MAX_LOW_SURROGATE != MAX_LOW) { 85 constantError("MAX_LOW_SURROGATE", Character.MAX_LOW_SURROGATE, MAX_LOW); 86 } 87 if (Character.MIN_SURROGATE != MIN_HIGH) { 88 constantError("MIN_SURROGATE", Character.MIN_SURROGATE, MIN_HIGH); 89 } 90 if (Character.MAX_SURROGATE != MAX_LOW) { 91 constantError("MAX_SURROGATE", Character.MAX_SURROGATE, MAX_LOW); 92 } 93 if (Character.MIN_SUPPLEMENTARY_CODE_POINT != MIN_SUPPLEMENTARY) { 94 constantError("MIN_SUPPLEMENTARY_CODE_POINT", 95 Character.MIN_SUPPLEMENTARY_CODE_POINT, MIN_SUPPLEMENTARY); 96 } 97 if (Character.MIN_CODE_POINT != MIN_CODE_POINT) { 98 constantError("MIN_CODE_POINT", Character.MIN_CODE_POINT, MIN_CODE_POINT); 99 } 100 if (Character.MAX_CODE_POINT != MAX_SUPPLEMENTARY) { 101 constantError("MAX_CODE_POINT", Character.MAX_CODE_POINT, MAX_SUPPLEMENTARY); 102 } 103 } 104 constantError(String name, int value, int expectedValue)105 static void constantError(String name, int value, int expectedValue) { 106 throw new RuntimeException("Character." + name + " has a wrong value: got " 107 + toHexString(value) 108 + ", expected " + toHexString(expectedValue)); 109 } 110 111 /* 112 * Test isValidCodePoint(int) 113 * isSupplementaryCodePoint(int) 114 * charCount(int) 115 */ test00()116 static void test00() { 117 for (int cp = -MAX_SUPPLEMENTARY; cp <= MAX_SUPPLEMENTARY*2; cp++) { 118 boolean isValid = cp >= 0 && cp <= MAX_SUPPLEMENTARY; 119 if (Character.isValidCodePoint(cp) != isValid) { 120 throw new RuntimeException("isValidCodePoint failed with " 121 + toHexString(cp)); 122 } 123 boolean isSupplementary = cp >= MIN_SUPPLEMENTARY && cp <= MAX_SUPPLEMENTARY; 124 if (Character.isSupplementaryCodePoint(cp) != isSupplementary) { 125 throw new RuntimeException("isSupplementaryCodePoint failed with " 126 + toHexString(cp)); 127 } 128 int len = Character.charCount(cp); 129 if (isValid) { 130 if ((isSupplementary && len != 2) 131 || (!isSupplementary && len != 1)) { 132 throw new RuntimeException("wrong character length "+len+" for " 133 + toHexString(cp)); 134 } 135 } else if (len != 1 && len != 2) { 136 throw new RuntimeException("wrong character length "+len+" for " 137 + toHexString(cp)); 138 } 139 } 140 } 141 142 /** 143 * Test toChar(int) 144 * toChar(int, char[], int) 145 * isHighSurrogate(char) 146 * isLowSurrogate(char) 147 * isSurrogatePair(int, int) 148 * 149 * While testing those methods, this method generates all Unicode 150 * code points (except for surrogate code points) and store them 151 * in cu. 152 * 153 * @return the number of code units generated in cu 154 */ test01(char[] cu)155 static int test01(char[] cu) { 156 int index = 0; 157 // Test toChar(int) 158 // toChar(int, char[], int) 159 // isHighSurrogate(char) 160 // isLowSurrogate(char) 161 // with BMP code points 162 for (int i = 0; i <= Character.MAX_VALUE; i++) { 163 char[] u = Character.toChars(i); 164 if (u.length != 1 || u[0] != i) { 165 throw new RuntimeException("wrong toChars(int) result for BMP: " 166 + toHexString("u", u)); 167 } 168 int n = Character.toChars(i, cu, index); 169 if (n != 1 || cu[index] != i) { 170 throw new RuntimeException("wrong toChars(int, char[], int) result for BMP:" 171 + " len=" + n 172 + ", cu["+index+"]="+toHexString(cu[index])); 173 } 174 boolean isHigh = i >= MIN_HIGH && i <= MAX_HIGH; 175 if (Character.isHighSurrogate((char) i) != isHigh) { 176 throw new RuntimeException("wrong high-surrogate test for " 177 + toHexString(i)); 178 } 179 boolean isLow = i >= MIN_LOW && i <= MAX_LOW; 180 if (Character.isLowSurrogate((char)i) != isLow) { 181 throw new RuntimeException("wrong low-surrogate test for " 182 + toHexString(i)); 183 } 184 if (!isHigh && !isLow) { 185 index++; 186 } 187 } 188 189 // Test isSurrogatePair with all surrogate pairs 190 // Test toChars(int) 191 // toChars(int, char[], int) 192 // with all supplementary characters 193 int supplementary = MIN_SUPPLEMENTARY; 194 for (int i = Character.MAX_VALUE/2; i <= Character.MAX_VALUE; i++) { 195 char hi = (char) i; 196 boolean isHigh = Character.isHighSurrogate(hi); 197 198 for (int j = Character.MAX_VALUE/2; j <= Character.MAX_VALUE; j++) { 199 char lo = (char) j; 200 boolean isLow = Character.isLowSurrogate(lo); 201 boolean isSurrogatePair = isHigh && isLow; 202 if (Character.isSurrogatePair(hi, lo) != isSurrogatePair) { 203 throw new RuntimeException("wrong surrogate pair test for hi=" 204 + toHexString(hi) 205 + ", lo="+toHexString(lo)); 206 } 207 if (isSurrogatePair) { 208 int cp = Character.toCodePoint(hi, lo); 209 if (cp != supplementary) { 210 throw new RuntimeException("wrong code point: got " 211 + toHexString(cp) 212 + ", expected=" 213 + toHexString(supplementary)); 214 } 215 char[] u = Character.toChars(cp); 216 if (u.length != 2 || u[0] != hi || u[1] != lo) { 217 throw new RuntimeException("wrong toChars(int) result for supplementary: "+ 218 toHexString("u", u)); 219 } 220 int n = Character.toChars(cp, cu, index); 221 if (n != 2 || cu[index] != hi || cu[index+1] != lo) { 222 throw new RuntimeException("wrong toChars(int, char[], int) result " 223 + "for supplementary: len=" + n 224 + ", cu["+index+"]=" + toHexString(cu[index]) 225 + ", cu["+(index+1)+"]=" + toHexString(cu[index+1])); 226 } 227 index += n; 228 supplementary++; 229 } 230 } 231 } 232 if (supplementary != MAX_SUPPLEMENTARY + 1) { 233 throw new RuntimeException("wrong supplementary count (supplementary=" 234 + toHexString(supplementary)+")"); 235 } 236 237 int nCodeUnits = Character.MAX_VALUE + 1 - (MAX_LOW - MIN_HIGH + 1) 238 + ((MAX_SUPPLEMENTARY - MIN_SUPPLEMENTARY + 1) * 2); 239 if (index != nCodeUnits) { 240 throw new RuntimeException("wrong number of code units: " + index 241 + ", expected " + nCodeUnits); 242 } 243 return index; 244 } 245 246 /** 247 * Test codePointAt(CharSequence, int) 248 * codePointBefore(CharSequence, int) 249 */ test02(CharSequence cs)250 static void test02(CharSequence cs) { 251 int cp = 0; 252 int ch; 253 for (int i = 0; i < cs.length(); i += Character.charCount(ch)) { 254 ch = Character.codePointAt(cs, i); 255 if (ch != cp) { 256 throw new RuntimeException("wrong codePointAt(CharSequence, "+i+") value: got " 257 + toHexString(ch) 258 + ", expected "+toHexString(cp)); 259 } 260 cp++; 261 // Skip surrogates 262 if (cp == MIN_HIGH) { 263 cp = MAX_LOW + 1; 264 } 265 } 266 267 cp--; 268 for (int i = cs.length(); i > 0; i -= Character.charCount(ch)) { 269 ch = Character.codePointBefore(cs, i); 270 if (ch != cp) { 271 throw new RuntimeException("codePointBefore(CharSequence, "+i+") returned " 272 + toHexString(ch) 273 + ", expected " + toHexString(cp)); 274 } 275 cp--; 276 // Skip surrogates 277 if (cp == MAX_LOW) { 278 cp = MIN_HIGH - 1; 279 } 280 } 281 } 282 283 /** 284 * Test codePointAt(char[], int) 285 * codePointAt(char[], int, int) 286 * codePointBefore(char[], int) 287 * codePointBefore(char[], int, int) 288 */ test03(char[] a)289 static void test03(char[] a) { 290 int cp = 0; 291 int ch; 292 for (int i = 0; i < a.length; i += Character.charCount(ch)) { 293 ch = Character.codePointAt(a, i); 294 if (ch != cp) { 295 throw new RuntimeException("codePointAt(char[], "+i+") returned " 296 + toHexString(ch) 297 + ", expected "+toHexString(cp)); 298 } 299 int x = Character.codePointAt(a, i, i+1); 300 if (x != a[i]) { 301 throw new RuntimeException(String.format( 302 "codePointAt(char[], %d, %d) returned 0x%04x, expected 0x%04x\n", 303 i, i+1, x, (int)a[i])); 304 } 305 cp++; 306 // Skip surrogates 307 if (cp == MIN_HIGH) { 308 cp = MAX_LOW + 1; 309 } 310 } 311 312 cp--; 313 for (int i = a.length; i > 0; i -= Character.charCount(ch)) { 314 ch = Character.codePointBefore(a, i); 315 if (ch != cp) { 316 throw new RuntimeException("codePointBefore(char[], "+i+") returned " 317 + toHexString(ch) 318 + ", expected " + toHexString(cp)); 319 } 320 int x = Character.codePointBefore(a, i, i-1); 321 if (x != a[i-1]) { 322 throw new RuntimeException(String.format( 323 "codePointAt(char[], %d, %d) returned 0x%04x, expected 0x%04x\n", 324 i, i-1, x, (int)a[i-1])); 325 } 326 cp--; 327 // Skip surrogates 328 if (cp == MAX_LOW) { 329 cp = MIN_HIGH - 1; 330 } 331 } 332 } 333 334 /** 335 * Test codePointCount(CharSequence, int, int) 336 * codePointCount(char[], int, int, int, int) 337 */ test04(String str)338 static void test04(String str) { 339 int length = str.length(); 340 char[] a = str.toCharArray(); 341 342 for (int i = 0; i <= length; i += 99, length -= 29999) { 343 int n = Character.codePointCount(str, i, length); 344 int m = codePointCount(str.substring(i, length)); 345 checkCodePointCount(str, n, m); 346 n = Character.codePointCount(a, i, length - i); 347 checkCodePointCount(a, n, m); 348 } 349 350 // test special cases 351 length = str.length(); 352 int n = Character.codePointCount(str, 0, 0); 353 checkCodePointCount(str, n, 0); 354 n = Character.codePointCount(str, length, length); 355 checkCodePointCount(str, n, 0); 356 n = Character.codePointCount(a, 0, 0); 357 checkCodePointCount(a, n, 0); 358 n = Character.codePointCount(a, length, 0); 359 checkCodePointCount(a, n, 0); 360 } 361 362 // This method assumes that Character.codePointAt() and 363 // Character.charCount() work correctly. codePointCount(CharSequence seq)364 private static int codePointCount(CharSequence seq) { 365 int n = 0, len; 366 for (int i = 0; i < seq.length(); i += len) { 367 int codepoint = Character.codePointAt(seq, i); 368 n++; 369 len = Character.charCount(codepoint); 370 } 371 return n; 372 } 373 checkCodePointCount(Object data, int n, int expected)374 private static void checkCodePointCount(Object data, int n, int expected) { 375 String type = getType(data); 376 if (n != expected) { 377 throw new RuntimeException("codePointCount(" + type + "...) returned " + n 378 + ", expected " + expected); 379 } 380 } 381 382 /** 383 * Test offsetByCodePoints(CharSequence, int, int) 384 * offsetByCodePoints(char[], int, int, int, int) 385 * 386 * This test case assumes that Character.codePointCount()s work 387 * correctly. 388 */ test05(String str)389 static void test05(String str) { 390 int length = str.length(); 391 char[] a = str.toCharArray(); 392 393 for (int i = 0; i <= length; i += 99, length -= 29999) { 394 int nCodePoints = Character.codePointCount(a, i, length - i); 395 int index; 396 397 // offsetByCodePoints(CharSequence, int, int) 398 399 int expectedHighIndex = length; 400 // For forward CharSequence scan, we need to adjust the 401 // expected index in case the last char in the text range 402 // is a high surrogate and forms a valid supplementary 403 // code point with the next char. 404 if (length < a.length) { 405 int cp = Character.codePointAt(a, length - 1); 406 if (Character.isSupplementaryCodePoint(cp)) { 407 expectedHighIndex++; 408 } 409 } 410 index = Character.offsetByCodePoints(str, i, nCodePoints); 411 checkNewIndex(str, nCodePoints, index, expectedHighIndex); 412 int expectedLowIndex = i; 413 if (i > 0) { 414 int cp = Character.codePointBefore(a, i + 1); 415 if (Character.isSupplementaryCodePoint(cp)) { 416 expectedLowIndex--; 417 } 418 } 419 index = Character.offsetByCodePoints(str, length, -nCodePoints); 420 checkNewIndex(str, -nCodePoints, index, expectedLowIndex); 421 422 // offsetByCodePoints(char[], int, int, int, int) 423 424 int start = Math.max(0, i-1); 425 int limit = Math.min(a.length, length+1); 426 index = Character.offsetByCodePoints(a, start, limit - start, 427 i, nCodePoints); 428 checkNewIndex(a, nCodePoints, index, expectedHighIndex); 429 if (length != expectedHighIndex) { 430 index = Character.offsetByCodePoints(a, start, length - start, 431 i, nCodePoints); 432 checkNewIndex(a, nCodePoints, index, length); 433 } 434 index = Character.offsetByCodePoints(a, start, limit - start, 435 length, -nCodePoints); 436 checkNewIndex(a, -nCodePoints, index, expectedLowIndex); 437 if (i != expectedLowIndex) { 438 index = Character.offsetByCodePoints(a, i, limit - i, 439 length, -nCodePoints); 440 checkNewIndex(a, -nCodePoints, index, i); 441 } 442 } 443 444 // test special cases for 0-length text ranges. 445 length = str.length(); 446 int index = Character.offsetByCodePoints(str, 0, 0); 447 checkNewIndex(str, 0, index, 0); 448 index = Character.offsetByCodePoints(str, length, 0); 449 checkNewIndex(str, 0, index, length); 450 index = Character.offsetByCodePoints(a, 0, 0, 0, 0); 451 checkNewIndex(a, 0, index, 0); 452 index = Character.offsetByCodePoints(a, 0, length, 0, 0); 453 checkNewIndex(a, 0, index, 0); 454 index = Character.offsetByCodePoints(a, 0, length, length, 0); 455 checkNewIndex(a, 0, index, length); 456 index = Character.offsetByCodePoints(a, length, 0, length, 0); 457 checkNewIndex(a, 0, index, length); 458 } 459 460 /** 461 * Test toString(int) 462 * 463 * This test case assumes that Character.toChars()/String(char[]) work 464 * correctly. 465 */ test06()466 static void test06() { 467 for (int cp = Character.MIN_CODE_POINT; cp <= Character.MAX_CODE_POINT; cp++) { 468 String result = Character.toString(cp); 469 String expected = new String(Character.toChars(cp)); 470 if (!result.equals(expected)) { 471 throw new RuntimeException("Wrong string is created. code point: " + 472 cp + ", result: " + result + ", expected: " + expected); 473 } 474 } 475 } 476 checkNewIndex(Object data, int offset, int result, int expected)477 private static void checkNewIndex(Object data, int offset, int result, int expected) { 478 String type = getType(data); 479 String offsetType = (offset > 0) ? "positive" : (offset < 0) ? "negative" : "0"; 480 if (result != expected) { 481 throw new RuntimeException("offsetByCodePoints(" + type + ", ...) [" 482 + offsetType + " offset]" 483 + " returned " + result 484 + ", expected " + expected); 485 } 486 } 487 488 // Test codePointAt(CharSequence, int) 489 // codePointBefore(CharSequence, int) 490 // codePointAt(char[], int) 491 // codePointBefore(char[], int) 492 // toChar(int) 493 // toChar(int, char[], int) 494 // with unpaired surrogates testUnpaired()495 static void testUnpaired() { 496 testCodePoint("\uD800", new int[] { 0xD800 }); 497 testCodePoint("\uDC00", new int[] { 0xDC00 }); 498 testCodePoint("a\uD800", new int[] { 'a', 0xD800 }); 499 testCodePoint("a\uDC00", new int[] { 'a', 0xDC00 }); 500 testCodePoint("\uD800a", new int[] { 0xD800, 'a' }); 501 testCodePoint("\uDBFFa", new int[] { 0xDBFF, 'a' }); 502 testCodePoint("a\uD800\uD801", new int[] { 'a', 0xD800, 0xD801 }); 503 testCodePoint("a\uD800x\uDC00", new int[] { 'a', 0xD800, 'x', 0xDC00 }); 504 testCodePoint("\uDC00\uD800", new int[] { 0xDC00, 0xD800 }); 505 testCodePoint("\uD800\uDC00\uDC00", new int[] { 0x10000, 0xDC00 }); 506 testCodePoint("\uD800\uD800\uDC00", new int[] { 0xD800, 0x10000 }); 507 testCodePoint("\uD800\uD800\uD800\uD800\uDC00\uDC00\uDC00\uDC00", 508 new int[] { 0xD800, 0xD800, 0xD800, 0x10000, 0xDC00, 0xDC00, 0xDC00}); 509 } 510 testCodePoint(String str, int[] codepoints)511 static void testCodePoint(String str, int[] codepoints) { 512 int c; 513 // Test Character.codePointAt/Before(CharSequence, int) 514 int j = 0; 515 for (int i = 0; i < str.length(); i += Character.charCount(c)) { 516 c = Character.codePointAt(str, i); 517 if (c != codepoints[j++]) { 518 throw new RuntimeException("codePointAt(CharSequence, " + i + ") returned " 519 + toHexString(c) 520 + ", expected " + toHexString(codepoints[j-1])); 521 } 522 } 523 if (j != codepoints.length) { 524 throw new RuntimeException("j != codepoints.length after codePointAt(CharSequence, int)" 525 + " (j=" + j + ")" 526 + ", expected: " + codepoints.length); 527 } 528 529 j = codepoints.length; 530 for (int i = str.length(); i > 0 ; i -= Character.charCount(c)) { 531 c = Character.codePointBefore(str, i); 532 if (c != codepoints[--j]) { 533 throw new RuntimeException("codePointBefore(CharSequence, " + i + ") returned " 534 + toHexString(c) 535 + ", expected " + toHexString(codepoints[j])); 536 } 537 } 538 if (j != 0) { 539 throw new RuntimeException("j != 0 after codePointBefore(CharSequence, int)" 540 + " (j=" + j + ")"); 541 } 542 543 // Test Character.codePointAt/Before(char[], int) 544 char[] a = str.toCharArray(); 545 j = 0; 546 for (int i = 0; i < a.length; i += Character.charCount(c)) { 547 c = Character.codePointAt(a, i); 548 if (c != codepoints[j++]) { 549 throw new RuntimeException("codePointAt(char[], " + i + ") returned " 550 + toHexString(c) 551 + ", expected " + toHexString(codepoints[j-1])); 552 } 553 } 554 if (j != codepoints.length) { 555 throw new RuntimeException("j != codepoints.length after codePointAt(char[], int)" 556 + " (j=" + j + ")" 557 + ", expected: " + codepoints.length); 558 } 559 560 j = codepoints.length; 561 for (int i = a.length; i > 0 ; i -= Character.charCount(c)) { 562 c = Character.codePointBefore(a, i); 563 if (c != codepoints[--j]) { 564 throw new RuntimeException("codePointBefore(char[], " + i + ") returned " 565 + toHexString(c) 566 + ", expected " + toHexString(codepoints[j])); 567 } 568 } 569 if (j != 0) { 570 throw new RuntimeException("j != 0 after codePointBefore(char[], int)" 571 + " (j=" + j + ")"); 572 } 573 574 // Test toChar(int) 575 j = 0; 576 for (int i = 0; i < codepoints.length; i++) { 577 a = Character.toChars(codepoints[i]); 578 for (int k = 0; k < a.length; k++) { 579 if (str.charAt(j++) != a[k]) { 580 throw new RuntimeException("toChars(int) returned " + toHexString("result", a) 581 + " from codepoint=" + toHexString(codepoints[i])); 582 } 583 } 584 } 585 586 // Test toChars(int, char[], int) 587 a = new char[codepoints.length * 2]; 588 j = 0; 589 for (int i = 0; i < codepoints.length; i++) { 590 int n = Character.toChars(codepoints[i], a, j); 591 j += n; 592 } 593 String s = new String(a, 0, j); 594 if (!str.equals(s)) { 595 throw new RuntimeException("toChars(int, char[], int) returned " 596 + toHexString("dst", s.toCharArray()) 597 + ", expected " + toHexString("data", str.toCharArray())); 598 } 599 } 600 601 // Test toChar(int) 602 // toChar(int, char[], int) 603 // toString(int) 604 // for exceptions testExceptions00()605 static void testExceptions00() { 606 callToChars1(-1, IllegalArgumentException.class); 607 callToChars1(MAX_SUPPLEMENTARY + 1, IllegalArgumentException.class); 608 609 callToChars3(MAX_SUPPLEMENTARY, null, 0, NullPointerException.class); 610 callToChars3(-MIN_SUPPLEMENTARY, new char[2], 0, IllegalArgumentException.class); 611 callToChars3(MAX_SUPPLEMENTARY + 1, new char[2], 0, IllegalArgumentException.class); 612 callToChars3('A', new char[0], 0, IndexOutOfBoundsException.class); 613 callToChars3('A', new char[1], -1, IndexOutOfBoundsException.class); 614 callToChars3('A', new char[1], 1, IndexOutOfBoundsException.class); 615 callToChars3(MIN_SUPPLEMENTARY, new char[0], 0, IndexOutOfBoundsException.class); 616 callToChars3(MIN_SUPPLEMENTARY, new char[1], 0, IndexOutOfBoundsException.class); 617 callToChars3(MIN_SUPPLEMENTARY, new char[2], -1, IndexOutOfBoundsException.class); 618 callToChars3(MIN_SUPPLEMENTARY, new char[2], 1, IndexOutOfBoundsException.class); 619 620 callToString(Character.MIN_CODE_POINT - 1, IllegalArgumentException.class); 621 callToString(Character.MAX_CODE_POINT + 1, IllegalArgumentException.class); 622 } 623 624 static final boolean At = true, Before = false; 625 626 /** 627 * Test codePointAt(CharSequence, int) 628 * codePointBefore(CharSequence, int) 629 * codePointCount(CharSequence, int, int) 630 * offsetByCodePoints(CharSequence, int, int) 631 * for exceptions 632 */ testExceptions01(CharSequence cs)633 static void testExceptions01(CharSequence cs) { 634 CharSequence nullSeq = null; 635 // codePointAt 636 callCodePoint(At, nullSeq, 0, NullPointerException.class); 637 callCodePoint(At, cs, -1, IndexOutOfBoundsException.class); 638 callCodePoint(At, cs, cs.length(), IndexOutOfBoundsException.class); 639 callCodePoint(At, cs, cs.length()*3, IndexOutOfBoundsException.class); 640 641 // codePointBefore 642 callCodePoint(Before, nullSeq, 0, NullPointerException.class); 643 callCodePoint(Before, cs, -1, IndexOutOfBoundsException.class); 644 callCodePoint(Before, cs, 0, IndexOutOfBoundsException.class); 645 callCodePoint(Before, cs, cs.length()+1, IndexOutOfBoundsException.class); 646 647 // codePointCount 648 callCodePointCount(nullSeq, 0, 0, NullPointerException.class); 649 callCodePointCount(cs, -1, 1, IndexOutOfBoundsException.class); 650 callCodePointCount(cs, 0, cs.length()+1, IndexOutOfBoundsException.class); 651 callCodePointCount(cs, 3, 1, IndexOutOfBoundsException.class); 652 653 // offsetByCodePoints 654 callOffsetByCodePoints(nullSeq, 0, 0, NullPointerException.class); 655 callOffsetByCodePoints(cs, -1, 1, IndexOutOfBoundsException.class); 656 callOffsetByCodePoints(cs, cs.length()+1, 1, IndexOutOfBoundsException.class); 657 callOffsetByCodePoints(cs, 0, cs.length()*2, IndexOutOfBoundsException.class); 658 callOffsetByCodePoints(cs, cs.length(), 1, IndexOutOfBoundsException.class); 659 callOffsetByCodePoints(cs, 0, -1, IndexOutOfBoundsException.class); 660 callOffsetByCodePoints(cs, cs.length(), -cs.length()*2, 661 IndexOutOfBoundsException.class); 662 callOffsetByCodePoints(cs, cs.length(), Integer.MIN_VALUE, 663 IndexOutOfBoundsException.class); 664 callOffsetByCodePoints(cs, 0, Integer.MAX_VALUE, IndexOutOfBoundsException.class); 665 } 666 667 /** 668 * Test codePointAt(char[], int) 669 * codePointAt(char[], int, int) 670 * codePointBefore(char[], int) 671 * codePointBefore(char[], int, int) 672 * codePointCount(char[], int, int) 673 * offsetByCodePoints(char[], int, int, int, int) 674 * for exceptions 675 */ testExceptions02(char[] a)676 static void testExceptions02(char[] a) { 677 char[] nullArray = null; 678 callCodePoint(At, nullArray, 0, NullPointerException.class); 679 callCodePoint(At, a, -1, IndexOutOfBoundsException.class); 680 callCodePoint(At, a, a.length, IndexOutOfBoundsException.class); 681 callCodePoint(At, a, a.length*3, IndexOutOfBoundsException.class); 682 callCodePoint(Before, nullArray, 0, NullPointerException.class); 683 callCodePoint(Before, a, -1, IndexOutOfBoundsException.class); 684 callCodePoint(Before, a, 0, IndexOutOfBoundsException.class); 685 callCodePoint(Before, a, a.length+1, IndexOutOfBoundsException.class); 686 687 // tests for the methods with limit 688 callCodePoint(At, nullArray, 0, 1, NullPointerException.class); 689 callCodePoint(At, a, 0, -1, IndexOutOfBoundsException.class); 690 callCodePoint(At, a, 0, 0, IndexOutOfBoundsException.class); 691 callCodePoint(At, a, 0, a.length+1, IndexOutOfBoundsException.class); 692 callCodePoint(At, a, 2, 1, IndexOutOfBoundsException.class); 693 callCodePoint(At, a, -1, 1, IndexOutOfBoundsException.class); 694 callCodePoint(At, a, a.length, 1, IndexOutOfBoundsException.class); 695 callCodePoint(At, a, a.length*3, 1, IndexOutOfBoundsException.class); 696 callCodePoint(Before, nullArray, 1, 0, NullPointerException.class); 697 callCodePoint(Before, a, 2, -1, IndexOutOfBoundsException.class); 698 callCodePoint(Before, a, 2, 2, IndexOutOfBoundsException.class); 699 callCodePoint(Before, a, 2, 3, IndexOutOfBoundsException.class); 700 callCodePoint(Before, a, 2, a.length, IndexOutOfBoundsException.class); 701 callCodePoint(Before, a, -1, -1, IndexOutOfBoundsException.class); 702 callCodePoint(Before, a, 0, 0, IndexOutOfBoundsException.class); 703 callCodePoint(Before, a, a.length+1, a.length-1, IndexOutOfBoundsException.class); 704 705 // codePointCount 706 callCodePointCount(nullArray, 0, 0, NullPointerException.class); 707 callCodePointCount(a, -1, 1, IndexOutOfBoundsException.class); 708 callCodePointCount(a, 0, -1, IndexOutOfBoundsException.class); 709 callCodePointCount(a, 0, a.length+1, IndexOutOfBoundsException.class); 710 callCodePointCount(a, 1, a.length, IndexOutOfBoundsException.class); 711 callCodePointCount(a, a.length, 1, IndexOutOfBoundsException.class); 712 callCodePointCount(a, a.length+1, -1, IndexOutOfBoundsException.class); 713 714 // offsetByCodePoints 715 callOffsetByCodePoints(nullArray, 0, 0, 0, 0, NullPointerException.class); 716 callOffsetByCodePoints(a, -1, a.length, 1, 1, IndexOutOfBoundsException.class); 717 callOffsetByCodePoints(a, 0, a.length+1, 1, 1, IndexOutOfBoundsException.class); 718 callOffsetByCodePoints(a, 10, a.length, 1, 1, IndexOutOfBoundsException.class); 719 callOffsetByCodePoints(a, 10, a.length-10, 1, 1, IndexOutOfBoundsException.class); 720 callOffsetByCodePoints(a, 10, 10, 21, 1, IndexOutOfBoundsException.class); 721 callOffsetByCodePoints(a, 20, -10, 15, 1, IndexOutOfBoundsException.class); 722 callOffsetByCodePoints(a, 10, 10, 15, 20, IndexOutOfBoundsException.class); 723 callOffsetByCodePoints(a, 10, 10, 15, -20, IndexOutOfBoundsException.class); 724 callOffsetByCodePoints(a, 0, a.length, -1, 1, IndexOutOfBoundsException.class); 725 callOffsetByCodePoints(a, 0, a.length, a.length+1, 1, IndexOutOfBoundsException.class); 726 callOffsetByCodePoints(a, 0, a.length, 0, a.length*2, IndexOutOfBoundsException.class); 727 callOffsetByCodePoints(a, 0, a.length, a.length, 1, IndexOutOfBoundsException.class); 728 callOffsetByCodePoints(a, 0, a.length, 0, -1, IndexOutOfBoundsException.class); 729 callOffsetByCodePoints(a, 0, a.length, a.length, -a.length*2, 730 IndexOutOfBoundsException.class); 731 callOffsetByCodePoints(a, 0, a.length, a.length, Integer.MIN_VALUE, 732 IndexOutOfBoundsException.class); 733 callOffsetByCodePoints(a, 0, a.length, 0, Integer.MAX_VALUE, 734 IndexOutOfBoundsException.class); 735 } 736 737 /** 738 * Test the 1-arg toChars(int) for exceptions 739 */ callToChars1(int codePoint, Class expectedException)740 private static void callToChars1(int codePoint, Class expectedException) { 741 try { 742 char[] a = Character.toChars(codePoint); 743 } catch (Exception e) { 744 if (expectedException.isInstance(e)) { 745 return; 746 } 747 throw new RuntimeException("Unspecified exception", e); 748 } 749 throw new RuntimeException("toChars(int) didn't throw " + expectedException.getName()); 750 } 751 752 /** 753 * Test the 3-arg toChars(int, char[], int) for exceptions 754 */ callToChars3(int codePoint, char[] dst, int index, Class expectedException)755 private static void callToChars3(int codePoint, char[] dst, int index, 756 Class expectedException) { 757 try { 758 int n = Character.toChars(codePoint, dst, index); 759 } catch (Exception e) { 760 if (expectedException.isInstance(e)) { 761 return; 762 } 763 throw new RuntimeException("Unspecified exception", e); 764 } 765 throw new RuntimeException("toChars(int,char[],int) didn't throw " 766 + expectedException.getName()); 767 } 768 callCodePoint(boolean isAt, CharSequence cs, int index, Class expectedException)769 private static void callCodePoint(boolean isAt, CharSequence cs, int index, 770 Class expectedException) { 771 try { 772 int c = isAt ? Character.codePointAt(cs, index) 773 : Character.codePointBefore(cs, index); 774 } catch (Exception e) { 775 if (expectedException.isInstance(e)) { 776 return; 777 } 778 throw new RuntimeException("Unspecified exception", e); 779 } 780 throw new RuntimeException("codePoint" + (isAt ? "At" : "Before") 781 + " didn't throw " + expectedException.getName()); 782 } 783 callCodePoint(boolean isAt, char[] a, int index, Class expectedException)784 private static void callCodePoint(boolean isAt, char[] a, int index, 785 Class expectedException) { 786 try { 787 int c = isAt ? Character.codePointAt(a, index) 788 : Character.codePointBefore(a, index); 789 } catch (Exception e) { 790 if (expectedException.isInstance(e)) { 791 return; 792 } 793 throw new RuntimeException("Unspecified exception", e); 794 } 795 throw new RuntimeException("codePoint" + (isAt ? "At" : "Before") 796 + " didn't throw " + expectedException.getName()); 797 } 798 callCodePoint(boolean isAt, char[] a, int index, int limit, Class expectedException)799 private static void callCodePoint(boolean isAt, char[] a, int index, int limit, 800 Class expectedException) { 801 try { 802 int c = isAt ? Character.codePointAt(a, index, limit) 803 : Character.codePointBefore(a, index, limit); 804 } catch (Exception e) { 805 if (expectedException.isInstance(e)) { 806 return; 807 } 808 throw new RuntimeException("Unspecified exception", e); 809 } 810 throw new RuntimeException("codePoint" + (isAt ? "At" : "Before") 811 + " didn't throw " + expectedException.getName()); 812 } 813 callCodePointCount(Object data, int beginIndex, int endIndex, Class expectedException)814 private static void callCodePointCount(Object data, int beginIndex, int endIndex, 815 Class expectedException) { 816 String type = getType(data); 817 try { 818 int n = (data instanceof CharSequence) ? 819 Character.codePointCount((CharSequence) data, beginIndex, endIndex) 820 : Character.codePointCount((char[]) data, beginIndex, endIndex); 821 } catch (Exception e) { 822 if (expectedException.isInstance(e)) { 823 return; 824 } 825 throw new RuntimeException("Unspecified exception", e); 826 } 827 throw new RuntimeException("codePointCount(" + type + "...) didn't throw " 828 + expectedException.getName()); 829 } 830 callOffsetByCodePoints(CharSequence seq, int index, int offset, Class expectedException)831 private static void callOffsetByCodePoints(CharSequence seq, int index, int offset, 832 Class expectedException) { 833 try { 834 int n = Character.offsetByCodePoints(seq, index, offset); 835 } catch (Exception e) { 836 if (expectedException.isInstance(e)) { 837 return; 838 } 839 throw new RuntimeException("Unspecified exception", e); 840 } 841 throw new RuntimeException("offsetCodePointCounts(CharSequnce...) didn't throw " 842 + expectedException.getName()); 843 } 844 845 callOffsetByCodePoints(char[] a, int start, int count, int index, int offset, Class expectedException)846 private static void callOffsetByCodePoints(char[] a, int start, int count, 847 int index, int offset, 848 Class expectedException) { 849 try { 850 int n = Character.offsetByCodePoints(a, start, count, index, offset); 851 } catch (Exception e) { 852 if (expectedException.isInstance(e)) { 853 return; 854 } 855 throw new RuntimeException("Unspecified exception", e); 856 } 857 throw new RuntimeException("offsetCodePointCounts(char[]...) didn't throw " 858 + expectedException.getName()); 859 } 860 callToString(int codePoint, Class expectedException)861 private static void callToString(int codePoint, Class expectedException) { 862 try { 863 String s = Character.toString(codePoint); 864 } catch (Exception e) { 865 if (expectedException.isInstance(e)) { 866 return; 867 } 868 throw new RuntimeException("Unspecified exception", e); 869 } 870 throw new RuntimeException("toString(int) didn't throw " 871 + expectedException.getName()); 872 } 873 getType(Object data)874 private static String getType(Object data) { 875 return (data instanceof CharSequence) ? "CharSequence" : "char[]"; 876 } 877 toHexString(int c)878 private static String toHexString(int c) { 879 return "0x" + Integer.toHexString(c); 880 } 881 toHexString(String name, char[] a)882 private static String toHexString(String name, char[] a) { 883 StringBuffer sb = new StringBuffer(); 884 for (int i = 0; i < a.length; i++) { 885 if (i > 0) { 886 sb.append(", "); 887 } 888 sb.append(name).append('[').append(i).append("]="); 889 sb.append(toHexString(a[i])); 890 } 891 return sb.toString(); 892 } 893 } 894