1 /* GENERATED SOURCE. DO NOT MODIFY. */ 2 // 2016 and later: Unicode, Inc. and others. 3 // License & terms of use: http://www.unicode.org/copyright.html#License 4 /* 5 ******************************************************************************* 6 * Copyright (C) 1996-2014, International Business Machines Corporation and * 7 * others. All Rights Reserved. * 8 ******************************************************************************* 9 */ 10 11 package android.icu.dev.test.lang; 12 13 import org.junit.Test; 14 import org.junit.runner.RunWith; 15 import org.junit.runners.JUnit4; 16 17 import android.icu.dev.test.TestFmwk; 18 import android.icu.dev.test.UTF16Util; 19 import android.icu.impl.Utility; 20 import android.icu.lang.UCharacter; 21 import android.icu.text.ReplaceableString; 22 import android.icu.text.UTF16; 23 import android.icu.text.UTF16.StringComparator; 24 import android.icu.testsharding.MainTestShard; 25 26 /** 27 * Testing class for UTF16 28 * @author Syn Wee Quek 29 * @since feb 09 2001 30 */ 31 @MainTestShard 32 @RunWith(JUnit4.class) 33 public final class UTF16Test extends TestFmwk 34 { 35 // constructor =================================================== 36 37 /** 38 * Constructor 39 */ 40 public UTF16Test() 41 { 42 } 43 44 // public methods ================================================ 45 46 /** 47 * Testing UTF16 class methods append 48 */ 49 @Test 50 public void TestAppend() 51 { 52 StringBuffer strbuff = new StringBuffer("this is a string "); 53 char array[] = new char[UCharacter.MAX_VALUE >> 2]; 54 int strsize = strbuff.length(); 55 int arraysize = strsize; 56 57 if (0 != strsize) { 58 strbuff.getChars(0, strsize, array, 0); 59 } 60 for (int i = 1; i < UCharacter.MAX_VALUE; i += 100) { 61 UTF16.append(strbuff, i); 62 arraysize = UTF16.append(array, arraysize, i); 63 64 String arraystr = new String(array, 0, arraysize); 65 if (!arraystr.equals(strbuff.toString())) { 66 errln("FAIL Comparing char array append and string append " + 67 "with 0x" + Integer.toHexString(i)); 68 } 69 70 // this is to cater for the combination of 0xDBXX 0xDC50 which 71 // forms a supplementary character 72 if (i == 0xDC51) { 73 strsize --; 74 } 75 76 if (UTF16.countCodePoint(strbuff) != strsize + (i / 100) + 1) { 77 errln("FAIL Counting code points in string appended with " + 78 " 0x" + Integer.toHexString(i)); 79 break; 80 } 81 } 82 83 // coverage for new 1.5 - cover only so no real test 84 strbuff = new StringBuffer(); 85 UTF16.appendCodePoint(strbuff, 0x10000); 86 if (strbuff.length() != 2) { 87 errln("fail appendCodePoint"); 88 } 89 } 90 91 /** 92 * Testing UTF16 class methods bounds 93 */ 94 @Test 95 public void TestBounds() 96 { 97 StringBuffer strbuff = 98 //0 12345 6 7 8 9 99 new StringBuffer("\udc000123\ud800\udc00\ud801\udc01\ud802"); 100 String str = strbuff.toString(); 101 char array[] = str.toCharArray(); 102 int boundtype[] = {UTF16.SINGLE_CHAR_BOUNDARY, 103 UTF16.SINGLE_CHAR_BOUNDARY, 104 UTF16.SINGLE_CHAR_BOUNDARY, 105 UTF16.SINGLE_CHAR_BOUNDARY, 106 UTF16.SINGLE_CHAR_BOUNDARY, 107 UTF16.LEAD_SURROGATE_BOUNDARY, 108 UTF16.TRAIL_SURROGATE_BOUNDARY, 109 UTF16.LEAD_SURROGATE_BOUNDARY, 110 UTF16.TRAIL_SURROGATE_BOUNDARY, 111 UTF16.SINGLE_CHAR_BOUNDARY}; 112 int length = str.length(); 113 for (int i = 0; i < length; i ++) { 114 if (UTF16.bounds(str, i) != boundtype[i]) { 115 errln("FAIL checking bound type at index " + i); 116 } 117 if (UTF16.bounds(strbuff, i) != boundtype[i]) { 118 errln("FAIL checking bound type at index " + i); 119 } 120 if (UTF16.bounds(array, 0, length, i) != boundtype[i]) { 121 errln("FAIL checking bound type at index " + i); 122 } 123 } 124 // does not straddle between supplementary character 125 int start = 4; 126 int limit = 9; 127 int subboundtype1[] = {UTF16.SINGLE_CHAR_BOUNDARY, 128 UTF16.LEAD_SURROGATE_BOUNDARY, 129 UTF16.TRAIL_SURROGATE_BOUNDARY, 130 UTF16.LEAD_SURROGATE_BOUNDARY, 131 UTF16.TRAIL_SURROGATE_BOUNDARY}; 132 try { 133 UTF16.bounds(array, start, limit, -1); 134 errln("FAIL Out of bounds index in bounds should fail"); 135 } catch (Exception e) { 136 // getting rid of warnings 137 System.out.print(""); 138 } 139 140 for (int i = 0; i < limit - start; i ++) { 141 if (UTF16.bounds(array, start, limit, i) != subboundtype1[i]) { 142 errln("FAILED Subarray bounds in [" + start + ", " + limit + 143 "] expected " + subboundtype1[i] + " at offset " + i); 144 } 145 } 146 147 // starts from the mid of a supplementary character 148 int subboundtype2[] = {UTF16.SINGLE_CHAR_BOUNDARY, 149 UTF16.LEAD_SURROGATE_BOUNDARY, 150 UTF16.TRAIL_SURROGATE_BOUNDARY}; 151 152 start = 6; 153 limit = 9; 154 for (int i = 0; i < limit - start; i ++) { 155 if (UTF16.bounds(array, start, limit, i) != subboundtype2[i]) { 156 errln("FAILED Subarray bounds in [" + start + ", " + limit + 157 "] expected " + subboundtype2[i] + " at offset " + i); 158 } 159 } 160 161 // ends in the mid of a supplementary character 162 int subboundtype3[] = {UTF16.LEAD_SURROGATE_BOUNDARY, 163 UTF16.TRAIL_SURROGATE_BOUNDARY, 164 UTF16.SINGLE_CHAR_BOUNDARY}; 165 start = 5; 166 limit = 8; 167 for (int i = 0; i < limit - start; i ++) { 168 if (UTF16.bounds(array, start, limit, i) != subboundtype3[i]) { 169 errln("FAILED Subarray bounds in [" + start + ", " + limit + 170 "] expected " + subboundtype3[i] + " at offset " + i); 171 } 172 } 173 } 174 175 /** 176 * Testing UTF16 class methods charAt and charAtCodePoint 177 */ 178 @Test 179 public void TestCharAt() 180 { 181 StringBuffer strbuff = 182 new StringBuffer("12345\ud800\udc0167890\ud800\udc02"); 183 if (UTF16.charAt(strbuff, 0) != '1' || UTF16.charAt(strbuff, 2) != '3' 184 || UTF16.charAt(strbuff, 5) != 0x10001 || 185 UTF16.charAt(strbuff, 6) != 0x10001 || 186 UTF16.charAt(strbuff, 12) != 0x10002 || 187 UTF16.charAt(strbuff, 13) != 0x10002) { 188 errln("FAIL Getting character from string buffer error" ); 189 } 190 String str = strbuff.toString(); 191 if (UTF16.charAt(str, 0) != '1' || UTF16.charAt(str, 2) != '3' || 192 UTF16.charAt(str, 5) != 0x10001 || UTF16.charAt(str, 6) != 0x10001 193 || UTF16.charAt(str, 12) != 0x10002 || 194 UTF16.charAt(str, 13) != 0x10002) 195 { 196 errln("FAIL Getting character from string error" ); 197 } 198 char array[] = str.toCharArray(); 199 int start = 0; 200 int limit = str.length(); 201 if (UTF16.charAt(array, start, limit, 0) != '1' || 202 UTF16.charAt(array, start, limit, 2) != '3' || 203 UTF16.charAt(array, start, limit, 5) != 0x10001 || 204 UTF16.charAt(array, start, limit, 6) != 0x10001 || 205 UTF16.charAt(array, start, limit, 12) != 0x10002 || 206 UTF16.charAt(array, start, limit, 13) != 0x10002) { 207 errln("FAIL Getting character from array error" ); 208 } 209 // check the sub array here. 210 start = 6; 211 limit = 13; 212 try { 213 UTF16.charAt(array, start, limit, -1); 214 errln("FAIL out of bounds error expected"); 215 } catch (Exception e) { 216 System.out.print(""); 217 } 218 try { 219 UTF16.charAt(array, start, limit, 8); 220 errln("FAIL out of bounds error expected"); 221 } catch (Exception e) { 222 System.out.print(""); 223 } 224 if (UTF16.charAt(array, start, limit, 0) != 0xdc01) { 225 errln("FAIL Expected result in subarray 0xdc01"); 226 } 227 if (UTF16.charAt(array, start, limit, 6) != 0xd800) { 228 errln("FAIL Expected result in subarray 0xd800"); 229 } 230 ReplaceableString replaceable = new ReplaceableString(str); 231 if (UTF16.charAt(replaceable, 0) != '1' || 232 UTF16.charAt(replaceable, 2) != '3' || 233 UTF16.charAt(replaceable, 5) != 0x10001 || 234 UTF16.charAt(replaceable, 6) != 0x10001 || 235 UTF16.charAt(replaceable, 12) != 0x10002 || 236 UTF16.charAt(replaceable, 13) != 0x10002) { 237 errln("FAIL Getting character from replaceable error" ); 238 } 239 240 StringBuffer strbuffer = new StringBuffer("0xD805"); 241 UTF16.charAt((CharSequence)strbuffer, 0); 242 } 243 244 /** 245 * Testing UTF16 class methods countCodePoint 246 */ 247 @Test 248 public void TestCountCodePoint() 249 { 250 StringBuffer strbuff = new StringBuffer(""); 251 char array[] = null; 252 if (UTF16.countCodePoint(strbuff) != 0 || 253 UTF16.countCodePoint("") != 0 || 254 UTF16.countCodePoint(array,0 ,0) != 0) { 255 errln("FAIL Counting code points for empty strings"); 256 } 257 258 strbuff = new StringBuffer("this is a string "); 259 String str = strbuff.toString(); 260 array = str.toCharArray(); 261 int size = str.length(); 262 263 if (UTF16.countCodePoint(array, 0, 0) != 0) { 264 errln("FAIL Counting code points for 0 offset array"); 265 } 266 267 if (UTF16.countCodePoint(str) != size || 268 UTF16.countCodePoint(strbuff) != size || 269 UTF16.countCodePoint(array, 0, size) != size) { 270 errln("FAIL Counting code points"); 271 } 272 273 UTF16.append(strbuff, 0x10000); 274 str = strbuff.toString(); 275 array = str.toCharArray(); 276 if (UTF16.countCodePoint(str) != size + 1 || 277 UTF16.countCodePoint(strbuff) != size + 1 || 278 UTF16.countCodePoint(array, 0, size + 1) != size + 1 || 279 UTF16.countCodePoint(array, 0, size + 2) != size + 1) { 280 errln("FAIL Counting code points"); 281 } 282 UTF16.append(strbuff, 0x61); 283 str = strbuff.toString(); 284 array = str.toCharArray(); 285 if (UTF16.countCodePoint(str) != size + 2 || 286 UTF16.countCodePoint(strbuff) != size + 2 || 287 UTF16.countCodePoint(array, 0, size + 1) != size + 1 || 288 UTF16.countCodePoint(array, 0, size + 2) != size + 1 || 289 UTF16.countCodePoint(array, 0, size + 3) != size + 2) { 290 errln("FAIL Counting code points"); 291 } 292 } 293 294 /** 295 * Testing UTF16 class methods delete 296 */ 297 @Test 298 public void TestDelete() 299 { //01234567890123456 300 StringBuffer strbuff = new StringBuffer("these are strings"); 301 int size = strbuff.length(); 302 char array[] = strbuff.toString().toCharArray(); 303 304 UTF16.delete(strbuff, 3); 305 UTF16.delete(strbuff, 3); 306 UTF16.delete(strbuff, 3); 307 UTF16.delete(strbuff, 3); 308 UTF16.delete(strbuff, 3); 309 UTF16.delete(strbuff, 3); 310 try { 311 UTF16.delete(strbuff, strbuff.length()); 312 errln("FAIL deleting out of bounds character should fail"); 313 } catch (Exception e) { 314 System.out.print(""); 315 } 316 UTF16.delete(strbuff, strbuff.length() - 1); 317 if (!strbuff.toString().equals("the string")) { 318 errln("FAIL expected result after deleting characters is " + 319 "\"the string\""); 320 } 321 322 size = UTF16.delete(array, size, 3); 323 size = UTF16.delete(array, size, 3); 324 size = UTF16.delete(array, size, 3); 325 size = UTF16.delete(array, size, 3); 326 size = UTF16.delete(array, size, 3); 327 size = UTF16.delete(array, size, 3); 328 try { 329 UTF16.delete(array, size, size); 330 errln("FAIL deleting out of bounds character should fail"); 331 } catch (Exception e) { 332 System.out.print(""); 333 } 334 size = UTF16.delete(array, size, size - 1); 335 String str = new String(array, 0, size); 336 if (!str.equals("the string")) { 337 errln("FAIL expected result after deleting characters is " + 338 "\"the string\""); 339 } 340 //012345678 9 01 2 3 4 341 strbuff = new StringBuffer("string: \ud800\udc00 \ud801\udc01 \ud801\udc01"); 342 size = strbuff.length(); 343 array = strbuff.toString().toCharArray(); 344 345 UTF16.delete(strbuff, 8); 346 UTF16.delete(strbuff, 8); 347 UTF16.delete(strbuff, 9); 348 UTF16.delete(strbuff, 8); 349 UTF16.delete(strbuff, 9); 350 UTF16.delete(strbuff, 6); 351 UTF16.delete(strbuff, 6); 352 if (!strbuff.toString().equals("string")) { 353 errln("FAIL expected result after deleting characters is \"string\""); 354 } 355 356 size = UTF16.delete(array, size, 8); 357 size = UTF16.delete(array, size, 8); 358 size = UTF16.delete(array, size, 9); 359 size = UTF16.delete(array, size, 8); 360 size = UTF16.delete(array, size, 9); 361 size = UTF16.delete(array, size, 6); 362 size = UTF16.delete(array, size, 6); 363 str = new String(array, 0, size); 364 if (!str.equals("string")) { 365 errln("FAIL expected result after deleting characters is \"string\""); 366 } 367 } 368 369 /** 370 * Testing findOffsetFromCodePoint and findCodePointOffset 371 */ 372 @Test 373 public void TestfindOffset() 374 { 375 // jitterbug 47 376 String str = "a\uD800\uDC00b"; 377 StringBuffer strbuff = new StringBuffer(str); 378 char array[] = str.toCharArray(); 379 int limit = str.length(); 380 if (UTF16.findCodePointOffset(str, 0) != 0 || 381 UTF16.findOffsetFromCodePoint(str, 0) != 0 || 382 UTF16.findCodePointOffset(strbuff, 0) != 0 || 383 UTF16.findOffsetFromCodePoint(strbuff, 0) != 0 || 384 UTF16.findCodePointOffset(array, 0, limit, 0) != 0 || 385 UTF16.findOffsetFromCodePoint(array, 0, limit, 0) != 0) { 386 errln("FAIL Getting the first codepoint offset to a string with " + 387 "supplementary characters"); 388 } 389 if (UTF16.findCodePointOffset(str, 1) != 1 || 390 UTF16.findOffsetFromCodePoint(str, 1) != 1 || 391 UTF16.findCodePointOffset(strbuff, 1) != 1 || 392 UTF16.findOffsetFromCodePoint(strbuff, 1) != 1 || 393 UTF16.findCodePointOffset(array, 0, limit, 1) != 1 || 394 UTF16.findOffsetFromCodePoint(array, 0, limit, 1) != 1) { 395 errln("FAIL Getting the second codepoint offset to a string with " + 396 "supplementary characters"); 397 } 398 if (UTF16.findCodePointOffset(str, 2) != 1 || 399 UTF16.findOffsetFromCodePoint(str, 2) != 3 || 400 UTF16.findCodePointOffset(strbuff, 2) != 1 || 401 UTF16.findOffsetFromCodePoint(strbuff, 2) != 3 || 402 UTF16.findCodePointOffset(array, 0, limit, 2) != 1 || 403 UTF16.findOffsetFromCodePoint(array, 0, limit, 2) != 3) { 404 errln("FAIL Getting the third codepoint offset to a string with " + 405 "supplementary characters"); 406 } 407 if (UTF16.findCodePointOffset(str, 3) != 2 || 408 UTF16.findOffsetFromCodePoint(str, 3) != 4 || 409 UTF16.findCodePointOffset(strbuff, 3) != 2 || 410 UTF16.findOffsetFromCodePoint(strbuff, 3) != 4 || 411 UTF16.findCodePointOffset(array, 0, limit, 3) != 2 || 412 UTF16.findOffsetFromCodePoint(array, 0, limit, 3) != 4) { 413 errln("FAIL Getting the last codepoint offset to a string with " + 414 "supplementary characters"); 415 } 416 if (UTF16.findCodePointOffset(str, 4) != 3 || 417 UTF16.findCodePointOffset(strbuff, 4) != 3 || 418 UTF16.findCodePointOffset(array, 0, limit, 4) != 3) { 419 errln("FAIL Getting the length offset to a string with " + 420 "supplementary characters"); 421 } 422 try { 423 UTF16.findCodePointOffset(str, 5); 424 errln("FAIL Getting the a non-existence codepoint to a string " + 425 "with supplementary characters"); 426 } catch (Exception e) { 427 // this is a success 428 logln("Passed out of bounds codepoint offset"); 429 } 430 try { 431 UTF16.findOffsetFromCodePoint(str, 4); 432 errln("FAIL Getting the a non-existence codepoint to a string " + 433 "with supplementary characters"); 434 } catch (Exception e) { 435 // this is a success 436 logln("Passed out of bounds codepoint offset"); 437 } 438 try { 439 UTF16.findCodePointOffset(strbuff, 5); 440 errln("FAIL Getting the a non-existence codepoint to a string " + 441 "with supplementary characters"); 442 } catch (Exception e) { 443 // this is a success 444 logln("Passed out of bounds codepoint offset"); 445 } 446 try { 447 UTF16.findOffsetFromCodePoint(strbuff, 4); 448 errln("FAIL Getting the a non-existence codepoint to a string " + 449 "with supplementary characters"); 450 } catch (Exception e) { 451 // this is a success 452 logln("Passed out of bounds codepoint offset"); 453 } 454 try { 455 UTF16.findCodePointOffset(array, 0, limit, 5); 456 errln("FAIL Getting the a non-existence codepoint to a string " + 457 "with supplementary characters"); 458 } catch (Exception e) { 459 // this is a success 460 logln("Passed out of bounds codepoint offset"); 461 } 462 try { 463 UTF16.findOffsetFromCodePoint(array, 0, limit, 4); 464 errln("FAIL Getting the a non-existence codepoint to a string " + 465 "with supplementary characters"); 466 } catch (Exception e) { 467 // this is a success 468 logln("Passed out of bounds codepoint offset"); 469 } 470 471 if (UTF16.findCodePointOffset(array, 1, 3, 0) != 0 || 472 UTF16.findOffsetFromCodePoint(array, 1, 3, 0) != 0 || 473 UTF16.findCodePointOffset(array, 1, 3, 1) != 0 || 474 UTF16.findCodePointOffset(array, 1, 3, 2) != 1 || 475 UTF16.findOffsetFromCodePoint(array, 1, 3, 1) != 2) { 476 errln("FAIL Getting valid codepoint offset in sub array"); 477 } 478 } 479 480 /** 481 * Testing UTF16 class methods getCharCount, *Surrogate 482 */ 483 @Test 484 public void TestGetCharCountSurrogate() 485 { 486 if (UTF16.getCharCount(0x61) != 1 || 487 UTF16.getCharCount(0x10000) != 2) { 488 errln("FAIL getCharCount result failure"); 489 } 490 if (UTF16.getLeadSurrogate(0x61) != 0 || 491 UTF16.getTrailSurrogate(0x61) != 0x61 || 492 UTF16.isLeadSurrogate((char)0x61) || 493 UTF16.isTrailSurrogate((char)0x61) || 494 UTF16.getLeadSurrogate(0x10000) != 0xd800 || 495 UTF16.getTrailSurrogate(0x10000) != 0xdc00 || 496 UTF16.isLeadSurrogate((char)0xd800) != true || 497 UTF16.isTrailSurrogate((char)0xd800) || 498 UTF16.isLeadSurrogate((char)0xdc00) || 499 UTF16.isTrailSurrogate((char)0xdc00) != true) { 500 errln("FAIL *Surrogate result failure"); 501 } 502 503 if (UTF16.isSurrogate((char)0x61) || !UTF16.isSurrogate((char)0xd800) 504 || !UTF16.isSurrogate((char)0xdc00)) { 505 errln("FAIL isSurrogate result failure"); 506 } 507 } 508 509 /** 510 * Testing UTF16 class method insert 511 */ 512 @Test 513 public void TestInsert() 514 { 515 StringBuffer strbuff = new StringBuffer("0123456789"); 516 char array[] = new char[128]; 517 int srcEnd = strbuff.length(); 518 if (0 != srcEnd) { 519 strbuff.getChars(0, srcEnd, array, 0); 520 } 521 int length = 10; 522 UTF16.insert(strbuff, 5, 't'); 523 UTF16.insert(strbuff, 5, 's'); 524 UTF16.insert(strbuff, 5, 'e'); 525 UTF16.insert(strbuff, 5, 't'); 526 if (!(strbuff.toString().equals("01234test56789"))) { 527 errln("FAIL inserting \"test\""); 528 } 529 length = UTF16.insert(array, length, 5, 't'); 530 length = UTF16.insert(array, length, 5, 's'); 531 length = UTF16.insert(array, length, 5, 'e'); 532 length = UTF16.insert(array, length, 5, 't'); 533 String str = new String(array, 0, length); 534 if (!(str.equals("01234test56789"))) { 535 errln("FAIL inserting \"test\""); 536 } 537 UTF16.insert(strbuff, 0, 0x10000); 538 UTF16.insert(strbuff, 11, 0x10000); 539 UTF16.insert(strbuff, strbuff.length(), 0x10000); 540 if (!(strbuff.toString().equals( 541 "\ud800\udc0001234test\ud800\udc0056789\ud800\udc00"))) { 542 errln("FAIL inserting supplementary characters"); 543 } 544 length = UTF16.insert(array, length, 0, 0x10000); 545 length = UTF16.insert(array, length, 11, 0x10000); 546 length = UTF16.insert(array, length, length, 0x10000); 547 str = new String(array, 0, length); 548 if (!(str.equals( 549 "\ud800\udc0001234test\ud800\udc0056789\ud800\udc00"))) { 550 errln("FAIL inserting supplementary characters"); 551 } 552 553 try { 554 UTF16.insert(strbuff, -1, 0); 555 errln("FAIL invalid insertion offset"); 556 } catch (Exception e) { 557 System.out.print(""); 558 } 559 try { 560 UTF16.insert(strbuff, 64, 0); 561 errln("FAIL invalid insertion offset"); 562 } catch (Exception e) { 563 System.out.print(""); 564 } 565 try { 566 UTF16.insert(array, length, -1, 0); 567 errln("FAIL invalid insertion offset"); 568 } catch (Exception e) { 569 System.out.print(""); 570 } 571 try { 572 UTF16.insert(array, length, 64, 0); 573 errln("FAIL invalid insertion offset"); 574 } catch (Exception e) { 575 System.out.print(""); 576 } 577 try { 578 // exceeded array size 579 UTF16.insert(array, array.length, 64, 0); 580 errln("FAIL invalid insertion offset"); 581 } catch (Exception e) { 582 System.out.print(""); 583 } 584 } 585 586 /* 587 * Testing moveCodePointOffset APIs 588 */ 589 590 // 591 // checkMoveCodePointOffset 592 // Run a single test case through each of the moveCodePointOffset() functions. 593 // Parameters - 594 // s The string to work in. 595 // startIdx The starting position within the string. 596 // amount The number of code points to move. 597 // expectedResult The string index after the move, or -1 if the 598 // function should throw an exception. 599 private void checkMoveCodePointOffset(String s, int startIdx, int amount, int expectedResult) { 600 // Test with the String flavor of moveCodePointOffset 601 try { 602 int result = UTF16.moveCodePointOffset(s, startIdx, amount); 603 if (result != expectedResult) { 604 errln("FAIL: UTF16.moveCodePointOffset(String \"" + s + "\", " + startIdx + ", " + amount + ")" + 605 " returned " + result + ", expected result was " + 606 (expectedResult==-1 ? "exception" : Integer.toString(expectedResult))); 607 } 608 } 609 catch (IndexOutOfBoundsException e) { 610 if (expectedResult != -1) { 611 errln("FAIL: UTF16.moveCodePointOffset(String \"" + s + "\", " + startIdx + ", " + amount + ")" + 612 " returned exception" + ", expected result was " + expectedResult); 613 } 614 } 615 616 // Test with the StringBuffer flavor of moveCodePointOffset 617 StringBuffer sb = new StringBuffer(s); 618 try { 619 int result = UTF16.moveCodePointOffset(sb, startIdx, amount); 620 if (result != expectedResult) { 621 errln("FAIL: UTF16.moveCodePointOffset(StringBuffer \"" + s + "\", " + startIdx + ", " + amount + ")" + 622 " returned " + result + ", expected result was " + 623 (expectedResult==-1 ? "exception" : Integer.toString(expectedResult))); 624 } 625 } 626 catch (IndexOutOfBoundsException e) { 627 if (expectedResult != -1) { 628 errln("FAIL: UTF16.moveCodePointOffset(StringBuffer \"" + s + "\", " + startIdx + ", " + amount + ")" + 629 " returned exception" + ", expected result was " + expectedResult); 630 } 631 } 632 633 // Test with the char[] flavor of moveCodePointOffset 634 char ca[] = s.toCharArray(); 635 try { 636 int result = UTF16.moveCodePointOffset(ca, 0, s.length(), startIdx, amount); 637 if (result != expectedResult) { 638 errln("FAIL: UTF16.moveCodePointOffset(char[] \"" + s + "\", 0, " + s.length() 639 + ", " + startIdx + ", " + amount + ")" + 640 " returned " + result + ", expected result was " + 641 (expectedResult==-1 ? "exception" : Integer.toString(expectedResult))); 642 } 643 } 644 catch (IndexOutOfBoundsException e) { 645 if (expectedResult != -1) { 646 errln("FAIL: UTF16.moveCodePointOffset(char[] \"" + s + "\", 0, " + s.length() 647 + ", " + startIdx + ", " + amount + ")" + 648 " returned exception" + ", expected result was " + expectedResult); 649 } 650 } 651 652 // Put the test string into the interior of a char array, 653 // run test on the subsection of the array. 654 char ca2[] = new char[s.length()+2]; 655 ca2[0] = (char)0xd800; 656 ca2[s.length()+1] = (char)0xd8ff; 657 s.getChars(0, s.length(), ca2, 1); 658 try { 659 int result = UTF16.moveCodePointOffset(ca2, 1, s.length()+1, startIdx, amount); 660 if (result != expectedResult) { 661 errln("UTF16.moveCodePointOffset(char[] \"" + "." + s + ".\", 1, " + (s.length()+1) 662 + ", " + startIdx + ", " + amount + ")" + 663 " returned " + result + ", expected result was " + 664 (expectedResult==-1 ? "exception" : Integer.toString(expectedResult))); 665 } 666 } 667 catch (IndexOutOfBoundsException e) { 668 if (expectedResult != -1) { 669 errln("UTF16.moveCodePointOffset(char[] \"" + "." + s + ".\", 1, " + (s.length()+1) 670 + ", " + startIdx + ", " + amount + ")" + 671 " returned exception" + ", expected result was " + expectedResult); 672 } 673 } 674 675 } 676 677 678 @Test 679 public void TestMoveCodePointOffset() 680 { 681 // checkMoveCodePointOffset(String, startIndex, amount, expected ); expected=-1 for exception. 682 683 // No Supplementary chars 684 checkMoveCodePointOffset("abc", 1, 1, 2); 685 checkMoveCodePointOffset("abc", 1, -1, 0); 686 checkMoveCodePointOffset("abc", 1, -2, -1); 687 checkMoveCodePointOffset("abc", 1, 2, 3); 688 checkMoveCodePointOffset("abc", 1, 3, -1); 689 checkMoveCodePointOffset("abc", 1, 0, 1); 690 691 checkMoveCodePointOffset("abc", 3, 0, 3); 692 checkMoveCodePointOffset("abc", 4, 0, -1); 693 checkMoveCodePointOffset("abc", 0, 0, 0); 694 checkMoveCodePointOffset("abc", -1, 0, -1); 695 696 checkMoveCodePointOffset("", 0, 0, 0); 697 checkMoveCodePointOffset("", 0, -1, -1); 698 checkMoveCodePointOffset("", 0, 1, -1); 699 700 checkMoveCodePointOffset("a", 0, 0, 0); 701 checkMoveCodePointOffset("a", 1, 0, 1); 702 checkMoveCodePointOffset("a", 0, 1, 1); 703 checkMoveCodePointOffset("a", 1, -1, 0); 704 705 706 // Supplementary in middle of string 707 checkMoveCodePointOffset("a\ud800\udc00b", 0, 1, 1); 708 checkMoveCodePointOffset("a\ud800\udc00b", 0, 2, 3); 709 checkMoveCodePointOffset("a\ud800\udc00b", 0, 3, 4); 710 checkMoveCodePointOffset("a\ud800\udc00b", 0, 4, -1); 711 712 checkMoveCodePointOffset("a\ud800\udc00b", 4, -1, 3); 713 checkMoveCodePointOffset("a\ud800\udc00b", 4, -2, 1); 714 checkMoveCodePointOffset("a\ud800\udc00b", 4, -3, 0); 715 checkMoveCodePointOffset("a\ud800\udc00b", 4, -4, -1); 716 717 // Supplementary at start of string 718 checkMoveCodePointOffset("\ud800\udc00ab", 0, 1, 2); 719 checkMoveCodePointOffset("\ud800\udc00ab", 1, 1, 2); 720 checkMoveCodePointOffset("\ud800\udc00ab", 2, 1, 3); 721 checkMoveCodePointOffset("\ud800\udc00ab", 2, -1, 0); 722 checkMoveCodePointOffset("\ud800\udc00ab", 1, -1, 0); 723 checkMoveCodePointOffset("\ud800\udc00ab", 0, -1, -1); 724 725 726 // Supplementary at end of string 727 checkMoveCodePointOffset("ab\ud800\udc00", 1, 1, 2); 728 checkMoveCodePointOffset("ab\ud800\udc00", 2, 1, 4); 729 checkMoveCodePointOffset("ab\ud800\udc00", 3, 1, 4); 730 checkMoveCodePointOffset("ab\ud800\udc00", 4, 1, -1); 731 732 checkMoveCodePointOffset("ab\ud800\udc00", 5, -2, -1); 733 checkMoveCodePointOffset("ab\ud800\udc00", 4, -1, 2); 734 checkMoveCodePointOffset("ab\ud800\udc00", 3, -1, 2); 735 checkMoveCodePointOffset("ab\ud800\udc00", 2, -1, 1); 736 checkMoveCodePointOffset("ab\ud800\udc00", 1, -1, 0); 737 738 // Unpaired surrogate in middle 739 checkMoveCodePointOffset("a\ud800b", 0, 1, 1); 740 checkMoveCodePointOffset("a\ud800b", 1, 1, 2); 741 checkMoveCodePointOffset("a\ud800b", 2, 1, 3); 742 743 checkMoveCodePointOffset("a\udc00b", 0, 1, 1); 744 checkMoveCodePointOffset("a\udc00b", 1, 1, 2); 745 checkMoveCodePointOffset("a\udc00b", 2, 1, 3); 746 747 checkMoveCodePointOffset("a\udc00\ud800b", 0, 1, 1); 748 checkMoveCodePointOffset("a\udc00\ud800b", 1, 1, 2); 749 checkMoveCodePointOffset("a\udc00\ud800b", 2, 1, 3); 750 checkMoveCodePointOffset("a\udc00\ud800b", 3, 1, 4); 751 752 checkMoveCodePointOffset("a\ud800b", 1, -1, 0); 753 checkMoveCodePointOffset("a\ud800b", 2, -1, 1); 754 checkMoveCodePointOffset("a\ud800b", 3, -1, 2); 755 756 checkMoveCodePointOffset("a\udc00b", 1, -1, 0); 757 checkMoveCodePointOffset("a\udc00b", 2, -1, 1); 758 checkMoveCodePointOffset("a\udc00b", 3, -1, 2); 759 760 checkMoveCodePointOffset("a\udc00\ud800b", 1, -1, 0); 761 checkMoveCodePointOffset("a\udc00\ud800b", 2, -1, 1); 762 checkMoveCodePointOffset("a\udc00\ud800b", 3, -1, 2); 763 checkMoveCodePointOffset("a\udc00\ud800b", 4, -1, 3); 764 765 // Unpaired surrogate at start 766 checkMoveCodePointOffset("\udc00ab", 0, 1, 1); 767 checkMoveCodePointOffset("\ud800ab", 0, 2, 2); 768 checkMoveCodePointOffset("\ud800\ud800ab", 0, 3, 3); 769 checkMoveCodePointOffset("\udc00\udc00ab", 0, 4, 4); 770 771 checkMoveCodePointOffset("\udc00ab", 2, -1, 1); 772 checkMoveCodePointOffset("\ud800ab", 1, -1, 0); 773 checkMoveCodePointOffset("\ud800ab", 1, -2, -1); 774 checkMoveCodePointOffset("\ud800\ud800ab", 2, -1, 1); 775 checkMoveCodePointOffset("\udc00\udc00ab", 2, -2, 0); 776 checkMoveCodePointOffset("\udc00\udc00ab", 2, -3, -1); 777 778 // Unpaired surrogate at end 779 checkMoveCodePointOffset("ab\udc00\udc00ab", 3, 1, 4); 780 checkMoveCodePointOffset("ab\udc00\udc00ab", 2, 1, 3); 781 checkMoveCodePointOffset("ab\udc00\udc00ab", 1, 1, 2); 782 783 checkMoveCodePointOffset("ab\udc00\udc00ab", 4, -1, 3); 784 checkMoveCodePointOffset("ab\udc00\udc00ab", 3, -1, 2); 785 checkMoveCodePointOffset("ab\udc00\udc00ab", 2, -1, 1); 786 787 788 //01234567890 1 2 3 45678901234 789 String str = new String("0123456789\ud800\udc00\ud801\udc010123456789"); 790 int move1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 791 12, 12, 14, 14, 15, 16, 17, 18, 19, 20, 792 21, 22, 23, 24}; 793 int move2[] = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 794 14, 14, 15, 15, 16, 17, 18, 19, 20, 21, 795 22, 23, 24, -1}; 796 int move3[] = { 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 797 15, 15, 16, 16, 17, 18, 19, 20, 21, 22, 798 23, 24, -1, -1}; 799 int size = str.length(); 800 for (int i = 0; i < size; i ++) { 801 checkMoveCodePointOffset(str, i, 1, move1[i]); 802 checkMoveCodePointOffset(str, i, 2, move2[i]); 803 checkMoveCodePointOffset(str, i, 3, move3[i]); 804 } 805 806 char strarray[] = str.toCharArray(); 807 if (UTF16.moveCodePointOffset(strarray, 9, 13, 0, 2) != 3) { 808 errln("FAIL: Moving offset 0 by 2 codepoint in subarray [9, 13] " + 809 "expected result 3"); 810 } 811 if (UTF16.moveCodePointOffset(strarray, 9, 13, 1, 2) != 4) { 812 errln("FAIL: Moving offset 1 by 2 codepoint in subarray [9, 13] " + 813 "expected result 4"); 814 } 815 if (UTF16.moveCodePointOffset(strarray, 11, 14, 0, 2) != 3) { 816 errln("FAIL: Moving offset 0 by 2 codepoint in subarray [11, 14] " 817 + "expected result 3"); 818 } 819 } 820 821 /** 822 * Testing UTF16 class methods setCharAt 823 */ 824 @Test 825 public void TestSetCharAt() 826 { 827 StringBuffer strbuff = new StringBuffer("012345"); 828 char array[] = new char[128]; 829 int srcEnd = strbuff.length(); 830 if (0 != srcEnd) { 831 strbuff.getChars(0, srcEnd, array, 0); 832 } 833 int length = 6; 834 for (int i = 0; i < length; i ++) { 835 UTF16.setCharAt(strbuff, i, '0'); 836 UTF16.setCharAt(array, length, i, '0'); 837 } 838 String str = new String(array, 0, length); 839 if (!(strbuff.toString().equals("000000")) || 840 !(str.equals("000000"))) { 841 errln("FAIL: setChar to '0' failed"); 842 } 843 UTF16.setCharAt(strbuff, 0, 0x10000); 844 UTF16.setCharAt(strbuff, 4, 0x10000); 845 UTF16.setCharAt(strbuff, 7, 0x10000); 846 if (!(strbuff.toString().equals( 847 "\ud800\udc0000\ud800\udc000\ud800\udc00"))) { 848 errln("FAIL: setChar to 0x10000 failed"); 849 } 850 length = UTF16.setCharAt(array, length, 0, 0x10000); 851 length = UTF16.setCharAt(array, length, 4, 0x10000); 852 length = UTF16.setCharAt(array, length, 7, 0x10000); 853 str = new String(array, 0, length); 854 if (!(str.equals("\ud800\udc0000\ud800\udc000\ud800\udc00"))) { 855 errln("FAIL: setChar to 0x10000 failed"); 856 } 857 UTF16.setCharAt(strbuff, 0, '0'); 858 UTF16.setCharAt(strbuff, 1, '1'); 859 UTF16.setCharAt(strbuff, 2, '2'); 860 UTF16.setCharAt(strbuff, 4, '3'); 861 UTF16.setCharAt(strbuff, 4, '4'); 862 UTF16.setCharAt(strbuff, 5, '5'); 863 if (!strbuff.toString().equals("012345")) { 864 errln("Fail converting supplementaries in StringBuffer to BMP " + 865 "characters"); 866 } 867 length = UTF16.setCharAt(array, length, 0, '0'); 868 length = UTF16.setCharAt(array, length, 1, '1'); 869 length = UTF16.setCharAt(array, length, 2, '2'); 870 length = UTF16.setCharAt(array, length, 4, '3'); 871 length = UTF16.setCharAt(array, length, 4, '4'); 872 length = UTF16.setCharAt(array, length, 5, '5'); 873 str = new String(array, 0, length); 874 if (!str.equals("012345")) { 875 errln("Fail converting supplementaries in array to BMP " + 876 "characters"); 877 } 878 try { 879 UTF16.setCharAt(strbuff, -1, 0); 880 errln("FAIL: setting character at invalid offset"); 881 } catch (Exception e) { 882 System.out.print(""); 883 } 884 try { 885 UTF16.setCharAt(array, length, -1, 0); 886 errln("FAIL: setting character at invalid offset"); 887 } catch (Exception e) { 888 System.out.print(""); 889 } 890 try { 891 UTF16.setCharAt(strbuff, length, 0); 892 errln("FAIL: setting character at invalid offset"); 893 } catch (Exception e) { 894 System.out.print(""); 895 } 896 try { 897 UTF16.setCharAt(array, length, length, 0); 898 errln("FAIL: setting character at invalid offset"); 899 } catch (Exception e) { 900 System.out.print(""); 901 } 902 } 903 904 /** 905 * Testing UTF16 valueof APIs 906 */ 907 @Test 908 public void TestValueOf() 909 { 910 if(UCharacter.getCodePoint('\ud800','\udc00')!=0x10000){ 911 errln("FAIL: getCodePoint('\ud800','\udc00')"); 912 } 913 if (!UTF16.valueOf(0x61).equals("a") || 914 !UTF16.valueOf(0x10000).equals("\ud800\udc00")) { 915 errln("FAIL: valueof(char32)"); 916 } 917 String str = new String("01234\ud800\udc0056789"); 918 StringBuffer strbuff = new StringBuffer(str); 919 char array[] = str.toCharArray(); 920 int length = str.length(); 921 922 String expected[] = {"0", "1", "2", "3", "4", "\ud800\udc00", 923 "\ud800\udc00", "5", "6", "7", "8", "9"}; 924 for (int i = 0; i < length; i ++) { 925 if (!UTF16.valueOf(str, i).equals(expected[i]) || 926 !UTF16.valueOf(strbuff, i).equals(expected[i]) || 927 !UTF16.valueOf(array, 0, length, i).equals(expected[i])) { 928 errln("FAIL: valueOf() expected " + expected[i]); 929 } 930 } 931 try { 932 UTF16.valueOf(str, -1); 933 errln("FAIL: out of bounds error expected"); 934 } catch (Exception e) { 935 System.out.print(""); 936 } 937 try { 938 UTF16.valueOf(strbuff, -1); 939 errln("FAIL: out of bounds error expected"); 940 } catch (Exception e) { 941 System.out.print(""); 942 } 943 try { 944 UTF16.valueOf(array, 0, length, -1); 945 errln("FAIL: out of bounds error expected"); 946 } catch (Exception e) { 947 System.out.print(""); 948 } 949 try { 950 UTF16.valueOf(str, length); 951 errln("FAIL: out of bounds error expected"); 952 } catch (Exception e) { 953 System.out.print(""); 954 } 955 try { 956 UTF16.valueOf(strbuff, length); 957 errln("FAIL: out of bounds error expected"); 958 } catch (Exception e) { 959 System.out.print(""); 960 } 961 try { 962 UTF16.valueOf(array, 0, length, length); 963 errln("FAIL: out of bounds error expected"); 964 } catch (Exception e) { 965 System.out.print(""); 966 } 967 if (!UTF16.valueOf(array, 6, length, 0).equals("\udc00") || 968 !UTF16.valueOf(array, 0, 6, 5).equals("\ud800")) { 969 errln("FAIL: error getting partial supplementary character"); 970 } 971 try { 972 UTF16.valueOf(array, 3, 5, -1); 973 errln("FAIL: out of bounds error expected"); 974 } catch (Exception e) { 975 System.out.print(""); 976 } 977 try { 978 UTF16.valueOf(array, 3, 5, 3); 979 errln("FAIL: out of bounds error expected"); 980 } catch (Exception e) { 981 System.out.print(""); 982 } 983 } 984 985 @Test 986 public void TestIndexOf() 987 { 988 //012345678901234567890123456789012345 989 String test1 = "test test ttest tetest testesteststt"; 990 String test2 = "test"; 991 int testChar1 = 0x74; 992 int testChar2 = 0x20402; 993 // int testChar3 = 0xdc02; 994 // int testChar4 = 0xd841; 995 String test3 = "\ud841\udc02\u0071\udc02\ud841\u0071\ud841\udc02\u0071\u0072\ud841\udc02\u0071\ud841\udc02\u0071\udc02\ud841\u0073"; 996 String test4 = UCharacter.toString(testChar2); 997 998 if (UTF16.indexOf(test1, test2) != 0 || 999 UTF16.indexOf(test1, test2, 0) != 0) { 1000 errln("indexOf failed: expected to find '" + test2 + 1001 "' at position 0 in text '" + test1 + "'"); 1002 } 1003 if (UTF16.indexOf(test1, testChar1) != 0 || 1004 UTF16.indexOf(test1, testChar1, 0) != 0) { 1005 errln("indexOf failed: expected to find 0x" + 1006 Integer.toHexString(testChar1) + 1007 " at position 0 in text '" + test1 + "'"); 1008 } 1009 if (UTF16.indexOf(test3, testChar2) != 0 || 1010 UTF16.indexOf(test3, testChar2, 0) != 0) { 1011 errln("indexOf failed: expected to find 0x" + 1012 Integer.toHexString(testChar2) + 1013 " at position 0 in text '" + Utility.hex(test3) + "'"); 1014 } 1015 String test5 = "\ud841\ud841\udc02"; 1016 if (UTF16.indexOf(test5, testChar2) != 1 || 1017 UTF16.indexOf(test5, testChar2, 0) != 1) { 1018 errln("indexOf failed: expected to find 0x" + 1019 Integer.toHexString(testChar2) + 1020 " at position 0 in text '" + Utility.hex(test3) + "'"); 1021 } 1022 if (UTF16.lastIndexOf(test1, test2) != 29 || 1023 UTF16.lastIndexOf(test1, test2, test1.length()) != 29) { 1024 errln("lastIndexOf failed: expected to find '" + test2 + 1025 "' at position 29 in text '" + test1 + "'"); 1026 } 1027 if (UTF16.lastIndexOf(test1, testChar1) != 35 || 1028 UTF16.lastIndexOf(test1, testChar1, test1.length()) != 35) { 1029 errln("lastIndexOf failed: expected to find 0x" + 1030 Integer.toHexString(testChar1) + 1031 " at position 35 in text '" + test1 + "'"); 1032 } 1033 if (UTF16.lastIndexOf(test3, testChar2) != 13 || 1034 UTF16.lastIndexOf(test3, testChar2, test3.length()) != 13) { 1035 errln("indexOf failed: expected to find 0x" + 1036 Integer.toHexString(testChar2) + 1037 " at position 13 in text '" + Utility.hex(test3) + "'"); 1038 } 1039 int occurrences = 0; 1040 for (int startPos = 0; startPos != -1 && startPos < test1.length();) 1041 { 1042 startPos = UTF16.indexOf(test1, test2, startPos); 1043 if (startPos >= 0) { 1044 ++ occurrences; 1045 startPos += 4; 1046 } 1047 } 1048 if (occurrences != 6) { 1049 errln("indexOf failed: expected to find 6 occurrences, found " 1050 + occurrences); 1051 } 1052 1053 occurrences = 0; 1054 for (int startPos = 10; startPos != -1 && startPos < test1.length();) 1055 { 1056 startPos = UTF16.indexOf(test1, test2, startPos); 1057 if (startPos >= 0) { 1058 ++ occurrences; 1059 startPos += 4; 1060 } 1061 } 1062 if (occurrences != 4) { 1063 errln("indexOf with starting offset failed: expected to find 4 occurrences, found " 1064 + occurrences); 1065 } 1066 1067 occurrences = 0; 1068 for (int startPos = 0; 1069 startPos != -1 && startPos < test3.length();) { 1070 startPos = UTF16.indexOf(test3, test4, startPos); 1071 if (startPos != -1) { 1072 ++ occurrences; 1073 startPos += 2; 1074 } 1075 } 1076 if (occurrences != 4) { 1077 errln("indexOf failed: expected to find 4 occurrences, found " 1078 + occurrences); 1079 } 1080 1081 occurrences = 0; 1082 for (int startPos = 10; 1083 startPos != -1 && startPos < test3.length();) { 1084 startPos = UTF16.indexOf(test3, test4, startPos); 1085 if (startPos != -1) { 1086 ++ occurrences; 1087 startPos += 2; 1088 } 1089 } 1090 if (occurrences != 2) { 1091 errln("indexOf failed: expected to find 2 occurrences, found " 1092 + occurrences); 1093 } 1094 1095 occurrences = 0; 1096 for (int startPos = 0; 1097 startPos != -1 && startPos < test1.length();) { 1098 startPos = UTF16.indexOf(test1, testChar1, startPos); 1099 if (startPos != -1) { 1100 ++ occurrences; 1101 startPos += 1; 1102 } 1103 } 1104 if (occurrences != 16) { 1105 errln("indexOf with character failed: expected to find 16 occurrences, found " 1106 + occurrences); 1107 } 1108 1109 occurrences = 0; 1110 for (int startPos = 10; 1111 startPos != -1 && startPos < test1.length();) { 1112 startPos = UTF16.indexOf(test1, testChar1, startPos); 1113 if (startPos != -1) { 1114 ++ occurrences; 1115 startPos += 1; 1116 } 1117 } 1118 if (occurrences != 12) { 1119 errln("indexOf with character & start offset failed: expected to find 12 occurrences, found " 1120 + occurrences); 1121 } 1122 1123 occurrences = 0; 1124 for (int startPos = 0; 1125 startPos != -1 && startPos < test3.length();) { 1126 startPos = UTF16.indexOf(test3, testChar2, startPos); 1127 if (startPos != -1) { 1128 ++ occurrences; 1129 startPos += 1; 1130 } 1131 } 1132 if (occurrences != 4) { 1133 errln("indexOf failed: expected to find 4 occurrences, found " 1134 + occurrences); 1135 } 1136 1137 occurrences = 0; 1138 for (int startPos = 5; startPos != -1 && startPos < test3.length();) { 1139 startPos = UTF16.indexOf(test3, testChar2, startPos); 1140 if (startPos != -1) { 1141 ++ occurrences; 1142 startPos += 1; 1143 } 1144 } 1145 if (occurrences != 3) { 1146 errln("indexOf with character & start & end offsets failed: expected to find 2 occurrences, found " 1147 + occurrences); 1148 } 1149 occurrences = 0; 1150 for (int startPos = 32; startPos != -1;) { 1151 startPos = UTF16.lastIndexOf(test1, test2, startPos); 1152 if (startPos != -1) { 1153 ++ occurrences; 1154 startPos -= 5; 1155 } 1156 } 1157 if (occurrences != 6) { 1158 errln("lastIndexOf with starting and ending offsets failed: expected to find 4 occurrences, found " 1159 + occurrences); 1160 } 1161 occurrences = 0; 1162 for (int startPos = 32; startPos != -1;) { 1163 startPos = UTF16.lastIndexOf(test1, testChar1, startPos); 1164 if (startPos != -1) { 1165 ++ occurrences; 1166 startPos -= 5; 1167 } 1168 } 1169 if (occurrences != 7) { 1170 errln("lastIndexOf with character & start & end offsets failed: expected to find 11 occurrences, found " 1171 + occurrences); 1172 } 1173 1174 //testing UChar32 1175 occurrences = 0; 1176 for (int startPos = test3.length(); startPos != -1;) { 1177 startPos = UTF16.lastIndexOf(test3, testChar2, startPos - 5); 1178 if (startPos != -1) { 1179 ++ occurrences; 1180 } 1181 } 1182 if (occurrences != 3) { 1183 errln("lastIndexOf with character & start & end offsets failed: expected to find 3 occurrences, found " 1184 + occurrences); 1185 } 1186 1187 // testing supplementary 1188 for (int i = 0; i < INDEXOF_SUPPLEMENTARY_CHAR_.length; i ++) { 1189 int ch = INDEXOF_SUPPLEMENTARY_CHAR_[i]; 1190 for (int j = 0; j < INDEXOF_SUPPLEMENTARY_CHAR_INDEX_[i].length; 1191 j ++) { 1192 int index = 0; 1193 int expected = INDEXOF_SUPPLEMENTARY_CHAR_INDEX_[i][j]; 1194 if (j > 0) { 1195 index = INDEXOF_SUPPLEMENTARY_CHAR_INDEX_[i][j - 1] + 1; 1196 } 1197 if (UTF16.indexOf(INDEXOF_SUPPLEMENTARY_STRING_, ch, index) != 1198 expected || 1199 UTF16.indexOf(INDEXOF_SUPPLEMENTARY_STRING_, 1200 UCharacter.toString(ch), index) != 1201 expected) { 1202 errln("Failed finding index for supplementary 0x" + 1203 Integer.toHexString(ch)); 1204 } 1205 index = INDEXOF_SUPPLEMENTARY_STRING_.length(); 1206 if (j < INDEXOF_SUPPLEMENTARY_CHAR_INDEX_[i].length - 1) { 1207 index = INDEXOF_SUPPLEMENTARY_CHAR_INDEX_[i][j + 1] - 1; 1208 } 1209 if (UTF16.lastIndexOf(INDEXOF_SUPPLEMENTARY_STRING_, ch, 1210 index) != expected || 1211 UTF16.lastIndexOf(INDEXOF_SUPPLEMENTARY_STRING_, 1212 UCharacter.toString(ch), index) 1213 != expected) 1214 { 1215 errln("Failed finding last index for supplementary 0x" + 1216 Integer.toHexString(ch)); 1217 } 1218 } 1219 } 1220 1221 for (int i = 0; i < INDEXOF_SUPPLEMENTARY_STR_INDEX_.length; i ++) { 1222 int index = 0; 1223 int expected = INDEXOF_SUPPLEMENTARY_STR_INDEX_[i]; 1224 if (i > 0) { 1225 index = INDEXOF_SUPPLEMENTARY_STR_INDEX_[i - 1] + 1; 1226 } 1227 if (UTF16.indexOf(INDEXOF_SUPPLEMENTARY_STRING_, 1228 INDEXOF_SUPPLEMENTARY_STR_, index) != expected) { 1229 errln("Failed finding index for supplementary string " + 1230 hex(INDEXOF_SUPPLEMENTARY_STRING_)); 1231 } 1232 index = INDEXOF_SUPPLEMENTARY_STRING_.length(); 1233 if (i < INDEXOF_SUPPLEMENTARY_STR_INDEX_.length - 1) { 1234 index = INDEXOF_SUPPLEMENTARY_STR_INDEX_[i + 1] - 1; 1235 } 1236 if (UTF16.lastIndexOf(INDEXOF_SUPPLEMENTARY_STRING_, 1237 INDEXOF_SUPPLEMENTARY_STR_, index) != expected) { 1238 errln("Failed finding last index for supplementary string " + 1239 hex(INDEXOF_SUPPLEMENTARY_STRING_)); 1240 } 1241 } 1242 } 1243 1244 @Test 1245 public void TestReplace() 1246 { 1247 String test1 = "One potato, two potato, three potato, four\n"; 1248 String test2 = "potato"; 1249 String test3 = "MISSISSIPPI"; 1250 1251 String result = UTF16.replace(test1, test2, test3); 1252 String expectedValue = 1253 "One MISSISSIPPI, two MISSISSIPPI, three MISSISSIPPI, four\n"; 1254 if (!result.equals(expectedValue)) { 1255 errln("findAndReplace failed: expected \"" + expectedValue + 1256 "\", got \"" + test1 + "\"."); 1257 } 1258 result = UTF16.replace(test1, test3, test2); 1259 expectedValue = test1; 1260 if (!result.equals(expectedValue)) { 1261 errln("findAndReplace failed: expected \"" + expectedValue + 1262 "\", got \"" + test1 + "\"."); 1263 } 1264 1265 result = UTF16.replace(test1, ',', 'e'); 1266 expectedValue = "One potatoe two potatoe three potatoe four\n"; 1267 if (!result.equals(expectedValue)) { 1268 errln("findAndReplace failed: expected \"" + expectedValue + 1269 "\", got \"" + test1 + "\"."); 1270 } 1271 1272 result = UTF16.replace(test1, ',', 0x10000); 1273 expectedValue = "One potato\ud800\udc00 two potato\ud800\udc00 three potato\ud800\udc00 four\n"; 1274 if (!result.equals(expectedValue)) { 1275 errln("findAndReplace failed: expected \"" + expectedValue + 1276 "\", got \"" + test1 + "\"."); 1277 } 1278 1279 result = UTF16.replace(test1, "potato", "\ud800\udc00\ud801\udc01"); 1280 expectedValue = "One \ud800\udc00\ud801\udc01, two \ud800\udc00\ud801\udc01, three \ud800\udc00\ud801\udc01, four\n"; 1281 if (!result.equals(expectedValue)) { 1282 errln("findAndReplace failed: expected \"" + expectedValue + 1283 "\", got \"" + test1 + "\"."); 1284 } 1285 1286 String test4 = "\ud800\ud800\udc00\ud800\udc00\udc00\ud800\ud800\udc00\ud800\udc00\udc00"; 1287 result = UTF16.replace(test4, 0xd800, 'A'); 1288 expectedValue = "A\ud800\udc00\ud800\udc00\udc00A\ud800\udc00\ud800\udc00\udc00"; 1289 if (!result.equals(expectedValue)) { 1290 errln("findAndReplace failed: expected \"" + expectedValue + 1291 "\", got \"" + test1 + "\"."); 1292 } 1293 1294 result = UTF16.replace(test4, 0xdC00, 'A'); 1295 expectedValue = "\ud800\ud800\udc00\ud800\udc00A\ud800\ud800\udc00\ud800\udc00A"; 1296 if (!result.equals(expectedValue)) { 1297 errln("findAndReplace failed: expected \"" + expectedValue + 1298 "\", got \"" + test1 + "\"."); 1299 } 1300 1301 result = UTF16.replace(test4, 0x10000, 'A'); 1302 expectedValue = "\ud800AA\udc00\ud800AA\udc00"; 1303 if (!result.equals(expectedValue)) { 1304 errln("findAndReplace failed: expected \"" + expectedValue + 1305 "\", got \"" + test1 + "\"."); 1306 } 1307 } 1308 1309 @Test 1310 public void TestReverse() 1311 { 1312 StringBuffer test = new StringBuffer( 1313 "backwards words say to used I"); 1314 1315 StringBuffer result = UTF16.reverse(test); 1316 if (!result.toString().equals("I desu ot yas sdrow sdrawkcab")) { 1317 errln("reverse() failed: Expected \"I desu ot yas sdrow sdrawkcab\",\n got \"" 1318 + result + "\""); 1319 } 1320 StringBuffer testbuffer = new StringBuffer(); 1321 UTF16.append(testbuffer, 0x2f999); 1322 UTF16.append(testbuffer, 0x1d15f); 1323 UTF16.append(testbuffer, 0x00c4); 1324 UTF16.append(testbuffer, 0x1ed0); 1325 result = UTF16.reverse(testbuffer); 1326 if (result.charAt(0) != 0x1ed0 || 1327 result.charAt(1) != 0xc4 || 1328 UTF16.charAt(result, 2) != 0x1d15f || 1329 UTF16.charAt(result, 4)!=0x2f999) { 1330 errln("reverse() failed with supplementary characters"); 1331 } 1332 } 1333 1334 /** 1335 * Testing the setter and getter apis for StringComparator 1336 */ 1337 @Test 1338 public void TestStringComparator() 1339 { 1340 UTF16.StringComparator compare = new UTF16.StringComparator(); 1341 if (compare.getCodePointCompare() != false) { 1342 errln("Default string comparator should be code unit compare"); 1343 } 1344 if (compare.getIgnoreCase() != false) { 1345 errln("Default string comparator should be case sensitive compare"); 1346 } 1347 if (compare.getIgnoreCaseOption() 1348 != UTF16.StringComparator.FOLD_CASE_DEFAULT) { 1349 errln("Default string comparator should have fold case default compare"); 1350 } 1351 compare.setCodePointCompare(true); 1352 if (compare.getCodePointCompare() != true) { 1353 errln("Error setting code point compare"); 1354 } 1355 compare.setCodePointCompare(false); 1356 if (compare.getCodePointCompare() != false) { 1357 errln("Error setting code point compare"); 1358 } 1359 compare.setIgnoreCase(true, UTF16.StringComparator.FOLD_CASE_DEFAULT); 1360 if (compare.getIgnoreCase() != true 1361 || compare.getIgnoreCaseOption() 1362 != UTF16.StringComparator.FOLD_CASE_DEFAULT) { 1363 errln("Error setting ignore case and options"); 1364 } 1365 compare.setIgnoreCase(false, UTF16.StringComparator.FOLD_CASE_EXCLUDE_SPECIAL_I); 1366 if (compare.getIgnoreCase() != false 1367 || compare.getIgnoreCaseOption() 1368 != UTF16.StringComparator.FOLD_CASE_EXCLUDE_SPECIAL_I) { 1369 errln("Error setting ignore case and options"); 1370 } 1371 compare.setIgnoreCase(true, UTF16.StringComparator.FOLD_CASE_EXCLUDE_SPECIAL_I); 1372 if (compare.getIgnoreCase() != true 1373 || compare.getIgnoreCaseOption() 1374 != UTF16.StringComparator.FOLD_CASE_EXCLUDE_SPECIAL_I) { 1375 errln("Error setting ignore case and options"); 1376 } 1377 compare.setIgnoreCase(false, UTF16.StringComparator.FOLD_CASE_DEFAULT); 1378 if (compare.getIgnoreCase() != false 1379 || compare.getIgnoreCaseOption() 1380 != UTF16.StringComparator.FOLD_CASE_DEFAULT) { 1381 errln("Error setting ignore case and options"); 1382 } 1383 } 1384 1385 @Test 1386 public void TestCodePointCompare() 1387 { 1388 // these strings are in ascending order 1389 String str[] = {"\u0061", "\u20ac\ud801", "\u20ac\ud800\udc00", 1390 "\ud800", "\ud800\uff61", "\udfff", 1391 "\uff61\udfff", "\uff61\ud800\udc02", "\ud800\udc02", 1392 "\ud84d\udc56"}; 1393 UTF16.StringComparator cpcompare 1394 = new UTF16.StringComparator(true, false, 1395 UTF16.StringComparator.FOLD_CASE_DEFAULT); 1396 UTF16.StringComparator cucompare 1397 = new UTF16.StringComparator(); 1398 for (int i = 0; i < str.length - 1; ++ i) { 1399 if (cpcompare.compare(str[i], str[i + 1]) >= 0) { 1400 errln("error: compare() in code point order fails for string " 1401 + Utility.hex(str[i]) + " and " 1402 + Utility.hex(str[i + 1])); 1403 } 1404 // test code unit compare 1405 if (cucompare.compare(str[i], str[i + 1]) 1406 != str[i].compareTo(str[i + 1])) { 1407 errln("error: compare() in code unit order fails for string " 1408 + Utility.hex(str[i]) + " and " 1409 + Utility.hex(str[i + 1])); 1410 } 1411 } 1412 } 1413 1414 @Test 1415 public void TestCaseCompare() 1416 { 1417 String mixed = "\u0061\u0042\u0131\u03a3\u00df\ufb03\ud93f\udfff"; 1418 String otherDefault = "\u0041\u0062\u0131\u03c3\u0073\u0053\u0046\u0066\u0049\ud93f\udfff"; 1419 String otherExcludeSpecialI = "\u0041\u0062\u0131\u03c3\u0053\u0073\u0066\u0046\u0069\ud93f\udfff"; 1420 String different = "\u0041\u0062\u0131\u03c3\u0073\u0053\u0046\u0066\u0049\ud93f\udffd"; 1421 1422 UTF16.StringComparator compare = new UTF16.StringComparator(); 1423 compare.setIgnoreCase(true, UTF16.StringComparator.FOLD_CASE_DEFAULT); 1424 // test u_strcasecmp() 1425 int result = compare.compare(mixed, otherDefault); 1426 if (result != 0) { 1427 errln("error: default compare(mixed, other) = " + result 1428 + " instead of 0"); 1429 } 1430 1431 // test u_strcasecmp() - exclude special i 1432 compare.setIgnoreCase(true, 1433 UTF16.StringComparator.FOLD_CASE_EXCLUDE_SPECIAL_I); 1434 result = compare.compare(mixed, otherExcludeSpecialI); 1435 if (result != 0) { 1436 errln("error: exclude_i compare(mixed, other) = " + result 1437 + " instead of 0"); 1438 } 1439 1440 // test u_strcasecmp() 1441 compare.setIgnoreCase(true, 1442 UTF16.StringComparator.FOLD_CASE_DEFAULT); 1443 result = compare.compare(mixed, different); 1444 if (result <= 0) { 1445 errln("error: default compare(mixed, different) = " + result 1446 + " instead of positive"); 1447 } 1448 1449 // test substrings - stop before the sharp s (U+00df) 1450 compare.setIgnoreCase(true, 1451 UTF16.StringComparator.FOLD_CASE_DEFAULT); 1452 result = compare.compare(mixed.substring(0, 4), 1453 different.substring(0, 4)); 1454 if (result != 0) { 1455 errln("error: default compare(mixed substring, different substring) = " 1456 + result + " instead of 0"); 1457 } 1458 // test substrings - stop in the middle of the sharp s (U+00df) 1459 compare.setIgnoreCase(true, 1460 UTF16.StringComparator.FOLD_CASE_DEFAULT); 1461 result = compare.compare(mixed.substring(0, 5), 1462 different.substring(0, 5)); 1463 if (result <= 0) { 1464 errln("error: default compare(mixed substring, different substring) = " 1465 + result + " instead of positive"); 1466 } 1467 } 1468 1469 @Test 1470 public void TestHasMoreCodePointsThan() 1471 { 1472 String str = "\u0061\u0062\ud800\udc00\ud801\udc01\u0063\ud802\u0064" 1473 + "\udc03\u0065\u0066\ud804\udc04\ud805\udc05\u0067"; 1474 int length = str.length(); 1475 while (length >= 0) { 1476 for (int i = 0; i <= length; ++ i) { 1477 String s = str.substring(0, i); 1478 for (int number = -1; number <= ((length - i) + 2); ++ number) { 1479 boolean flag = UTF16.hasMoreCodePointsThan(s, number); 1480 if (flag != (UTF16.countCodePoint(s) > number)) { 1481 errln("hasMoreCodePointsThan(" + Utility.hex(s) 1482 + ", " + number + ") = " + flag + " is wrong"); 1483 } 1484 } 1485 } 1486 -- length; 1487 } 1488 1489 // testing for null bad input 1490 for(length = -1; length <= 1; ++ length) { 1491 for (int i = 0; i <= length; ++ i) { 1492 for (int number = -2; number <= 2; ++ number) { 1493 boolean flag = UTF16.hasMoreCodePointsThan((String)null, 1494 number); 1495 if (flag != (UTF16.countCodePoint((String)null) > number)) { 1496 errln("hasMoreCodePointsThan(null, " + number + ") = " 1497 + flag + " is wrong"); 1498 } 1499 } 1500 } 1501 } 1502 1503 length = str.length(); 1504 while (length >= 0) { 1505 for (int i = 0; i <= length; ++ i) { 1506 StringBuffer s = new StringBuffer(str.substring(0, i)); 1507 for (int number = -1; number <= ((length - i) + 2); ++ number) { 1508 boolean flag = UTF16.hasMoreCodePointsThan(s, number); 1509 if (flag != (UTF16.countCodePoint(s) > number)) { 1510 errln("hasMoreCodePointsThan(" + Utility.hex(s) 1511 + ", " + number + ") = " + flag + " is wrong"); 1512 } 1513 } 1514 } 1515 -- length; 1516 } 1517 1518 // testing for null bad input 1519 for (length = -1; length <= 1; ++ length) { 1520 for (int i = 0; i <= length; ++ i) { 1521 for (int number = -2; number <= 2; ++ number) { 1522 boolean flag = UTF16.hasMoreCodePointsThan( 1523 (StringBuffer)null, number); 1524 if (flag 1525 != (UTF16.countCodePoint((StringBuffer)null) > number)) 1526 { 1527 errln("hasMoreCodePointsThan(null, " + number + ") = " 1528 + flag + " is wrong"); 1529 } 1530 } 1531 } 1532 } 1533 1534 char strarray[] = str.toCharArray(); 1535 while (length >= 0) { 1536 for (int limit = 0; limit <= length; ++ limit) { 1537 for (int start = 0; start <= limit; ++ start) { 1538 for (int number = -1; number <= ((limit - start) + 2); 1539 ++ number) { 1540 boolean flag = UTF16.hasMoreCodePointsThan(strarray, 1541 start, limit, number); 1542 if (flag != (UTF16.countCodePoint(strarray, start, 1543 limit) > number)) { 1544 errln("hasMoreCodePointsThan(" 1545 + Utility.hex(str.substring(start, limit)) 1546 + ", " + start + ", " + limit + ", " + number 1547 + ") = " + flag + " is wrong"); 1548 } 1549 } 1550 } 1551 } 1552 -- length; 1553 } 1554 1555 // testing for null bad input 1556 for (length = -1; length <= 1; ++ length) { 1557 for (int i = 0; i <= length; ++ i) { 1558 for (int number = -2; number <= 2; ++ number) { 1559 boolean flag = UTF16.hasMoreCodePointsThan( 1560 (StringBuffer)null, number); 1561 if (flag 1562 != (UTF16.countCodePoint((StringBuffer)null) > number)) 1563 { 1564 errln("hasMoreCodePointsThan(null, " + number + ") = " 1565 + flag + " is wrong"); 1566 } 1567 } 1568 } 1569 } 1570 1571 // bad input 1572 try { 1573 UTF16.hasMoreCodePointsThan(strarray, -2, -1, 5); 1574 errln("hasMoreCodePointsThan(chararray) with negative indexes has to throw an exception"); 1575 } catch (Exception e) { 1576 logln("PASS: UTF16.hasMoreCodePointsThan failed as expected"); 1577 } 1578 try { 1579 UTF16.hasMoreCodePointsThan(strarray, 5, 2, 5); 1580 errln("hasMoreCodePointsThan(chararray) with limit less than start index has to throw an exception"); 1581 } catch (Exception e) { 1582 logln("PASS: UTF16.hasMoreCodePointsThan failed as expected"); 1583 } 1584 try { 1585 if (UTF16.hasMoreCodePointsThan(strarray, -2, 2, 5)) { 1586 errln("hasMoreCodePointsThan(chararray) with negative start indexes can't return true"); 1587 } 1588 } catch (Exception e) { 1589 } 1590 } 1591 1592 @Test 1593 public void TestUtilities() { 1594 String[] tests = { 1595 "a", 1596 "\uFFFF", 1597 "", 1598 "\uD800", 1599 "\uDC00", 1600 "\uDBFF\uDfff", 1601 "", 1602 "\u0000", 1603 "\uDC00\uD800", 1604 "ab", 1605 "a", 1606 null, 1607 }; 1608 StringComparator sc = new UTF16.StringComparator(true,false,0); 1609 for (String item1 : tests) { 1610 String nonNull1 = item1 == null ? "" : item1; 1611 int count = UTF16.countCodePoint(nonNull1); 1612 int expected = count == 0 || count > 1 ? -1 : nonNull1.codePointAt(0); 1613 assertEquals("codepoint test " + Utility.hex(nonNull1), expected, UTF16.getSingleCodePoint(item1)); 1614 if (expected == -1) { 1615 continue; 1616 } 1617 for (String item2 : tests) { 1618 String nonNull2 = item2 == null ? "" : item2; 1619 int scValue = Integer.signum(sc.compare(nonNull1, nonNull2)); 1620 int fValue = Integer.signum(UTF16.compareCodePoint(expected, item2)); 1621 assertEquals("comparison " + Utility.hex(nonNull1) + ", " + Utility.hex(nonNull2), scValue, fValue); 1622 } 1623 } 1624 } 1625 1626 @Test 1627 public void TestNewString() { 1628 final int[] codePoints = { 1629 UCharacter.toCodePoint(UCharacter.MIN_HIGH_SURROGATE, UCharacter.MAX_LOW_SURROGATE), 1630 UCharacter.toCodePoint(UCharacter.MAX_HIGH_SURROGATE, UCharacter.MIN_LOW_SURROGATE), 1631 UCharacter.MAX_HIGH_SURROGATE, 1632 'A', 1633 -1, 1634 }; 1635 1636 1637 final String cpString = "" + 1638 UCharacter.MIN_HIGH_SURROGATE + 1639 UCharacter.MAX_LOW_SURROGATE + 1640 UCharacter.MAX_HIGH_SURROGATE + 1641 UCharacter.MIN_LOW_SURROGATE + 1642 UCharacter.MAX_HIGH_SURROGATE + 1643 'A'; 1644 1645 final int[][] tests = { 1646 { 0, 1, 0, 2 }, 1647 { 0, 2, 0, 4 }, 1648 { 1, 1, 2, 2 }, 1649 { 1, 2, 2, 3 }, 1650 { 1, 3, 2, 4 }, 1651 { 2, 2, 4, 2 }, 1652 { 2, 3, 0, -1 }, 1653 { 4, 5, 0, -1 }, 1654 { 3, -1, 0, -1 } 1655 }; 1656 1657 for (int i = 0; i < tests.length; ++i) { 1658 int[] t = tests[i]; 1659 int s = t[0]; 1660 int c = t[1]; 1661 int rs = t[2]; 1662 int rc = t[3]; 1663 1664 Exception e = null; 1665 try { 1666 String str = UTF16.newString(codePoints, s, c); 1667 if (rc == -1 || !str.equals(cpString.substring(rs, rs+rc))) { 1668 errln("failed codePoints iter: " + i + " start: " + s + " len: " + c); 1669 } 1670 continue; 1671 } 1672 catch (IndexOutOfBoundsException e1) { 1673 e = e1; 1674 } 1675 catch (IllegalArgumentException e2) { 1676 e = e2; 1677 } 1678 if (rc != -1) { 1679 errln(e.getMessage()); 1680 } 1681 } 1682 } 1683 1684 // private data members ---------------------------------------------- 1685 1686 private final static String INDEXOF_SUPPLEMENTARY_STRING_ = 1687 "\ud841\udc02\u0071\udc02\ud841\u0071\ud841\udc02\u0071\u0072" + 1688 "\ud841\udc02\u0071\ud841\udc02\u0071\udc02\ud841\u0073"; 1689 private final static int INDEXOF_SUPPLEMENTARY_CHAR_[] = 1690 {0x71, 0xd841, 0xdc02, 1691 UTF16Util.getRawSupplementary((char)0xd841, 1692 (char)0xdc02)}; 1693 private final static int INDEXOF_SUPPLEMENTARY_CHAR_INDEX_[][] = 1694 {{2, 5, 8, 12, 15}, 1695 {4, 17}, 1696 {3, 16}, 1697 {0, 6, 10, 13} 1698 }; 1699 private final static String INDEXOF_SUPPLEMENTARY_STR_ = "\udc02\ud841"; 1700 private final static int INDEXOF_SUPPLEMENTARY_STR_INDEX_[] = 1701 {3, 16}; 1702 1703 // private methods --------------------------------------------------- 1704 } 1705 1706