2 *******************************************************************************
\r
3 * Copyright (C) 2001-2010, International Business Machines
\r
4 * Corporation and others. All Rights Reserved.
\r
5 *******************************************************************************
\r
8 package com.ibm.icu.dev.test.bidi;
\r
10 import java.util.Arrays;
\r
12 import com.ibm.icu.impl.Utility;
\r
13 import com.ibm.icu.text.Bidi;
\r
16 * Regression test for the basic "inverse" Bidi mode.
\r
18 * ported from C by Lina Kemmel, Matitiahu Allouche
\r
21 public class TestInverse extends BidiTest {
\r
23 private int countRoundtrips = 0;
\r
24 private int countNonRoundtrips = 0;
\r
26 static final String[] testCases = {
\r
27 "\u006c\u0061\u0028\u0074\u0069\u006e\u0020\u05d0\u05d1\u0029\u05d2\u05d3",
\r
28 "\u006c\u0061\u0074\u0020\u05d0\u05d1\u05d2\u0020\u0031\u0032\u0033",
\r
29 "\u006c\u0061\u0074\u0020\u05d0\u0028\u05d1\u05d2\u0020\u0031\u0029\u0032\u0033",
\r
30 "\u0031\u0032\u0033\u0020\u05d0\u05d1\u05d2\u0020\u0034\u0035\u0036",
\r
31 "\u0061\u0062\u0020\u0061\u0062\u0020\u0661\u0662"
\r
34 public void testInverse() {
\r
38 logln("\nEntering TestInverse\n");
\r
40 log("inverse Bidi: testInverse(L) with " + testCases.length +
\r
41 " test cases ---\n");
\r
42 for(i = 0; i < testCases.length; ++i) {
\r
43 logln("Testing case " + i);
\r
44 _testInverseBidi(bidi, testCases[i], Bidi.DIRECTION_LEFT_TO_RIGHT);
\r
47 log("inverse Bidi: testInverse(R) with " + testCases.length +
\r
48 " test cases ---\n");
\r
49 for (i = 0; i < testCases.length; ++i) {
\r
50 logln("Testing case " + i);
\r
51 _testInverseBidi(bidi, testCases[i], Bidi.DIRECTION_RIGHT_TO_LEFT);
\r
54 _testManyInverseBidi(bidi, Bidi.DIRECTION_LEFT_TO_RIGHT);
\r
55 _testManyInverseBidi(bidi, Bidi.DIRECTION_RIGHT_TO_LEFT);
\r
57 logln("inverse Bidi: rountrips: " + countRoundtrips +
\r
58 " non-roundtrips: " + countNonRoundtrips);
\r
60 _testWriteReverse();
\r
62 _testManyAddedPoints();
\r
66 logln("\nExiting TestInverse\n");
\r
69 private static final char[][] repeatSegments = {
\r
70 { 0x61, 0x62 }, /* L */
\r
71 { 0x5d0, 0x5d1 }, /* R */
\r
72 { 0x627, 0x628 }, /* AL */
\r
73 { 0x31, 0x32 }, /* EN */
\r
74 { 0x661, 0x662 }, /* AN */
\r
75 { 0x20, 0x20 } /* WS (N) */
\r
77 private static final int COUNT_REPEAT_SEGMENTS = 6;
\r
79 private void _testManyInverseBidi(Bidi bidi, int direction) {
\r
80 char[] text = { 0, 0, 0x20, 0, 0, 0x20, 0, 0 };
\r
83 log("inverse Bidi: testManyInverseBiDi(" +
\r
84 (direction == Bidi.DIRECTION_LEFT_TO_RIGHT ? 'L' : 'R') +
\r
85 ") - test permutations of text snippets ---\n");
\r
86 for (i = 0; i < COUNT_REPEAT_SEGMENTS; ++i) {
\r
87 text[0] = repeatSegments[i][0];
\r
88 text[1] = repeatSegments[i][1];
\r
89 for (j = 0; j < COUNT_REPEAT_SEGMENTS; ++j) {
\r
90 text[3] = repeatSegments[j][0];
\r
91 text[4] = repeatSegments[j][1];
\r
92 for (k = 0; k < COUNT_REPEAT_SEGMENTS; ++k) {
\r
93 text[6] = repeatSegments[k][0];
\r
94 text[7] = repeatSegments[k][1];
\r
96 log("inverse Bidi: testManyInverseBiDi()[" +
\r
97 i + " " + j + " " + k + "]\n");
\r
98 _testInverseBidi(bidi, new String(text), direction);
\r
104 private void _testInverseBidi(Bidi bidi, String src, int direction) {
\r
105 String visualLTR, logicalDest, visualDest;
\r
107 if (direction == Bidi.DIRECTION_LEFT_TO_RIGHT) {
\r
108 log("inverse Bidi: testInverse(L)\n");
\r
110 /* convert visual to logical */
\r
111 bidi.setInverse(true);
\r
112 if (!bidi.isInverse()) {
\r
113 err("Error while doing setInverse(true)\n");
\r
115 bidi.setPara(src, Bidi.LTR, null);
\r
116 if (!Arrays.equals(src.toCharArray(), bidi.getText())) {
\r
117 err("Wrong value returned by getText\n");
\r
119 if (!src.equals(bidi.getTextAsString())) {
\r
120 err("Wrong value returned by getTextAsString\n");
\r
122 logicalDest = bidi.writeReordered(Bidi.DO_MIRRORING |
\r
123 Bidi.INSERT_LRM_FOR_NUMERIC);
\r
125 printUnicode(src.toCharArray(), bidi.getLevels());
\r
128 /* convert back to visual LTR */
\r
129 bidi.setInverse(false);
\r
130 if (bidi.isInverse()) {
\r
131 err("Error while doing setInverse(false)\n");
\r
133 bidi.setPara(logicalDest, Bidi.LTR, null);
\r
134 visualDest = bidi.writeReordered(Bidi.DO_MIRRORING |
\r
135 Bidi.REMOVE_BIDI_CONTROLS);
\r
137 logln("inverse Bidi: testInverse(R)\n");
\r
139 /* reverse visual from RTL to LTR */
\r
140 visualLTR = Bidi.writeReverse(src, 0);
\r
142 printUnicode(src.toCharArray(), null);
\r
145 /* convert visual RTL to logical */
\r
146 bidi.setInverse(true);
\r
147 bidi.setPara(visualLTR, Bidi.LTR, null);
\r
148 logicalDest = bidi.writeReordered(Bidi.DO_MIRRORING |
\r
149 Bidi.INSERT_LRM_FOR_NUMERIC);
\r
151 printUnicode(visualLTR.toCharArray(), bidi.getLevels());
\r
154 /* convert back to visual RTL */
\r
155 bidi.setInverse(false);
\r
156 bidi.setPara(logicalDest, Bidi.LTR, null);
\r
157 visualDest = bidi.writeReordered(Bidi.DO_MIRRORING |
\r
158 Bidi.REMOVE_BIDI_CONTROLS | Bidi.OUTPUT_REVERSE);
\r
161 printUnicode(logicalDest.toCharArray(), bidi.getLevels());
\r
164 printUnicode(visualDest.toCharArray(), null);
\r
166 } catch (Exception e) {
\r
167 errln("inverse Bidi: *** failed");
\r
171 /* check and print results */
\r
172 if (src.equals(visualDest)) {
\r
174 log(" + roundtripped\n");
\r
176 ++countNonRoundtrips;
\r
177 log(" * did not roundtrip\n");
\r
181 private void _testWriteReverse() {
\r
182 /* U+064e and U+0650 are combining marks (Mn) */
\r
184 forward = "\u200f\u0627\u064e\u0650\u0020\u0028\u0031\u0029",
\r
185 reverseKeepCombining =
\r
186 "\u0029\u0031\u0028\u0020\u0627\u064e\u0650\u200f",
\r
187 reverseRemoveControlsKeepCombiningDoMirror =
\r
188 "\u0028\u0031\u0029\u0020\u0627\u064e\u0650";
\r
192 /* test Bidi.writeReverse() with "interesting" options */
\r
194 reverse = Bidi.writeReverse(forward, Bidi.KEEP_BASE_COMBINING);
\r
195 } catch (Exception e) {
\r
196 errln("Failure in Bidi.writeReverse(KEEP_BASE_COMBINING)");
\r
199 assertEquals("\nFailure in " + getClass().toString() +
\r
200 " in Bidi.writeReverse", reverseKeepCombining,
\r
201 reverse, forward, null, "KEEP_BASE_COMBINING", null);
\r
204 reverse = Bidi.writeReverse(forward, Bidi.REMOVE_BIDI_CONTROLS |
\r
205 Bidi.DO_MIRRORING | Bidi.KEEP_BASE_COMBINING);
\r
206 } catch (Exception e) {
\r
207 errln("Failure in Bidi.writeReverse(KEEP_BASE_COMBINING)");
\r
209 assertEquals("\nFailure in " + getClass().toString() +
\r
210 " in Bidi.writeReverse",
\r
211 reverseRemoveControlsKeepCombiningDoMirror,
\r
212 reverse, forward, null,
\r
213 "REMOVE_BIDI_CONTROLS|DO_MIRRORING|KEEP_BASE_COMBINING",
\r
217 private void printUnicode(char[] chars, byte[] levels) {
\r
221 for (i = 0; i < chars.length; ++i) {
\r
222 log("0x" + Utility.hex(chars[i]));
\r
223 if (levels != null) {
\r
224 log("." + levels[i]);
\r
231 private void _testManyAddedPoints() {
\r
232 Bidi bidi = new Bidi();
\r
233 char[] text = new char[90];
\r
234 for (int i = 0; i < text.length; i+=3) {
\r
236 text[i+1] = '\u05d0';
\r
239 bidi.setReorderingMode(Bidi.REORDER_INVERSE_LIKE_DIRECT);
\r
240 bidi.setReorderingOptions(Bidi.OPTION_INSERT_MARKS);
\r
241 bidi.setPara(text, Bidi.LTR, null);
\r
242 String out = bidi.writeReordered(0);
\r
243 char[] expected = new char[120];
\r
244 for (int i = 0; i < expected.length; i+=4) {
\r
246 expected[i+1] = '\u05d0';
\r
247 expected[i+2] = '\u200e';
\r
248 expected[i+3] = '3';
\r
250 assertEquals("\nInvalid output with many added points",
\r
251 new String(expected), out);
\r
254 private void _testMisc() {
\r
255 Bidi bidi = new Bidi();
\r
256 bidi.setInverse(true);
\r
257 bidi.setPara(" ", Bidi.RTL, null);
\r
258 String out = bidi.writeReordered(Bidi.OUTPUT_REVERSE | Bidi.INSERT_LRM_FOR_NUMERIC);
\r
259 assertEquals("\nInvalid output with RLM at both sides",
\r
260 "\u200f \u200f", out);
\r
264 public static void main(String[] args) {
\r
266 new TestInverse().run(args);
\r
268 catch (Exception e) {
\r
269 System.out.println(e);
\r