xref: /trunk/test/testuno/source/api/i18n/XBreakIteratorTest.java (revision 2f709283d1bd576d3b419fe5eab3c9c4e094bc79)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 package api.i18n;
25 
26 import java.io.ByteArrayOutputStream;
27 import java.io.File;
28 import java.io.FileInputStream;
29 import java.io.IOException;
30 import java.util.ArrayList;
31 import java.util.Vector;
32 
33 import com.sun.star.beans.PropertyState;
34 import com.sun.star.beans.PropertyValue;
35 import com.sun.star.i18n.Boundary;
36 import com.sun.star.i18n.LineBreakHyphenationOptions;
37 import com.sun.star.i18n.LineBreakResults;
38 import com.sun.star.i18n.LineBreakUserOptions;
39 import com.sun.star.i18n.ScriptType;
40 import com.sun.star.i18n.WordType;
41 import com.sun.star.i18n.XBreakIterator;
42 import com.sun.star.lang.Locale;
43 import com.sun.star.lang.XComponent;
44 import com.sun.star.text.XTextDocument;
45 import com.sun.star.text.XTextRange;
46 import com.sun.star.uno.UnoRuntime;
47 import com.sun.star.uno.XComponentContext;
48 import org.junit.After;
49 import org.junit.AfterClass;
50 import org.junit.Before;
51 import org.junit.BeforeClass;
52 import org.junit.Assert;
53 import org.junit.Test;
54 import org.openoffice.test.common.Testspace;
55 import org.openoffice.test.uno.UnoApp;
56 
57 /**
58 * Testing <code>com.sun.star.i18n.XBreakIterator</code>
59 * interface methods :
60 * <ul>
61 *  <li><code> nextCharacters()</code></li>
62 *  <li><code> previousCharacters()</code></li>
63 *  <li><code> nextWord()</code></li>
64 *  <li><code> previousWord()</code></li>
65 *  <li><code> getWordBoundary()</code></li>
66 *  <li><code> getWordType()</code></li>
67 *  <li><code> isBeginWord()</code></li>
68 *  <li><code> isEndWord()</code></li>
69 *  <li><code> beginOfSentence()</code></li>
70 *  <li><code> endOfSentence()</code></li>
71 *  <li><code> getLineBreak()</code></li>
72 *  <li><code> beginOfScript()</code></li>
73 *  <li><code> endOfScript()</code></li>
74 *  <li><code> nextScript()</code></li>
75 *  <li><code> previousScript()</code></li>
76 *  <li><code> getScriptType()</code></li>
77 *  <li><code> beginOfCharBlock()</code></li>
78 *  <li><code> endOfCharBlock()</code></li>
79 *  <li><code> nextCharBlock()</code></li>
80 *  <li><code> previousCharBlock()</code></li>
81 * </ul> <p>
82 * This test needs the following object relations :
83 * <ul>
84 *  <li> <code>'Locale'</code>
85 *   (of type <code>com.sun.star.lang.Locale</code>):
86 *   this locale is used as locale argument for tested methods.
87 *  </li>
88 *  <li> <code>'UnicodeString'</code>
89 *   (of type <code>String</code>): Unicode string which is passed
90 *   to methods except 'CharacterBlock' methods.
91 *  </li>
92 * <ul> <p>
93 * @see com.sun.star.i18n.XBreakIterator
94 */
95 public class XBreakIteratorTest {
96     private static final UnoApp app = new UnoApp();
97     private static final String iteratorPath = "api/i18n/Iterator.sxw";
98     private static String UnicodeString;
99 
100     private XComponentContext xContext = null;
101     public XBreakIterator oObj = null;
102 
103     Locale locale = null;
104 
105     short wordType = WordType.ANYWORD_IGNOREWHITESPACES;
106 
107     // setup and close connections
108     @BeforeClass
109     public static void setUpConnection() throws Exception
110     {
111         app.start();
112         UnicodeString = readFileContents(iteratorPath);
113     }
114 
115     @AfterClass
116     public static void tearDownConnection() throws InterruptedException, com.sun.star.uno.Exception
117     {
118         app.close();
119     }
120 
121     /**
122      * Retrieves object relations.
123      * @throws StatusException If one of relations not found.
124      */
125     @Before
126     public void before() throws Exception {
127         xContext = app.getComponentContext();
128         oObj = UnoRuntime.queryInterface(
129             XBreakIterator.class,
130             xContext.getServiceManager().createInstanceWithContext("com.sun.star.i18n.BreakIterator", xContext)
131         );
132 
133         locale = new Locale("en", "US", "");
134     }
135 
136     private static String readFileContents(String path) throws Exception {
137         String sample = Testspace.prepareData(path);
138         PropertyValue[] properties = new PropertyValue[1];
139         properties[0] = new PropertyValue("Hidden", -1, true, PropertyState.DIRECT_VALUE);
140         XComponent docComponent = app.loadDocument(sample, properties);
141         XTextDocument textDocument = (XTextDocument) UnoRuntime.queryInterface(XTextDocument.class, docComponent);
142         XTextRange xTextRange = (XTextRange)textDocument.getText();
143         return xTextRange.getString();
144     }
145 
146     /**
147      * Compares returned next character positions with expected values. <p>
148      *
149      * Has <b>OK</b> status if position after travel and traveled length
150      * has expected values.
151      */
152     @Test
153     public void _nextCharacters() {
154         short nCharacterIteratorMode =
155             com.sun.star.i18n.CharacterIteratorMode.SKIPCHARACTER;
156 
157         int strLength = UnicodeString.length();
158 
159         //Start from position : Travel ... chars :
160         // Actual position after : How many chars traveled
161         int[][] nextCharacters = {
162             { 1, 5000, strLength , strLength - 1 },
163             { 10, 6, 16, 6}};
164 
165         boolean bRes = true;
166 
167         for(int i = 0; i < nextCharacters.length; i++) {
168             int[] lDone = new int[1];
169             long lRes = oObj.nextCharacters(UnicodeString, nextCharacters[i][0],
170                 locale, nCharacterIteratorMode, nextCharacters[i][1], lDone);
171             System.out.println("Expected result is: lRes = " + nextCharacters[i][2] +
172                         "; lDone = " + nextCharacters[i][3] );
173             System.out.println("Actual result is: lRes = " + lRes +
174                         "; lDone = " + lDone[0] );
175 
176             bRes = bRes && lRes == nextCharacters[i][2];
177             bRes = bRes && lDone[0] == nextCharacters[i][3];
178         }
179 
180         Assert.assertTrue("nextCharacters()", bRes);
181     }
182 
183     /**
184      * Compares returned previous character positions with expected values. <p>
185      *
186      * Has <b>OK</b> status if position after travel and traveled length
187      * has expected values.
188      */
189     @Test
190     public void _previousCharacters() {
191         short nCharacterIteratorMode =
192             com.sun.star.i18n.CharacterIteratorMode.SKIPCHARACTER;
193 
194 
195         //Start from position : Travel ... chars : Actual position after :
196         //How many chars traveled
197         int[][] previousCharacters = {
198             {5, 5000, 0, 5},
199             {10, 6, 4, 6}};
200 
201         boolean bRes = true;
202         for(int i = 0; i < previousCharacters.length; i++) {
203             int[] lDone = new int[1];
204             int lRes = oObj.previousCharacters(UnicodeString,
205                 previousCharacters[i][0],
206                 locale, nCharacterIteratorMode,
207                 previousCharacters[i][1], lDone);
208             System.out.println("Expected result is: lRes = " + previousCharacters[i][2]
209                 + "; lDone = " + previousCharacters[i][3] );
210             System.out.println("Actual result is: lRes = " + lRes
211                 + "; lDone = " + lDone[0]);
212 
213             bRes = bRes && lRes == previousCharacters[i][2];
214             bRes = bRes && lDone[0] == previousCharacters[i][3];
215         }
216 
217         Assert.assertTrue("previousCharacters()", bRes);
218     }
219 
220     /**
221     * Saves bounds of all returned words for the future tests. <p>
222     * Has <b>OK</b> status.
223     */
224     @Test
225     public void _nextWord() {
226         ArrayList<Boundary> vBounds = nextWord();
227         Assert.assertTrue("nextWord()", vBounds != null && vBounds.size() > 0);
228     }
229 
230     private ArrayList<Boundary> nextWord() {
231         int i = 0;
232         ArrayList<Boundary> vBounds = new ArrayList<>();
233         while( i < UnicodeString.length() - 1 ) {
234             Boundary bounds = oObj.nextWord
235                 (UnicodeString, i, locale, wordType);
236             if (bounds.endPos - bounds.startPos > 3) {
237                 vBounds.add( bounds );
238                 System.out.println("Word " + vBounds.size() + "("
239                     + bounds.startPos + "," + bounds.endPos + "): '" +
240                     UnicodeString.substring(bounds.startPos,
241                                             bounds.endPos) + "'");
242             }
243             i = bounds.endPos - 1;
244         }
245         System.out.println("In text there are " + vBounds.size()
246             + " words, if count from left to right");
247         return vBounds;
248     }
249 
250     /**
251     * Compares number of word bounds with number of word bounds saved
252     * by the method _nextWord().<p>
253     * Has <b>OK</b> status if number of word bounds are equal.
254     */
255     @Test
256     public void _previousWord() {
257         ArrayList<Boundary> vBounds = nextWord();
258 
259         int i = UnicodeString.length() - 1;
260         ArrayList<Boundary> vPrevBounds = new ArrayList<>();
261         while( i > 0  ) {
262             Boundary bounds =
263                 oObj.previousWord(UnicodeString, i, locale, wordType);
264             if (bounds.endPos - bounds.startPos > 3) {
265                 vPrevBounds.add( bounds );
266                 System.out.println("Word " + vPrevBounds.size() + "("
267                     + bounds.startPos + "," + bounds.endPos + "): '"
268                     + UnicodeString.substring(bounds.startPos, bounds.endPos)
269                     + "'");
270             }
271             i = bounds.startPos;
272         }
273         System.out.println("In text there are " + vPrevBounds.size()
274             + " words, if count from right to left");
275         Assert.assertTrue("previousWord()", vPrevBounds.size() == vBounds.size() );
276     }
277 
278     /**
279      * For every word in array obtained by <code>nextWord</code> method test
280      * computes bounds of the word, passing its internal character position.<p>
281      *
282      * Has <b>OK</b> status if bounds calculated by <code>getWordBoundary()</code>
283      * method are the same as bounds obtained by <code>nextWord</code> method.
284      */
285     @Test
286     public void _getWordBoundary() {
287         ArrayList<Boundary> vBounds = nextWord();
288 
289         boolean bRes = true;
290 
291         for(int i = 0; i < vBounds.size(); i++) {
292             // calculate middle of the word
293             Boundary iBounds = (Boundary)vBounds.get(i);
294             int iPos = (iBounds.endPos - iBounds.startPos) / 2
295                         + iBounds.startPos;
296             Boundary bounds = oObj.getWordBoundary(UnicodeString, iPos,
297                 locale, wordType, true);
298             System.out.println("Expected result is: startPos = " + iBounds.startPos +
299                                  "; endPos = " + iBounds.endPos);
300             System.out.println("Actual result is: startPos = " + bounds.startPos
301                 + "; endPos = " + bounds.endPos + " Word is: '"
302                 + UnicodeString.substring(bounds.startPos, bounds.endPos) + "'");
303 
304             bRes = bRes && iBounds.startPos == bounds.startPos;
305             bRes = bRes && iBounds.endPos == bounds.endPos;
306         }
307 
308         Assert.assertTrue("getWordBoundary()", bRes);
309     }
310 
311     /**
312      * For every word in array obtained by <code>nextWord</code> method test
313      * get its type, passing its internal character position.<p>
314      *
315      * Has <b>OK</b> status if every word has type <code>WordType.ANY_WORD</code>
316      */
317     @Test
318     public void _getWordType() {
319         ArrayList<Boundary> vBounds = nextWord();
320 
321         boolean bRes = true;
322 
323         for(int i = 0; i < vBounds.size(); i++) {
324             // calculate middle of the word
325             Boundary iBounds = (Boundary)vBounds.get(i);
326             int iPos = (iBounds.endPos - iBounds.startPos) / 2
327                         + iBounds.startPos;
328 
329             short type = oObj.getWordType(UnicodeString, iPos, locale);
330 
331             bRes = bRes && type == WordType.ANY_WORD;
332         }
333 
334         Assert.assertTrue("getWordType()", bRes);
335     }
336 
337     /**
338      * For every word in array obtained by <code>nextWord</code> method test
339      * tries to determine if the character at a position starts a word.
340      * First word starting position is passed, then internal character
341      * position is passed. <p>
342      * Has <b>OK</b> status if in the first case <code>true</code>
343      * returned and in the second - <code>false</code> for every word.
344      */
345     @Test
346     public void _isBeginWord() {
347         ArrayList<Boundary> vBounds = nextWord();
348 
349         boolean bRes = true;
350 
351         for(int i = 0; i < vBounds.size(); i++) {
352             Boundary iBounds = (Boundary)vBounds.get(i);
353             boolean isBegin = oObj.isBeginWord(UnicodeString, iBounds.startPos,
354                                                locale, WordType.ANY_WORD);
355             bRes = bRes && isBegin;
356             Assert.assertTrue("isBeginWord is wrong at position " + iBounds.startPos + ", string len " + UnicodeString.length(), isBegin);
357             boolean isNotBegin = !oObj.isBeginWord(UnicodeString,
358                     iBounds.startPos + 1, locale, WordType.ANY_WORD);
359             bRes = bRes && isNotBegin;
360             Assert.assertTrue("isBeginWord is wrong at position " + (iBounds.startPos + 1) + " for bounds (" + iBounds.startPos + "," + iBounds.endPos, isNotBegin);
361 
362             System.out.println("At position + " + iBounds.startPos
363                 + " isBeginWord? " + isBegin);
364             System.out.println("At position + " + (iBounds.startPos + 1)
365                 + " isBeginWord? " + !isNotBegin);
366         }
367 
368         Assert.assertTrue("isBeginWord()", bRes);
369     }
370 
371     /**
372      * For every word in array obtained by <code>nextWord</code> method test
373      * tries to determine if the character at a position ends a word.
374      * First word ending position is passed, then internal character
375      * position is passed. <p>
376      *
377      * Has <b>OK</b> status if in the first case <code>true</code>
378      * returned and in the second - <code>false</code> for every word.
379      */
380     @Test
381     public void _isEndWord() {
382         ArrayList<Boundary> vBounds = nextWord();
383 
384         boolean bRes = true;
385 
386         for(int i = 0; i < vBounds.size(); i++) {
387             Boundary iBounds = (Boundary)vBounds.get(i);
388             boolean isEnd = oObj.isEndWord(UnicodeString, iBounds.endPos,
389                 locale, WordType.ANY_WORD);
390             bRes = bRes && isEnd;
391             boolean isNotEnd = !oObj.isEndWord(UnicodeString,
392                 iBounds.endPos - 1, locale, WordType.ANY_WORD);
393             bRes = bRes && isNotEnd;
394 
395             System.out.println("At position + " + iBounds.endPos
396                 + " isEndWord? " + isEnd);
397             System.out.println("At position + " + (iBounds.endPos - 1)
398                 + " isEndWord? " + !isNotEnd);
399         }
400 
401         Assert.assertTrue("isEndWord()", bRes);
402     }
403 
404     Vector vSentenceStart = new Vector();
405     /**
406      * Tries to find all sentences starting positions passing every character
407      * as position parameter and stores them. Then tries to pass invalid
408      * position parameters.
409      *
410      * Has <b>OK</b> status if -1 is returned for wrong position arguments.
411      */
412     @Test
413     public void _beginOfSentence() {
414         int iPos = 0;
415         while( iPos < UnicodeString.length() ) {
416             Integer start = new Integer( oObj.beginOfSentence(UnicodeString,
417                 iPos, locale) );
418             if (start.intValue() >= 0 && !vSentenceStart.contains(start) ) {
419                 vSentenceStart.add( start );
420                 System.out.println("Sentence " + vSentenceStart.size()
421                     + " : start from position " + start);
422             }
423             iPos++;
424         }
425 
426         //test for invalid nStartPosition
427         boolean bRes = oObj.beginOfSentence(UnicodeString, -10, locale) == -1;
428         bRes &= oObj.beginOfSentence(UnicodeString,
429             UnicodeString.length() + 1, locale) == -1;
430 
431         if (!bRes) {
432             System.out.println("When invalid position, returned value isn't equal to -1");
433         }
434 
435         Assert.assertTrue("beginOfSentence()", bRes);
436     }
437 
438     /**
439      * For every sentence starting position found in
440      * <code>beginOfSentence()</code> test tries to compute end
441      * position of a sentence and checks that the end position is
442      * greater than starting.
443      * Then wrong position arguments are passed.
444      *
445      * Has <b>OK</b> status if the end position of every sentence
446      * greater than starting and -1 returned for invalid arguments.
447      */
448     @Test
449     public void _endOfSentence() {
450         boolean bRes = true;
451         for(int i = 0; i < vSentenceStart.size(); i++) {
452             int start = ((Integer)vSentenceStart.get(i)).intValue();
453             int end = oObj.endOfSentence(UnicodeString, start, locale);
454             bRes &= end > start;
455             System.out.println("Sentence " + i + " range is [" + start + ", "
456                 + end + "]");
457         }
458 
459         //test for invalid nStartPosition
460         boolean bInvRes = oObj.endOfSentence(UnicodeString, -10, locale) == -1;
461         bInvRes &= oObj.endOfSentence(UnicodeString,
462             UnicodeString.length() + 1, locale) == -1;
463 
464         if (!bInvRes) {
465             System.out.println("When invalid position, returned value isn't equal to -1");
466         }
467 
468         Assert.assertTrue("endOfSentence()", bRes && bInvRes);
469     }
470 
471     /**
472     * Tries to break a string in position other than 0 iterating characters
473     * from the string beginning (Hyphenation is not used for a while). <p>
474     *
475     * Has <b>OK</b> status if non-zero break position was found and it is
476     * less or equal than position we trying to break.
477     */
478     @Test
479     public void _getLineBreak() {
480         boolean bRes = true;
481         LineBreakResults lineBreakResults;
482         LineBreakHyphenationOptions lineBreakHyphenationOptions =
483             new LineBreakHyphenationOptions();
484         LineBreakUserOptions lineBreakUserOptions = new LineBreakUserOptions();
485 
486         lineBreakUserOptions.applyForbiddenRules = false;
487         lineBreakUserOptions.allowHyphenateEnglish = false;
488 
489         int breakPos = 0;
490         int pos = 0;
491 
492         while(breakPos == 0 && pos < UnicodeString.length() ) {
493             lineBreakResults = oObj.getLineBreak(UnicodeString, pos,
494                 locale, 0, lineBreakHyphenationOptions, lineBreakUserOptions);
495             breakPos = lineBreakResults.breakIndex;
496             pos++;
497         }
498 
499         // finally the position of break must be found in the middle and
500         // it must be before the break position specified
501         bRes = breakPos <= pos && breakPos > 0;
502 
503         if (!bRes) {
504             System.out.println("The last position was: " + pos
505                 + ", and the break position was: " + breakPos);
506         }
507 
508         Assert.assertTrue("getLineBreak()", bRes);
509     }
510 
511     // Asian type script
512     private static String katakana = new String(new char[] {0x30A1, 0x30A2}) ;
513     // Weak type script
514     private static String arrows = new String(new char[] {0x2190, 0x2191}) ;
515     // Complex type script
516     private static String arabic = new String(new char[] {0x0641, 0x0642}) ;
517 
518     /**
519     * Tries to find the beginning of the nearest script specified
520     * relatively to position passed. <p>
521     * Has <b>OK</b> status if the starting position of script is returned.
522     */
523     @Test
524     public void _beginOfScript() {
525         String multiScript = "ab" + katakana  ;
526 
527         int pos = oObj.beginOfScript(multiScript, 3, ScriptType.ASIAN) ;
528 
529         System.out.println("Position = " + pos) ;
530 
531         Assert.assertTrue("beginOfScript()", pos == 2) ;
532     }
533 
534     /**
535     * Tries to find the end of the nearest script specified
536     * relatively to position passed. <p>
537     * Has <b>OK</b> status if the end position of script is returned.
538     */
539     @Test
540     public void _endOfScript() {
541         String multiScript = "ab" + katakana + "cd" ;
542 
543         int pos = oObj.endOfScript(multiScript, 2, ScriptType.ASIAN) ;
544 
545         System.out.println("Position = " + pos) ;
546 
547         Assert.assertTrue("endOfScript()", pos == 4) ;
548     }
549 
550     /**
551     * Tries to find the next script starting position specified
552     * relatively to position passed. <p>
553     * Has <b>OK</b> status if the appropriate position is returned.
554     */
555     @Test
556     public void _nextScript() {
557         String multiScript = "ab" + katakana + "cd"  ;
558 
559         int pos = oObj.nextScript(multiScript, 0, ScriptType.LATIN) ;
560 
561         System.out.println("Position = " + pos) ;
562 
563         Assert.assertTrue("nextScript()", pos == 4) ;
564     }
565 
566     /**
567     * Tries to find the previous script starting position specified
568     * relatively to position passed. <p>
569     * Has <b>OK</b> status if the appropriate position is returned.
570     */
571     @Test
572     public void _previousScript() {
573         String multiScript = "ab" + katakana + "cd"  ;
574 
575         int pos = oObj.previousScript(multiScript, 5, ScriptType.ASIAN) ;
576 
577         System.out.println("Position = " + pos) ;
578 
579         Assert.assertTrue("previousScript()", pos == 2) ;
580     }
581 
582     /**
583     * Tries to determine script type (of all four types). <p>
584     * Has <b>OK</b> status if <code>LATIN</code> type returned
585     * for ACSII character, <code>ASIAN</code> for Katakana Unicode
586     * codepoints, <code>COMPLEX</code> for Arabic Unicode
587     * codepoints and <code>WEAK</code> for codepoints from Arrows
588     * Unicode block.
589     */
590     @Test
591     public void _getScriptType() {
592         boolean res = true ;
593 
594         res &= oObj.getScriptType("abcd", 0) == ScriptType.LATIN ;
595         res &= oObj.getScriptType(katakana, 0) == ScriptType.ASIAN;
596         res &= oObj.getScriptType(arabic, 0) == ScriptType.COMPLEX ;
597         res &= oObj.getScriptType(arrows, 0) == ScriptType.WEAK ;
598 
599         Assert.assertTrue("getScriptType()", res) ;
600     }
601 
602     protected short getCharBlockType(int pos) {
603         short i = 1;
604         short cType = 0;
605         while (i < 31) {
606             if (oObj.beginOfCharBlock(UnicodeString, pos, locale, i) != -1) {
607                 cType = i;
608                 i = 100;
609             }
610             i++;
611         }
612 
613         return cType;
614     }
615 
616     Vector vCharBlockBounds = new Vector();
617     Vector vCharBlockTypes = new Vector();
618 
619     /**
620      * Creates array of all char blocks with their boundaries and
621      * types using <code>beginOfCharBlock()</code> and
622      * <code>endOfCharBlock()</code> methods. <p>
623      *
624      * Has <b>OK</b> status if the end of each boundary is the same
625      * as start of the next one and if the start of the first block
626      * has position 0 and the end of the last block is at the end
627      * of the whole string.
628      */
629     @Test
630     public void _beginOfCharBlock() {
631         Assert.assertTrue("beginOfCharBlock()", beginOfCharBlock());
632     }
633 
634     private boolean beginOfCharBlock() {
635         boolean bCharBlockRes = true;
636         int iPos = 0;
637 
638         while( iPos < UnicodeString.length() && iPos > -1) {
639             short charType = getCharBlockType(iPos);
640             int startPos = oObj.beginOfCharBlock(UnicodeString, iPos,
641                 locale, charType);
642             int endPos = oObj.endOfCharBlock(UnicodeString, iPos,
643                 locale, charType);
644             iPos = endPos;
645             vCharBlockBounds.add(new Boundary(startPos, endPos));
646             System.out.println("" + vCharBlockBounds.size() + "). Bounds: ["
647                 + startPos + "," + endPos + "]; Type = " + charType);
648             vCharBlockTypes.add(new Short(charType));
649         }
650 
651         for(int i = 0; i < vCharBlockBounds.size() - 1; i++) {
652             int endPos = ((Boundary)vCharBlockBounds.get(i)).endPos;
653             int startPos = ((Boundary)vCharBlockBounds.get(i + 1)).startPos;
654             bCharBlockRes &= endPos == startPos;
655         }
656 
657         System.out.println("Testing for no intersections : " + bCharBlockRes);
658         int startPos = ((Boundary)vCharBlockBounds.get(0)).startPos;
659         bCharBlockRes &= startPos == 0;
660         int endPos = ((Boundary)vCharBlockBounds.get
661             (vCharBlockBounds.size() - 1)).endPos;
662         bCharBlockRes &= endPos == UnicodeString.length();
663         System.out.println("Regions should starts with 0 and ends with "
664             + UnicodeString.length());
665 
666         return bCharBlockRes;
667     }
668 
669     /**
670      * Testing of this method is performed in <code>beginOfCharBlock()</code>
671      * method test. <p>
672      *
673      * Has the status same as <code>beginOfCharBlock()</code> method status.
674      */
675     public void _endOfCharBlock() {
676         Assert.assertTrue("endOfCharBlock()", beginOfCharBlock());
677     }
678 
679     /**
680      * For every character block obtained in <code>beginOfCharBlock()</code>
681      * method test (except the first) tries to find its starting position
682      * by mean of <code>nextCharBlock()</code> method passing as position
683      * argument the position before the start of a block. <p>
684      *
685      * Has <b>OK</b> status if the start of every block was found and it's
686      * equal to this block boundary start.
687      */
688     public void _nextCharBlock() {
689         beginOfCharBlock();
690 
691         boolean bRes = true;
692         for(int i = 0; i < vCharBlockBounds.size(); i++) {
693             Boundary bounds = (Boundary)vCharBlockBounds.get(i);
694             Short type = (Short)vCharBlockTypes.get(i);
695             if (bounds.startPos - 1 < 0) continue;
696             int iPos = oObj.nextCharBlock(UnicodeString, bounds.startPos - 1,
697                 locale, type.shortValue());
698             if (iPos != bounds.startPos) {
699                 bRes = false;
700                 System.out.println("nextCharBlock(UnicodeString, "
701                     + (bounds.startPos - 1) + ", locale, " + type
702                     + ") should return " + bounds.startPos);
703                 System.out.println("... and actual value is " + iPos);
704             }
705         }
706 
707         Assert.assertTrue("nextCharBlock()", bRes);
708     }
709 
710     /**
711      * For every character block obtained in <code>beginOfCharBlock()</code>
712      * method test (except the first) tries to find its starting position
713      * by mean of <code>previousCharBlock()</code> method passing as position
714      * argument the position after the end of a block. <p>
715      *
716      * Has <b>OK</b> status if the start of every block was found and it's
717      * equal to this block boundary start.
718      */
719     public void _previousCharBlock() {
720         beginOfCharBlock();
721 
722         boolean bRes = true;
723         for(int i = 0; i < vCharBlockBounds.size(); i++) {
724             Boundary bounds = (Boundary)vCharBlockBounds.get(i);
725             Short type = (Short)vCharBlockTypes.get(i);
726             int iPos = oObj.previousCharBlock(UnicodeString,
727                 bounds.endPos + 1, locale, type.shortValue());
728             if (iPos != bounds.startPos) {
729                 bRes = false;
730                 System.out.println("previousCharBlock(UnicodeString, "
731                     + (bounds.endPos + 1) + ", locale, " + type
732                     + ") should return " + bounds.startPos);
733                 System.out.println("... and actual value is " + iPos);
734             }
735         }
736 
737         Assert.assertTrue("previousCharBlock()", bRes);
738     }
739 
740 }
741