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