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