1/*
2*******************************************************************************
3*   Copyright (C) 2001-2010, International Business Machines
4*   Corporation and others.  All Rights Reserved.
5*******************************************************************************
6*/
7
8package com.ibm.icu.dev.test.bidi;
9
10import java.util.Arrays;
11
12import com.ibm.icu.text.Bidi;
13
14/**
15 * Regression test for variants to the UBA.
16 *
17 * @author Lina Kemmel, Matitiahu Allouche
18 */
19
20public class TestReorderingMode extends BidiTest {
21
22    static final String[] textIn = {
23    /* (0) 123 */
24        "123",
25    /* (1) .123->4.5 */
26        ".123->4.5",
27    /* (2) 678 */
28        "678",
29    /* (3) .678->8.9 */
30        ".678->8.9",
31    /* (4) JIH1.2,3MLK */
32        "JIH1.2,3MLK",
33    /* (5) FE.>12-> */
34        "FE.>12->",
35    /* (6) JIH.>12->a */
36        "JIH.>12->a",
37    /* (7) CBA.>67->89=a */
38        "CBA.>67->89=a",
39    /* (8) CBA.123->xyz */
40        "CBA.123->xyz",
41    /* (9) .>12->xyz */
42        ".>12->xyz",
43    /* (10) a.>67->xyz */
44        "a.>67->xyz",
45    /* (11) 123JIH */
46        "123JIH",
47    /* (12) 123 JIH */
48        "123 JIH"
49    };
50
51    static final String[] textOut = {
52    /* TC 0: 123 */
53        "123",                                                              /* (0) */
54    /* TC 1: .123->4.5 */
55        ".123->4.5",                                                        /* (1) */
56        "4.5<-123.",                                                        /* (2) */
57    /* TC 2: 678 */
58        "678",                                                              /* (3) */
59    /* TC 3: .678->8.9 */
60        ".8.9<-678",                                                        /* (4) */
61        "8.9<-678.",                                                        /* (5) */
62        ".678->8.9",                                                        /* (6) */
63    /* TC 4: MLK1.2,3JIH */
64        "KLM1.2,3HIJ",                                                      /* (7) */
65    /* TC 5: FE.>12-> */
66        "12<.EF->",                                                         /* (8) */
67        "<-12<.EF",                                                         /* (9) */
68        "EF.>@12->",                                                        /* (10) */
69    /* TC 6: JIH.>12->a */
70        "12<.HIJ->a",                                                       /* (11) */
71        "a<-12<.HIJ",                                                       /* (12) */
72        "HIJ.>@12->a",                                                      /* (13) */
73        "a&<-12<.HIJ",                                                      /* (14) */
74    /* TC 7: CBA.>67->89=a */
75        "ABC.>@67->89=a",                                                   /* (15) */
76        "a=89<-67<.ABC",                                                    /* (16) */
77        "a&=89<-67<.ABC",                                                   /* (17) */
78        "89<-67<.ABC=a",                                                    /* (18) */
79    /* TC 8: CBA.123->xyz */
80        "123.ABC->xyz",                                                     /* (19) */
81        "xyz<-123.ABC",                                                     /* (20) */
82        "ABC.@123->xyz",                                                    /* (21) */
83        "xyz&<-123.ABC",                                                    /* (22) */
84    /* TC 9: .>12->xyz */
85        ".>12->xyz",                                                        /* (23) */
86        "xyz<-12<.",                                                        /* (24) */
87        "xyz&<-12<.",                                                       /* (25) */
88    /* TC 10: a.>67->xyz */
89        "a.>67->xyz",                                                       /* (26) */
90        "a.>@67@->xyz",                                                     /* (27) */
91        "xyz<-67<.a",                                                       /* (28) */
92    /* TC 11: 123JIH */
93        "123HIJ",                                                           /* (29) */
94        "HIJ123",                                                           /* (30) */
95    /* TC 12: 123 JIH */
96        "123 HIJ",                                                          /* (31) */
97        "HIJ 123",                                                          /* (32) */
98    };
99
100    static final int[][][][] outIndices = {
101        { /* TC 0: 123 */
102            {{ 0,  0}, { 0,  0}}, /* REORDER_GROUP_NUMBERS_WITH_R */
103            {{ 0,  0}, { 0,  0}}, /* REORDER_INVERSE_LIKE_DIRECT */
104            {{ 0,  0}, { 0,  0}}, /* REORDER_NUMBERS_SPECIAL */
105            {{ 0,  0}, { 0,  0}}  /* REORDER_INVERSE_FOR_NUMBERS_SPECIAL */
106        },
107        { /* TC 1: .123->4.5 */
108            {{ 1,  2}, { 1,  2}}, /* REORDER_GROUP_NUMBERS_WITH_R */
109            {{ 1,  2}, { 1,  2}}, /* REORDER_INVERSE_LIKE_DIRECT */
110            {{ 1,  2}, { 1,  2}}, /* REORDER_NUMBERS_SPECIAL */
111            {{ 1,  2}, { 1,  2}}  /* REORDER_INVERSE_FOR_NUMBERS_SPECIAL */
112        },
113        { /* TC 2: 678 */
114            {{ 3,  3}, { 3,  3}}, /* REORDER_GROUP_NUMBERS_WITH_R */
115            {{ 3,  3}, { 3,  3}}, /* REORDER_INVERSE_LIKE_DIRECT */
116            {{ 3,  3}, { 3,  3}}, /* REORDER_NUMBERS_SPECIAL */
117            {{ 3,  3}, { 3,  3}}  /* REORDER_INVERSE_FOR_NUMBERS_SPECIAL */
118        },
119        { /* TC 3: .678->8.9 */
120            {{ 6,  5}, { 6,  5}}, /* REORDER_GROUP_NUMBERS_WITH_R */
121            {{ 4,  5}, { 4,  5}}, /* REORDER_INVERSE_LIKE_DIRECT */
122            {{ 6,  5}, { 6,  5}}, /* REORDER_NUMBERS_SPECIAL */
123            {{ 6,  5}, { 6,  5}}  /* REORDER_INVERSE_FOR_NUMBERS_SPECIAL */
124        },
125        { /* TC 4: MLK1.2,3JIH */
126            {{ 7,  7}, { 7,  7}}, /* REORDER_GROUP_NUMBERS_WITH_R */
127            {{ 7,  7}, { 7,  7}}, /* REORDER_INVERSE_LIKE_DIRECT */
128            {{ 7,  7}, { 7,  7}}, /* REORDER_NUMBERS_SPECIAL */
129            {{ 7,  7}, { 7,  7}}  /* REORDER_INVERSE_FOR_NUMBERS_SPECIAL */
130        },
131        { /* TC 5: FE.>12-> */
132            {{ 8,  9}, { 8,  9}}, /* REORDER_GROUP_NUMBERS_WITH_R */
133            {{10,  9}, { 8,  9}}, /* REORDER_INVERSE_LIKE_DIRECT */
134            {{ 8,  9}, { 8,  9}}, /* REORDER_NUMBERS_SPECIAL */
135            {{10,  9}, { 8,  9}}  /* REORDER_INVERSE_FOR_NUMBERS_SPECIAL */
136        },
137        { /* TC 6: JIH.>12->a */
138            {{11, 12}, {11, 12}}, /* REORDER_GROUP_NUMBERS_WITH_R */
139            {{13, 14}, {11, 12}}, /* REORDER_INVERSE_LIKE_DIRECT */
140            {{11, 12}, {11, 12}}, /* REORDER_NUMBERS_SPECIAL */
141            {{13, 14}, {11, 12}}  /* REORDER_INVERSE_FOR_NUMBERS_SPECIAL */
142        },
143        { /* TC 7: CBA.>67->89=a */
144            {{18, 16}, {18, 16}}, /* REORDER_GROUP_NUMBERS_WITH_R */
145            {{18, 17}, {18, 16}}, /* REORDER_INVERSE_LIKE_DIRECT */
146            {{18, 16}, {18, 16}}, /* REORDER_NUMBERS_SPECIAL */
147            {{15, 17}, {18, 16}}  /* REORDER_INVERSE_FOR_NUMBERS_SPECIAL */
148        },
149        { /* TC 8: CBA.>124->xyz */
150            {{19, 20}, {19, 20}}, /* REORDER_GROUP_NUMBERS_WITH_R */
151            {{21, 22}, {19, 20}}, /* REORDER_INVERSE_LIKE_DIRECT */
152            {{19, 20}, {19, 20}}, /* REORDER_NUMBERS_SPECIAL */
153            {{21, 22}, {19, 20}}  /* REORDER_INVERSE_FOR_NUMBERS_SPECIAL */
154        },
155        { /* TC 9: .>12->xyz */
156            {{23, 24}, {23, 24}}, /* REORDER_GROUP_NUMBERS_WITH_R */
157            {{23, 25}, {23, 24}}, /* REORDER_INVERSE_LIKE_DIRECT */
158            {{23, 24}, {23, 24}}, /* REORDER_NUMBERS_SPECIAL */
159            {{23, 25}, {23, 24}}  /* REORDER_INVERSE_FOR_NUMBERS_SPECIAL */
160        },
161        { /* TC 10: a.>67->xyz */
162            {{26, 26}, {26, 26}}, /* REORDER_GROUP_NUMBERS_WITH_R */
163            {{26, 27}, {26, 28}}, /* REORDER_INVERSE_LIKE_DIRECT */
164            {{26, 28}, {26, 28}}, /* REORDER_NUMBERS_SPECIAL */
165            {{26, 27}, {26, 28}}  /* REORDER_INVERSE_FOR_NUMBERS_SPECIAL */
166        },
167        { /* TC 11: 124JIH */
168            {{30, 30}, {30, 30}}, /* REORDER_GROUP_NUMBERS_WITH_R */
169            {{29, 30}, {29, 30}}, /* REORDER_INVERSE_LIKE_DIRECT */
170            {{30, 30}, {30, 30}}, /* REORDER_NUMBERS_SPECIAL */
171            {{30, 30}, {30, 30}}  /* REORDER_INVERSE_FOR_NUMBERS_SPECIAL */
172        },
173        { /* TC 12: 124 JIH */
174            {{32, 32}, {32, 32}}, /* REORDER_GROUP_NUMBERS_WITH_R */
175            {{31, 32}, {31, 32}}, /* REORDER_INVERSE_LIKE_DIRECT */
176            {{31, 32}, {31, 32}}, /* REORDER_NUMBERS_SPECIAL */
177            {{31, 32}, {31, 32}}  /* REORDER_INVERSE_FOR_NUMBERS_SPECIAL */
178        }
179    };
180
181    static final short[] modes = {
182        Bidi.REORDER_GROUP_NUMBERS_WITH_R,
183        Bidi.REORDER_INVERSE_LIKE_DIRECT,
184        Bidi.REORDER_NUMBERS_SPECIAL,
185        Bidi.REORDER_INVERSE_FOR_NUMBERS_SPECIAL,
186        Bidi.REORDER_INVERSE_NUMBERS_AS_L
187    };
188
189    static final int[] options = { Bidi.OPTION_INSERT_MARKS, 0 };
190
191    static final byte[] paraLevels = { Bidi.LTR, Bidi.RTL };
192
193    static final int TC_COUNT = textIn.length;
194    static final int MODES_COUNT = modes.length;
195    static final int OPTIONS_COUNT = options.length;
196    static final int LEVELS_COUNT = paraLevels.length;
197
198    public void testReorderingMode() {
199
200        String src, dest;
201        Bidi bidi = new Bidi();
202        Bidi bidi2 = new Bidi();
203        Bidi bidi3 = new Bidi();
204        int tc, mode, option, level;
205        int modeValue, modeBack;
206        int optionValue, optionBack;
207        int index;
208        String expected;
209        boolean testOK = true;
210
211        logln("\nEntering TestReorderingMode\n");
212
213        bidi2.setInverse(true);
214
215        for (tc = 0; tc < TC_COUNT; tc++) {
216            src = textIn[tc];
217
218            for (mode = 0; mode < MODES_COUNT; mode++) {
219                modeValue = modes[mode];
220                bidi.setReorderingMode(modeValue);
221                modeBack = bidi.getReorderingMode();
222                if (modeValue != modeBack) {
223                    errln("Error while setting reordering mode to " +
224                    modeValue + ", returned " + modeBack);
225                }
226
227                for (option = 0; option < OPTIONS_COUNT; option++) {
228                    optionValue = options[option];
229                    bidi.setReorderingOptions(optionValue);
230                    optionBack = bidi.getReorderingOptions();
231                    if (optionValue != optionBack) {
232                        errln("Error while setting reordering options to " +
233                        modeValue + ", returned " + modeBack);
234                    }
235
236                    for (level = 0; level < LEVELS_COUNT; level++) {
237                        logln("starting test " + tc + " mode=" + modeValue +
238                            " option=" + optionValue + " level=" + level);
239                        bidi.setPara(pseudoToU16(src), paraLevels[level], null);
240
241                        dest = bidi.writeReordered(Bidi.DO_MIRRORING);
242                        dest = u16ToPseudo(dest);
243                        if (!((modeValue == Bidi.REORDER_INVERSE_NUMBERS_AS_L) &&
244                              (optionValue == Bidi.OPTION_INSERT_MARKS))) {
245                            checkWhatYouCan(bidi, src, dest);
246                        }
247                        String modeDesc = modeToString(modeValue);
248                        String optDesc = spOptionsToString(optionValue);
249
250                        if (modeValue == Bidi.REORDER_INVERSE_NUMBERS_AS_L) {
251                            index = -1;
252                            expected = inverseBasic(bidi2, src, optionValue,
253                                                    paraLevels[level]);
254                        }
255                        else {
256                            index = outIndices[tc][mode][option][level];
257                            expected = textOut[index];
258                        }
259                        if (!assertEquals("Actual and expected output mismatch",
260                                          expected, dest, src, modeDesc, optDesc,
261                                          String.valueOf(level))) {
262                            testOK = false;
263                            continue;
264                        }
265                        if ((optionValue == Bidi.OPTION_INSERT_MARKS) &&
266                            !assertRoundTrip(bidi3, tc, index, src, dest,
267                                             mode, option,
268                                             paraLevels[level])) {
269                            testOK = false;
270                            continue;
271                        }
272                        if (!checkResultLength(bidi, src, dest, modeDesc, optDesc,
273                                               paraLevels[level])) {
274                            testOK = false;
275                            continue;
276                        }
277                        if ((index > -1) &&
278                            !checkMaps(bidi, index, src, dest, modeDesc, optDesc,
279                                       paraLevels[level], true)) {
280                            testOK = false;
281                        }
282                    }
283                }
284            }
285        }
286        if (testOK) {
287            logln("Reordering mode test OK");
288        }
289
290        logln("\nExiting TestReorderingMode\n");
291    }
292
293    String inverseBasic(Bidi bidi, String src, int option, byte level) {
294        String dest2;
295
296        if (bidi == null || src == null) {
297            return null;
298        }
299        bidi.setReorderingOptions(option);
300        bidi.setPara(pseudoToU16(src), level, null);
301        dest2 = u16ToPseudo(bidi.writeReordered(Bidi.DO_MIRRORING));
302        if (!(option == Bidi.OPTION_INSERT_MARKS)) {
303            checkWhatYouCan(bidi, src, dest2);
304        }
305        return dest2;
306    }
307
308    static final byte roundtrip[][][][] =
309    {
310        { /* TC 0: 123 */
311            {{ 1,  1}, { 1,  1}}, /* REORDER_GROUP_NUMBERS_WITH_R */
312            {{ 1,  1}, { 1,  1}}, /* REORDER_INVERSE_LIKE_DIRECT */
313            {{ 1,  1}, { 1,  1}}, /* REORDER_NUMBERS_SPECIAL */
314            {{ 1,  1}, { 1,  1}}, /* REORDER_INVERSE_FOR_NUMBERS_SPECIAL */
315            {{ 1,  1}, { 1,  1}}  /* REORDER_INVERSE_NUMBERS_AS_L */
316        },
317        { /* TC 1: .123->4.5 */
318            {{ 1,  1}, { 1,  1}}, /* REORDER_GROUP_NUMBERS_WITH_R */
319            {{ 1,  1}, { 1,  1}}, /* REORDER_INVERSE_LIKE_DIRECT */
320            {{ 1,  1}, { 1,  1}}, /* REORDER_NUMBERS_SPECIAL */
321            {{ 1,  1}, { 1,  1}}, /* REORDER_INVERSE_FOR_NUMBERS_SPECIAL */
322            {{ 1,  1}, { 1,  1}}  /* REORDER_INVERSE_NUMBERS_AS_L */
323        },
324        { /* TC 2: 678 */
325            {{ 1,  1}, { 1,  1}}, /* REORDER_GROUP_NUMBERS_WITH_R */
326            {{ 1,  1}, { 1,  1}}, /* REORDER_INVERSE_LIKE_DIRECT */
327            {{ 1,  1}, { 1,  1}}, /* REORDER_NUMBERS_SPECIAL */
328            {{ 1,  1}, { 1,  1}}, /* REORDER_INVERSE_FOR_NUMBERS_SPECIAL */
329            {{ 1,  1}, { 1,  1}}  /* REORDER_INVERSE_NUMBERS_AS_L */
330        },
331        { /* TC 3: .678->8.9 */
332            {{ 1,  1}, { 1,  1}}, /* REORDER_GROUP_NUMBERS_WITH_R */
333            {{ 1,  1}, { 1,  1}}, /* REORDER_INVERSE_LIKE_DIRECT */
334            {{ 1,  1}, { 1,  1}}, /* REORDER_NUMBERS_SPECIAL */
335            {{ 1,  1}, { 1,  1}}, /* REORDER_INVERSE_FOR_NUMBERS_SPECIAL */
336            {{ 0,  0}, { 1,  1}}  /* REORDER_INVERSE_NUMBERS_AS_L */
337        },
338        { /* TC 4: MLK1.2,3JIH */
339            {{ 1,  1}, { 1,  1}}, /* REORDER_GROUP_NUMBERS_WITH_R */
340            {{ 1,  1}, { 1,  1}}, /* REORDER_INVERSE_LIKE_DIRECT */
341            {{ 1,  1}, { 1,  1}}, /* REORDER_NUMBERS_SPECIAL */
342            {{ 1,  1}, { 1,  1}}, /* REORDER_INVERSE_FOR_NUMBERS_SPECIAL */
343            {{ 1,  1}, { 1,  1}}  /* REORDER_INVERSE_NUMBERS_AS_L */
344        },
345        { /* TC 5: FE.>12-> */
346            {{ 1,  1}, { 1,  1}}, /* REORDER_GROUP_NUMBERS_WITH_R */
347            {{ 1,  1}, { 1,  1}}, /* REORDER_INVERSE_LIKE_DIRECT */
348            {{ 0,  1}, { 1,  1}}, /* REORDER_NUMBERS_SPECIAL */
349            {{ 1,  1}, { 1,  1}}, /* REORDER_INVERSE_FOR_NUMBERS_SPECIAL */
350            {{ 1,  1}, { 1,  1}}  /* REORDER_INVERSE_NUMBERS_AS_L */
351        },
352        { /* TC 6: JIH.>12->a */
353            {{ 1,  1}, { 1,  1}}, /* REORDER_GROUP_NUMBERS_WITH_R */
354            {{ 1,  1}, { 1,  1}}, /* REORDER_INVERSE_LIKE_DIRECT */
355            {{ 0,  0}, { 1,  1}}, /* REORDER_NUMBERS_SPECIAL */
356            {{ 1,  1}, { 1,  1}}, /* REORDER_INVERSE_FOR_NUMBERS_SPECIAL */
357            {{ 1,  1}, { 1,  1}}  /* REORDER_INVERSE_NUMBERS_AS_L */
358        },
359        { /* TC 7: CBA.>67->89=a */
360            {{ 1,  1}, { 1,  1}}, /* REORDER_GROUP_NUMBERS_WITH_R */
361            {{ 1,  1}, { 1,  1}}, /* REORDER_INVERSE_LIKE_DIRECT */
362            {{ 0,  1}, { 1,  1}}, /* REORDER_NUMBERS_SPECIAL */
363            {{ 1,  1}, { 1,  1}}, /* REORDER_INVERSE_FOR_NUMBERS_SPECIAL */
364            {{ 0,  0}, { 1,  1}}  /* REORDER_INVERSE_NUMBERS_AS_L */
365        },
366        { /* TC 8: CBA.>123->xyz */
367            {{ 1,  1}, { 1,  1}}, /* REORDER_GROUP_NUMBERS_WITH_R */
368            {{ 1,  1}, { 1,  1}}, /* REORDER_INVERSE_LIKE_DIRECT */
369            {{ 0,  0}, { 1,  1}}, /* REORDER_NUMBERS_SPECIAL */
370            {{ 1,  1}, { 1,  1}}, /* REORDER_INVERSE_FOR_NUMBERS_SPECIAL */
371            {{ 1,  1}, { 1,  1}}  /* REORDER_INVERSE_NUMBERS_AS_L */
372        },
373        { /* TC 9: .>12->xyz */
374            {{ 1,  1}, { 1,  1}}, /* REORDER_GROUP_NUMBERS_WITH_R */
375            {{ 1,  1}, { 1,  1}}, /* REORDER_INVERSE_LIKE_DIRECT */
376            {{ 1,  0}, { 1,  1}}, /* REORDER_NUMBERS_SPECIAL */
377            {{ 1,  1}, { 1,  1}}, /* REORDER_INVERSE_FOR_NUMBERS_SPECIAL */
378            {{ 1,  1}, { 1,  1}}  /* REORDER_INVERSE_NUMBERS_AS_L */
379        },
380        { /* TC 10: a.>67->xyz */
381            {{ 1,  1}, { 1,  1}}, /* REORDER_GROUP_NUMBERS_WITH_R */
382            {{ 1,  1}, { 1,  1}}, /* REORDER_INVERSE_LIKE_DIRECT */
383            {{ 1,  1}, { 1,  1}}, /* REORDER_NUMBERS_SPECIAL */
384            {{ 1,  1}, { 1,  1}}, /* REORDER_INVERSE_FOR_NUMBERS_SPECIAL */
385            {{ 1,  0}, { 1,  1}}  /* REORDER_INVERSE_NUMBERS_AS_L */
386        },
387        { /* TC 11: 123JIH */
388            {{ 1,  1}, { 1,  1}}, /* REORDER_GROUP_NUMBERS_WITH_R */
389            {{ 1,  1}, { 1,  1}}, /* REORDER_INVERSE_LIKE_DIRECT */
390            {{ 1,  1}, { 1,  1}}, /* REORDER_NUMBERS_SPECIAL */
391            {{ 1,  1}, { 1,  1}}, /* REORDER_INVERSE_FOR_NUMBERS_SPECIAL */
392            {{ 1,  1}, { 1,  1}}  /* REORDER_INVERSE_NUMBERS_AS_L */
393        },
394        { /* TC 12: 123 JIH */
395            {{ 1,  1}, { 1,  1}}, /* REORDER_GROUP_NUMBERS_WITH_R */
396            {{ 1,  1}, { 1,  1}}, /* REORDER_INVERSE_LIKE_DIRECT */
397            {{ 1,  1}, { 1,  1}}, /* REORDER_NUMBERS_SPECIAL */
398            {{ 1,  1}, { 1,  1}}, /* REORDER_INVERSE_FOR_NUMBERS_SPECIAL */
399            {{ 1,  1}, { 1,  1}}  /* REORDER_INVERSE_NUMBERS_AS_L */
400        }
401    };
402
403    private boolean assertRoundTrip(Bidi bidi, int tc, int outIndex,
404                                    String src, String dest,
405                                    int mode, int option, byte level) {
406        String descMode, descOption;
407        String dest2;
408
409        switch (modes[mode]) {
410            case Bidi.REORDER_NUMBERS_SPECIAL:
411                bidi.setReorderingMode(Bidi.REORDER_INVERSE_FOR_NUMBERS_SPECIAL);
412                break;
413            case Bidi.REORDER_GROUP_NUMBERS_WITH_R:
414                bidi.setReorderingMode(Bidi.REORDER_GROUP_NUMBERS_WITH_R);
415                break;
416            case Bidi.REORDER_RUNS_ONLY:
417                bidi.setReorderingMode(Bidi.REORDER_RUNS_ONLY);
418                break;
419            case Bidi.REORDER_INVERSE_NUMBERS_AS_L:
420                bidi.setReorderingMode(Bidi.REORDER_DEFAULT);
421                break;
422            case Bidi.REORDER_INVERSE_LIKE_DIRECT:
423                bidi.setReorderingMode(Bidi.REORDER_DEFAULT);
424                break;
425            case Bidi.REORDER_INVERSE_FOR_NUMBERS_SPECIAL:
426                bidi.setReorderingMode(Bidi.REORDER_NUMBERS_SPECIAL);
427                break;
428            default:
429                bidi.setReorderingMode(Bidi.REORDER_INVERSE_LIKE_DIRECT);
430                break;
431        }
432        bidi.setReorderingOptions(Bidi.OPTION_REMOVE_CONTROLS);
433
434        bidi.setPara(pseudoToU16(dest), level, null);
435        dest2 = bidi.writeReordered(Bidi.DO_MIRRORING);
436
437        dest2 = u16ToPseudo(dest2);
438        checkWhatYouCan(bidi, dest, dest2);
439        descMode = modeToString(modes[mode]);
440        descOption = spOptionsToString(options[option]);
441        if (!src.equals(dest2)) {
442            if (roundtrip[tc][mode][option][level] == 1) {
443                errln("\nRound trip failed for case=" + tc +
444                      " mode=" + mode + " option=" + option +
445                      "\nOriginal text:      " + src +
446                      "\nRound-tripped text: " + dest2 +
447                      "\nIntermediate text:  " + dest +
448                      "\nReordering mode:    " + descMode +
449                      "\nReordering option:  " + descOption +
450                      "\nParagraph level:    " + level);
451            } else {
452                logln("\nExpected round trip failure for case=" + tc +
453                      " mode=" + mode + " option=" + option +
454                      "\nOriginal text:      " + src +
455                      "\nRound-tripped text: " + dest2 +
456                      "\nIntermediate text:  " + dest +
457                      "\nReordering mode:    " + descMode +
458                      "\nReordering option:  " + descOption +
459                      "\nParagraph level:    " + level);
460            }
461            return false;
462        }
463        if (!checkResultLength(bidi, dest, dest2, descMode,
464                               "OPTION_REMOVE_CONTROLS", level)) {
465            return false;
466        }
467        if ((outIndex > -1) &&
468            !checkMaps(bidi, outIndex, src, dest, descMode,
469                       "OPTION_REMOVE_CONTROLS", level, false)) {
470            return false;
471        }
472        return true;
473    }
474
475    private boolean checkResultLength(Bidi bidi, String src, String dest,
476                                   String mode, String option, byte level) {
477        int actualLen;
478        if (mode.equals("REORDER_INVERSE_NUMBERS_AS_L"))
479            actualLen = dest.length();
480        else
481            actualLen = bidi.getResultLength();
482        if (actualLen != dest.length()) {
483            errln("\nBidi.getResultLength failed." +
484                  "\nExpected:           " + dest.length() +
485                  "\nActual:             " + actualLen +
486                  "\nInput:              " + src +
487                  "\nOutput:             " + dest +
488                  "\nReordering mode:    " + mode +
489                  "\nReordering option:  " + option +
490                  "\nParagraph level:    " + level);
491            return false;
492        }
493        return true;
494    }
495
496    static String formatMap(int[] map)
497    {
498        char[] buffer = new char[map.length];
499        int i, k;
500        char c;
501        for (i = 0; i < map.length; i++) {
502            k = map[i];
503            if (k < 0)
504                c = '-';
505            else if (k >= columns.length)
506                c = '+';
507            else
508                c = columns[k];
509            buffer[i] = c;
510        }
511        return new String(buffer);
512    }
513
514    static final int NO = Bidi.MAP_NOWHERE;
515
516    static final int forwardMap[][] = {
517    /* TC 0: 123 */
518        { 0, 1, 2 },                                                    /* (0) */
519    /* TC 1: .123->4.5 */
520        { 0, 1, 2, 3, 4, 5, 6, 7, 8 },                                  /* (1) */
521        { 8, 5, 6, 7, 4, 3, 0, 1, 2 },                                  /* (2) */
522    /* TC 2: 678 */
523        { 0, 1, 2 },                                                    /* (3) */
524    /* TC 3: .678->8.9 */
525        { 0, 6, 7, 8, 5, 4, 1, 2, 3 },                                  /* (4) */
526        { 8, 5, 6, 7, 4, 3, 0, 1, 2 },                                  /* (5) */
527        { 0, 1, 2, 3, 4, 5, 6, 7, 8 },                                  /* (6) */
528    /* TC 4: MLK1.2,3JIH */
529        { 10, 9, 8, 3, 4, 5, 6, 7, 2, 1, 0 },                           /* (7) */
530    /* TC 5: FE.>12-> */
531        { 5, 4, 3, 2, 0, 1, 6, 7 },                                     /* (8) */
532        { 7, 6, 5, 4, 2, 3, 1, 0 },                                     /* (9) */
533        { 1, 0, 2, 3, 5, 6, 7, 8 },                                     /* (10) */
534    /* TC 6: JIH.>12->a */
535        { 6, 5, 4, 3, 2, 0, 1, 7, 8, 9 },                               /* (11) */
536        { 9, 8, 7, 6, 5, 3, 4, 2, 1, 0 },                               /* (12) */
537        { 2, 1, 0, 3, 4, 6, 7, 8, 9, 10 },                              /* (13) */
538        { 10, 9, 8, 7, 6, 4, 5, 3, 2, 0 },                              /* (14) */
539    /* TC 7: CBA.>67->89=a */
540        { 2, 1, 0, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13 },                  /* (15) */
541        { 12, 11, 10, 9, 8, 6, 7, 5, 4, 2, 3, 1, 0 },                   /* (16) */
542        { 13, 12, 11, 10, 9, 7, 8, 6, 5, 3, 4, 2, 0 },                  /* (17) */
543        { 10, 9, 8, 7, 6, 4, 5, 3, 2, 0, 1, 11, 12 },                   /* (18) */
544    /* TC 8: CBA.123->xyz */
545        { 6, 5, 4, 3, 0, 1, 2, 7, 8, 9, 10, 11 },                       /* (19) */
546        { 11, 10, 9, 8, 5, 6, 7, 4, 3, 0, 1, 2 },                       /* (20) */
547        { 2, 1, 0, 3, 5, 6, 7, 8, 9, 10, 11, 12 },                      /* (21) */
548        { 12, 11, 10, 9, 6, 7, 8, 5, 4, 0, 1, 2 },                      /* (22) */
549    /* TC 9: .>12->xyz */
550        { 0, 1, 2, 3, 4, 5, 6, 7, 8 },                                  /* (23) */
551        { 8, 7, 5, 6, 4, 3, 0, 1, 2 },                                  /* (24) */
552        { 9, 8, 6, 7, 5, 4, 0, 1, 2 },                                  /* (25) */
553    /* TC 10: a.>67->xyz */
554        { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },                               /* (26) */
555        { 0, 1, 2, 4, 5, 7, 8, 9, 10, 11 },                             /* (27) */
556        { 9, 8, 7, 5, 6, 4, 3, 0, 1, 2 },                               /* (28) */
557    /* TC 11: 123JIH */
558        { 0, 1, 2, 5, 4, 3 },                                           /* (29) */
559        { 3, 4, 5, 2, 1, 0 },                                           /* (30) */
560    /* TC 12: 123 JIH */
561        { 0, 1, 2, 3, 6, 5, 4 },                                        /* (31) */
562        { 4, 5, 6, 3, 2, 1, 0 },                                        /* (32) */
563    };
564    static final int inverseMap[][] = {
565    /* TC 0: 123 */
566        { 0, 1, 2 },                                                    /* (0) */
567    /* TC 1: .123->4.5 */
568        { 0, 1, 2, 3, 4, 5, 6, 7, 8 },                                  /* (1) */
569        { 6, 7, 8, 5, 4, 1, 2, 3, 0 },                                  /* (2) */
570    /* TC 2: 678 */
571        { 0, 1, 2 },                                                    /* (3) */
572    /* TC 3: .678->8.9 */
573        { 0, 6, 7, 8, 5, 4, 1, 2, 3 },                                  /* (4) */
574        { 6, 7, 8, 5, 4, 1, 2, 3, 0 },                                  /* (5) */
575        { 0, 1, 2, 3, 4, 5, 6, 7, 8 },                                  /* (6) */
576    /* TC 4: MLK1.2,3JIH */
577        { 10, 9, 8, 3, 4, 5, 6, 7, 2, 1, 0 },                           /* (7) */
578    /* TC 5: FE.>12-> */
579        { 4, 5, 3, 2, 1, 0, 6, 7 },                                     /* (8) */
580        { 7, 6, 4, 5, 3, 2, 1, 0 },                                     /* (9) */
581        { 1, 0, 2, 3, NO, 4, 5, 6, 7 },                                 /* (10) */
582    /* TC 6: JIH.>12->a */
583        { 5, 6, 4, 3, 2, 1, 0, 7, 8, 9 },                               /* (11) */
584        { 9, 8, 7, 5, 6, 4, 3, 2, 1, 0 },                               /* (12) */
585        { 2, 1, 0, 3, 4, NO, 5, 6, 7, 8, 9 },                           /* (13) */
586        { 9, NO, 8, 7, 5, 6, 4, 3, 2, 1, 0 },                           /* (14) */
587    /* TC 7: CBA.>67->89=a */
588        { 2, 1, 0, 3, 4, NO, 5, 6, 7, 8, 9, 10, 11, 12 },               /* (15) */
589        { 12, 11, 9, 10, 8, 7, 5, 6, 4, 3, 2, 1, 0 },                   /* (16) */
590        { 12, NO, 11, 9, 10, 8, 7, 5, 6, 4, 3, 2, 1, 0 },               /* (17) */
591        { 9, 10, 8, 7, 5, 6, 4, 3, 2, 1, 0, 11, 12 },                   /* (18) */
592    /* TC 8: CBA.123->xyz */
593        { 4, 5, 6, 3, 2, 1, 0, 7, 8, 9, 10, 11 },                       /* (19) */
594        { 9, 10, 11, 8, 7, 4, 5, 6, 3, 2, 1, 0 },                       /* (20) */
595        { 2, 1, 0, 3, NO, 4, 5, 6, 7, 8, 9, 10, 11 },                   /* (21) */
596        { 9, 10, 11, NO, 8, 7, 4, 5, 6, 3, 2, 1, 0 },                   /* (22) */
597    /* TC 9: .>12->xyz */
598        { 0, 1, 2, 3, 4, 5, 6, 7, 8 },                                  /* (23) */
599        { 6, 7, 8, 5, 4, 2, 3, 1, 0 },                                  /* (24) */
600        { 6, 7, 8, NO, 5, 4, 2, 3, 1, 0 },                              /* (25) */
601    /* TC 10: a.>67->xyz */
602        { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },                               /* (26) */
603        { 0, 1, 2, NO, 3, 4, NO, 5, 6, 7, 8, 9 },                       /* (27) */
604        { 7, 8, 9, 6, 5, 3, 4, 2, 1, 0 },                               /* (28) */
605    /* TC 11: 123JIH */
606        { 0, 1, 2, 5, 4, 3 },                                           /* (29) */
607        { 5, 4, 3, 0, 1, 2 },                                           /* (30) */
608    /* TC 12: 123 JIH */
609        { 0, 1, 2, 3, 6, 5, 4 },                                        /* (31) */
610        { 6, 5, 4, 3, 0, 1, 2 },                                        /* (32) */
611    };
612
613    private boolean checkMaps(Bidi bidi, int stringIndex, String src, String dest,
614            String mode, String option, byte level, boolean forward) {
615
616        int[] actualLogicalMap;
617        int[] actualVisualMap;
618        int[] getIndexMap;
619        int i, srcLen, resLen, index;
620        int[] expectedLogicalMap, expectedVisualMap;
621        boolean testOK = true;
622
623        if (forward) {
624            expectedLogicalMap = forwardMap[stringIndex];
625            expectedVisualMap  = inverseMap[stringIndex];
626        } else {
627            expectedLogicalMap = inverseMap[stringIndex];
628            expectedVisualMap  = forwardMap[stringIndex];
629        }
630        actualLogicalMap = bidi.getLogicalMap();
631        srcLen = bidi.getProcessedLength();
632        if (!Arrays.equals(expectedLogicalMap, actualLogicalMap)) {
633            err("Bidi.getLogicalMap returned unexpected map for output " +
634                "string index " + stringIndex + "\n" +
635                "source: " + src + "\n" +
636                "dest  : " + dest + "\n" +
637                "Scale : " + columnString + "\n" +
638                "ExpMap: " + formatMap(expectedLogicalMap) + "\n" +
639                "Actual: " + formatMap(actualLogicalMap) + "\n" +
640                "Paragraph level  : " + level + " == " + bidi.getParaLevel() + "\n" +
641                "Reordering mode  : " + mode + " == " + bidi.getReorderingMode() + "\n" +
642                "Reordering option: " + option + " == " + bidi.getReorderingOptions() + "\n" +
643                "Forward flag     : " + forward + "\n");
644            testOK = false;
645        }
646        resLen = bidi.getResultLength();
647        actualVisualMap = bidi.getVisualMap();
648        if (!Arrays.equals(expectedVisualMap, actualVisualMap)) {
649            err("Bidi.getVisualMap returned unexpected map for output " +
650                "string index " + stringIndex + "\n" +
651                "source: " + src + "\n" +
652                "dest  : " + dest + "\n" +
653                "Scale : " + columnString + "\n" +
654                "ExpMap: " + formatMap(expectedVisualMap) + "\n" +
655                "Actual: " + formatMap(actualVisualMap) + "\n" +
656                "Paragraph level  : " + level + " == " + bidi.getParaLevel() + "\n" +
657                "Reordering mode  : " + mode + " == " + bidi.getReorderingMode() + "\n" +
658                "Reordering option: " + option + " == " + bidi.getReorderingOptions() + "\n" +
659                "Forward flag     : " + forward + "\n");
660            testOK = false;
661        }
662        getIndexMap = new int[srcLen];
663        for (i = 0; i < srcLen; i++) {
664            index = bidi.getVisualIndex(i);
665            getIndexMap[i] = index;
666        }
667        if (!Arrays.equals(actualLogicalMap, getIndexMap)) {
668            err("Mismatch between getLogicalMap and getVisualIndex for output " +
669                "string index " + stringIndex + "\n" +
670                "source: " + src + "\n" +
671                "dest  : " + dest + "\n" +
672                "Scale : " + columnString + "\n" +
673                "ActMap: " + formatMap(actualLogicalMap) + "\n" +
674                "IdxMap: " + formatMap(getIndexMap) + "\n" +
675                "Paragraph level  : " + level + " == " + bidi.getParaLevel() + "\n" +
676                "Reordering mode  : " + mode + " == " + bidi.getReorderingMode() + "\n" +
677                "Reordering option: " + option + " == " + bidi.getReorderingOptions() + "\n" +
678                "Forward flag     : " + forward + "\n");
679            testOK = false;
680        }
681        getIndexMap = new int[resLen];
682        for (i = 0; i < resLen; i++) {
683            index = bidi.getLogicalIndex(i);
684            getIndexMap[i] = index;
685        }
686        if (!Arrays.equals(actualVisualMap, getIndexMap)) {
687            err("Mismatch between getVisualMap and getLogicalIndex for output " +
688                "string index " + stringIndex + "\n" +
689                "source: " + src + "\n" +
690                "dest  : " + dest + "\n" +
691                "Scale : " + columnString + "\n" +
692                "ActMap: " + formatMap(actualVisualMap) + "\n" +
693                "IdxMap: " + formatMap(getIndexMap) + "\n" +
694                "Paragraph level  : " + level + " == " + bidi.getParaLevel() + "\n" +
695                "Reordering mode  : " + mode + " == " + bidi.getReorderingMode() + "\n" +
696                "Reordering option: " + option + " == " + bidi.getReorderingOptions() + "\n" +
697                "Forward flag     : " + forward + "\n");
698            testOK = false;
699        }
700        return testOK;
701    }
702
703
704    public static void main(String[] args) {
705        try {
706            new TestReorderingMode().run(args);
707        }
708        catch (Exception e) {
709            System.out.println(e);
710        }
711    }
712
713}
714