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) 2009-2015, International Business Machines Corporation and 7 * others. All Rights Reserved. 8 ******************************************************************************* 9 */ 10 11 package android.icu.dev.test.util; 12 13 import java.io.ByteArrayInputStream; 14 import java.io.ByteArrayOutputStream; 15 import java.io.IOException; 16 import java.io.InputStream; 17 import java.nio.ByteBuffer; 18 import java.util.Iterator; 19 20 import org.junit.Test; 21 import org.junit.runner.RunWith; 22 import org.junit.runners.JUnit4; 23 24 import android.icu.dev.test.TestFmwk; 25 import android.icu.impl.ICUBinary; 26 import android.icu.impl.Trie2; 27 import android.icu.impl.Trie2Writable; 28 import android.icu.impl.Trie2_16; 29 import android.icu.impl.Trie2_32; 30 import android.icu.testsharding.MainTestShard; 31 32 @MainTestShard 33 @RunWith(JUnit4.class) 34 public class Trie2Test extends TestFmwk { 35 /** 36 * Constructor 37 */ 38 public Trie2Test() 39 { 40 } 41 42 // public methods ----------------------------------------------- 43 44 // 45 // TestAPI. Check that all API methods can be called, and do at least some minimal 46 // operation correctly. This is not a full test of correct behavior. 47 // 48 @Test 49 public void TestTrie2API() { 50 // Trie2.createFromSerialized() 51 // This function is well exercised by TestRanges(). 52 53 // Trie2.getVersion(InputStream is, boolean anyEndianOk) 54 // 55 56 try { 57 Trie2Writable trie = new Trie2Writable(0,0); 58 ByteArrayOutputStream os = new ByteArrayOutputStream(); 59 trie.toTrie2_16().serialize(os); 60 ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray()); 61 assertEquals(null, 2, Trie2.getVersion(is, true)); 62 } catch (IOException e) { 63 errln(where() + e.toString()); 64 } 65 66 // Equals & hashCode 67 // 68 { 69 Trie2Writable trieWA = new Trie2Writable(0,0); 70 Trie2Writable trieWB = new Trie2Writable(0,0); 71 Trie2 trieA = trieWA; 72 Trie2 trieB = trieWB; 73 assertTrue("", trieA.equals(trieB)); 74 assertEquals("", trieA, trieB); 75 assertEquals("", trieA.hashCode(), trieB.hashCode()); 76 trieWA.set(500, 2); 77 assertNotEquals("", trieA, trieB); 78 // Note that the hash codes do not strictly need to be different, 79 // but it's highly likely that something is wrong if they are the same. 80 assertNotEquals("", trieA.hashCode(), trieB.hashCode()); 81 trieWB.set(500, 2); 82 trieA = trieWA.toTrie2_16(); 83 assertEquals("", trieA, trieB); 84 assertEquals("", trieA.hashCode(), trieB.hashCode()); 85 } 86 87 // 88 // Iterator creation 89 // 90 { 91 Trie2Writable trie = new Trie2Writable(17,0); 92 Iterator<Trie2.Range> it; 93 it = trie.iterator(); 94 95 Trie2.Range r = it.next(); 96 assertEquals("", 0, r.startCodePoint); 97 assertEquals("", 0x10ffff, r.endCodePoint); 98 assertEquals("", 17, r.value); 99 assertEquals("", false, r.leadSurrogate); 100 101 r = it.next(); 102 assertEquals("", 0xd800, r.startCodePoint); 103 assertEquals("", 0xdbff, r.endCodePoint); 104 assertEquals("", 17, r.value); 105 assertEquals("", true, r.leadSurrogate); 106 107 108 int i = 0; 109 for (Trie2.Range rr: trie) { 110 switch (i) { 111 case 0: 112 assertEquals("", 0, rr.startCodePoint); 113 assertEquals("", 0x10ffff, rr.endCodePoint); 114 assertEquals("", 17, rr.value); 115 assertEquals("", false, rr.leadSurrogate); 116 break; 117 case 1: 118 assertEquals("", 0xd800, rr.startCodePoint); 119 assertEquals("", 0xdbff, rr.endCodePoint); 120 assertEquals("", 17, rr.value); 121 assertEquals("", true, rr.leadSurrogate); 122 break; 123 default: 124 errln(where() + " Unexpected iteration result"); 125 } 126 i++; 127 } 128 } 129 130 // Iteration with a value mapping function 131 // 132 { 133 Trie2Writable trie = new Trie2Writable(0xbadfeed, 0); 134 trie.set(0x10123, 42); 135 136 Trie2.ValueMapper vm = new Trie2.ValueMapper() { 137 @Override 138 public int map(int v) { 139 if (v == 0xbadfeed) { 140 v = 42; 141 } 142 return v; 143 } 144 }; 145 Iterator<Trie2.Range> it = trie.iterator(vm); 146 Trie2.Range r = it.next(); 147 assertEquals("", 0, r.startCodePoint); 148 assertEquals("", 0x10ffff, r.endCodePoint); 149 assertEquals("", 42, r.value); 150 assertEquals("", false, r.leadSurrogate); 151 } 152 153 154 // Iteration over a leading surrogate range. 155 // 156 { 157 Trie2Writable trie = new Trie2Writable(0xdefa17, 0); 158 trie.set(0x2f810, 10); 159 Iterator<Trie2.Range> it = trie.iteratorForLeadSurrogate((char)0xd87e); 160 Trie2.Range r = it.next(); 161 assertEquals("", 0x2f800, r.startCodePoint); 162 assertEquals("", 0x2f80f, r.endCodePoint); 163 assertEquals("", 0xdefa17, r.value); 164 assertEquals("", false, r.leadSurrogate); 165 166 r = it.next(); 167 assertEquals("", 0x2f810, r.startCodePoint); 168 assertEquals("", 0x2f810, r.endCodePoint); 169 assertEquals("", 10, r.value); 170 assertEquals("", false, r.leadSurrogate); 171 172 r = it.next(); 173 assertEquals("", 0x2f811, r.startCodePoint); 174 assertEquals("", 0x2fbff, r.endCodePoint); 175 assertEquals("", 0xdefa17, r.value); 176 assertEquals("", false, r.leadSurrogate); 177 178 assertFalse("", it.hasNext()); 179 } 180 181 // Iteration over a leading surrogate range with a ValueMapper. 182 // 183 { 184 Trie2Writable trie = new Trie2Writable(0xdefa17, 0); 185 trie.set(0x2f810, 10); 186 Trie2.ValueMapper m = new Trie2.ValueMapper() { 187 @Override 188 public int map(int in) { 189 if (in==10) { 190 in = 0xdefa17; 191 } 192 return in; 193 } 194 }; 195 Iterator<Trie2.Range> it = trie.iteratorForLeadSurrogate((char)0xd87e, m); 196 Trie2.Range r = it.next(); 197 assertEquals("", 0x2f800, r.startCodePoint); 198 assertEquals("", 0x2fbff, r.endCodePoint); 199 assertEquals("", 0xdefa17, r.value); 200 assertEquals("", false, r.leadSurrogate); 201 202 assertFalse("", it.hasNext()); 203 } 204 205 // Trie2.serialize() 206 // Test the implementation in Trie2, which is used with Read Only Tries. 207 // 208 { 209 Trie2Writable trie = new Trie2Writable(101, 0); 210 trie.setRange(0xf000, 0x3c000, 200, true); 211 trie.set(0xffee, 300); 212 Trie2_16 frozen16 = trie.toTrie2_16(); 213 Trie2_32 frozen32 = trie.toTrie2_32(); 214 assertEquals("", trie, frozen16); 215 assertEquals("", trie, frozen32); 216 assertEquals("", frozen16, frozen32); 217 ByteArrayOutputStream os = new ByteArrayOutputStream(); 218 try { 219 frozen16.serialize(os); 220 Trie2 unserialized16 = Trie2.createFromSerialized(ByteBuffer.wrap(os.toByteArray())); 221 assertEquals("", trie, unserialized16); 222 assertEquals("", Trie2_16.class, unserialized16.getClass()); 223 224 os.reset(); 225 frozen32.serialize(os); 226 Trie2 unserialized32 = Trie2.createFromSerialized(ByteBuffer.wrap(os.toByteArray())); 227 assertEquals("", trie, unserialized32); 228 assertEquals("", Trie2_32.class, unserialized32.getClass()); 229 } catch (IOException e) { 230 errln(where() + " Unexpected exception: " + e); 231 } 232 233 234 } 235 } 236 237 238 @Test 239 public void TestTrie2WritableAPI() { 240 // 241 // Trie2Writable methods. Check that all functions are present and 242 // nominally working. Not an in-depth test. 243 // 244 245 // Trie2Writable constructor 246 Trie2 t1 = new Trie2Writable(6, 666); 247 248 // Constructor from another Trie2 249 Trie2 t2 = new Trie2Writable(t1); 250 assertTrue("", t1.equals(t2)); 251 252 // Set / Get 253 Trie2Writable t1w = new Trie2Writable(10, 666); 254 t1w.set(0x4567, 99); 255 assertEquals("", 10, t1w.get(0x4566)); 256 assertEquals("", 99, t1w.get(0x4567)); 257 assertEquals("", 666, t1w.get(-1)); 258 assertEquals("", 666, t1w.get(0x110000)); 259 260 261 // SetRange 262 t1w = new Trie2Writable(10, 666); 263 t1w.setRange(13 /*start*/, 6666 /*end*/, 7788 /*value*/, false /*overwrite */); 264 t1w.setRange(6000, 7000, 9900, true); 265 assertEquals("", 10, t1w.get(12)); 266 assertEquals("", 7788, t1w.get(13)); 267 assertEquals("", 7788, t1w.get(5999)); 268 assertEquals("", 9900, t1w.get(6000)); 269 assertEquals("", 9900, t1w.get(7000)); 270 assertEquals("", 10, t1w.get(7001)); 271 assertEquals("", 666, t1w.get(0x110000)); 272 273 // setRange from a Trie2.Range 274 // (Ranges are more commonly created by iterating over a Trie2, 275 // but create one by hand here) 276 Trie2.Range r = new Trie2.Range(); 277 r.startCodePoint = 50; 278 r.endCodePoint = 52; 279 r.value = 0x12345678; 280 r.leadSurrogate = false; 281 t1w = new Trie2Writable(0, 0xbad); 282 t1w.setRange(r, true); 283 assertEquals(null, 0, t1w.get(49)); 284 assertEquals("", 0x12345678, t1w.get(50)); 285 assertEquals("", 0x12345678, t1w.get(52)); 286 assertEquals("", 0, t1w.get(53)); 287 288 289 // setForLeadSurrogateCodeUnit / getFromU16SingleLead 290 t1w = new Trie2Writable(10, 0xbad); 291 assertEquals("", 10, t1w.getFromU16SingleLead((char)0x0d801)); 292 t1w.setForLeadSurrogateCodeUnit((char)0xd801, 5000); 293 t1w.set(0xd801, 6000); 294 assertEquals("", 5000, t1w.getFromU16SingleLead((char)0x0d801)); 295 assertEquals("", 6000, t1w.get(0x0d801)); 296 297 // get(). Is covered by nearly every other test. 298 299 300 // Trie2_16 getAsFrozen_16() 301 t1w = new Trie2Writable(10, 666); 302 t1w.set(42, 5555); 303 t1w.set(0x1ff00, 224); 304 Trie2_16 t1_16 = t1w.toTrie2_16(); 305 assertTrue("", t1w.equals(t1_16)); 306 // alter the writable Trie2 and then re-freeze. 307 t1w.set(152, 129); 308 t1_16 = t1w.toTrie2_16(); 309 assertTrue("", t1w.equals(t1_16)); 310 assertEquals("", 129, t1w.get(152)); 311 312 // Trie2_32 getAsFrozen_32() 313 // 314 t1w = new Trie2Writable(10, 666); 315 t1w.set(42, 5555); 316 t1w.set(0x1ff00, 224); 317 Trie2_32 t1_32 = t1w.toTrie2_32(); 318 assertTrue("", t1w.equals(t1_32)); 319 // alter the writable Trie2 and then re-freeze. 320 t1w.set(152, 129); 321 assertNotEquals("", t1_32, t1w); 322 t1_32 = t1w.toTrie2_32(); 323 assertTrue("", t1w.equals(t1_32)); 324 assertEquals("", 129, t1w.get(152)); 325 326 327 // serialize(OutputStream os, ValueWidth width) 328 // 329 ByteArrayOutputStream os = new ByteArrayOutputStream(); 330 t1w = new Trie2Writable(0, 0xbad); 331 t1w.set(0x41, 0x100); 332 t1w.set(0xc2, 0x200); 333 t1w.set(0x404, 0x300); 334 t1w.set(0xd903, 0x500); 335 t1w.set(0xdd29, 0x600); 336 t1w.set(0x1055d3, 0x700); 337 t1w.setForLeadSurrogateCodeUnit((char)0xda1a, 0x800); 338 try { 339 // Serialize to 16 bits. 340 int serializedLen = t1w.toTrie2_16().serialize(os); 341 // Fragile test. Serialized length could change with changes to compaction. 342 // But it should not change unexpectedly. 343 assertEquals("", 3508, serializedLen); 344 Trie2 t1ws16 = Trie2.createFromSerialized(ByteBuffer.wrap(os.toByteArray())); 345 assertEquals("", t1ws16.getClass(), Trie2_16.class); 346 assertEquals("", t1w, t1ws16); 347 348 // Serialize to 32 bits 349 os.reset(); 350 serializedLen = t1w.toTrie2_32().serialize(os); 351 // Fragile test. Serialized length could change with changes to compaction. 352 // But it should not change unexpectedly. 353 assertEquals("", 4332, serializedLen); 354 Trie2 t1ws32 = Trie2.createFromSerialized(ByteBuffer.wrap(os.toByteArray())); 355 assertEquals("", t1ws32.getClass(), Trie2_32.class); 356 assertEquals("", t1w, t1ws32); 357 } catch (IOException e) { 358 errln(where() + e.toString()); 359 } 360 361 362 } 363 364 @Test 365 public void TestCharSequenceIterator() { 366 String text = "abc123\ud800\udc01 "; // Includes a Unicode supplemental character 367 String vals = "LLLNNNX?S"; 368 369 Trie2Writable tw = new Trie2Writable(0, 666); 370 tw.setRange('a', 'z', 'L', false); 371 tw.setRange('1', '9', 'N', false); 372 tw.set(' ', 'S'); 373 tw.set(0x10001, 'X'); 374 375 Trie2.CharSequenceIterator it = tw.charSequenceIterator(text, 0); 376 377 // Check forwards iteration. 378 Trie2.CharSequenceValues ir; 379 int i; 380 for (i=0; it.hasNext(); i++) { 381 ir = it.next(); 382 int expectedCP = Character.codePointAt(text, i); 383 assertEquals("" + " i="+i, expectedCP, ir.codePoint); 384 assertEquals("" + " i="+i, i, ir.index); 385 assertEquals("" + " i="+i, vals.charAt(i), ir.value); 386 if (expectedCP >= 0x10000) { 387 i++; 388 } 389 } 390 assertEquals("", text.length(), i); 391 392 // Check reverse iteration, starting at an intermediate point. 393 it.set(5); 394 for (i=5; it.hasPrevious(); ) { 395 ir = it.previous(); 396 int expectedCP = Character.codePointBefore(text, i); 397 i -= (expectedCP < 0x10000? 1 : 2); 398 assertEquals("" + " i="+i, expectedCP, ir.codePoint); 399 assertEquals("" + " i="+i, i, ir.index); 400 assertEquals("" + " i="+i, vals.charAt(i), ir.value); 401 } 402 assertEquals("", 0, i); 403 404 } 405 406 407 // 408 // Port of Tests from ICU4C ... 409 // 410 // setRanges array elements are 411 // {start Code point, limit CP, value, overwrite} 412 // 413 // There must be an entry with limit 0 and with the intialValue. 414 // It may be preceded by an entry with negative limit and the errorValue. 415 // 416 // checkRanges array elemets are 417 // { limit code point, value} 418 // 419 // The expected value range is from the previous boundary's limit to before 420 // this boundary's limit 421 422 // 423 String[] trieNames = {"setRanges1", "setRanges2", "setRanges3", "setRangesEmpty", "setRangesSingleValue"}; 424 /* set consecutive ranges, even with value 0 */ 425 426 427 428 private static int[][] setRanges1 ={ 429 { 0, 0, 0, 0 }, 430 { 0, 0x40, 0, 0 }, 431 { 0x40, 0xe7, 0x1234, 0 }, 432 { 0xe7, 0x3400, 0, 0 }, 433 { 0x3400, 0x9fa6, 0x6162, 0 }, 434 { 0x9fa6, 0xda9e, 0x3132, 0 }, 435 { 0xdada, 0xeeee, 0x87ff, 0 }, 436 { 0xeeee, 0x11111, 1, 0 }, 437 { 0x11111, 0x44444, 0x6162, 0 }, 438 { 0x44444, 0x60003, 0, 0 }, 439 { 0xf0003, 0xf0004, 0xf, 0 }, 440 { 0xf0004, 0xf0006, 0x10, 0 }, 441 { 0xf0006, 0xf0007, 0x11, 0 }, 442 { 0xf0007, 0xf0040, 0x12, 0 }, 443 { 0xf0040, 0x110000, 0, 0 } 444 }; 445 446 private static int[][] checkRanges1 = { 447 { 0, 0 }, 448 { 0x40, 0 }, 449 { 0xe7, 0x1234 }, 450 { 0x3400, 0 }, 451 { 0x9fa6, 0x6162 }, 452 { 0xda9e, 0x3132 }, 453 { 0xdada, 0 }, 454 { 0xeeee, 0x87ff }, 455 { 0x11111, 1 }, 456 { 0x44444, 0x6162 }, 457 { 0xf0003, 0 }, 458 { 0xf0004, 0xf }, 459 { 0xf0006, 0x10 }, 460 { 0xf0007, 0x11 }, 461 { 0xf0040, 0x12 }, 462 { 0x110000, 0 } 463 }; 464 465 /* set some interesting overlapping ranges */ 466 private static int [][] setRanges2={ 467 { 0, 0, 0, 0 }, 468 { 0x21, 0x7f, 0x5555, 1 }, 469 { 0x2f800, 0x2fedc, 0x7a, 1 }, 470 { 0x72, 0xdd, 3, 1 }, 471 { 0xdd, 0xde, 4, 0 }, 472 { 0x201, 0x240, 6, 1 }, /* 3 consecutive blocks with the same pattern but */ 473 { 0x241, 0x280, 6, 1 }, /* discontiguous value ranges, testing utrie2_enum() */ 474 { 0x281, 0x2c0, 6, 1 }, 475 { 0x2f987, 0x2fa98, 5, 1 }, 476 { 0x2f777, 0x2f883, 0, 1 }, 477 { 0x2f900, 0x2ffaa, 1, 0 }, 478 { 0x2ffaa, 0x2ffab, 2, 1 }, 479 { 0x2ffbb, 0x2ffc0, 7, 1 } 480 }; 481 482 private static int[] [] checkRanges2={ 483 { 0, 0 }, 484 { 0x21, 0 }, 485 { 0x72, 0x5555 }, 486 { 0xdd, 3 }, 487 { 0xde, 4 }, 488 { 0x201, 0 }, 489 { 0x240, 6 }, 490 { 0x241, 0 }, 491 { 0x280, 6 }, 492 { 0x281, 0 }, 493 { 0x2c0, 6 }, 494 { 0x2f883, 0 }, 495 { 0x2f987, 0x7a }, 496 { 0x2fa98, 5 }, 497 { 0x2fedc, 0x7a }, 498 { 0x2ffaa, 1 }, 499 { 0x2ffab, 2 }, 500 { 0x2ffbb, 0 }, 501 { 0x2ffc0, 7 }, 502 { 0x110000, 0 } 503 }; 504 505 /* 506 private static int[] [] checkRanges2_d800={ 507 { 0x10000, 0 }, 508 { 0x10400, 0 } 509 }; 510 511 private static int[][] checkRanges2_d87e={ 512 { 0x2f800, 6 }, 513 { 0x2f883, 0 }, 514 { 0x2f987, 0x7a }, 515 { 0x2fa98, 5 }, 516 { 0x2fc00, 0x7a } 517 }; 518 519 private static int[][] checkRanges2_d87f={ 520 { 0x2fc00, 0 }, 521 { 0x2fedc, 0x7a }, 522 { 0x2ffaa, 1 }, 523 { 0x2ffab, 2 }, 524 { 0x2ffbb, 0 }, 525 { 0x2ffc0, 7 }, 526 { 0x30000, 0 } 527 }; 528 529 private static int[][] checkRanges2_dbff={ 530 { 0x10fc00, 0 }, 531 { 0x110000, 0 } 532 }; 533 */ 534 535 /* use a non-zero initial value */ 536 private static int[][] setRanges3={ 537 { 0, 0, 9, 0 }, // non-zero initial value. 538 { 0x31, 0xa4, 1, 0 }, 539 { 0x3400, 0x6789, 2, 0 }, 540 { 0x8000, 0x89ab, 9, 1 }, 541 { 0x9000, 0xa000, 4, 1 }, 542 { 0xabcd, 0xbcde, 3, 1 }, 543 { 0x55555, 0x110000, 6, 1 }, /* highStart<U+ffff with non-initialValue */ 544 { 0xcccc, 0x55555, 6, 1 } 545 }; 546 547 private static int[][] checkRanges3={ 548 { 0, 9 }, /* non-zero initialValue */ 549 { 0x31, 9 }, 550 { 0xa4, 1 }, 551 { 0x3400, 9 }, 552 { 0x6789, 2 }, 553 { 0x9000, 9 }, 554 { 0xa000, 4 }, 555 { 0xabcd, 9 }, 556 { 0xbcde, 3 }, 557 { 0xcccc, 9 }, 558 { 0x110000, 6 } 559 }; 560 561 /* empty or single-value tries, testing highStart==0 */ 562 private static int[][] setRangesEmpty={ 563 { 0, 0, 3, 0 } // Only the element with the initial value. 564 }; 565 566 private static int[][] checkRangesEmpty={ 567 { 0, 3 }, 568 { 0x110000, 3 } 569 }; 570 571 private static int[][] setRangesSingleValue={ 572 { 0, 0, 3, 0 }, // Initial value = 3 573 { 0, 0x110000, 5, 1 }, 574 }; 575 576 private static int[][] checkRangesSingleValue={ 577 { 0, 3 }, 578 { 0x110000, 5 } 579 }; 580 581 582 // 583 // Create a test Trie2 from a setRanges test array. 584 // Range data ported from C. 585 // 586 private Trie2Writable genTrieFromSetRanges(int [][] ranges) { 587 int i = 0; 588 int initialValue = 0; 589 int errorValue = 0x0bad; 590 591 if (ranges[i][1] < 0) { 592 errorValue = ranges[i][2]; 593 i++; 594 } 595 initialValue = ranges[i++][2]; 596 Trie2Writable trie = new Trie2Writable(initialValue, errorValue); 597 598 for (; i<ranges.length; i++) { 599 int rangeStart = ranges[i][0]; 600 int rangeEnd = ranges[i][1]-1; 601 int value = ranges[i][2]; 602 boolean overwrite = (ranges[i][3] != 0); 603 trie.setRange(rangeStart, rangeEnd, value, overwrite); 604 } 605 606 // Insert some non-default values for lead surrogates. 607 // TODO: this should be represented in the data. 608 trie.setForLeadSurrogateCodeUnit((char)0xd800, 90); 609 trie.setForLeadSurrogateCodeUnit((char)0xd999, 94); 610 trie.setForLeadSurrogateCodeUnit((char)0xdbff, 99); 611 612 return trie; 613 } 614 615 616 // 617 // Check the expected values from a single Trie2. 618 // 619 private void trieGettersTest(String testName, 620 Trie2 trie, // The Trie2 to test. 621 int[][] checkRanges) // Expected data. 622 // Tuples of (value, high limit code point) 623 // High limit is first code point following the range 624 // with the indicated value. 625 // (Structures copied from ICU4C tests.) 626 { 627 int countCheckRanges = checkRanges.length; 628 629 int initialValue, errorValue; 630 int value, value2; 631 int start, limit; 632 int i, countSpecials; 633 634 countSpecials=0; /*getSpecialValues(checkRanges, countCheckRanges, &initialValue, &errorValue);*/ 635 errorValue = 0x0bad; 636 initialValue = 0; 637 if (checkRanges[countSpecials][0] == 0) { 638 initialValue = checkRanges[countSpecials][1]; 639 countSpecials++; 640 } 641 642 start=0; 643 for(i=countSpecials; i<countCheckRanges; ++i) { 644 limit=checkRanges[i][0]; 645 value=checkRanges[i][1]; 646 647 while(start<limit) { 648 value2=trie.get(start); 649 if (value != value2) { 650 // The redundant if, outside of the assert, is for speed. 651 // It makes a significant difference for this test. 652 assertEquals("wrong value for " + testName + " of " + Integer.toHexString(start), value, value2); 653 } 654 ++start; 655 } 656 } 657 658 659 if(!testName.startsWith("dummy") && !testName.startsWith("trie1")) { 660 /* Test values for lead surrogate code units. 661 * For non-lead-surrogate code units, getFromU16SingleLead() and get() 662 * should be the same. 663 */ 664 for(start=0xd7ff; start<0xdc01; ++start) { 665 switch(start) { 666 case 0xd7ff: 667 case 0xdc00: 668 value=trie.get(start); 669 break; 670 case 0xd800: 671 value=90; 672 break; 673 case 0xd999: 674 value=94; 675 break; 676 case 0xdbff: 677 value=99; 678 break; 679 default: 680 value=initialValue; 681 break; 682 } 683 value2 = trie.getFromU16SingleLead((char)start); 684 if(value2!=value) { 685 errln(where() + " testName: " + testName + " getFromU16SingleLead() failed." + 686 "char, exected, actual = " + Integer.toHexString(start) + ", " + 687 Integer.toHexString(value) + ", " + Integer.toHexString(value2)); 688 } 689 } 690 } 691 692 /* test errorValue */ 693 value=trie.get(-1); 694 value2=trie.get(0x110000); 695 if(value!=errorValue || value2!=errorValue) { 696 errln("trie2.get() error value test. Expected, actual1, actual2 = " + 697 errorValue + ", " + value + ", " + value2); 698 } 699 700 // Check that Trie enumeration produces the same contents as simple get() 701 for (Trie2.Range range: trie) { 702 for (int cp=range.startCodePoint; cp<=range.endCodePoint; cp++) { 703 if (range.leadSurrogate) { 704 assertTrue(testName, cp>=(char)0xd800 && cp<(char)0xdc00); 705 assertEquals(testName, range.value, trie.getFromU16SingleLead((char)cp)); 706 } else { 707 assertEquals(testName, range.value, trie.get(cp)); 708 } 709 } 710 } 711 } 712 713 // Was testTrieRanges in ICU4C. Renamed to not conflict with ICU4J test framework. 714 private void checkTrieRanges(String testName, String serializedName, boolean withClone, 715 int[][] setRanges, int [][] checkRanges) throws IOException { 716 717 // Run tests against Tries that were built by ICU4C and serialized. 718 String fileName16 = "Trie2Test." + serializedName + ".16.tri2"; 719 String fileName32 = "Trie2Test." + serializedName + ".32.tri2"; 720 721 InputStream is = Trie2Test.class.getResourceAsStream(fileName16); 722 Trie2 trie16; 723 try { 724 trie16 = Trie2.createFromSerialized(ICUBinary.getByteBufferFromInputStreamAndCloseStream(is)); 725 } finally { 726 is.close(); 727 } 728 trieGettersTest(testName, trie16, checkRanges); 729 730 is = Trie2Test.class.getResourceAsStream(fileName32); 731 Trie2 trie32; 732 try { 733 trie32 = Trie2.createFromSerialized(ICUBinary.getByteBufferFromInputStreamAndCloseStream(is)); 734 } finally { 735 is.close(); 736 } 737 trieGettersTest(testName, trie32, checkRanges); 738 739 // Run the same tests against locally contructed Tries. 740 Trie2Writable trieW = genTrieFromSetRanges(setRanges); 741 trieGettersTest(testName, trieW, checkRanges); 742 assertEquals("", trieW, trie16); // Locally built tries must be 743 assertEquals("", trieW, trie32); // the same as those imported from ICU4C 744 745 746 Trie2_32 trie32a = trieW.toTrie2_32(); 747 trieGettersTest(testName, trie32a, checkRanges); 748 749 Trie2_16 trie16a = trieW.toTrie2_16(); 750 trieGettersTest(testName, trie16a, checkRanges); 751 752 } 753 754 // Was "TrieTest" in trie2test.c 755 @Test 756 public void TestRanges() throws IOException { 757 checkTrieRanges("set1", "setRanges1", false, setRanges1, checkRanges1); 758 checkTrieRanges("set2-overlap", "setRanges2", false, setRanges2, checkRanges2); 759 checkTrieRanges("set3-initial-9", "setRanges3", false, setRanges3, checkRanges3); 760 checkTrieRanges("set-empty", "setRangesEmpty", false, setRangesEmpty, checkRangesEmpty); 761 checkTrieRanges("set-single-value", "setRangesSingleValue", false, setRangesSingleValue, 762 checkRangesSingleValue); 763 checkTrieRanges("set2-overlap.withClone", "setRanges2", true, setRanges2, checkRanges2); 764 } 765 766 767 private String where() { 768 StackTraceElement[] st = new Throwable().getStackTrace(); 769 String w = "File: " + st[1].getFileName() + ", Line " + st[1].getLineNumber(); 770 return w; 771 } 772 } 773