]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-52_1/main/tests/core/src/com/ibm/icu/dev/test/bidi/TestMultipleParagraphs.java
Upgrade ICU4J.
[Dictionary.git] / jars / icu4j-52_1 / main / tests / core / src / com / ibm / icu / dev / test / bidi / TestMultipleParagraphs.java
1 /*
2 *******************************************************************************
3 *   Copyright (C) 2008-2010, International Business Machines
4 *   Corporation and others.  All Rights Reserved.
5 *******************************************************************************
6 */
7
8 package com.ibm.icu.dev.test.bidi;
9
10 import java.util.Arrays;
11
12 import com.ibm.icu.impl.Utility;
13 import com.ibm.icu.text.Bidi;
14 import com.ibm.icu.text.BidiRun;
15
16 /**
17  * Regression test for Bidi multiple paragraphs
18  *
19  * @author Lina Kemmel, Matitiahu Allouche
20  */
21
22 public class TestMultipleParagraphs extends BidiTest {
23
24     private static final String text =
25         "__ABC\u001c"                  /* Para #0 offset 0 */
26         + "__\u05d0DE\u001c"           /*       1        6 */
27         + "__123\u001c"                /*       2       12 */
28         + "\r\n"                       /*       3       18 */
29         + "FG\r"                       /*       4       20 */
30         + "\r"                         /*       5       23 */
31         + "HI\r\n"                     /*       6       24 */
32         + "\r\n"                       /*       7       28 */
33         + "\n"                         /*       8       30 */
34         + "\n"                         /*       9       31 */
35         + "JK\u001c";                  /*      10       32 */
36     private static final int paraCount = 11;
37     private static final int[] paraBounds = {
38         0, 6, 12, 18, 20, 23, 24, 28, 30, 31, 32, 35
39     };
40     private static final byte[] paraLevels = {
41         Bidi.LTR, Bidi.RTL, Bidi.LEVEL_DEFAULT_LTR, Bidi.LEVEL_DEFAULT_RTL, 22, 23
42     };
43     private static final byte[][] multiLevels = {
44         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
45         {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
46         {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
47         {0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0},
48         {22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22},
49         {23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23}
50     };
51     private static final String text2 = "\u05d0 1-2\u001c\u0630 1-2\u001c1-2";
52     private static final byte[] levels2 = {
53         1, 1, 2, 2, 2, 0, 1, 1, 2, 1, 2, 0, 2, 2, 2
54     };
55     private static final char[] multiparaTestString = {
56         0x5de, 0x5e0, 0x5e1, 0x5d4, 0x20,  0x5e1, 0x5e4, 0x5da,
57         0x20,  0xa,   0xa,   0x41,  0x72,  0x74,  0x69,  0x73,
58         0x74,  0x3a,  0x20,  0x5de, 0x5e0, 0x5e1, 0x5d4, 0x20,
59         0x5e1, 0x5e4, 0x5da, 0x20,  0xa,   0xa,   0x41,  0x6c,
60         0x62,  0x75,  0x6d,  0x3a,  0x20,  0x5de, 0x5e0, 0x5e1,
61         0x5d4, 0x20,  0x5e1, 0x5e4, 0x5da, 0x20,  0xa,   0xa,
62         0x54,  0x69,  0x6d,  0x65,  0x3a,  0x20,  0x32,  0x3a,
63         0x32,  0x37,  0xa,  0xa
64     };
65     private static final byte[] multiparaTestLevels = {
66         1, 1, 1, 1, 1, 1, 1, 1,
67         1, 1, 0, 0, 0, 0, 0, 0,
68         0, 0, 0, 1, 1, 1, 1, 1,
69         1, 1, 1, 0, 0, 0, 0, 0,
70         0, 0, 0, 0, 0, 1, 1, 1,
71         1, 1, 1, 1, 1, 0, 0, 0,
72         0, 0, 0, 0, 0, 0, 0, 0,
73         0, 0, 0, 0
74     };
75
76     public void testMultipleParagraphs()
77     {
78         byte gotLevel;
79         byte[] gotLevels;
80         boolean orderParagraphsLTR;
81         String src;
82         Bidi bidi = new Bidi();
83         Bidi bidiLine;
84         int count, paraStart, paraLimit, paraIndex, length;
85         int i, j, k;
86
87         logln("\nEntering TestMultipleParagraphs\n");
88         try {
89             bidi.setPara(text, Bidi.LTR, null);
90         } catch (IllegalArgumentException e) {
91             errln("1st Bidi.setPara failed, paraLevel = " + Bidi.LTR);
92         }
93
94         /* check paragraph count and boundaries */
95         if (paraCount != (count = bidi.countParagraphs())) {
96             errln("1st Bidi.countParagraphs returned " + count + ", should be " +
97                   paraCount);
98         }
99         BidiRun run;
100         for (i = 0; i < paraCount; i++) {
101             run = bidi.getParagraphByIndex(i);
102             paraStart = run.getStart();
103             paraLimit = run.getLimit();
104             if ((paraStart != paraBounds[i]) ||
105                 (paraLimit != paraBounds[i + 1])) {
106                 errln("Found boundaries of paragraph " + i + ": " +
107                       paraStart + "-" + paraLimit + "; expected: " +
108                       paraBounds[i] + "-" + paraBounds[i + 1]);
109             }
110         }
111
112         /* check with last paragraph not terminated by B */
113         char[] chars = text.toCharArray();
114         chars[chars.length - 1] = 'L';
115         src = new String(chars);
116         try {
117             bidi.setPara(src, Bidi.LTR, null);
118         } catch (IllegalArgumentException e) {
119             errln("2nd Bidi.setPara failed, paraLevel = " + Bidi.LTR);
120         }
121         if (paraCount != (count = bidi.countParagraphs())) {
122             errln("2nd Bidi.countParagraphs returned " + count +
123                   ", should be " + paraCount);
124         }
125         i = paraCount - 1;
126         run = bidi.getParagraphByIndex(i);
127         paraStart = run.getStart();
128         paraLimit = run.getLimit();
129         if ((paraStart != paraBounds[i]) ||
130             (paraLimit != paraBounds[i + 1])) {
131             errln("2nd Found boundaries of paragraph " + i + ": " +
132                   paraStart + "-" + paraLimit + "; expected: " +
133                   paraBounds[i] + "-" + paraBounds[i + 1]);
134         }
135
136         /* check paraLevel for all paragraphs under various paraLevel specs */
137         for (k = 0; k < 6; k++) {
138             try {
139                 bidi.setPara(src, paraLevels[k], null);
140             } catch (IllegalArgumentException e) {
141                 errln("3nd Bidi.setPara failed, paraLevel = " + paraLevels[k]);
142             }
143             for (i = 0; i < paraCount; i++) {
144                 paraIndex = bidi.getParagraphIndex(paraBounds[i]);
145                 run = bidi.getParagraph(paraBounds[i]);
146                 if (paraIndex != i) {
147                     errln("#1 For paraLevel = " + paraLevels[k] +
148                           " paragraph = " + i + ", found paragraph" +
149                           " index = " + paraIndex + " expected = " + i);
150                 }
151                 gotLevel = run.getEmbeddingLevel();
152                 if (gotLevel != multiLevels[k][i]) {
153                     errln("#2 For paraLevel = " + paraLevels[k] +
154                           " paragraph = " + i + ", found level = " + gotLevel +
155                           ", expected = " + multiLevels[k][i]);
156                 }
157             }
158             gotLevel = bidi.getParaLevel();
159             if (gotLevel != multiLevels[k][0]) {
160                 errln("#3 For paraLevel = " + paraLevels[k] +
161                       " getParaLevel = " + gotLevel + ", expected " +
162                       multiLevels[k][0]);
163             }
164         }
165
166         /* check that the result of Bidi.getParaLevel changes if the first
167          * paragraph has a different level
168          */
169         chars[0] = '\u05d2';            /* Hebrew letter Gimel */
170         src = new String(chars);
171         try {
172             bidi.setPara(src, Bidi.LEVEL_DEFAULT_LTR, null);
173         } catch (IllegalArgumentException e) {
174             errln("Bidi.setPara failed, paraLevel = " + Bidi.LEVEL_DEFAULT_LTR);
175         }
176         gotLevel = bidi.getParaLevel();
177         if (gotLevel != Bidi.RTL) {
178             errln("#4 For paraLevel = Bidi.LEVEL_DEFAULT_LTR getParaLevel = " +
179                   gotLevel + ", expected = " + Bidi.RTL);
180         }
181
182         /* check that line cannot overlap paragraph boundaries */
183         bidiLine = new Bidi();
184         i = paraBounds[1];
185         k = paraBounds[2] + 1;
186         try {
187             bidiLine = bidi.setLine(i, k);
188             errln("For line limits " + i + "-" + k
189                     + " got success, while expected failure");
190         } catch (Exception e) {}
191
192         i = paraBounds[1];
193         k = paraBounds[2];
194         try {
195             bidiLine = bidi.setLine(i, k);
196         } catch (Exception e) {
197             errln("For line limits " + i + "-" + k + " got failure");
198         }
199
200         /* check level of block separator at end of paragraph when orderParagraphsLTR==FALSE */
201         try {
202             bidi.setPara(src, Bidi.RTL, null);
203         } catch (IllegalArgumentException e) {
204             errln("Bidi.setPara failed, paraLevel = " + Bidi.RTL);
205         }
206         /* get levels through para Bidi block */
207         try {
208             gotLevels = bidi.getLevels();
209         } catch (Exception e) {
210             errln("Error on Bidi.getLevels");
211             gotLevels = new byte[bidi.getLength()];
212             Arrays.fill(gotLevels, (byte)-1);
213         }
214         for (i = 26; i < 32; i++) {
215             if (gotLevels[i] != Bidi.RTL) {
216                 errln("For char " + i + "(0x" + Utility.hex(chars[i]) +
217                       "), level = " + gotLevels[i] + ", expected = " + Bidi.RTL);
218             }
219         }
220         /* get levels through para Line block */
221         i = paraBounds[1];
222         k = paraBounds[2];
223         try {
224             bidiLine = bidi.setLine(i, k);
225         } catch (Exception e) {
226             errln("For line limits " + i + "-" + k + " got failure");
227             return;
228         }
229         paraIndex = bidiLine.getParagraphIndex(i);
230         run = bidiLine.getParagraph(i);
231         try {
232             gotLevels = bidiLine.getLevels();
233         } catch (Exception e) {
234             errln("Error on bidiLine.getLevels");
235             gotLevels = new byte[bidiLine.getLength()];
236             Arrays.fill(gotLevels, (byte)-1);
237         }
238         length = bidiLine.getLength();
239         gotLevel = run.getEmbeddingLevel();
240         if ((gotLevel != Bidi.RTL) || (gotLevels[length - 1] != Bidi.RTL)) {
241             errln("For paragraph " + paraIndex + " with limits " +
242                   run.getStart() + "-" + run.getLimit() +
243                   ", paraLevel = " + gotLevel +
244                   "expected = " + Bidi.RTL +
245                   ", level of separator = " + gotLevels[length - 1] +
246                   " expected = " + Bidi.RTL);
247         }
248         orderParagraphsLTR = bidi.isOrderParagraphsLTR();
249         assertFalse("orderParagraphsLTR is true", orderParagraphsLTR);
250         bidi.orderParagraphsLTR(true);
251         orderParagraphsLTR = bidi.isOrderParagraphsLTR();
252         assertTrue("orderParagraphsLTR is false", orderParagraphsLTR);
253
254         /* check level of block separator at end of paragraph when orderParagraphsLTR==TRUE */
255         try {
256             bidi.setPara(src, Bidi.RTL, null);
257         } catch (IllegalArgumentException e) {
258             errln("Bidi.setPara failed, paraLevel = " + Bidi.RTL);
259         }
260         /* get levels through para Bidi block */
261         try {
262             gotLevels = bidi.getLevels();
263         } catch (Exception e) {
264             errln("Error on Bidi.getLevels");
265             gotLevels = new byte[bidi.getLength()];
266             Arrays.fill(gotLevels, (byte)-1);
267         }
268         for (i = 26; i < 32; i++) {
269             if (gotLevels[i] != 0) {
270                 errln("For char " + i + "(0x" + Utility.hex(chars[i]) +
271                       "), level = "+ gotLevels[i] + ", expected = 0");
272             }
273         }
274         /* get levels through para Line block */
275         i = paraBounds[1];
276         k = paraBounds[2];
277         paraStart = run.getStart();
278         paraLimit = run.getLimit();
279         try {
280             bidiLine = bidi.setLine(paraStart, paraLimit);
281         } catch (Exception e) {
282             errln("For line limits " + paraStart + "-" + paraLimit +
283                   " got failure");
284         }
285         paraIndex = bidiLine.getParagraphIndex(i);
286         run = bidiLine.getParagraph(i);
287         try {
288             gotLevels = bidiLine.getLevels();
289         } catch (Exception e) {
290             errln("Error on bidiLine.getLevels");
291             gotLevels = new byte[bidiLine.getLength()];
292             Arrays.fill(gotLevels, (byte)-1);
293         }
294         length = bidiLine.getLength();
295         gotLevel = run.getEmbeddingLevel();
296         if ((gotLevel != Bidi.RTL) || (gotLevels[length - 1] != 0)) {
297             err("\nFor paragraph " + paraIndex + " with limits " +
298                 run.getStart() + "-" + run.getLimit() +
299                 ", paraLevel = " + gotLevel + "expected = " + Bidi.RTL +
300                 ", level of separator = " + gotLevels[length - 1] +
301                 " expected = 0\nlevels = ");
302             for (count = 0; count < length; count++) {
303                 errcont(gotLevels[count] + "  ");
304             }
305             errcont("\n");
306         }
307
308         /* test that the concatenation of separate invocations of the bidi code
309          * on each individual paragraph in order matches the levels array that
310          * results from invoking bidi once over the entire multiparagraph tests
311          * (with orderParagraphsLTR false, of course)
312          */
313         src = text;                     /* restore original content */
314         bidi.orderParagraphsLTR(false);
315         try {
316             bidi.setPara(src, Bidi.LEVEL_DEFAULT_RTL, null);
317         } catch (IllegalArgumentException e) {
318             errln("Bidi.setPara failed, paraLevel = " + Bidi.LEVEL_DEFAULT_RTL);
319         }
320         try {
321             gotLevels = bidi.getLevels();
322         } catch (Exception e) {
323             errln("Error on bidiLine.getLevels");
324             gotLevels = new byte[bidi.getLength()];
325             Arrays.fill(gotLevels, (byte)-1);
326         }
327         for (i = 0; i < paraCount; i++) {
328             /* use pLine for individual paragraphs */
329             paraStart = paraBounds[i];
330             length = paraBounds[i + 1] - paraStart;
331             try {
332                 bidiLine.setPara(src.substring(paraStart, paraStart + length),
333                                  Bidi.LEVEL_DEFAULT_RTL, null);
334             } catch (IllegalArgumentException e) {
335                 errln("Bidi.setPara failed, paraLevel = " + Bidi.LEVEL_DEFAULT_RTL);
336             }
337             for (j = 0; j < length; j++) {
338                 if ((k = bidiLine.getLevelAt(j)) !=
339                         (gotLevel = gotLevels[paraStart + j])) {
340                     errln("Checking paragraph concatenation: for paragraph[" +
341                           i + "], char[" + j + "] = 0x" +
342                           Utility.hex(src.charAt(paraStart + j)) +
343                           ", level = " + k + ", expected = " + gotLevel);
344                 }
345             }
346         }
347
348         /* ensure that leading numerics in a paragraph are not treated as arabic
349            numerals because of arabic text in a preceding paragraph
350          */
351         src = text2;
352         bidi.orderParagraphsLTR(true);
353         try {
354             bidi.setPara(src, Bidi.RTL, null);
355         } catch (IllegalArgumentException e) {
356             errln("Bidi.setPara failed, paraLevel = " + Bidi.RTL);
357         }
358         try {
359             gotLevels = bidi.getLevels();
360         } catch (Exception e) {
361             errln("Error on Bidi.getLevels");
362             gotLevels = new byte[bidi.getLength()];
363             Arrays.fill(gotLevels, (byte)-1);
364         }
365         for (i = 0, length = src.length(); i < length; i++) {
366             if (gotLevels[i] != levels2[i]) {
367                 errln("Checking leading numerics: for char " + i + "(0x" +
368                       Utility.hex(src.charAt(i)) + "), level = " +
369                       gotLevels[i] + ", expected = " + levels2[i]);
370             }
371         }
372
373         /* check handling of whitespace before end of paragraph separator when
374          * orderParagraphsLTR==TRUE, when last paragraph has, and lacks, a terminating B
375          */
376         chars = src.toCharArray();
377         Arrays.fill(chars, '\u0020');
378         bidi.orderParagraphsLTR(true);
379         for (i = 0x001c; i <= 0x0020; i += (0x0020-0x001c)) {
380             chars[4] = (char)i;         /* with and without terminating B */
381             for (j = 0x0041; j <= 0x05d0; j += (0x05d0-0x0041)) {
382                 chars[0] = (char)j;     /* leading 'A' or Alef */
383                 src = new String(chars);
384                 for (gotLevel = 4; gotLevel <= 5; gotLevel++) {
385                     /* test even and odd paraLevel */
386                     try {
387                         bidi.setPara(src, gotLevel, null);
388                     } catch (IllegalArgumentException e) {
389                         errln("Bidi.setPara failed, paraLevel = " + gotLevel);
390                     }
391                     try {
392                         gotLevels = bidi.getLevels();
393                     } catch (Exception e) {
394                         errln("Error on Bidi.getLevels");
395                         gotLevels = new byte[bidi.getLength()];
396                         Arrays.fill(gotLevels, (byte)-1);
397                     }
398                     for (k = 1; k <= 3; k++) {
399                         if (gotLevels[k] != gotLevel) {
400                             errln("Checking trailing spaces for leading char 0x" +
401                                   Utility.hex(chars[0]) + ", last_char = " +
402                                   Utility.hex(chars[4]) + ", index = " + k +
403                                   "level = " + gotLevels[k] +
404                                   ", expected = " + gotLevel);
405                         }
406                     }
407                 }
408             }
409         }
410
411         /* check default orientation when inverse bidi and paragraph starts
412          * with LTR strong char and ends with RTL strong char, with and without
413          * a terminating B
414          */
415         bidi.setReorderingMode(Bidi.REORDER_INVERSE_LIKE_DIRECT);
416         bidi.setPara("abc \u05d2\u05d1\n", Bidi.LEVEL_DEFAULT_LTR, null);
417         String out = bidi.writeReordered(0);
418         assertEquals("\nInvalid output", "\u05d1\u05d2 abc\n", out);
419         bidi.setPara("abc \u05d2\u05d1", Bidi.LEVEL_DEFAULT_LTR, null);
420         out = bidi.writeReordered(0);
421         assertEquals("\nInvalid output #1", "\u05d1\u05d2 abc", out);
422
423         /* check multiple paragraphs together with explicit levels
424          */
425         bidi.setReorderingMode(Bidi.REORDER_DEFAULT);
426         gotLevels = new byte[] {0,0,0,0,0,0,0,0,0,0};
427         bidi.setPara("ab\u05d1\u05d2\n\u05d3\u05d4123", Bidi.LTR, gotLevels);
428         out = bidi.writeReordered(0);
429         assertEquals("\nInvalid output #2", "ab\u05d2\u05d1\n123\u05d4\u05d3", out);
430         assertEquals("\nInvalid number of paras", 2, bidi.countParagraphs());
431
432         logln("\nExiting TestMultipleParagraphs\n");
433
434         /* check levels in multiple paragraphs with default para level
435          */
436         bidi = new Bidi();
437         bidi.setPara(multiparaTestString, Bidi.LEVEL_DEFAULT_LTR, null);
438         try {
439             gotLevels = bidi.getLevels();
440         } catch (Exception e) {
441             errln("Error on Bidi.getLevels for multiparaTestString");
442             return;
443         }
444         for (i = 0; i < multiparaTestString.length; i++) {
445             if (gotLevels[i] != multiparaTestLevels[i]) {
446                 errln("Error on level for multiparaTestString at index " + i +
447                       ", expected=" + multiparaTestLevels[i] +
448                       ", actual=" + gotLevels[i]);
449             }
450         }
451     }
452
453
454     public static void main(String[] args) {
455         try {
456             new TestMultipleParagraphs().run(args);
457         }
458         catch (Exception e) {
459             System.out.println(e);
460         }
461     }
462 }