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