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) 2001-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.impl.Utility;
     18 import android.icu.text.Bidi;
     19 import android.icu.testsharding.MainTestShard;
     20 
     21 /**
     22  * Regression test for the basic "inverse" Bidi mode.
     23  *
     24  * ported from C by Lina Kemmel, Matitiahu Allouche
     25  */
     26 
     27 @MainTestShard
     28 public class TestInverse extends BidiFmwk {
     29 
     30     private int countRoundtrips = 0;
     31     private int countNonRoundtrips = 0;
     32 
     33     static final String[] testCases = {
     34         "\u006c\u0061\u0028\u0074\u0069\u006e\u0020\u05d0\u05d1\u0029\u05d2\u05d3",
     35         "\u006c\u0061\u0074\u0020\u05d0\u05d1\u05d2\u0020\u0031\u0032\u0033",
     36         "\u006c\u0061\u0074\u0020\u05d0\u0028\u05d1\u05d2\u0020\u0031\u0029\u0032\u0033",
     37         "\u0031\u0032\u0033\u0020\u05d0\u05d1\u05d2\u0020\u0034\u0035\u0036",
     38         "\u0061\u0062\u0020\u0061\u0062\u0020\u0661\u0662"
     39     };
     40 
     41     @Test
     42     public void testInverse() {
     43         Bidi bidi;
     44         int i;
     45 
     46         logln("\nEntering TestInverse\n");
     47         bidi = new Bidi();
     48         log("inverse Bidi: testInverse(L) with " + testCases.length +
     49             " test cases ---\n");
     50         for(i = 0; i < testCases.length; ++i) {
     51             logln("Testing case " + i);
     52             _testInverseBidi(bidi, testCases[i], Bidi.DIRECTION_LEFT_TO_RIGHT);
     53         }
     54 
     55         log("inverse Bidi: testInverse(R) with " + testCases.length +
     56             " test cases ---\n");
     57         for (i = 0; i < testCases.length; ++i) {
     58             logln("Testing case " + i);
     59             _testInverseBidi(bidi, testCases[i], Bidi.DIRECTION_RIGHT_TO_LEFT);
     60         }
     61 
     62         _testManyInverseBidi(bidi, Bidi.DIRECTION_LEFT_TO_RIGHT);
     63         _testManyInverseBidi(bidi, Bidi.DIRECTION_RIGHT_TO_LEFT);
     64 
     65         logln("inverse Bidi: rountrips: " + countRoundtrips +
     66               "   non-roundtrips: " + countNonRoundtrips);
     67 
     68         _testWriteReverse();
     69 
     70         _testManyAddedPoints();
     71 
     72         _testMisc();
     73 
     74         logln("\nExiting TestInverse\n");
     75     }
     76 
     77     private static final char[][] repeatSegments = {
     78         { 0x61, 0x62 },     /* L */
     79         { 0x5d0, 0x5d1 },   /* R */
     80         { 0x627, 0x628 },   /* AL */
     81         { 0x31, 0x32 },     /* EN */
     82         { 0x661, 0x662 },   /* AN */
     83         { 0x20, 0x20 }      /* WS (N) */
     84     };
     85     private static final int COUNT_REPEAT_SEGMENTS = 6;
     86 
     87     private void _testManyInverseBidi(Bidi bidi, int direction) {
     88         char[] text = { 0, 0, 0x20, 0, 0, 0x20, 0, 0 };
     89         int i, j, k;
     90 
     91         log("inverse Bidi: testManyInverseBiDi(" +
     92             (direction == Bidi.DIRECTION_LEFT_TO_RIGHT ? 'L' : 'R') +
     93             ") - test permutations of text snippets ---\n");
     94         for (i = 0; i < COUNT_REPEAT_SEGMENTS; ++i) {
     95             text[0] = repeatSegments[i][0];
     96             text[1] = repeatSegments[i][1];
     97             for (j = 0; j < COUNT_REPEAT_SEGMENTS; ++j) {
     98                 text[3] = repeatSegments[j][0];
     99                 text[4] = repeatSegments[j][1];
    100                 for (k = 0; k < COUNT_REPEAT_SEGMENTS; ++k) {
    101                     text[6] = repeatSegments[k][0];
    102                     text[7] = repeatSegments[k][1];
    103 
    104                     log("inverse Bidi: testManyInverseBiDi()[" +
    105                         i + " " + j + " " + k + "]\n");
    106                     _testInverseBidi(bidi, new String(text), direction);
    107                 }
    108             }
    109         }
    110     }
    111 
    112     private void _testInverseBidi(Bidi bidi, String src, int direction) {
    113         String visualLTR, logicalDest, visualDest;
    114         try {
    115             if (direction == Bidi.DIRECTION_LEFT_TO_RIGHT) {
    116                 log("inverse Bidi: testInverse(L)\n");
    117 
    118                 /* convert visual to logical */
    119                 bidi.setInverse(true);
    120                 if (!bidi.isInverse()) {
    121                     err("Error while doing setInverse(true)\n");
    122                 }
    123                 bidi.setPara(src, Bidi.LTR, null);
    124                 if (!Arrays.equals(src.toCharArray(), bidi.getText())) {
    125                     err("Wrong value returned by getText\n");
    126                 }
    127                 if (!src.equals(bidi.getTextAsString())) {
    128                     err("Wrong value returned by getTextAsString\n");
    129                 }
    130                 logicalDest = bidi.writeReordered(Bidi.DO_MIRRORING |
    131                                                   Bidi.INSERT_LRM_FOR_NUMERIC);
    132                 log("  v ");
    133                 printUnicode(src.toCharArray(), bidi.getLevels());
    134                 log("\n");
    135 
    136                 /* convert back to visual LTR */
    137                 bidi.setInverse(false);
    138                 if (bidi.isInverse()) {
    139                     err("Error while doing setInverse(false)\n");
    140                 }
    141                 bidi.setPara(logicalDest, Bidi.LTR, null);
    142                 visualDest = bidi.writeReordered(Bidi.DO_MIRRORING |
    143                                                  Bidi.REMOVE_BIDI_CONTROLS);
    144             } else {
    145                 logln("inverse Bidi: testInverse(R)\n");
    146 
    147                 /* reverse visual from RTL to LTR */
    148                 visualLTR = Bidi.writeReverse(src, 0);
    149                 log("  vr");
    150                 printUnicode(src.toCharArray(), null);
    151                 log("\n");
    152 
    153                 /* convert visual RTL to logical */
    154                 bidi.setInverse(true);
    155                 bidi.setPara(visualLTR, Bidi.LTR, null);
    156                 logicalDest = bidi.writeReordered(Bidi.DO_MIRRORING |
    157                                                   Bidi.INSERT_LRM_FOR_NUMERIC);
    158                 log("  vl");
    159                 printUnicode(visualLTR.toCharArray(), bidi.getLevels());
    160                 log("\n");
    161 
    162                 /* convert back to visual RTL */
    163                 bidi.setInverse(false);
    164                 bidi.setPara(logicalDest, Bidi.LTR, null);
    165                 visualDest = bidi.writeReordered(Bidi.DO_MIRRORING |
    166                              Bidi.REMOVE_BIDI_CONTROLS | Bidi.OUTPUT_REVERSE);
    167             }
    168             log("  l ");
    169             printUnicode(logicalDest.toCharArray(), bidi.getLevels());
    170             log("\n");
    171             log("  v ");
    172             printUnicode(visualDest.toCharArray(), null);
    173             log("\n");
    174         } catch (Exception e) {
    175             errln("\ninverse Bidi: *** failed");
    176             errln("   error message: " + e.getMessage());
    177             e.printStackTrace();
    178             visualDest = null;
    179         }
    180 
    181         /* check and print results */
    182         if (src.equals(visualDest)) {
    183             ++countRoundtrips;
    184             log(" + roundtripped\n");
    185         } else {
    186             ++countNonRoundtrips;
    187             log(" * did not roundtrip\n");
    188         }
    189     }
    190 
    191     private void _testWriteReverse() {
    192         /* U+064e and U+0650 are combining marks (Mn) */
    193         final String
    194             forward = "\u200f\u0627\u064e\u0650\u0020\u0028\u0031\u0029",
    195             reverseKeepCombining =
    196                 "\u0029\u0031\u0028\u0020\u0627\u064e\u0650\u200f",
    197             reverseRemoveControlsKeepCombiningDoMirror =
    198                 "\u0028\u0031\u0029\u0020\u0627\u064e\u0650";
    199 
    200         String reverse;
    201 
    202         /* test Bidi.writeReverse() with "interesting" options */
    203         try {
    204             reverse = Bidi.writeReverse(forward, Bidi.KEEP_BASE_COMBINING);
    205         } catch (Exception e) {
    206             errln("Failure in Bidi.writeReverse(KEEP_BASE_COMBINING)");
    207             reverse = null;
    208         }
    209         assertEquals("\nFailure in " + getClass().toString() +
    210                      " in Bidi.writeReverse", reverseKeepCombining,
    211                      reverse, forward, null, "KEEP_BASE_COMBINING", null);
    212 
    213         try {
    214             reverse = Bidi.writeReverse(forward, Bidi.REMOVE_BIDI_CONTROLS |
    215                                         Bidi.DO_MIRRORING | Bidi.KEEP_BASE_COMBINING);
    216         } catch (Exception e) {
    217             errln("Failure in Bidi.writeReverse(KEEP_BASE_COMBINING)");
    218         }
    219         assertEquals("\nFailure in " + getClass().toString() +
    220                      " in Bidi.writeReverse",
    221                      reverseRemoveControlsKeepCombiningDoMirror,
    222                      reverse, forward, null,
    223                      "REMOVE_BIDI_CONTROLS|DO_MIRRORING|KEEP_BASE_COMBINING",
    224                      null);
    225     }
    226 
    227     private void printUnicode(char[] chars, byte[] levels) {
    228         int i;
    229 
    230         log("{ ");
    231         for (i = 0; i < chars.length; ++i) {
    232             log("0x" + Utility.hex(chars[i]));
    233             if (levels != null) {
    234                 log("." + levels[i]);
    235             }
    236             log("   ");
    237         }
    238         log(" }");
    239     }
    240 
    241     private void _testManyAddedPoints() {
    242         Bidi bidi = new Bidi();
    243         char[] text = new char[90];
    244         for (int i = 0; i < text.length; i+=3) {
    245             text[i] = 'a';
    246             text[i+1] = '\u05d0';
    247             text[i+2] = '3';
    248         }
    249         bidi.setReorderingMode(Bidi.REORDER_INVERSE_LIKE_DIRECT);
    250         bidi.setReorderingOptions(Bidi.OPTION_INSERT_MARKS);
    251         bidi.setPara(text, Bidi.LTR, null);
    252         String out = bidi.writeReordered(0);
    253         char[] expected = new char[120];
    254         for (int i = 0; i < expected.length; i+=4) {
    255             expected[i] = 'a';
    256             expected[i+1] = '\u05d0';
    257             expected[i+2] = '\u200e';
    258             expected[i+3] = '3';
    259         }
    260         assertEquals("\nInvalid output with many added points",
    261                      new String(expected), out);
    262     }
    263 
    264     private void _testMisc() {
    265         Bidi bidi = new Bidi();
    266         bidi.setInverse(true);
    267         bidi.setPara("   ", Bidi.RTL, null);
    268         String out = bidi.writeReordered(Bidi.OUTPUT_REVERSE | Bidi.INSERT_LRM_FOR_NUMERIC);
    269         assertEquals("\nInvalid output with RLM at both sides",
    270                      "\u200f   \u200f", out);
    271     }
    272 }
    273