Home | History | Annotate | Download | only in bidi
      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) 2007-2013, International Business Machines
      7 *   Corporation and others.  All Rights Reserved.
      8 *******************************************************************************
      9 */
     10 
     11 package android.icu.dev.test.bidi;
     12 
     13 import java.util.Arrays;
     14 
     15 import org.junit.Test;
     16 
     17 import android.icu.text.Bidi;
     18 import android.icu.text.BidiRun;
     19 import android.icu.testsharding.MainTestShard;
     20 
     21 /**
     22  * Regression test for Bidi class override.
     23  *
     24  * @author Lina Kemmel, Matitiahu Allouche
     25  */
     26 
     27 @MainTestShard
     28 public class TestBidi extends BidiFmwk {
     29 
     30     private static final int MAXLEN = 256;
     31     private static final String levelString = "............................";
     32 
     33     @Test
     34     public void testBidi() {
     35         Bidi bidi;
     36         Bidi bidiLine;
     37 
     38         logln("\nEntering TestBidi");
     39         bidi = new Bidi(MAXLEN, 0);
     40         bidiLine = new Bidi();
     41 
     42         doTests(bidi, bidiLine, false);
     43         doTests(bidi, bidiLine, true);
     44         doMisc();
     45         logln("\nExiting TestBidi");
     46     }
     47 
     48     private void doTests(Bidi bidi, Bidi bidiLine, boolean countRunsFirst) {
     49         int testNumber;
     50         String string;
     51         int lineStart;
     52         byte paraLevel;
     53         int bidiTestCount = TestData.testCount();
     54 
     55         for (testNumber = 0; testNumber < bidiTestCount; ++testNumber) {
     56             TestData test = TestData.getTestData(testNumber);
     57             string = getStringFromDirProps(test.dirProps);
     58             paraLevel = test.paraLevel;
     59             try {
     60                 bidi.setPara(string, paraLevel, null);
     61                 logln("Bidi.setPara(tests[" + testNumber + "] OK, direction "
     62                         + bidi.getDirection() + " paraLevel "
     63                         + paraLevel);
     64             } catch (Exception e) {
     65                 errln("Bidi.setPara(tests[" + testNumber + "] failed, direction "
     66                         + bidi.getDirection() + " paraLevel "
     67                         + paraLevel);
     68             }
     69             lineStart = test.lineStart;
     70             if (lineStart == -1) {
     71                 doTest(bidi, testNumber, test, 0, countRunsFirst);
     72             } else {
     73                 try {
     74                     bidiLine = bidi.setLine(lineStart, test.lineLimit);
     75                     logln("Bidi.setLine(" + lineStart + ", " + test.lineLimit
     76                             + "), in tests[" + testNumber + "] OK, direction "
     77                             + bidiLine.getDirection() + " paraLevel "
     78                             + bidiLine.getBaseLevel());
     79                     doTest(bidiLine, testNumber, test, lineStart, countRunsFirst);
     80                 } catch (Exception e)  {
     81                     errln("Bidi.setLine(" + lineStart + ", " + test.lineLimit
     82                             + "), in runAll test[" + testNumber + "] failed");
     83                 }
     84                 /* do it again using createLineBidi instead of setLine */
     85                 try {
     86                     bidiLine = bidi.createLineBidi(lineStart, test.lineLimit);
     87                     logln("Bidi.createLineBidi(" + lineStart + ", " + test.lineLimit
     88                             + "), in tests[" + testNumber + "] OK, direction "
     89                             + bidiLine.getDirection() + " paraLevel "
     90                             + bidiLine.getBaseLevel());
     91                     doTest(bidiLine, testNumber, test, lineStart, countRunsFirst);
     92                 } catch (Exception e)  {
     93                     errln("Bidi.createLineBidi(" + lineStart + ", " + test.lineLimit
     94                             + "), in runAll test[" + testNumber + "] failed");
     95                 }
     96             }
     97         }
     98     }
     99 
    100     private void doTest(Bidi bidi, int testNumber, TestData test,
    101                         int lineStart, boolean countRunsFirst) {
    102         short[] dirProps = test.dirProps;
    103         byte[] levels = test.levels;
    104         int[] visualMap = test.visualMap;
    105         int i, len = bidi.getLength(), logicalIndex = -1, runCount = 0;
    106         byte level, level2;
    107 
    108         if (countRunsFirst) {
    109             logln("Calling Bidi.countRuns() first.");
    110             try {
    111                 runCount = bidi.countRuns();
    112             } catch (IllegalStateException e) {
    113                 errln("Bidi.countRuns(test[" + testNumber + "]) failed");
    114             }
    115         } else {
    116             logln("Calling Bidi.getLogicalMap() first.");
    117         }
    118 
    119         _testReordering(bidi, testNumber);
    120 
    121         for (i = 0; i < len; ++i) {
    122             logln(i + "  " + bidi.getLevelAt(i) + "  " + levelString
    123                     + TestData.dirPropNames[dirProps[lineStart + i]] + "  "
    124                     + bidi.getVisualIndex(i));
    125         }
    126 
    127         log("\n-----levels:");
    128         for (i = 0; i < len; ++i) {
    129             if (i > 0) {
    130                 log(",");
    131             }
    132             log(" " + bidi.getLevelAt(i));
    133         }
    134 
    135         log("\n--reordered:");
    136         for (i = 0; i < len; ++i) {
    137             if (i > 0) {
    138                 log(",");
    139             }
    140             log(" " + bidi.getVisualIndex(i));
    141         }
    142         log("\n");
    143 
    144         assertEquals("\nFailure in Bidi.getDirection(test[" + testNumber + "])",
    145                      test.direction, bidi.getDirection());
    146         assertEquals("\nFailure in Bidi.getParaLevel(test[" + testNumber + "])",
    147                      test.resultLevel, bidi.getParaLevel());
    148 
    149         for (i = 0; i < len; ++i) {
    150             assertEquals("\nFailure in Bidi.getLevelAt(" + i +
    151                          ") in test[" + testNumber + "]",
    152                          levels[i], bidi.getLevelAt(i));
    153         }
    154 
    155         for (i = 0; i < len; ++i) {
    156             try {
    157                 logicalIndex = bidi.getVisualIndex(i);
    158             } catch (Throwable th) {
    159                 errln("Bidi.getVisualIndex(" + i + ") in test[" + testNumber
    160                         + "] failed");
    161             }
    162             if(visualMap[i] != logicalIndex) {
    163                 assertEquals("\nFailure in Bidi.getVisualIndex(" + i +
    164                              ") in test[" + testNumber + "])",
    165                              visualMap[i], logicalIndex);
    166             }
    167         }
    168 
    169         if (!countRunsFirst) {
    170             try {
    171                 runCount = bidi.countRuns();
    172             } catch (IllegalStateException e) {
    173                 errln("Bidi.countRuns(test[" + testNumber + "]) failed");
    174             }
    175         }
    176 
    177         BidiRun run;
    178 
    179         for (logicalIndex = 0; logicalIndex < len; ) {
    180             level = bidi.getLevelAt(logicalIndex);
    181             run = bidi.getLogicalRun(logicalIndex);
    182             logicalIndex = run.getLimit();
    183             level2 = run.getEmbeddingLevel();
    184             assertEquals("Logical " + run.toString() +
    185                          " in test[" + testNumber + "]: wrong level",
    186                          level, level2);
    187             if (--runCount < 0) {
    188                 errln("Bidi.getLogicalRun(test[" + testNumber
    189                       + "]): wrong number of runs compared to Bidi.countRuns() = "
    190                       + bidi.countRuns());
    191             }
    192         }
    193         if (runCount != 0) {
    194             errln("Bidi.getLogicalRun(test[" + testNumber
    195                     + "]): wrong number of runs compared to Bidi.countRuns() = "
    196                     + bidi.countRuns());
    197         }
    198 
    199         log("\n\n");
    200     }
    201 
    202     private void _testReordering(Bidi bidi, int testNumber) {
    203         int[] logicalMap1;
    204         int[] logicalMap2;
    205         int[] logicalMap3;
    206         int[] visualMap1;
    207         int[] visualMap2;
    208         int[] visualMap3;
    209         int[] visualMap4 = new int[MAXLEN];
    210         byte[] levels;
    211         int i, length = bidi.getLength(),
    212                destLength = bidi.getResultLength();
    213         int runCount, visualIndex, logicalIndex = -1, logicalStart, runLength;
    214         boolean odd;
    215 
    216         if(length <= 0) {
    217             return;
    218         }
    219         /* get the logical and visual maps from the object */
    220         logicalMap1 = bidi.getLogicalMap();
    221         if (logicalMap1 == null) {
    222             errln("getLogicalMap in test " + testNumber + " is null");
    223             logicalMap1 = new int[0];
    224         }
    225 
    226         visualMap1 = bidi.getVisualMap();
    227 
    228         if (visualMap1 == null) {
    229             errln("getVisualMap() in test " + testNumber + " is null");
    230             visualMap1 = new int[0];
    231         }
    232 
    233         /* invert them both */
    234         visualMap2 = Bidi.invertMap(logicalMap1);
    235         logicalMap2 = Bidi.invertMap(visualMap1);
    236 
    237         /* get them from the levels array, too */
    238         levels = bidi.getLevels();
    239 
    240         if (levels == null || levels.length != length) {
    241             errln("getLevels() in test " + testNumber + " failed");
    242         }
    243 
    244         logicalMap3 = Bidi.reorderLogical(levels);
    245         visualMap3 = Bidi.reorderVisual(levels);
    246 
    247         /* get the visual map from the runs, too */
    248         try {
    249             runCount = bidi.countRuns();
    250         } catch (IllegalStateException e) {
    251             errln("countRuns() in test " + testNumber + " failed");
    252             runCount = 0;
    253         }
    254 
    255         logln("\n---- " + runCount + " runs");
    256         visualIndex = 0;
    257         BidiRun run;
    258         for (i = 0; i < runCount; ++i) {
    259             run = bidi.getVisualRun(i);
    260             if (run == null) {
    261                 errln("null visual run encountered at index " + i +
    262                       ", in test " + testNumber);
    263                 continue;
    264             }
    265             odd = run.isOddRun();
    266             logicalStart = run.getStart();
    267             runLength = run.getLength();
    268             log("(" + (run.isOddRun() ? "R" : "L"));
    269             log(" @" + run.getStart() + '[' + run.getLength() + "])\n");
    270             if (!odd) {
    271                 do {    /* LTR */
    272                     visualMap4[visualIndex++] = logicalStart++;
    273                 } while (--runLength > 0);
    274             } else {
    275                 logicalStart += runLength;  /* logicalLimit */
    276                 do {    /* RTL */
    277                     visualMap4[visualIndex++] = --logicalStart;
    278                 } while (--runLength > 0);
    279             }
    280         }
    281         log("\n");
    282 
    283         /* print all the maps */
    284         logln("logical maps:");
    285         for (i = 0; i < length; ++i) {
    286             log(logicalMap1[i] + " ");
    287         }
    288         log("\n");
    289         for (i = 0; i < length; ++i) {
    290             log(logicalMap2[i] + " ");
    291         }
    292         log("\n");
    293         for (i = 0; i < length; ++i) {
    294             log(logicalMap3[i] + " ");
    295         }
    296 
    297         log("\nvisual maps:\n");
    298         for (i = 0; i < destLength; ++i) {
    299             log(visualMap1[i] + " ");
    300         }
    301         log("\n");
    302         for (i = 0; i < destLength; ++i) {
    303             log(visualMap2[i] + " ");
    304         }
    305         log("\n");
    306         for (i = 0; i < length; ++i) {
    307             log(visualMap3[i] + " ");
    308         }
    309         log("\n");
    310         for (i = 0; i < length; ++i) {
    311             log(visualMap4[i] + " ");
    312         }
    313         log("\n");
    314 
    315         /* check that the indexes are the same between these and Bidi.getLogical/VisualIndex() */
    316         for (i = 0; i < length; ++i) {
    317             if (logicalMap1[i] != logicalMap2[i]) {
    318                 errln("Error in tests[" + testNumber + "]: (logicalMap1[" + i +
    319                       "] == " + logicalMap1[i] + ") != (logicalMap2[" + i +
    320                       "] == " + logicalMap2[i] + ")");
    321             }
    322             if (logicalMap1[i] != logicalMap3[i]) {
    323                 errln("Error in tests[" + testNumber + "]: (logicalMap1[" + i +
    324                       "] == " + logicalMap1[i] + ") != (logicalMap3[" + i +
    325                       "] == " + logicalMap3[i] + ")");
    326             }
    327             if (visualMap1[i] != visualMap2[i]) {
    328                 errln("Error in tests[" + testNumber + "]: (visualMap1[" + i +
    329                       "] == " + visualMap1[i] + ") != (visualMap2[" + i +
    330                       "] == " + visualMap2[i] + ")");
    331             }
    332             if (visualMap1[i] != visualMap3[i]) {
    333                 errln("Error in tests[" + testNumber + "]: (visualMap1[" + i +
    334                       "] == " + visualMap1[i] + ") != (visualMap3[" + i +
    335                       "] == " + visualMap3[i] + ")");
    336             }
    337             if (visualMap1[i] != visualMap4[i]) {
    338                 errln("Error in tests[" + testNumber + "]: (visualMap1[" + i +
    339                       "] == " + visualMap1[i] + ") != (visualMap4[" + i +
    340                       "] == " + visualMap4[i] + ")");
    341             }
    342             try {
    343                 visualIndex = bidi.getVisualIndex(i);
    344             } catch (Exception e) {
    345                 errln("Bidi.getVisualIndex(" + i + ") failed in tests[" +
    346                       testNumber + "]");
    347             }
    348             if (logicalMap1[i] != visualIndex) {
    349                 errln("Error in tests[" + testNumber + "]: (logicalMap1[" + i +
    350                       "] == " + logicalMap1[i] + ") != (Bidi.getVisualIndex(" + i +
    351                       ") == " + visualIndex + ")");
    352             }
    353             try {
    354                 logicalIndex = bidi.getLogicalIndex(i);
    355             } catch (Exception e) {
    356                 errln("Bidi.getLogicalIndex(" + i + ") failed in tests[" +
    357                       testNumber + "]");
    358             }
    359             if (visualMap1[i] != logicalIndex) {
    360                 errln("Error in tests[" + testNumber + "]: (visualMap1[" + i +
    361                       "] == " + visualMap1[i] + ") != (Bidi.getLogicalIndex(" + i +
    362                       ") == " + logicalIndex + ")");
    363             }
    364         }
    365     }
    366 
    367     private String getStringFromDirProps(short[] dirProps) {
    368         int i;
    369 
    370         if (dirProps == null) {
    371             return null;
    372         }
    373         int length = dirProps.length;
    374         char[] buffer = new char[length];
    375 
    376         /* this part would have to be modified for UTF-x */
    377         for (i = 0; i < length; ++i) {
    378             buffer[i] = charFromDirProp[dirProps[i]];
    379         }
    380         return new String(buffer);
    381     }
    382 
    383     private void doMisc() {
    384     /* Miscellaneous tests to exercize less popular code paths */
    385         Bidi bidi = new Bidi(120, 66), bidiLine;
    386 
    387         assertEquals("\nwriteReverse should return an empty string",
    388                      "", Bidi.writeReverse("", 0));
    389 
    390         bidi.setPara("", Bidi.LTR, null);
    391         assertEquals("\nwriteReordered should return an empty string",
    392                      "", bidi.writeReordered(0));
    393 
    394         bidi.setPara("abc", Bidi.LTR, null);
    395         assertEquals("\ngetRunStart should return 0",
    396                      0, bidi.getRunStart(0));
    397         assertEquals("\ngetRunLimit should return 3",
    398                      3, bidi.getRunLimit(0));
    399 
    400         bidi.setPara("abc          ", Bidi.RTL, null);
    401         bidiLine = bidi.setLine(0, 6);
    402         for (int i = 3; i < 6; i++) {
    403             assertEquals("\nTrailing space at " + i + " should get paragraph level",
    404                          Bidi.RTL, bidiLine.getLevelAt(i));
    405         }
    406 
    407         bidi.setPara("abc       def", Bidi.RTL, null);
    408         bidiLine = bidi.setLine(0, 6);
    409         for (int i = 3; i < 6; i++) {
    410             assertEquals("\nTrailing space at " + i + " should get paragraph level",
    411                          Bidi.RTL, bidiLine.getLevelAt(i));
    412         }
    413 
    414         bidi.setPara("abcdefghi    ", Bidi.RTL, null);
    415         bidiLine = bidi.setLine(0, 6);
    416         for (int i = 3; i < 6; i++) {
    417             assertEquals("\nTrailing char at " + i + " should get level 2",
    418                          2, bidiLine.getLevelAt(i));
    419         }
    420 
    421         bidi.setReorderingOptions(Bidi.OPTION_REMOVE_CONTROLS);
    422         bidi.setPara("\u200eabc       def", Bidi.RTL, null);
    423         bidiLine = bidi.setLine(0, 6);
    424         assertEquals("\nWrong result length", 5, bidiLine.getResultLength());
    425 
    426         bidi.setPara("abcdefghi", Bidi.LTR, null);
    427         bidiLine = bidi.setLine(0, 6);
    428         assertEquals("\nWrong direction #1", Bidi.LTR, bidiLine.getDirection());
    429 
    430         bidi.setPara("", Bidi.LTR, null);
    431         byte[] levels = bidi.getLevels();
    432         assertEquals("\nWrong number of level elements", 0, levels.length);
    433         assertEquals("\nWrong number of runs #1", 0, bidi.countRuns());
    434 
    435         bidi.setPara("          ", Bidi.RTL, null);
    436         bidiLine = bidi.setLine(0, 6);
    437         assertEquals("\nWrong number of runs #2", 1, bidiLine.countRuns());
    438 
    439         bidi.setPara("a\u05d0        bc", Bidi.RTL, null);
    440         bidiLine = bidi.setLine(0, 6);
    441         assertEquals("\nWrong direction #2", Bidi.MIXED, bidi.getDirection());
    442         assertEquals("\nWrong direction #3", Bidi.MIXED, bidiLine.getDirection());
    443         assertEquals("\nWrong number of runs #3", 2, bidiLine.countRuns());
    444 
    445         int[] map = Bidi.reorderLogical(null);
    446         assertTrue("\nWe should have got a null map #1", map == null);
    447         map = Bidi.reorderLogical(new byte[] {0,126, 127});
    448         assertTrue("\nWe should have got a null map #2", map == null);
    449         map = Bidi.reorderVisual(null);
    450         assertTrue("\nWe should have got a null map #3", map == null);
    451         map = Bidi.reorderVisual(new byte[] {0, -1, 4});
    452         assertTrue("\nWe should have got a null map #4", map == null);
    453 
    454         map = Bidi.invertMap(null);
    455         assertTrue("\nWe should have got a null map #5", map == null);
    456         map = Bidi.invertMap(new int[] {0,1,-1,5,4});
    457         assertTrue("\nUnexpected inverted Map",
    458                    Arrays.equals(map, new int[] {0,1,-1,-1,4,3}));
    459 
    460         bidi.setPara("", Bidi.LTR, null);
    461         map = bidi.getLogicalMap();
    462         assertTrue("\nMap should have length==0 #1", map.length == 0);
    463         map = bidi.getVisualMap();
    464         assertTrue("\nMap should have length==0 #2", map.length == 0);
    465 
    466         /* test BidiRun.toString and allocation of run memory > 1 */
    467         bidi.setPara("abc", Bidi.LTR, null);
    468         assertEquals("\nWrong run display", "BidiRun 0 - 3 @ 0",
    469                      bidi.getLogicalRun(0).toString());
    470 
    471         /* test REMOVE_BIDI_CONTROLS together with DO_MIRRORING */
    472         bidi.setPara("abc\u200e", Bidi.LTR, null);
    473         String out = bidi.writeReordered(Bidi.REMOVE_BIDI_CONTROLS | Bidi.DO_MIRRORING);
    474         assertEquals("\nWrong result #1", "abc", out);
    475 
    476         /* test inverse Bidi with marks and contextual orientation */
    477         bidi.setReorderingMode(Bidi.REORDER_INVERSE_LIKE_DIRECT);
    478         bidi.setReorderingOptions(Bidi.OPTION_INSERT_MARKS);
    479         bidi.setPara("", Bidi.LEVEL_DEFAULT_RTL, null);
    480         out = bidi.writeReordered(0);
    481         assertEquals("\nWrong result #2", "", out);
    482         bidi.setPara("   ", Bidi.LEVEL_DEFAULT_RTL, null);
    483         out = bidi.writeReordered(0);
    484         assertEquals("\nWrong result #3", "   ", out);
    485         bidi.setPara("abc", Bidi.LEVEL_DEFAULT_RTL, null);
    486         out = bidi.writeReordered(0);
    487         assertEquals("\nWrong result #4", "abc", out);
    488         bidi.setPara("\u05d0\u05d1", Bidi.LEVEL_DEFAULT_RTL, null);
    489         out = bidi.writeReordered(0);
    490         assertEquals("\nWrong result #5", "\u05d1\u05d0", out);
    491         bidi.setPara("abc \u05d0\u05d1", Bidi.LEVEL_DEFAULT_RTL, null);
    492         out = bidi.writeReordered(0);
    493         assertEquals("\nWrong result #6", "\u05d1\u05d0 abc", out);
    494         bidi.setPara("\u05d0\u05d1 abc", Bidi.LEVEL_DEFAULT_RTL, null);
    495         out = bidi.writeReordered(0);
    496         assertEquals("\nWrong result #7", "\u200fabc \u05d1\u05d0", out);
    497         bidi.setPara("\u05d0\u05d1 abc .-=", Bidi.LEVEL_DEFAULT_RTL, null);
    498         out = bidi.writeReordered(0);
    499         assertEquals("\nWrong result #8", "\u200f=-. abc \u05d1\u05d0", out);
    500         bidi.orderParagraphsLTR(true);
    501         bidi.setPara("\n\r   \n\rabc\n\u05d0\u05d1\rabc \u05d2\u05d3\n\r" +
    502                      "\u05d4\u05d5 abc\n\u05d6\u05d7 abc .-=\r\n" +
    503                      "-* \u05d8\u05d9 abc .-=", Bidi.LEVEL_DEFAULT_RTL, null);
    504         out = bidi.writeReordered(0);
    505         assertEquals("\nWrong result #9",
    506                      "\n\r   \n\rabc\n\u05d1\u05d0\r\u05d3\u05d2 abc\n\r" +
    507                      "\u200fabc \u05d5\u05d4\n\u200f=-. abc \u05d7\u05d6\r\n" +
    508                      "\u200f=-. abc \u05d9\u05d8 *-", out);
    509 
    510         bidi.setPara("\u05d0 \t", Bidi.LTR, null);
    511         out = bidi.writeReordered(0);
    512         assertEquals("\nWrong result #10", "\u05D0\u200e \t", out);
    513         bidi.setPara("\u05d0 123 \t\u05d1 123 \u05d2", Bidi.LTR, null);
    514         out = bidi.writeReordered(0);
    515         assertEquals("\nWrong result #11", "\u05d0 \u200e123\u200e \t\u05d2 123 \u05d1", out);
    516         bidi.setPara("\u05d0 123 \u0660\u0661 ab", Bidi.LTR, null);
    517         out = bidi.writeReordered(0);
    518         assertEquals("\nWrong result #12", "\u05d0 \u200e123 \u200e\u0660\u0661 ab", out);
    519         bidi.setPara("ab \t", Bidi.RTL, null);
    520         out = bidi.writeReordered(0);
    521         assertEquals("\nWrong result #13", "\u200f\t ab", out);
    522 
    523         /* check exceeding para level */
    524         bidi = new Bidi();
    525         bidi.setPara("A\u202a\u05d0\u202aC\u202c\u05d1\u202cE", (byte)(Bidi.MAX_EXPLICIT_LEVEL - 1), null);
    526         assertEquals("\nWrong level at index 2", Bidi.MAX_EXPLICIT_LEVEL, bidi.getLevelAt(2));
    527 
    528         /* check 1-char runs with RUNS_ONLY */
    529         bidi.setReorderingMode(Bidi.REORDER_RUNS_ONLY);
    530         bidi.setPara("a \u05d0 b \u05d1 c \u05d2 d ", Bidi.LTR, null);
    531         assertEquals("\nWrong number of runs #4", 14, bidi.countRuns());
    532 
    533         /* test testGetBaseDirection to verify fast string direction detection function */
    534         /* mixed start with L */
    535         String mixedEnglishFirst = "\u0061\u0627\u0032\u06f3\u0061\u0034";
    536         assertEquals("\nWrong direction through fast detection #1", Bidi.LTR, Bidi.getBaseDirection(mixedEnglishFirst));
    537         /* mixed start with AL */
    538         String mixedArabicFirst = "\u0661\u0627\u0662\u06f3\u0061\u0664";
    539         assertEquals("\nWrong direction through fast detection #2", Bidi.RTL, Bidi.getBaseDirection(mixedArabicFirst));
    540         /* mixed Start with R */
    541         String mixedHebrewFirst = "\u05EA\u0627\u0662\u06f3\u0061\u0664";
    542         assertEquals("\nWrong direction through fast detection #3", Bidi.RTL, Bidi.getBaseDirection(mixedHebrewFirst));
    543         /* all AL (Arabic. Persian) */
    544         String persian = "\u0698\u067E\u0686\u06AF";
    545         assertEquals("\nWrong direction through fast detection #4", Bidi.RTL, Bidi.getBaseDirection(persian));
    546         /* all R (Hebrew etc.) */
    547         String hebrew = "\u0590\u05D5\u05EA\u05F1";
    548         assertEquals("\nWrong direction through fast detection #5", Bidi.RTL, Bidi.getBaseDirection(hebrew));
    549         /* all L (English) */
    550         String english = "\u0071\u0061\u0066";
    551         assertEquals("\nWrong direction through fast detection #6", Bidi.LTR, Bidi.getBaseDirection(english));
    552         /* mixed start with weak AL an then L */
    553         String startWeakAL = "\u0663\u0071\u0061\u0066";
    554         assertEquals("\nWrong direction through fast detection #7", Bidi.LTR, Bidi.getBaseDirection(startWeakAL));
    555         /* mixed start with weak L and then AL */
    556         String startWeakL = "\u0031\u0698\u067E\u0686\u06AF";
    557         assertEquals("\nWrong direction through fast detection #8", Bidi.RTL, Bidi.getBaseDirection(startWeakL));
    558         /* empty */
    559         String empty = "";
    560         assertEquals("\nWrong direction through fast detection #9", Bidi.NEUTRAL, Bidi.getBaseDirection(empty));
    561         /* surrogate character */
    562         String surrogateChar = "\uD800\uDC00";
    563         assertEquals("\nWrong direction through fast detection #10", Bidi.LTR, Bidi.getBaseDirection(surrogateChar));
    564         /* all weak L (English digits) */
    565         String allEnglishDigits = "\u0031\u0032\u0033";
    566         assertEquals("\nWrong direction through fast detection #11", Bidi.NEUTRAL, Bidi.getBaseDirection(allEnglishDigits));
    567         /* all weak AL (Arabic digits) */
    568         String allArabicDigits = "\u0663\u0664\u0665";
    569         assertEquals("\nWrong direction through fast detection #12", Bidi.NEUTRAL, Bidi.getBaseDirection(allArabicDigits));
    570         /* null string */
    571         String nullString = null;
    572         assertEquals("\nWrong direction through fast detection #13", Bidi.NEUTRAL, Bidi.getBaseDirection(nullString));
    573         /* first L (English) others are R (Hebrew etc.) */
    574         String startEnglishOthersHebrew = "\u0071\u0590\u05D5\u05EA\u05F1";
    575         assertEquals("\nWrong direction through fast detection #14", Bidi.LTR, Bidi.getBaseDirection(startEnglishOthersHebrew));
    576         /* last R (Hebrew etc.) others are weak L (English Digits) */
    577         String lastHebrewOthersEnglishDigit = "\u0031\u0032\u0033\u05F1";
    578         assertEquals("\nWrong direction through fast detection #15", Bidi.RTL, Bidi.getBaseDirection(lastHebrewOthersEnglishDigit));
    579     }
    580 
    581     @Test
    582     public void testExplicitLevel0() {
    583         // The following used to fail with an error, see ICU ticket #12922.
    584         String text = "\u202d\u05d0";
    585         byte[] embeddings = new byte[2];  // all 0
    586         int flags = Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT;  // 0x7e
    587         Bidi bidi = new Bidi(text.toCharArray(), 0, embeddings, 0, text.length(), flags);
    588         assertEquals("resolved level at 0", 1, bidi.getLevelAt(0));
    589         assertEquals("resolved level at 1", 1, bidi.getLevelAt(1));
    590 
    591         flags = java.text.Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT;  // -2
    592         java.text.Bidi jb = new java.text.Bidi(text.toCharArray(), 0, embeddings, 0, text.length(), flags);
    593         assertEquals("java.text resolved level at 0", 1, jb.getLevelAt(0));
    594         assertEquals("java.text resolved level at 1", 1, jb.getLevelAt(1));
    595     }
    596 }
    597