1/*
2*******************************************************************************
3*   Copyright (C) 2007-2010, International Business Machines
4*   Corporation and others.  All Rights Reserved.
5*******************************************************************************
6*/
7
8package com.ibm.icu.dev.test.bidi;
9
10import java.awt.font.NumericShaper;
11import java.awt.font.TextAttribute;
12import java.text.AttributedCharacterIterator;
13import java.text.AttributedString;
14
15import com.ibm.icu.text.Bidi;
16
17/**
18 * Regression test for java.text.Bidi compatibility
19 *
20 * @author Matitiahu Allouche
21 */
22
23public class TestCompatibility extends BidiTest {
24
25    void compareBidi(Bidi bidi, java.text.Bidi jbidi)
26    {
27        byte paraLevel = bidi.getParaLevel();
28        if (bidi.baseIsLeftToRight() != jbidi.baseIsLeftToRight()) {
29            errln("Discrepancy in baseIsLeftToRight for case " +
30                  "(level=" + paraLevel + "): " +
31                  u16ToPseudo(bidi.getTextAsString()) +
32                  "\n    bidi: " + bidi.baseIsLeftToRight() +
33                  "\n   jbidi: " + jbidi.baseIsLeftToRight());
34        }
35        if (bidi.getBaseLevel() != jbidi.getBaseLevel()) {
36            errln("Discrepancy in getBaseLevel for case " +
37                  "(level=" + paraLevel + "): " +
38                  u16ToPseudo(bidi.getTextAsString()) +
39                  "\n    bidi: " + bidi.getBaseLevel() +
40                  "\n   jbidi: " + jbidi.getBaseLevel());
41        }
42        if (bidi.getLength() != jbidi.getLength()) {
43            errln("Discrepancy in getLength for case " +
44                  "(level=" + paraLevel + "): " +
45                  u16ToPseudo(bidi.getTextAsString()) +
46                  "\n    bidi: " + bidi.getLength() +
47                  "\n   jbidi: " + jbidi.getLength());
48        }
49        int len = bidi.getLength();
50        for (int i = 0; i < len; i++) {
51            if (bidi.getLevelAt(i) != jbidi.getLevelAt(i)) {
52                errln("Discrepancy in getLevelAt for offset " + i +
53                      " of case " +
54                      "(level=" + paraLevel + "): " +
55                      u16ToPseudo(bidi.getTextAsString()) +
56                      "\n    bidi: " + bidi.getLevelAt(i) +
57                      "\n   jbidi: " + jbidi.getLevelAt(i));
58            }
59        }
60        if (bidi.getRunCount() != jbidi.getRunCount()) {
61            if (!(len == 0 && jbidi.getRunCount() == 1)) {
62                errln("Discrepancy in getRunCount for case " +
63                      "(level=" + paraLevel + "): " +
64                      u16ToPseudo(bidi.getTextAsString()) +
65                      "\n    bidi: " + bidi.getRunCount() +
66                      "\n   jbidi: " + jbidi.getRunCount());
67            }
68        }
69        int runCount = bidi.getRunCount();
70        for (int i = 0; i < runCount; i++) {
71            if (bidi.getRunLevel(i) != jbidi.getRunLevel(i)) {
72                errln("Discrepancy in getRunLevel for run " + i +
73                      " of case " +
74                      "(level=" + paraLevel + "): " +
75                      u16ToPseudo(bidi.getTextAsString()) +
76                      "\n    bidi: " + bidi.getRunLevel(i) +
77                      "\n   jbidi: " + jbidi.getRunLevel(i));
78            }
79            if (bidi.getRunLimit(i) != jbidi.getRunLimit(i)) {
80                errln("Discrepancy in getRunLimit for run " + i +
81                      " of case " +
82                      "(level=" + paraLevel + "): " +
83                      u16ToPseudo(bidi.getTextAsString()) +
84                      "\n    bidi: " + bidi.getRunLimit(i) +
85                      "\n   jbidi: " + jbidi.getRunLimit(i));
86            }
87            if (bidi.getRunStart(i) != jbidi.getRunStart(i)) {
88                errln("Discrepancy in getRunStart for run " + i +
89                      " of case " +
90                      "(level=" + paraLevel + "): " +
91                      u16ToPseudo(bidi.getTextAsString()) +
92                      "\n    bidi: " + bidi.getRunStart(i) +
93                      "\n   jbidi: " + jbidi.getRunStart(i));
94            }
95        }
96        if (bidi.isLeftToRight() != jbidi.isLeftToRight()) {
97            errln("Discrepancy in isLeftToRight for case " +
98                  "(level=" + paraLevel + "): " +
99                  u16ToPseudo(bidi.getTextAsString()) +
100                  "\n    bidi: " + bidi.isLeftToRight() +
101                  "\n   jbidi: " + jbidi.isLeftToRight());
102        }
103        if (bidi.isMixed() != jbidi.isMixed()) {
104            errln("Discrepancy in isMixed for case " +
105                  "(level=" + paraLevel + "): " +
106                  u16ToPseudo(bidi.getTextAsString()) +
107                  "\n    bidi: " + bidi.isMixed() +
108                  "\n   jbidi: " + jbidi.isMixed());
109        }
110        if (bidi.isRightToLeft() != jbidi.isRightToLeft()) {
111            errln("Discrepancy in isRightToLeft for case " +
112                  "(level=" + paraLevel + "): " +
113                  u16ToPseudo(bidi.getTextAsString()) +
114                  "\n    bidi: " + bidi.isRightToLeft() +
115                  "\n   jbidi: " + jbidi.isRightToLeft());
116        }
117        char[] text = bidi.getText();
118        if (Bidi.requiresBidi(text, 0, text.length) !=
119            java.text.Bidi.requiresBidi(text, 0, text.length)) {
120            errln("Discrepancy in requiresBidi for case " +
121                  u16ToPseudo(bidi.getTextAsString()) +
122                  "\n    bidi: " + Bidi.requiresBidi(text, 0, text.length) +
123                  "\n   jbidi: " + java.text.Bidi.requiresBidi(text, 0, text.length));
124        }
125        /* skip the next test, since the toString implementation are
126         * not compatible
127        if (!bidi.toString().equals(jbidi.toString())) {
128            errln("Discrepancy in toString for case " +
129                  "(level=" + paraLevel + "): " +
130                  u16ToPseudo(bidi.getTextAsString() +
131                  "\n    bidi: " + bidi.toString() +
132                  "\n   jbidi: " + jbidi.toString()));
133        }
134         */
135    }
136
137    public void testCompatibility()
138    {
139        // This test case does not work well on Java 1.4/1.4.1 environment,
140        // because of insufficient Bidi implementation in these versions.
141        // This test case also does not work will with Java 1.7 environment,
142        // because the changes to the Java Bidi implementation.
143        String javaVersion = System.getProperty("java.version");
144        if (javaVersion.startsWith("1.4.0") || javaVersion.startsWith("1.4.1") || javaVersion.startsWith("1.7")) {
145            logln("\nSkipping TestCompatibility.  The test case is known to fail on Java "
146                    + javaVersion + "\n");
147            return;
148        }
149        logln("\nEntering TestCompatibility\n");
150        /* check constant field values */
151        int val;
152        val = Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT;
153        val = Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT;
154        val = Bidi.DIRECTION_LEFT_TO_RIGHT;
155        val = Bidi.DIRECTION_RIGHT_TO_LEFT;
156        logln("last val = " + val);
157
158        String[] data = {"",
159                         /* the following 2 cases are skipped, because
160                          * java.text.Bidi has bugs which cause discrepancies
161                         "abc",
162                         "ABC",
163                          */
164                         "abc def",
165                         "ABC DEF",
166                         "abc 123 def",
167                         "ABC 123 DEF",
168                         "abc DEF ghi",
169                         "abc DEF 123 xyz",
170                         "abc GHIJ 12345 def KLM"
171                        };
172        int dataCnt = data.length;
173        Bidi bidi;
174        java.text.Bidi jbidi;
175        for (int i = 0; i < dataCnt; i++) {
176            String src = pseudoToU16(data[i]);
177            bidi = new Bidi(src, Bidi.DIRECTION_LEFT_TO_RIGHT);
178            jbidi = new java.text.Bidi(src, java.text.Bidi.DIRECTION_LEFT_TO_RIGHT);
179            compareBidi(bidi, jbidi);
180            bidi = new Bidi(src, Bidi.DIRECTION_RIGHT_TO_LEFT);
181            jbidi = new java.text.Bidi(src, java.text.Bidi.DIRECTION_RIGHT_TO_LEFT);
182            compareBidi(bidi, jbidi);
183            char[] chars = src.toCharArray();
184            bidi = new Bidi(chars, 0, null, 0, chars.length, Bidi.DIRECTION_LEFT_TO_RIGHT);
185            jbidi = new java.text.Bidi(chars, 0, null, 0, chars.length, java.text.Bidi.DIRECTION_LEFT_TO_RIGHT);
186            compareBidi(bidi, jbidi);
187        }
188        /* check bogus flags */
189        bidi = new Bidi("abc", 999);
190        assertEquals("\nDirection should be LTR", Bidi.LTR, bidi.getDirection());
191        /* check constructor with overriding embeddings */
192        bidi = new Bidi(new char[] { 's', 's', 's' }, 0,
193                        new byte[] {(byte) -7, (byte) -2, (byte) -3 },
194                        0, 3, Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT);
195        jbidi = new java.text.Bidi(new char[] { 's', 's', 's' }, 0,
196                        new byte[] {(byte) -7, (byte) -2, (byte) -3 },
197                        0, 3, Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT);
198
199        AttributedString as = new AttributedString("HEBREW 123 english MOREHEB");
200        as.addAttribute(TextAttribute.RUN_DIRECTION, TextAttribute.RUN_DIRECTION_RTL);
201        as.addAttribute(TextAttribute.NUMERIC_SHAPING, NumericShaper.getShaper(NumericShaper.ARABIC));
202        as.addAttribute(TextAttribute.BIDI_EMBEDDING, new Integer(1), 0, 26);
203        as.addAttribute(TextAttribute.BIDI_EMBEDDING, new Integer(-1), 0, 6);
204        as.addAttribute(TextAttribute.BIDI_EMBEDDING, new Integer(-1), 19, 26);
205        AttributedCharacterIterator aci = as.getIterator();
206        bidi = new Bidi(aci);
207        jbidi = new java.text.Bidi(aci);
208        compareBidi(bidi, jbidi);
209        String out = bidi.writeReordered(0);
210        logln("Output #1 of Bidi(AttributedCharacterIterator): " + out);
211
212        as = new AttributedString("HEBREW 123 english MOREHEB");
213        as.addAttribute(TextAttribute.RUN_DIRECTION, TextAttribute.RUN_DIRECTION_RTL);
214        as.addAttribute(TextAttribute.BIDI_EMBEDDING, new Integer(0), 0, 26);
215        aci = as.getIterator();
216        bidi = new Bidi(aci);
217        jbidi = new java.text.Bidi(aci);
218        compareBidi(bidi, jbidi);
219        out = bidi.writeReordered(0);
220        logln("Output #2 of Bidi(AttributedCharacterIterator): " + out);
221
222        as = new AttributedString("HEBREW 123 english MOREHEB");
223        aci = as.getIterator();
224        bidi = new Bidi(aci);
225        jbidi = new java.text.Bidi(aci);
226        compareBidi(bidi, jbidi);
227        out = bidi.writeReordered(0);
228        logln("Output #3 of Bidi(AttributedCharacterIterator): " + out);
229
230        char[] text = "abc==(123)==>def".toCharArray();
231        bidi = new Bidi(text, 3, null, 0, 10, Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT);
232        jbidi = new java.text.Bidi(text, 3, null, 0, 10, java.text.Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT);
233        compareBidi(bidi, jbidi);
234        out = bidi.writeReordered(0);
235        logln("Output of Bidi(abc==(123)==>def,3,null,0,10, DEFAULT_LTR): " + out);
236        bidi = new Bidi(text, 3, null, 0, 10, Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT);
237        jbidi = new java.text.Bidi(text, 3, null, 0, 10, java.text.Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT);
238        compareBidi(bidi, jbidi);
239        out = bidi.writeReordered(0);
240        logln("Output of Bidi(abc==(123)==>def,3,null,0,10, DEFAULT_RTL): " + out);
241        byte[] levels = new byte[] {0,0,0,-1,-1,-1,0,0,0,0};
242        bidi = new Bidi(text, 3, levels, 0, 10, Bidi.DIRECTION_LEFT_TO_RIGHT);
243        jbidi = new java.text.Bidi(text, 3, levels, 0, 10, java.text.Bidi.DIRECTION_LEFT_TO_RIGHT);
244        compareBidi(bidi, jbidi);
245        out = bidi.writeReordered(0);
246        logln("Output of Bidi(abc==(123)==>def,3,levels,0,10, LTR): " + out);
247        bidi = new Bidi(text, 3, levels, 0, 10, Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT);
248        jbidi = new java.text.Bidi(text, 3, levels, 0, 10, java.text.Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT);
249        compareBidi(bidi, jbidi);
250        out = bidi.writeReordered(0);
251        logln("Output of Bidi(abc==(123)==>def,3,levels,0,10, DEFAULT_RTL): " + out);
252
253        /* test reorderVisually */
254        byte[] myLevels = new byte[] {1,2,0,1,2,1,2,0,1,2};
255        Character[] objects = new Character[10];
256        levels = new byte[objects.length];
257        for (int i = 0; i < objects.length; i++) {
258            objects[i] = new Character((char)('a'+i));
259            levels[i] = myLevels[i];
260        }
261        Bidi.reorderVisually(levels, 3, objects, 3, 7);
262        String strbidi = "";
263        for (int i = 0; i < objects.length; i++) {
264            strbidi += objects[i].toString();
265        }
266        for (int i = 0; i < objects.length; i++) {
267            objects[i] = new Character((char)('a'+i));
268            levels[i] = myLevels[i];
269        }
270        java.text.Bidi.reorderVisually(levels, 3, objects, 3, 7);
271        String strjbidi = "";
272        for (int i = 0; i < objects.length; i++) {
273            strjbidi += objects[i].toString();
274        }
275        if (!strjbidi.equals(strbidi)) {
276            errln("Discrepancy in reorderVisually " +
277                  "\n      bidi: " + strbidi +
278                  "\n     jbidi: " + strjbidi);
279        } else {
280            logln("Correct match in reorderVisually " +
281                  "\n      bidi: " + strbidi +
282                  "\n     jbidi: " + strjbidi);
283        }
284
285        logln("\nExiting TestCompatibility\n");
286    }
287
288    public static void main(String[] args) {
289        try {
290            new TestCompatibility().run(args);
291        }
292        catch (Exception e) {
293            System.out.println(e);
294        }
295    }
296}
297